Merge "Support min/max height for FloatingToolbar overflow." into mnc-dev
diff --git a/Android.mk b/Android.mk
index 264ad48..eb6e7b5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -280,8 +280,6 @@
core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
core/java/com/android/internal/backup/IBackupTransport.aidl \
core/java/com/android/internal/backup/IObbBackupService.aidl \
- core/java/com/android/internal/policy/IFaceLockCallback.aidl \
- core/java/com/android/internal/policy/IFaceLockInterface.aidl \
core/java/com/android/internal/policy/IKeyguardShowCallback.aidl \
core/java/com/android/internal/policy/IKeyguardExitCallback.aidl \
core/java/com/android/internal/policy/IKeyguardService.aidl \
@@ -519,10 +517,11 @@
frameworks/base/core/java/android/net/Uri.aidl \
frameworks/base/core/java/android/net/NetworkRequest.aidl \
frameworks/base/core/java/android/net/LinkAddress.aidl \
- frameworks/base/core/java/android/view/Surface.aidl \
- frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
+ frameworks/base/core/java/android/view/Display.aidl \
frameworks/base/core/java/android/view/InputDevice.aidl \
frameworks/base/core/java/android/view/InputEvent.aidl \
+ frameworks/base/core/java/android/view/Surface.aidl \
+ frameworks/base/core/java/android/view/WindowContentFrameStats.aidl \
frameworks/base/core/java/android/view/inputmethod/InputMethodSubtype.aidl \
frameworks/base/core/java/android/view/inputmethod/CursorAnchorInfo.aidl \
frameworks/base/core/java/android/view/inputmethod/CompletionInfo.aidl \
diff --git a/api/current.txt b/api/current.txt
index 9b7042a..a400fa6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20,10 +20,9 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
- field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
- field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
+ field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
+ field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
- field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
field public static final java.lang.String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
@@ -32,6 +31,7 @@
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
@@ -653,6 +653,7 @@
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
+ field public static final int hyphenationFrequency = 16844024; // 0x10104f8
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
field public static final int iconTint = 16843999; // 0x10104df
@@ -3571,7 +3572,6 @@
method public int getMemoryClass();
method public void getMemoryInfo(android.app.ActivityManager.MemoryInfo);
method public static void getMyMemoryState(android.app.ActivityManager.RunningAppProcessInfo);
- method public int getPackageImportance(java.lang.String);
method public android.os.Debug.MemoryInfo[] getProcessMemoryInfo(int[]);
method public java.util.List<android.app.ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
method public deprecated java.util.List<android.app.ActivityManager.RecentTaskInfo> getRecentTasks(int, int) throws java.lang.SecurityException;
@@ -3882,6 +3882,7 @@
field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
field public static final java.lang.String OPSTR_FINE_LOCATION = "android:fine_location";
field public static final java.lang.String OPSTR_GET_USAGE_STATS = "android:get_usage_stats";
+ field public static final java.lang.String OPSTR_MOCK_LOCATION = "android:mock_location";
field public static final java.lang.String OPSTR_MONITOR_HIGH_POWER_LOCATION = "android:monitor_location_high_power";
field public static final java.lang.String OPSTR_MONITOR_LOCATION = "android:monitor_location";
}
@@ -4780,6 +4781,8 @@
method public android.app.Notification clone();
method public int describeContents();
method public java.lang.String getGroup();
+ method public android.graphics.drawable.Icon getLargeIcon();
+ method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public void writeToParcel(android.os.Parcel, int);
@@ -4924,6 +4927,7 @@
ctor public Notification.BigPictureStyle();
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence);
@@ -4962,6 +4966,7 @@
method public android.app.Notification.Builder setGroup(java.lang.String);
method public android.app.Notification.Builder setGroupSummary(boolean);
method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method public android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setLocalOnly(boolean);
method public android.app.Notification.Builder setNumber(int);
@@ -4973,6 +4978,7 @@
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
+ method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon);
method public android.app.Notification.Builder setSortKey(java.lang.String);
method public android.app.Notification.Builder setSound(android.net.Uri);
method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int);
@@ -5627,7 +5633,7 @@
ctor public DeviceAdminReceiver();
method public android.app.admin.DevicePolicyManager getManager(android.content.Context);
method public android.content.ComponentName getWho(android.content.Context);
- method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, java.lang.String, int, java.lang.String, java.lang.String);
+ method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
method public void onDisabled(android.content.Context, android.content.Intent);
method public void onEnabled(android.content.Context, android.content.Intent);
@@ -5749,7 +5755,7 @@
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
- method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+ method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -6052,22 +6058,14 @@
field public static final android.os.Parcelable.Creator<android.app.usage.ConfigurationStats> CREATOR;
}
- public class NetworkStatsManager {
- method public android.app.usage.NetworkUsageStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- }
-
- public final class NetworkUsageStats implements java.lang.AutoCloseable {
+ public final class NetworkStats implements java.lang.AutoCloseable {
method public void close();
- method public boolean getNextBucket(android.app.usage.NetworkUsageStats.Bucket);
+ method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket);
method public boolean hasNextBucket();
}
- public static class NetworkUsageStats.Bucket {
- ctor public NetworkUsageStats.Bucket();
+ public static class NetworkStats.Bucket {
+ ctor public NetworkStats.Bucket();
method public long getEndTimeStamp();
method public long getRxBytes();
method public long getRxPackets();
@@ -6079,10 +6077,19 @@
field public static final int STATE_ALL = -1; // 0xffffffff
field public static final int STATE_DEFAULT = 1; // 0x1
field public static final int STATE_FOREGROUND = 2; // 0x2
+ field public static final int UID_ALL = -1; // 0xffffffff
field public static final int UID_REMOVED = -4; // 0xfffffffc
field public static final int UID_TETHERING = -5; // 0xfffffffb
}
+ public class NetworkStatsManager {
+ method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ }
+
public final class UsageEvents implements android.os.Parcelable {
method public int describeContents();
method public boolean getNextEvent(android.app.usage.UsageEvents.Event);
@@ -7759,7 +7766,7 @@
field public static final java.lang.String MIDI_SERVICE = "midi";
field public static final int MODE_APPEND = 32768; // 0x8000
field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
- field public static final int MODE_MULTI_PROCESS = 4; // 0x4
+ field public static final deprecated int MODE_MULTI_PROCESS = 4; // 0x4
field public static final int MODE_PRIVATE = 0; // 0x0
field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1
field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2
@@ -8918,7 +8925,6 @@
field public int descriptionRes;
field public boolean enabled;
field public int flags;
- field public int fullBackupContent;
field public boolean hardwareAccelerated;
field public int largestWidthLimitDp;
field public java.lang.String manageSpaceActivityName;
@@ -12403,11 +12409,12 @@
method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
- method public static android.graphics.drawable.Icon createWithResource(android.content.res.Resources, int);
+ method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
+ method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
method public int describeContents();
method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
method public void loadDrawableAsync(android.content.Context, android.os.Message);
- method public void loadDrawableAsync(android.content.Context, android.os.Handler, android.graphics.drawable.Icon.OnDrawableLoadedListener);
+ method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
}
@@ -13162,7 +13169,7 @@
method public abstract void close();
method public abstract android.hardware.camera2.CameraDevice getDevice();
method public abstract android.view.Surface getInputSurface();
- method public abstract boolean isReprocessible();
+ method public abstract boolean isReprocessable();
method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
@@ -13283,7 +13290,7 @@
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createReprocessibleCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -13462,7 +13469,7 @@
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
- field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
@@ -14684,12 +14691,19 @@
method public android.media.AudioAttributes.Builder setUsage(int);
}
+ public abstract class AudioDeviceCallback {
+ ctor public AudioDeviceCallback();
+ method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]);
+ method public void onAudioDevicesRemoved(android.media.AudioDeviceInfo[]);
+ }
+
public final class AudioDeviceInfo {
method public int[] getChannelCounts();
+ method public int[] getChannelIndexMasks();
method public int[] getChannelMasks();
- method public int[] getFormats();
+ method public int[] getEncodings();
method public int getId();
- method public java.lang.CharSequence getName();
+ method public java.lang.CharSequence getProductName();
method public int[] getSampleRates();
method public int getType();
method public boolean isSink();
@@ -14786,7 +14800,6 @@
public class AudioManager {
method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
- method public void addOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener, android.os.Handler);
method public void adjustStreamVolume(int, int, int);
method public void adjustSuggestedStreamVolume(int, int, int);
method public void adjustVolume(int, int);
@@ -14813,11 +14826,11 @@
method public void loadSoundEffects();
method public void playSoundEffect(int);
method public void playSoundEffect(int, float);
+ method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler);
method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
method public deprecated boolean registerRemoteController(android.media.RemoteController);
- method public void removeOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener);
method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
method public deprecated void setBluetoothA2dpOn(boolean);
method public void setBluetoothScoOn(boolean);
@@ -14836,6 +14849,7 @@
method public void startBluetoothSco();
method public void stopBluetoothSco();
method public void unloadSoundEffects();
+ method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
method public deprecated void unregisterRemoteControlClient(android.media.RemoteControlClient);
@@ -15220,7 +15234,6 @@
method public abstract android.media.Image.Plane[] getPlanes();
method public abstract long getTimestamp();
method public abstract int getWidth();
- method public boolean isOpaque();
method public void setCropRect(android.graphics.Rect);
method public void setTimestamp(long);
}
@@ -15240,9 +15253,7 @@
method public int getMaxImages();
method public android.view.Surface getSurface();
method public int getWidth();
- method public boolean isOpaque();
method public static android.media.ImageReader newInstance(int, int, int, int);
- method public static android.media.ImageReader newOpaqueInstance(int, int, int);
method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
}
@@ -15257,11 +15268,11 @@
method public int getMaxImages();
method public static android.media.ImageWriter newInstance(android.view.Surface, int);
method public void queueInputImage(android.media.Image);
- method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler);
+ method public void setOnImageReleasedListener(android.media.ImageWriter.OnImageReleasedListener, android.os.Handler);
}
- public static abstract interface ImageWriter.ImageListener {
- method public abstract void onInputImageReleased(android.media.ImageWriter);
+ public static abstract interface ImageWriter.OnImageReleasedListener {
+ method public abstract void onImageReleased(android.media.ImageWriter);
}
public class JetPlayer {
@@ -15332,14 +15343,14 @@
method public final void reset();
method public void setCallback(android.media.MediaCodec.Callback, android.os.Handler);
method public void setCallback(android.media.MediaCodec.Callback);
+ method public void setInputSurface(android.view.Surface);
method public void setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler);
+ method public void setOutputSurface(android.view.Surface);
method public final void setParameters(android.os.Bundle);
- method public void setSurface(android.view.Surface);
method public final void setVideoScalingMode(int);
method public final void signalEndOfInputStream();
method public final void start();
method public final void stop();
- method public void usePersistentInputSurface(android.view.Surface);
field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
@@ -15663,9 +15674,10 @@
ctor public MediaCryptoException(java.lang.String);
}
- public abstract interface MediaDataSource implements java.io.Closeable {
- method public abstract long getSize();
- method public abstract int readAt(long, byte[], int);
+ public abstract class MediaDataSource implements java.io.Closeable {
+ ctor public MediaDataSource();
+ method public abstract long getSize() throws java.io.IOException;
+ method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
}
public class MediaDescription implements android.os.Parcelable {
@@ -15718,7 +15730,7 @@
method public void restoreKeys(byte[], byte[]);
method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
- method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler);
+ method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
method public void setPropertyByteArray(java.lang.String, byte[]);
method public void setPropertyString(java.lang.String, java.lang.String);
field public static final int EVENT_KEY_EXPIRED = 3; // 0x3
@@ -15726,11 +15738,6 @@
field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
- field public static final int KEY_STATUS_EXPIRED = 1; // 0x1
- field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4
- field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
- field public static final int KEY_STATUS_PENDING = 3; // 0x3
- field public static final int KEY_STATUS_USABLE = 0; // 0x0
field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
field public static final int KEY_TYPE_RELEASE = 3; // 0x3
field public static final int KEY_TYPE_STREAMING = 1; // 0x1
@@ -15739,9 +15746,6 @@
field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
field public static final java.lang.String PROPERTY_VENDOR = "vendor";
field public static final java.lang.String PROPERTY_VERSION = "version";
- field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
- field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
- field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
}
public final class MediaDrm.CryptoSession {
@@ -15755,11 +15759,19 @@
method public byte[] getData();
method public java.lang.String getDefaultUrl();
method public int getRequestType();
+ field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
+ field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
+ field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
}
public static final class MediaDrm.KeyStatus {
method public byte[] getKeyId();
method public int getStatusCode();
+ field public static final int STATUS_EXPIRED = 1; // 0x1
+ field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4
+ field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
+ field public static final int STATUS_PENDING = 3; // 0x3
+ field public static final int STATUS_USABLE = 0; // 0x0
}
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -15774,8 +15786,8 @@
method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
}
- public static abstract interface MediaDrm.OnKeysChangeListener {
- method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
+ public static abstract interface MediaDrm.OnKeyStatusChangeListener {
+ method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
}
public static final class MediaDrm.ProvisionRequest {
@@ -16085,11 +16097,10 @@
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
- method public void setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener);
+ method public void setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataAvailableListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackParams(android.media.PlaybackParams);
- method public void setPlaybackRate(float, int);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setSyncParams(android.media.SyncParams);
@@ -16116,9 +16127,6 @@
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
- field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
- field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
@@ -16147,8 +16155,8 @@
method public abstract void onSeekComplete(android.media.MediaPlayer);
}
- public static abstract interface MediaPlayer.OnTimedMetaDataListener {
- method public abstract void onTimedMetaData(android.media.MediaPlayer, android.media.TimedMetaData);
+ public static abstract interface MediaPlayer.OnTimedMetaDataAvailableListener {
+ method public abstract void onTimedMetaDataAvailable(android.media.MediaPlayer, android.media.TimedMetaData);
}
public static abstract interface MediaPlayer.OnTimedTextListener {
@@ -16188,6 +16196,7 @@
method public void setAudioSource(int) throws java.lang.IllegalStateException;
method public deprecated void setCamera(android.hardware.Camera);
method public void setCaptureRate(double);
+ method public void setInputSurface(android.view.Surface);
method public void setLocation(float, float);
method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
@@ -16206,7 +16215,6 @@
method public void setVideoSource(int) throws java.lang.IllegalStateException;
method public void start() throws java.lang.IllegalStateException;
method public void stop() throws java.lang.IllegalStateException;
- method public void usePersistentSurface(android.view.Surface);
field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
field public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1; // 0x1
field public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800; // 0x320
@@ -16420,14 +16428,10 @@
method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler);
method public void setPlaybackParams(android.media.PlaybackParams);
- method public void setPlaybackRate(float, int);
method public void setSurface(android.view.Surface);
method public void setSyncParams(android.media.SyncParams);
field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1
field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
- field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
}
public static abstract class MediaSync.Callback {
@@ -16449,19 +16453,15 @@
}
public final class MediaTimestamp {
- field public final float clockRate;
- field public final long mediaTimeUs;
- field public final long nanoTime;
+ method public long getAnchorMediaTimeUs();
+ method public long getAnchorSytemNanoTime();
+ method public float getMediaClockRate();
}
public final class NotProvisionedException extends android.media.MediaDrmException {
ctor public NotProvisionedException(java.lang.String);
}
- public abstract interface OnAudioDeviceConnectionListener {
- method public abstract void onAudioDeviceConnection();
- }
-
public final class PlaybackParams {
ctor public PlaybackParams();
method public android.media.PlaybackParams allowDefaults();
@@ -16689,9 +16689,9 @@
field public static final int OPTIONS_RECYCLE_INPUT = 2; // 0x2
}
- public class TimedMetaData {
- method public byte[] getRawData();
- method public long getTimeUs();
+ public final class TimedMetaData {
+ method public byte[] getMetaData();
+ method public long getTimestamp();
}
public final class TimedText {
@@ -17259,7 +17259,7 @@
method public int getId();
method public int getInputPortCount();
method public int getOutputPortCount();
- method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList();
+ method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts();
method public android.os.Bundle getProperties();
method public int getType();
method public boolean isPrivate();
@@ -17307,22 +17307,17 @@
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
method public void close() throws java.io.IOException;
method public final int getPortNumber();
- method public void onReceive(byte[], int, int, long) throws java.io.IOException;
+ method public void onSend(byte[], int, int, long) throws java.io.IOException;
}
public final class MidiManager {
- method public android.media.midi.MidiDeviceInfo[] getDeviceList();
- method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler);
- method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler);
+ method public android.media.midi.MidiDeviceInfo[] getDevices();
+ method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
+ method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
}
- public static abstract class MidiManager.BluetoothOpenCallback {
- ctor public MidiManager.BluetoothOpenCallback();
- method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice);
- }
-
public static class MidiManager.DeviceCallback {
ctor public MidiManager.DeviceCallback();
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
@@ -17330,31 +17325,34 @@
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
}
- public static abstract class MidiManager.DeviceOpenCallback {
- ctor public MidiManager.DeviceOpenCallback();
- method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice);
+ public static abstract interface MidiManager.OnDeviceOpenedListener {
+ method public abstract void onDeviceOpened(android.media.midi.MidiDevice);
}
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
method public void close() throws java.io.IOException;
- method public void connect(android.media.midi.MidiReceiver);
- method public void disconnect(android.media.midi.MidiReceiver);
method public final int getPortNumber();
+ method public void onConnect(android.media.midi.MidiReceiver);
+ method public void onDisconnect(android.media.midi.MidiReceiver);
}
public abstract class MidiReceiver {
ctor public MidiReceiver();
+ ctor public MidiReceiver(int);
method public void flush() throws java.io.IOException;
- method public int getMaxMessageSize();
- method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException;
+ method public final int getMaxMessageSize();
+ method public void onFlush() throws java.io.IOException;
+ method public abstract void onSend(byte[], int, int, long) throws java.io.IOException;
method public void send(byte[], int, int) throws java.io.IOException;
- method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException;
+ method public void send(byte[], int, int, long) throws java.io.IOException;
}
public abstract class MidiSender {
ctor public MidiSender();
- method public abstract void connect(android.media.midi.MidiReceiver);
- method public abstract void disconnect(android.media.midi.MidiReceiver);
+ method public void connect(android.media.midi.MidiReceiver);
+ method public void disconnect(android.media.midi.MidiReceiver);
+ method public abstract void onConnect(android.media.midi.MidiReceiver);
+ method public abstract void onDisconnect(android.media.midi.MidiReceiver);
}
}
@@ -17853,7 +17851,7 @@
method public void onTimeShiftPause();
method public void onTimeShiftResume();
method public void onTimeShiftSeekTo(long);
- method public void onTimeShiftSetPlaybackRate(float, int);
+ method public void onTimeShiftSetPlaybackParams(android.media.PlaybackParams);
method public boolean onTouchEvent(android.view.MotionEvent);
method public boolean onTrackballEvent(android.view.MotionEvent);
method public abstract boolean onTune(android.net.Uri);
@@ -17865,7 +17863,7 @@
method public int describeContents();
method public final int getAudioChannelCount();
method public final int getAudioSampleRate();
- method public final java.lang.String getDescription();
+ method public final java.lang.CharSequence getDescription();
method public final android.os.Bundle getExtra();
method public final java.lang.String getId();
method public final java.lang.String getLanguage();
@@ -17886,7 +17884,7 @@
method public android.media.tv.TvTrackInfo build();
method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
- method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.String);
+ method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.CharSequence);
method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
@@ -17914,7 +17912,7 @@
method public void timeShiftPause();
method public void timeShiftResume();
method public void timeShiftSeekTo(long);
- method public void timeShiftSetPlaybackRate(float, int);
+ method public void timeShiftSetPlaybackParams(android.media.PlaybackParams);
method public void tune(java.lang.String, android.net.Uri);
}
@@ -18093,7 +18091,7 @@
method public void ignoreNetworkWithCaptivePortal(android.net.Network, java.lang.String);
method public boolean isActiveNetworkMetered();
method public boolean isDefaultNetworkActive();
- method public static boolean isNetworkTypeValid(int);
+ method public static deprecated boolean isNetworkTypeValid(int);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
@@ -26600,7 +26598,7 @@
field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
- field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
+ field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
field public static final java.lang.String ANDROID_ID = "android_id";
field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
field public static final deprecated java.lang.String BLUETOOTH_ON = "bluetooth_on";
@@ -27736,7 +27734,7 @@
method public final android.content.Context getApplicationContext();
method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
- method public static long getMinorID();
+ method public static long getMinorVersion();
method public static void releaseAllContexts();
method public void sendMessage(int, int[]);
method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
@@ -28310,6 +28308,9 @@
method public java.lang.String getKemKdfAlgorithm();
method public int getKemPointFormat();
field public static final android.security.EcIesParameterSpec DEFAULT;
+ field public static final int POINT_FORMAT_COMPRESSED = 1; // 0x1
+ field public static final int POINT_FORMAT_UNCOMPRESSED = 0; // 0x0
+ field public static final int POINT_FORMAT_UNSPECIFIED = -1; // 0xffffffff
}
public static class EcIesParameterSpec.Builder {
@@ -28323,19 +28324,10 @@
method public android.security.EcIesParameterSpec.Builder setKemPointFormat(int);
}
- public static abstract class EcIesParameterSpec.PointFormat {
- field public static final int COMPRESSED = 1; // 0x1
- field public static final int UNCOMPRESSED = 0; // 0x0
- field public static final int UNSPECIFIED = -1; // 0xffffffff
- }
-
- public static abstract class EcIesParameterSpec.PointFormatEnum implements java.lang.annotation.Annotation {
- }
-
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
- method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String, java.lang.String);
+ method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], android.net.Uri, java.lang.String);
method public static android.content.Intent createInstallIntent();
method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
@@ -28358,186 +28350,104 @@
ctor public KeyChainException(java.lang.Throwable);
}
+ public final deprecated class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+ method public android.content.Context getContext();
+ method public java.util.Date getEndDate();
+ method public int getKeySize();
+ method public java.lang.String getKeyType();
+ method public java.lang.String getKeystoreAlias();
+ method public java.math.BigInteger getSerialNumber();
+ method public java.util.Date getStartDate();
+ method public javax.security.auth.x500.X500Principal getSubjectDN();
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final deprecated class KeyPairGeneratorSpec.Builder {
+ ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
+ method public android.security.KeyPairGeneratorSpec build();
+ method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+ method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
+ method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
+ method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ }
+
+ public final deprecated class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ method public android.content.Context getContext();
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final deprecated class KeyStoreParameter.Builder {
+ ctor public KeyStoreParameter.Builder(android.content.Context);
+ method public android.security.KeyStoreParameter build();
+ method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
+ }
+
+ public class NetworkSecurityPolicy {
+ method public static android.security.NetworkSecurityPolicy getInstance();
+ method public boolean isCleartextTrafficPermitted();
+ }
+
+}
+
+package android.security.keystore {
+
public class KeyExpiredException extends java.security.InvalidKeyException {
ctor public KeyExpiredException();
ctor public KeyExpiredException(java.lang.String);
ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
}
- public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
- method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
- method public java.lang.String[] getEncryptionPaddings();
- method public int getKeySize();
- method public java.util.Date getKeyValidityForConsumptionEnd();
- method public java.util.Date getKeyValidityForOriginationEnd();
- method public java.util.Date getKeyValidityStart();
- method public java.lang.String getKeystoreAlias();
- method public int getPurposes();
- method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isEncryptionRequired();
- method public boolean isRandomizedEncryptionRequired();
- method public boolean isUserAuthenticationRequired();
- }
-
- public static class KeyGeneratorSpec.Builder {
- ctor public KeyGeneratorSpec.Builder(android.content.Context);
- method public android.security.KeyGeneratorSpec build();
- method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String);
- method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired();
- method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
- method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
- }
-
- public class KeyNotYetValidException extends java.security.InvalidKeyException {
- ctor public KeyNotYetValidException();
- ctor public KeyNotYetValidException(java.lang.String);
- ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
- }
-
- public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
+ method public java.util.Date getCertificateNotAfter();
+ method public java.util.Date getCertificateNotBefore();
+ method public java.math.BigInteger getCertificateSerialNumber();
+ method public javax.security.auth.x500.X500Principal getCertificateSubject();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
- method public java.util.Date getEndDate();
method public int getKeySize();
- method public java.lang.String getKeyType();
method public java.util.Date getKeyValidityForConsumptionEnd();
method public java.util.Date getKeyValidityForOriginationEnd();
method public java.util.Date getKeyValidityStart();
method public java.lang.String getKeystoreAlias();
method public int getPurposes();
- method public java.math.BigInteger getSerialNumber();
method public java.lang.String[] getSignaturePaddings();
- method public java.util.Date getStartDate();
- method public javax.security.auth.x500.X500Principal getSubjectDN();
method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isEncryptionRequired();
+ method public boolean isDigestsSpecified();
method public boolean isRandomizedEncryptionRequired();
method public boolean isUserAuthenticationRequired();
}
- public static final class KeyPairGeneratorSpec.Builder {
- ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
- method public android.security.KeyPairGeneratorSpec build();
- method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
- method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
- method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
- method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int);
- method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
- method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
- method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ public static final class KeyGenParameterSpec.Builder {
+ ctor public KeyGenParameterSpec.Builder(java.lang.String, int);
+ method public android.security.keystore.KeyGenParameterSpec build();
+ method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(java.math.BigInteger);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(javax.security.auth.x500.X500Principal);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeySize(int);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
}
- public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
- ctor public KeyPermanentlyInvalidatedException();
- ctor public KeyPermanentlyInvalidatedException(java.lang.String);
- ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
- }
-
- public abstract class KeyStoreKeyProperties {
- }
-
- public static abstract class KeyStoreKeyProperties.Algorithm {
- field public static final java.lang.String AES = "AES";
- field public static final java.lang.String EC = "EC";
- field public static final java.lang.String HMAC_SHA1 = "HmacSHA1";
- field public static final java.lang.String HMAC_SHA224 = "HmacSHA224";
- field public static final java.lang.String HMAC_SHA256 = "HmacSHA256";
- field public static final java.lang.String HMAC_SHA384 = "HmacSHA384";
- field public static final java.lang.String HMAC_SHA512 = "HmacSHA512";
- field public static final java.lang.String RSA = "RSA";
- }
-
- public static abstract class KeyStoreKeyProperties.AlgorithmEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.BlockMode {
- field public static final java.lang.String CBC = "CBC";
- field public static final java.lang.String CTR = "CTR";
- field public static final java.lang.String ECB = "ECB";
- field public static final java.lang.String GCM = "GCM";
- }
-
- public static abstract class KeyStoreKeyProperties.BlockModeEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Digest {
- field public static final java.lang.String MD5 = "MD5";
- field public static final java.lang.String NONE = "NONE";
- field public static final java.lang.String SHA1 = "SHA-1";
- field public static final java.lang.String SHA224 = "SHA-224";
- field public static final java.lang.String SHA256 = "SHA-256";
- field public static final java.lang.String SHA384 = "SHA-384";
- field public static final java.lang.String SHA512 = "SHA-512";
- }
-
- public static abstract class KeyStoreKeyProperties.DigestEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.EncryptionPadding {
- field public static final java.lang.String NONE = "NoPadding";
- field public static final java.lang.String PKCS7 = "PKCS7Padding";
- field public static final java.lang.String RSA_OAEP = "OAEPPadding";
- field public static final java.lang.String RSA_PKCS1 = "PKCS1Padding";
- }
-
- public static abstract class KeyStoreKeyProperties.EncryptionPaddingEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Origin {
- field public static final int GENERATED = 1; // 0x1
- field public static final int IMPORTED = 2; // 0x2
- field public static final int UNKNOWN = 4; // 0x4
- }
-
- public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Purpose {
- field public static final int DECRYPT = 2; // 0x2
- field public static final int ENCRYPT = 1; // 0x1
- field public static final int SIGN = 4; // 0x4
- field public static final int VERIFY = 8; // 0x8
- }
-
- public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.SignaturePadding {
- field public static final java.lang.String RSA_PKCS1 = "PKCS1";
- field public static final java.lang.String RSA_PSS = "PSS";
- }
-
- public static abstract class KeyStoreKeyProperties.SignaturePaddingEnum implements java.lang.annotation.Annotation {
- }
-
- public class KeyStoreKeySpec implements java.security.spec.KeySpec {
+ public class KeyInfo implements java.security.spec.KeySpec {
method public java.lang.String[] getBlockModes();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
@@ -28555,9 +28465,55 @@
method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware();
}
- public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ public class KeyNotYetValidException extends java.security.InvalidKeyException {
+ ctor public KeyNotYetValidException();
+ ctor public KeyNotYetValidException(java.lang.String);
+ ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
+ }
+
+ public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
+ ctor public KeyPermanentlyInvalidatedException();
+ ctor public KeyPermanentlyInvalidatedException(java.lang.String);
+ ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
+ }
+
+ public abstract class KeyProperties {
+ field public static final java.lang.String BLOCK_MODE_CBC = "CBC";
+ field public static final java.lang.String BLOCK_MODE_CTR = "CTR";
+ field public static final java.lang.String BLOCK_MODE_ECB = "ECB";
+ field public static final java.lang.String BLOCK_MODE_GCM = "GCM";
+ field public static final java.lang.String DIGEST_MD5 = "MD5";
+ field public static final java.lang.String DIGEST_NONE = "NONE";
+ field public static final java.lang.String DIGEST_SHA1 = "SHA-1";
+ field public static final java.lang.String DIGEST_SHA224 = "SHA-224";
+ field public static final java.lang.String DIGEST_SHA256 = "SHA-256";
+ field public static final java.lang.String DIGEST_SHA384 = "SHA-384";
+ field public static final java.lang.String DIGEST_SHA512 = "SHA-512";
+ field public static final java.lang.String ENCRYPTION_PADDING_NONE = "NoPadding";
+ field public static final java.lang.String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
+ field public static final java.lang.String ENCRYPTION_PADDING_RSA_OAEP = "OAEPPadding";
+ field public static final java.lang.String ENCRYPTION_PADDING_RSA_PKCS1 = "PKCS1Padding";
+ field public static final java.lang.String KEY_ALGORITHM_AES = "AES";
+ field public static final java.lang.String KEY_ALGORITHM_EC = "EC";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA1 = "HmacSHA1";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA224 = "HmacSHA224";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA256 = "HmacSHA256";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA384 = "HmacSHA384";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA512 = "HmacSHA512";
+ field public static final java.lang.String KEY_ALGORITHM_RSA = "RSA";
+ field public static final int ORIGIN_GENERATED = 1; // 0x1
+ field public static final int ORIGIN_IMPORTED = 2; // 0x2
+ field public static final int ORIGIN_UNKNOWN = 4; // 0x4
+ field public static final int PURPOSE_DECRYPT = 2; // 0x2
+ field public static final int PURPOSE_ENCRYPT = 1; // 0x1
+ field public static final int PURPOSE_SIGN = 4; // 0x4
+ field public static final int PURPOSE_VERIFY = 8; // 0x8
+ field public static final java.lang.String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
+ field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS";
+ }
+
+ public final class KeyProtection implements java.security.KeyStore.ProtectionParameter {
method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
method public java.util.Date getKeyValidityForConsumptionEnd();
@@ -28567,32 +28523,24 @@
method public java.lang.String[] getSignaturePaddings();
method public int getUserAuthenticationValidityDurationSeconds();
method public boolean isDigestsSpecified();
- method public boolean isEncryptionRequired();
method public boolean isRandomizedEncryptionRequired();
method public boolean isUserAuthenticationRequired();
}
- public static final class KeyStoreParameter.Builder {
- ctor public KeyStoreParameter.Builder(android.content.Context);
- method public android.security.KeyStoreParameter build();
- method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setPurposes(int);
- method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
- }
-
- public class NetworkSecurityPolicy {
- method public static android.security.NetworkSecurityPolicy getInstance();
- method public boolean isCleartextTrafficPermitted();
+ public static final class KeyProtection.Builder {
+ ctor public KeyProtection.Builder(int);
+ method public android.security.keystore.KeyProtection build();
+ method public android.security.keystore.KeyProtection.Builder setBlockModes(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setDigests(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
+ method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
}
public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
@@ -28608,7 +28556,7 @@
public abstract class CarrierConfigService extends android.app.Service {
ctor public CarrierConfigService();
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
}
@@ -28682,10 +28630,10 @@
package android.service.chooser {
public final class ChooserTarget implements android.os.Parcelable {
- ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
- ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.IntentSender);
method public int describeContents();
- method public android.graphics.Bitmap getIcon();
+ method public android.graphics.drawable.Icon getIcon();
method public android.content.IntentSender getIntentSender();
method public float getScore();
method public java.lang.CharSequence getTitle();
@@ -29984,23 +29932,6 @@
package android.telecom {
- public final class AudioState implements android.os.Parcelable {
- ctor public AudioState(boolean, int, int);
- ctor public AudioState(android.telecom.AudioState);
- method public static java.lang.String audioRouteToString(int);
- method public int describeContents();
- method public int getRoute();
- method public int getSupportedRouteMask();
- method public boolean isMuted();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.telecom.AudioState> CREATOR;
- field public static final int ROUTE_BLUETOOTH = 2; // 0x2
- field public static final int ROUTE_EARPIECE = 1; // 0x1
- field public static final int ROUTE_SPEAKER = 8; // 0x8
- field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4
- field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
- }
-
public final class Call {
method public void answer(int);
method public void conference(android.telecom.Call);
@@ -30094,32 +30025,38 @@
field public static final int PROPERTY_WIFI = 8; // 0x8
}
- public final class CameraCapabilities implements android.os.Parcelable {
- ctor public CameraCapabilities(int, int);
+ public final class CallAudioState implements android.os.Parcelable {
+ ctor public CallAudioState(boolean, int, int);
+ method public static java.lang.String audioRouteToString(int);
method public int describeContents();
- method public int getHeight();
- method public int getWidth();
+ method public int getRoute();
+ method public int getSupportedRouteMask();
+ method public boolean isMuted();
method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.telecom.CameraCapabilities> CREATOR;
+ field public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR;
+ field public static final int ROUTE_BLUETOOTH = 2; // 0x2
+ field public static final int ROUTE_EARPIECE = 1; // 0x1
+ field public static final int ROUTE_SPEAKER = 8; // 0x8
+ field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4
+ field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
- public abstract class Conference implements android.telecom.Conferenceable {
+ public abstract class Conference extends android.telecom.Conferenceable {
ctor public Conference(android.telecom.PhoneAccountHandle);
method public final boolean addConnection(android.telecom.Connection);
method public final void destroy();
- method public final android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
- method public final long getConnectTimeMillis();
method public final int getConnectionCapabilities();
+ method public final long getConnectionTime();
method public final java.util.List<android.telecom.Connection> getConnections();
method public final android.telecom.DisconnectCause getDisconnectCause();
method public final android.telecom.PhoneAccountHandle getPhoneAccountHandle();
- method public android.telecom.Connection getPrimaryConnection();
method public final int getState();
method public final android.telecom.StatusHints getStatusHints();
method public android.telecom.Connection.VideoProvider getVideoProvider();
method public int getVideoState();
- method public void onAudioStateChanged(android.telecom.AudioState);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onConnectionAdded(android.telecom.Connection);
method public void onDisconnect();
method public void onHold();
@@ -30133,8 +30070,8 @@
method public final void removeConnection(android.telecom.Connection);
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
- method public void setConnectTimeMillis(long);
method public final void setConnectionCapabilities(int);
+ method public final void setConnectionTime(long);
method public final void setDisconnected(android.telecom.DisconnectCause);
method public final void setOnHold();
method public final void setStatusHints(android.telecom.StatusHints);
@@ -30143,10 +30080,10 @@
field public static final long CONNECT_TIME_NOT_SPECIFIED = 0L; // 0x0L
}
- public abstract interface Conferenceable {
+ public abstract class Conferenceable {
}
- public abstract class Connection implements android.telecom.Conferenceable {
+ public abstract class Connection extends android.telecom.Conferenceable {
ctor public Connection();
method public static java.lang.String capabilitiesToString(int);
method public static android.telecom.Connection createCanceledConnection();
@@ -30155,7 +30092,7 @@
method public final android.net.Uri getAddress();
method public final int getAddressPresentation();
method public final boolean getAudioModeIsVoip();
- method public final android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.lang.String getCallerDisplayName();
method public final int getCallerDisplayNamePresentation();
method public final android.telecom.Conference getConference();
@@ -30169,7 +30106,7 @@
method public void onAbort();
method public void onAnswer(int);
method public void onAnswer();
- method public void onAudioStateChanged(android.telecom.AudioState);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onDisconnect();
method public void onHold();
method public void onPlayDtmfTone(char);
@@ -30228,8 +30165,7 @@
public static abstract class Connection.VideoProvider {
ctor public Connection.VideoProvider();
- method public void changeCallDataUsage(long);
- method public void changeCameraCapabilities(android.telecom.CameraCapabilities);
+ method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
method public void changePeerDimensions(int, int);
method public void changeVideoQuality(int);
method public void handleCallSessionEvent(int);
@@ -30240,11 +30176,12 @@
method public abstract void onSetCamera(java.lang.String);
method public abstract void onSetDeviceOrientation(int);
method public abstract void onSetDisplaySurface(android.view.Surface);
- method public abstract void onSetPauseImage(java.lang.String);
+ method public abstract void onSetPauseImage(android.net.Uri);
method public abstract void onSetPreviewSurface(android.view.Surface);
method public abstract void onSetZoom(float);
method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
+ method public void setCallDataUsage(long);
field public static final int SESSION_EVENT_CAMERA_FAILURE = 5; // 0x5
field public static final int SESSION_EVENT_CAMERA_READY = 6; // 0x6
field public static final int SESSION_EVENT_RX_PAUSE = 1; // 0x1
@@ -30327,12 +30264,12 @@
public abstract class InCallService extends android.app.Service {
ctor public InCallService();
method public final boolean canAddCall();
- method public final android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.util.List<android.telecom.Call> getCalls();
- method public void onAudioStateChanged(android.telecom.AudioState);
method public android.os.IBinder onBind(android.content.Intent);
method public void onBringToForeground(boolean);
method public void onCallAdded(android.telecom.Call);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Call);
method public void onCanAddCallChanged(boolean);
method public final void setAudioRoute(int);
@@ -30351,7 +30288,7 @@
method public abstract void setCamera(java.lang.String);
method public abstract void setDeviceOrientation(int);
method public abstract void setDisplaySurface(android.view.Surface);
- method public abstract void setPauseImage(java.lang.String);
+ method public abstract void setPauseImage(android.net.Uri);
method public abstract void setPreviewSurface(android.view.Surface);
method public abstract void setZoom(float);
method public abstract void unregisterCallback(android.telecom.InCallService.VideoCall.Callback);
@@ -30361,25 +30298,21 @@
ctor public InCallService.VideoCall.Callback();
method public abstract void onCallDataUsageChanged(long);
method public abstract void onCallSessionEvent(int);
- method public abstract void onCameraCapabilitiesChanged(android.telecom.CameraCapabilities);
+ method public abstract void onCameraCapabilitiesChanged(android.telecom.VideoProfile.CameraCapabilities);
method public abstract void onPeerDimensionsChanged(int, int);
method public abstract void onSessionModifyRequestReceived(android.telecom.VideoProfile);
method public abstract void onSessionModifyResponseReceived(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
method public abstract void onVideoQualityChanged(int);
}
- public class PhoneAccount implements android.os.Parcelable {
+ public final class PhoneAccount implements android.os.Parcelable {
method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
- method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
method public int describeContents();
method public android.telecom.PhoneAccountHandle getAccountHandle();
method public android.net.Uri getAddress();
method public int getCapabilities();
method public int getHighlightColor();
- method public android.graphics.Bitmap getIconBitmap();
- method public java.lang.String getIconPackageName();
- method public int getIconResId();
- method public int getIconTint();
+ method public android.graphics.drawable.Icon getIcon();
method public java.lang.CharSequence getLabel();
method public java.lang.CharSequence getShortDescription();
method public android.net.Uri getSubscriptionAddress();
@@ -30395,7 +30328,6 @@
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
- field public static final int NO_ICON_TINT = 0; // 0x0
field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
field public static final java.lang.String SCHEME_SIP = "sip";
field public static final java.lang.String SCHEME_TEL = "tel";
@@ -30410,17 +30342,13 @@
method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setCapabilities(int);
method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon);
method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence);
method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>);
}
- public class PhoneAccountHandle implements android.os.Parcelable {
+ public final class PhoneAccountHandle implements android.os.Parcelable {
ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String);
ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String, android.os.UserHandle);
method public int describeContents();
@@ -30444,7 +30372,7 @@
method public final void registerCallback(android.telecom.RemoteConference.Callback);
method public final void registerCallback(android.telecom.RemoteConference.Callback, android.os.Handler);
method public void separate(android.telecom.RemoteConnection);
- method public void setAudioState(android.telecom.AudioState);
+ method public void setCallAudioState(android.telecom.CallAudioState);
method public void stopDtmfTone();
method public void swap();
method public void unhold();
@@ -30484,7 +30412,7 @@
method public void registerCallback(android.telecom.RemoteConnection.Callback);
method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler);
method public void reject();
- method public void setAudioState(android.telecom.AudioState);
+ method public void setCallAudioState(android.telecom.CallAudioState);
method public void stopDtmfTone();
method public void unhold();
method public void unregisterCallback(android.telecom.RemoteConnection.Callback);
@@ -30508,13 +30436,11 @@
}
public final class StatusHints implements android.os.Parcelable {
- ctor public StatusHints(android.content.ComponentName, java.lang.CharSequence, int, android.os.Bundle);
+ ctor public StatusHints(java.lang.CharSequence, android.graphics.drawable.Icon, android.os.Bundle);
method public int describeContents();
method public android.os.Bundle getExtras();
- method public android.graphics.drawable.Drawable getIcon(android.content.Context);
- method public int getIconResId();
+ method public android.graphics.drawable.Icon getIcon();
method public java.lang.CharSequence getLabel();
- method public android.content.ComponentName getPackageName();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telecom.StatusHints> CREATOR;
}
@@ -30576,21 +30502,29 @@
field public static final int QUALITY_HIGH = 1; // 0x1
field public static final int QUALITY_LOW = 3; // 0x3
field public static final int QUALITY_MEDIUM = 2; // 0x2
+ field public static final int STATE_AUDIO_ONLY = 0; // 0x0
+ field public static final int STATE_BIDIRECTIONAL = 3; // 0x3
+ field public static final int STATE_PAUSED = 4; // 0x4
+ field public static final int STATE_RX_ENABLED = 2; // 0x2
+ field public static final int STATE_TX_ENABLED = 1; // 0x1
+ }
+
+ public static final class VideoProfile.CameraCapabilities implements android.os.Parcelable {
+ ctor public VideoProfile.CameraCapabilities(int, int);
+ method public int describeContents();
+ method public int getHeight();
+ method public int getWidth();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile.CameraCapabilities> CREATOR;
}
public static class VideoProfile.VideoState {
- ctor public VideoProfile.VideoState();
method public static boolean isAudioOnly(int);
method public static boolean isBidirectional(int);
method public static boolean isPaused(int);
method public static boolean isReceptionEnabled(int);
method public static boolean isTransmissionEnabled(int);
method public static java.lang.String videoStateToString(int);
- field public static final int AUDIO_ONLY = 0; // 0x0
- field public static final int BIDIRECTIONAL = 3; // 0x3
- field public static final int PAUSED = 4; // 0x4
- field public static final int RX_ENABLED = 2; // 0x2
- field public static final int TX_ENABLED = 1; // 0x1
}
}
@@ -30598,8 +30532,8 @@
package android.telephony {
public class CarrierConfigManager {
- method public android.os.Bundle getConfig();
- method public android.os.Bundle getConfigForSubId(int);
+ method public android.os.PersistableBundle getConfig();
+ method public android.os.PersistableBundle getConfigForSubId(int);
method public void reloadCarrierConfigForSubId(int);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
field public static final java.lang.String BOOL_ADDITIONAL_CALL_SETTING = "bool_additional_call_setting";
@@ -30620,7 +30554,7 @@
field public static final java.lang.String BOOL_OPERATOR_SELECTION_EXPAND = "bool_operator_selection_expand";
field public static final java.lang.String BOOL_PREFER_2G = "bool_prefer_2g";
field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
- field public static final java.lang.String BOOL_SHOW_CDMA = "bool_show_cdma";
+ field public static final java.lang.String BOOL_SHOW_CDMA_CHOICES = "bool_show_cdma_choices";
field public static final java.lang.String BOOL_SHOW_ONSCREEN_DIAL_BUTTON = "bool_show_onscreen_dial_button";
field public static final java.lang.String BOOL_SIM_NETWORK_UNLOCK_ALLOW_DISMISS = "bool_sim_network_unlock_allow_dismiss";
field public static final java.lang.String BOOL_SUPPORT_PAUSE_IMS_VIDEO_CALLS = "bool_support_pause_ims_video_calls";
@@ -32193,6 +32127,9 @@
field public static final int BREAK_STRATEGY_SIMPLE = 0; // 0x0
field public static final int DIR_LEFT_TO_RIGHT = 1; // 0x1
field public static final int DIR_RIGHT_TO_LEFT = -1; // 0xffffffff
+ field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
+ field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
+ field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
}
public static final class Layout.Alignment extends java.lang.Enum {
@@ -32391,6 +32328,7 @@
method public android.text.StaticLayout.Builder setBreakStrategy(int);
method public android.text.StaticLayout.Builder setEllipsize(android.text.TextUtils.TruncateAt);
method public android.text.StaticLayout.Builder setEllipsizedWidth(int);
+ method public android.text.StaticLayout.Builder setHyphenationFrequency(int);
method public android.text.StaticLayout.Builder setIncludePad(boolean);
method public android.text.StaticLayout.Builder setIndents(int[], int[]);
method public android.text.StaticLayout.Builder setLineSpacing(float, float);
@@ -34576,6 +34514,7 @@
method public int getFlags();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
+ method public android.view.Display.Mode getMode();
method public java.lang.String getName();
method public deprecated int getOrientation();
method public deprecated int getPixelFormat();
@@ -34587,7 +34526,8 @@
method public int getRotation();
method public void getSize(android.graphics.Point);
method public int getState();
- method public float[] getSupportedRefreshRates();
+ method public android.view.Display.Mode[] getSupportedModes();
+ method public deprecated float[] getSupportedRefreshRates();
method public deprecated int getWidth();
method public boolean isValid();
field public static final int DEFAULT_DISPLAY = 0; // 0x0
@@ -34602,6 +34542,16 @@
field public static final int STATE_UNKNOWN = 0; // 0x0
}
+ public static final class Display.Mode implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getModeId();
+ method public int getPhysicalHeight();
+ method public int getPhysicalWidth();
+ method public float getRefreshRate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
+ }
+
public class DragEvent implements android.os.Parcelable {
method public int describeContents();
method public int getAction();
@@ -35400,6 +35350,7 @@
method public static java.lang.String axisToString(int);
method public final int findPointerIndex(int);
method public final int getAction();
+ method public final int getActionButton();
method public final int getActionIndex();
method public final int getActionMasked();
method public final float getAxisValue(int);
@@ -35463,7 +35414,6 @@
method public final float getY(int);
method public final float getYPrecision();
method public final boolean isButtonPressed(int);
- method public final boolean isStylusButtonPressed();
method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
method public static deprecated android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -35479,6 +35429,8 @@
method public final void setSource(int);
method public final void transform(android.graphics.Matrix);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ACTION_BUTTON_PRESS = 11; // 0xb
+ field public static final int ACTION_BUTTON_RELEASE = 12; // 0xc
field public static final int ACTION_CANCEL = 3; // 0x3
field public static final int ACTION_DOWN = 0; // 0x0
field public static final int ACTION_HOVER_ENTER = 9; // 0x9
@@ -35547,6 +35499,8 @@
field public static final int BUTTON_FORWARD = 16; // 0x10
field public static final int BUTTON_PRIMARY = 1; // 0x1
field public static final int BUTTON_SECONDARY = 2; // 0x2
+ field public static final int BUTTON_STYLUS_PRIMARY = 32; // 0x20
+ field public static final int BUTTON_STYLUS_SECONDARY = 64; // 0x40
field public static final int BUTTON_TERTIARY = 4; // 0x4
field public static final android.os.Parcelable.Creator<android.view.MotionEvent> CREATOR;
field public static final int EDGE_BOTTOM = 2; // 0x2
@@ -36064,7 +36018,6 @@
method public boolean isSaveEnabled();
method public boolean isSaveFromParentEnabled();
method public boolean isScrollContainer();
- method public boolean isScrollIndicatorEnabled(int);
method public boolean isScrollbarFadingEnabled();
method public boolean isSelected();
method public boolean isShown();
@@ -37392,7 +37345,8 @@
field public float horizontalWeight;
field public deprecated int memoryType;
field public java.lang.String packageName;
- field public float preferredRefreshRate;
+ field public int preferredDisplayModeId;
+ field public deprecated float preferredRefreshRate;
field public int rotationAnimation;
field public float screenBrightness;
field public int screenOrientation;
@@ -38832,7 +38786,6 @@
}
public abstract class WebMessagePort {
- ctor public WebMessagePort();
method public abstract void close();
method public abstract void postMessage(android.webkit.WebMessage);
method public abstract void setWebMessageCallback(android.webkit.WebMessagePort.WebMessageCallback);
@@ -38845,8 +38798,7 @@
}
public abstract class WebResourceError {
- ctor public WebResourceError();
- method public abstract java.lang.String getDescription();
+ method public java.lang.CharSequence getDescription();
method public abstract int getErrorCode();
}
@@ -38876,12 +38828,6 @@
public abstract class WebResourceResponseBase {
ctor public WebResourceResponseBase();
- method public abstract java.io.InputStream getData();
- method public abstract java.lang.String getEncoding();
- method public abstract java.lang.String getMimeType();
- method public abstract java.lang.String getReasonPhrase();
- method public abstract java.util.Map<java.lang.String, java.lang.String> getResponseHeaders();
- method public abstract int getStatusCode();
}
public abstract class WebSettings {
@@ -39114,7 +39060,6 @@
method public void goBack();
method public void goBackOrForward(int);
method public void goForward();
- method public void insertVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
method public void invokeZoomPicker();
method public boolean isPrivateBrowsingEnabled();
method public void loadData(java.lang.String, java.lang.String, java.lang.String);
@@ -39131,8 +39076,9 @@
method public boolean pageDown(boolean);
method public boolean pageUp(boolean);
method public void pauseTimers();
- method public void postMessageToMainFrame(android.webkit.WebMessage, android.net.Uri);
method public void postUrl(java.lang.String, byte[]);
+ method public void postVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
+ method public void postWebMessage(android.webkit.WebMessage, android.net.Uri);
method public void reload();
method public void removeJavascriptInterface(java.lang.String);
method public void requestFocusNodeHref(android.os.Message);
@@ -39213,6 +39159,7 @@
method public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
method public void onReceivedHttpAuthRequest(android.webkit.WebView, android.webkit.HttpAuthHandler, java.lang.String, java.lang.String);
method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponseBase);
+ method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponse);
method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
method public void onScaleChanged(android.webkit.WebView, float, float);
@@ -40315,6 +40262,7 @@
method public void setImageAlpha(int);
method public void setImageBitmap(android.graphics.Bitmap);
method public void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setImageIcon(android.graphics.drawable.Icon);
method public void setImageLevel(int);
method public void setImageMatrix(android.graphics.Matrix);
method public void setImageResource(int);
@@ -40895,7 +40843,9 @@
method public void setDouble(int, java.lang.String, double);
method public void setEmptyView(int, int);
method public void setFloat(int, java.lang.String, float);
+ method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon);
method public void setImageViewBitmap(int, android.graphics.Bitmap);
+ method public void setImageViewIcon(int, android.graphics.drawable.Icon);
method public void setImageViewResource(int, int);
method public void setImageViewUri(int, android.net.Uri);
method public void setInt(int, java.lang.String, int);
@@ -41473,6 +41423,7 @@
method public int getHighlightColor();
method public java.lang.CharSequence getHint();
method public final android.content.res.ColorStateList getHintTextColors();
+ method public int getHyphenationFrequency();
method public int getImeActionId();
method public java.lang.CharSequence getImeActionLabel();
method public int getImeOptions();
@@ -41579,6 +41530,7 @@
method public final void setHintTextColor(int);
method public final void setHintTextColor(android.content.res.ColorStateList);
method public void setHorizontallyScrolling(boolean);
+ method public void setHyphenationFrequency(int);
method public void setImeActionLabel(java.lang.CharSequence, int);
method public void setImeOptions(int);
method public void setIncludeFontPadding(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 3f734ed..351ec8e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -28,11 +28,11 @@
field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
- field public static final java.lang.String BIND_CARRIER_CONFIG_SERVICE = "android.permission.BIND_CARRIER_CONFIG_SERVICE";
- field public static final java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
+ field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
+ field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
field public static final java.lang.String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
- field public static final java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
+ field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
@@ -43,6 +43,7 @@
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+ field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
@@ -725,6 +726,7 @@
field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
field public static final int horizontalSpacing = 16843028; // 0x1010114
field public static final int host = 16842792; // 0x1010028
+ field public static final int hyphenationFrequency = 16844024; // 0x10104f8
field public static final int icon = 16842754; // 0x1010002
field public static final int iconPreview = 16843337; // 0x1010249
field public static final int iconTint = 16843999; // 0x10104df
@@ -3974,6 +3976,7 @@
field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
field public static final java.lang.String OPSTR_FINE_LOCATION = "android:fine_location";
field public static final java.lang.String OPSTR_GET_USAGE_STATS = "android:get_usage_stats";
+ field public static final java.lang.String OPSTR_MOCK_LOCATION = "android:mock_location";
field public static final java.lang.String OPSTR_MONITOR_HIGH_POWER_LOCATION = "android:monitor_location_high_power";
field public static final java.lang.String OPSTR_MONITOR_LOCATION = "android:monitor_location";
}
@@ -4872,6 +4875,8 @@
method public android.app.Notification clone();
method public int describeContents();
method public java.lang.String getGroup();
+ method public android.graphics.drawable.Icon getLargeIcon();
+ method public android.graphics.drawable.Icon getSmallIcon();
method public java.lang.String getSortKey();
method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
method public void writeToParcel(android.os.Parcel, int);
@@ -5016,6 +5021,7 @@
ctor public Notification.BigPictureStyle();
ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence);
@@ -5054,6 +5060,7 @@
method public android.app.Notification.Builder setGroup(java.lang.String);
method public android.app.Notification.Builder setGroupSummary(boolean);
method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
+ method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method public android.app.Notification.Builder setLights(int, int, int);
method public android.app.Notification.Builder setLocalOnly(boolean);
method public android.app.Notification.Builder setNumber(int);
@@ -5065,6 +5072,7 @@
method public android.app.Notification.Builder setShowWhen(boolean);
method public android.app.Notification.Builder setSmallIcon(int);
method public android.app.Notification.Builder setSmallIcon(int, int);
+ method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon);
method public android.app.Notification.Builder setSortKey(java.lang.String);
method public android.app.Notification.Builder setSound(android.net.Uri);
method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int);
@@ -5723,7 +5731,7 @@
ctor public DeviceAdminReceiver();
method public android.app.admin.DevicePolicyManager getManager(android.content.Context);
method public android.content.ComponentName getWho(android.content.Context);
- method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, java.lang.String, int, java.lang.String, java.lang.String);
+ method public java.lang.String onChoosePrivateKeyAlias(android.content.Context, android.content.Intent, int, android.net.Uri, java.lang.String);
method public java.lang.CharSequence onDisableRequested(android.content.Context, android.content.Intent);
method public void onDisabled(android.content.Context, android.content.Intent);
method public void onEnabled(android.content.Context, android.content.Intent);
@@ -5855,7 +5863,7 @@
method public void setCameraDisabled(android.content.ComponentName, boolean);
method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
- method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+ method public boolean setDeviceInitializer(android.content.ComponentName, android.content.ComponentName) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
method public void setKeyguardDisabledFeatures(android.content.ComponentName, int);
@@ -6241,22 +6249,14 @@
field public static final android.os.Parcelable.Creator<android.app.usage.ConfigurationStats> CREATOR;
}
- public class NetworkStatsManager {
- method public android.app.usage.NetworkUsageStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- method public android.app.usage.NetworkUsageStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
- }
-
- public final class NetworkUsageStats implements java.lang.AutoCloseable {
+ public final class NetworkStats implements java.lang.AutoCloseable {
method public void close();
- method public boolean getNextBucket(android.app.usage.NetworkUsageStats.Bucket);
+ method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket);
method public boolean hasNextBucket();
}
- public static class NetworkUsageStats.Bucket {
- ctor public NetworkUsageStats.Bucket();
+ public static class NetworkStats.Bucket {
+ ctor public NetworkStats.Bucket();
method public long getEndTimeStamp();
method public long getRxBytes();
method public long getRxPackets();
@@ -6268,10 +6268,19 @@
field public static final int STATE_ALL = -1; // 0xffffffff
field public static final int STATE_DEFAULT = 1; // 0x1
field public static final int STATE_FOREGROUND = 2; // 0x2
+ field public static final int UID_ALL = -1; // 0xffffffff
field public static final int UID_REMOVED = -4; // 0xfffffffc
field public static final int UID_TETHERING = -5; // 0xfffffffb
}
+ public class NetworkStatsManager {
+ method public android.app.usage.NetworkStats queryDetails(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats queryDetailsForUid(int, java.lang.String, long, long, int) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats querySummary(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ method public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, java.lang.String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
+ }
+
public final class UsageEvents implements android.os.Parcelable {
method public int describeContents();
method public boolean getNextEvent(android.app.usage.UsageEvents.Event);
@@ -7976,7 +7985,7 @@
field public static final java.lang.String MIDI_SERVICE = "midi";
field public static final int MODE_APPEND = 32768; // 0x8000
field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
- field public static final int MODE_MULTI_PROCESS = 4; // 0x4
+ field public static final deprecated int MODE_MULTI_PROCESS = 4; // 0x4
field public static final int MODE_PRIVATE = 0; // 0x0
field public static final deprecated int MODE_WORLD_READABLE = 1; // 0x1
field public static final deprecated int MODE_WORLD_WRITEABLE = 2; // 0x2
@@ -8358,6 +8367,7 @@
field public static final java.lang.String ACTION_MANAGE_APP_PERMISSIONS = "android.intent.action.MANAGE_APP_PERMISSIONS";
field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE";
field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
+ field public static final java.lang.String ACTION_MANAGE_PERMISSIONS = "android.intent.action.MANAGE_PERMISSIONS";
field public static final java.lang.String ACTION_MANAGE_PERMISSION_APPS = "android.intent.action.MANAGE_PERMISSION_APPS";
field public static final java.lang.String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
field public static final java.lang.String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";
@@ -9147,7 +9157,6 @@
field public int descriptionRes;
field public boolean enabled;
field public int flags;
- field public int fullBackupContent;
field public boolean hardwareAccelerated;
field public int largestWidthLimitDp;
field public java.lang.String manageSpaceActivityName;
@@ -9543,6 +9552,7 @@
method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int);
method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
method public abstract void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
+ method public abstract void verifyIntentFilter(int, int, java.util.List<java.lang.String>);
method public abstract void verifyPendingInstall(int, int);
field public static final java.lang.String ACTION_REQUEST_PERMISSIONS = "android.content.pm.action.REQUEST_PERMISSIONS";
field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
@@ -9630,6 +9640,7 @@
field public static final java.lang.String FEATURE_WIFI_DIRECT = "android.hardware.wifi.direct";
field public static final int FLAG_PERMISSION_POLICY_FIXED = 4; // 0x4
field public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 8; // 0x8
+ field public static final int FLAG_PERMISSION_SYSTEM_FIXED = 16; // 0x10
field public static final int FLAG_PERMISSION_USER_FIXED = 2; // 0x2
field public static final int FLAG_PERMISSION_USER_SET = 1; // 0x1
field public static final int GET_ACTIVITIES = 1; // 0x1
@@ -9667,6 +9678,7 @@
field public static final int INSTALL_FAILED_NO_SHARED_USER = -6; // 0xfffffffa
field public static final int INSTALL_FAILED_OLDER_SDK = -12; // 0xfffffff4
field public static final int INSTALL_FAILED_PACKAGE_CHANGED = -23; // 0xffffffe9
+ field public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26; // 0xffffffe6
field public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10; // 0xfffffff6
field public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8; // 0xfffffff8
field public static final int INSTALL_FAILED_TEST_ONLY = -15; // 0xfffffff1
@@ -9684,7 +9696,7 @@
field public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; // 0xffffff99
field public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; // 0xffffff9a
field public static final int INSTALL_SUCCEEDED = 1; // 0x1
- field public static final int MASK_PERMISSION_FLAGS = 15; // 0xf
+ field public static final int MASK_PERMISSION_FLAGS = 255; // 0xff
field public static final int MATCH_ALL = 131072; // 0x20000
field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L
@@ -12707,11 +12719,12 @@
method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
- method public static android.graphics.drawable.Icon createWithResource(android.content.res.Resources, int);
+ method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
+ method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
method public int describeContents();
method public android.graphics.drawable.Drawable loadDrawable(android.content.Context);
method public void loadDrawableAsync(android.content.Context, android.os.Message);
- method public void loadDrawableAsync(android.content.Context, android.os.Handler, android.graphics.drawable.Icon.OnDrawableLoadedListener);
+ method public void loadDrawableAsync(android.content.Context, android.graphics.drawable.Icon.OnDrawableLoadedListener, android.os.Handler);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.graphics.drawable.Icon> CREATOR;
}
@@ -13471,7 +13484,7 @@
method public abstract void close();
method public abstract android.hardware.camera2.CameraDevice getDevice();
method public abstract android.view.Surface getInputSurface();
- method public abstract boolean isReprocessible();
+ method public abstract boolean isReprocessable();
method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract int setRepeatingRequest(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
@@ -13592,7 +13605,7 @@
method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException;
method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException;
- method public abstract void createReprocessibleCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+ method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method public abstract java.lang.String getId();
field public static final int TEMPLATE_MANUAL = 6; // 0x6
field public static final int TEMPLATE_PREVIEW = 1; // 0x1
@@ -13771,7 +13784,7 @@
field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2
field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1
- field public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4; // 0x4
+ field public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4; // 0x4
field public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3; // 0x3
field public static final int REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS = 5; // 0x5
field public static final int REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING = 7; // 0x7
@@ -15892,12 +15905,19 @@
method public android.media.AudioAttributes.Builder setUsage(int);
}
+ public abstract class AudioDeviceCallback {
+ ctor public AudioDeviceCallback();
+ method public void onAudioDevicesAdded(android.media.AudioDeviceInfo[]);
+ method public void onAudioDevicesRemoved(android.media.AudioDeviceInfo[]);
+ }
+
public final class AudioDeviceInfo {
method public int[] getChannelCounts();
+ method public int[] getChannelIndexMasks();
method public int[] getChannelMasks();
- method public int[] getFormats();
+ method public int[] getEncodings();
method public int getId();
- method public java.lang.CharSequence getName();
+ method public java.lang.CharSequence getProductName();
method public int[] getSampleRates();
method public int getType();
method public boolean isSink();
@@ -16007,7 +16027,6 @@
public class AudioManager {
method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
- method public void addOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener, android.os.Handler);
method public void adjustStreamVolume(int, int, int);
method public void adjustSuggestedStreamVolume(int, int, int);
method public void adjustVolume(int, int);
@@ -16035,12 +16054,12 @@
method public void loadSoundEffects();
method public void playSoundEffect(int);
method public void playSoundEffect(int, float);
+ method public void registerAudioDeviceCallback(android.media.AudioDeviceCallback, android.os.Handler);
method public int registerAudioPolicy(android.media.audiopolicy.AudioPolicy);
method public deprecated void registerMediaButtonEventReceiver(android.content.ComponentName);
method public deprecated void registerMediaButtonEventReceiver(android.app.PendingIntent);
method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
method public deprecated boolean registerRemoteController(android.media.RemoteController);
- method public void removeOnAudioDeviceConnectionListener(android.media.OnAudioDeviceConnectionListener);
method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
@@ -16061,6 +16080,7 @@
method public void startBluetoothSco();
method public void stopBluetoothSco();
method public void unloadSoundEffects();
+ method public void unregisterAudioDeviceCallback(android.media.AudioDeviceCallback);
method public void unregisterAudioPolicyAsync(android.media.audiopolicy.AudioPolicy);
method public deprecated void unregisterMediaButtonEventReceiver(android.content.ComponentName);
method public deprecated void unregisterMediaButtonEventReceiver(android.app.PendingIntent);
@@ -16452,7 +16472,6 @@
method public abstract android.media.Image.Plane[] getPlanes();
method public abstract long getTimestamp();
method public abstract int getWidth();
- method public boolean isOpaque();
method public void setCropRect(android.graphics.Rect);
method public void setTimestamp(long);
}
@@ -16472,9 +16491,7 @@
method public int getMaxImages();
method public android.view.Surface getSurface();
method public int getWidth();
- method public boolean isOpaque();
method public static android.media.ImageReader newInstance(int, int, int, int);
- method public static android.media.ImageReader newOpaqueInstance(int, int, int);
method public void setOnImageAvailableListener(android.media.ImageReader.OnImageAvailableListener, android.os.Handler);
}
@@ -16489,11 +16506,11 @@
method public int getMaxImages();
method public static android.media.ImageWriter newInstance(android.view.Surface, int);
method public void queueInputImage(android.media.Image);
- method public void setImageListener(android.media.ImageWriter.ImageListener, android.os.Handler);
+ method public void setOnImageReleasedListener(android.media.ImageWriter.OnImageReleasedListener, android.os.Handler);
}
- public static abstract interface ImageWriter.ImageListener {
- method public abstract void onInputImageReleased(android.media.ImageWriter);
+ public static abstract interface ImageWriter.OnImageReleasedListener {
+ method public abstract void onImageReleased(android.media.ImageWriter);
}
public class JetPlayer {
@@ -16564,14 +16581,14 @@
method public final void reset();
method public void setCallback(android.media.MediaCodec.Callback, android.os.Handler);
method public void setCallback(android.media.MediaCodec.Callback);
+ method public void setInputSurface(android.view.Surface);
method public void setOnFrameRenderedListener(android.media.MediaCodec.OnFrameRenderedListener, android.os.Handler);
+ method public void setOutputSurface(android.view.Surface);
method public final void setParameters(android.os.Bundle);
- method public void setSurface(android.view.Surface);
method public final void setVideoScalingMode(int);
method public final void signalEndOfInputStream();
method public final void start();
method public final void stop();
- method public void usePersistentInputSurface(android.view.Surface);
field public static final int BUFFER_FLAG_CODEC_CONFIG = 2; // 0x2
field public static final int BUFFER_FLAG_END_OF_STREAM = 4; // 0x4
field public static final int BUFFER_FLAG_KEY_FRAME = 1; // 0x1
@@ -16895,9 +16912,10 @@
ctor public MediaCryptoException(java.lang.String);
}
- public abstract interface MediaDataSource implements java.io.Closeable {
- method public abstract long getSize();
- method public abstract int readAt(long, byte[], int);
+ public abstract class MediaDataSource implements java.io.Closeable {
+ ctor public MediaDataSource();
+ method public abstract long getSize() throws java.io.IOException;
+ method public abstract int readAt(long, byte[], int, int) throws java.io.IOException;
}
public class MediaDescription implements android.os.Parcelable {
@@ -16950,7 +16968,7 @@
method public void restoreKeys(byte[], byte[]);
method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
method public void setOnExpirationUpdateListener(android.media.MediaDrm.OnExpirationUpdateListener, android.os.Handler);
- method public void setOnKeysChangeListener(android.media.MediaDrm.OnKeysChangeListener, android.os.Handler);
+ method public void setOnKeyStatusChangeListener(android.media.MediaDrm.OnKeyStatusChangeListener, android.os.Handler);
method public void setPropertyByteArray(java.lang.String, byte[]);
method public void setPropertyString(java.lang.String, java.lang.String);
method public void unprovisionDevice();
@@ -16959,11 +16977,6 @@
field public static final deprecated int EVENT_PROVISION_REQUIRED = 1; // 0x1
field public static final int EVENT_SESSION_RECLAIMED = 5; // 0x5
field public static final int EVENT_VENDOR_DEFINED = 4; // 0x4
- field public static final int KEY_STATUS_EXPIRED = 1; // 0x1
- field public static final int KEY_STATUS_INTERNAL_ERROR = 4; // 0x4
- field public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
- field public static final int KEY_STATUS_PENDING = 3; // 0x3
- field public static final int KEY_STATUS_USABLE = 0; // 0x0
field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
field public static final int KEY_TYPE_RELEASE = 3; // 0x3
field public static final int KEY_TYPE_STREAMING = 1; // 0x1
@@ -16972,9 +16985,6 @@
field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
field public static final java.lang.String PROPERTY_VENDOR = "vendor";
field public static final java.lang.String PROPERTY_VERSION = "version";
- field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
- field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
- field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
}
public final class MediaDrm.CryptoSession {
@@ -16988,11 +16998,19 @@
method public byte[] getData();
method public java.lang.String getDefaultUrl();
method public int getRequestType();
+ field public static final int REQUEST_TYPE_INITIAL = 0; // 0x0
+ field public static final int REQUEST_TYPE_RELEASE = 2; // 0x2
+ field public static final int REQUEST_TYPE_RENEWAL = 1; // 0x1
}
public static final class MediaDrm.KeyStatus {
method public byte[] getKeyId();
method public int getStatusCode();
+ field public static final int STATUS_EXPIRED = 1; // 0x1
+ field public static final int STATUS_INTERNAL_ERROR = 4; // 0x4
+ field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
+ field public static final int STATUS_PENDING = 3; // 0x3
+ field public static final int STATUS_USABLE = 0; // 0x0
}
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -17007,8 +17025,8 @@
method public abstract void onExpirationUpdate(android.media.MediaDrm, byte[], long);
}
- public static abstract interface MediaDrm.OnKeysChangeListener {
- method public abstract void onKeysChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
+ public static abstract interface MediaDrm.OnKeyStatusChangeListener {
+ method public abstract void onKeyStatusChange(android.media.MediaDrm, byte[], java.util.List<android.media.MediaDrm.KeyStatus>, boolean);
}
public static final class MediaDrm.ProvisionRequest {
@@ -17318,11 +17336,10 @@
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
- method public void setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener);
+ method public void setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataAvailableListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackParams(android.media.PlaybackParams);
- method public void setPlaybackRate(float, int);
method public void setScreenOnWhilePlaying(boolean);
method public void setSurface(android.view.Surface);
method public void setSyncParams(android.media.SyncParams);
@@ -17349,9 +17366,6 @@
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
- field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
- field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1; // 0x1
field public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2; // 0x2
}
@@ -17380,8 +17394,8 @@
method public abstract void onSeekComplete(android.media.MediaPlayer);
}
- public static abstract interface MediaPlayer.OnTimedMetaDataListener {
- method public abstract void onTimedMetaData(android.media.MediaPlayer, android.media.TimedMetaData);
+ public static abstract interface MediaPlayer.OnTimedMetaDataAvailableListener {
+ method public abstract void onTimedMetaDataAvailable(android.media.MediaPlayer, android.media.TimedMetaData);
}
public static abstract interface MediaPlayer.OnTimedTextListener {
@@ -17421,6 +17435,7 @@
method public void setAudioSource(int) throws java.lang.IllegalStateException;
method public deprecated void setCamera(android.hardware.Camera);
method public void setCaptureRate(double);
+ method public void setInputSurface(android.view.Surface);
method public void setLocation(float, float);
method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
@@ -17439,7 +17454,6 @@
method public void setVideoSource(int) throws java.lang.IllegalStateException;
method public void start() throws java.lang.IllegalStateException;
method public void stop() throws java.lang.IllegalStateException;
- method public void usePersistentSurface(android.view.Surface);
field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
field public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1; // 0x1
field public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800; // 0x320
@@ -17655,14 +17669,10 @@
method public void setCallback(android.media.MediaSync.Callback, android.os.Handler);
method public void setOnErrorListener(android.media.MediaSync.OnErrorListener, android.os.Handler);
method public void setPlaybackParams(android.media.PlaybackParams);
- method public void setPlaybackRate(float, int);
method public void setSurface(android.view.Surface);
method public void setSyncParams(android.media.SyncParams);
field public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1; // 0x1
field public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0; // 0x0
- field public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2; // 0x2
- field public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1; // 0x1
}
public static abstract class MediaSync.Callback {
@@ -17684,19 +17694,15 @@
}
public final class MediaTimestamp {
- field public final float clockRate;
- field public final long mediaTimeUs;
- field public final long nanoTime;
+ method public long getAnchorMediaTimeUs();
+ method public long getAnchorSytemNanoTime();
+ method public float getMediaClockRate();
}
public final class NotProvisionedException extends android.media.MediaDrmException {
ctor public NotProvisionedException(java.lang.String);
}
- public abstract interface OnAudioDeviceConnectionListener {
- method public abstract void onAudioDeviceConnection();
- }
-
public final class PlaybackParams {
ctor public PlaybackParams();
method public android.media.PlaybackParams allowDefaults();
@@ -17924,9 +17930,9 @@
field public static final int OPTIONS_RECYCLE_INPUT = 2; // 0x2
}
- public class TimedMetaData {
- method public byte[] getRawData();
- method public long getTimeUs();
+ public final class TimedMetaData {
+ method public byte[] getMetaData();
+ method public long getTimestamp();
}
public final class TimedText {
@@ -18562,7 +18568,7 @@
method public int getId();
method public int getInputPortCount();
method public int getOutputPortCount();
- method public android.media.midi.MidiDeviceInfo.PortInfo[] getPortList();
+ method public android.media.midi.MidiDeviceInfo.PortInfo[] getPorts();
method public android.os.Bundle getProperties();
method public int getType();
method public boolean isPrivate();
@@ -18610,22 +18616,17 @@
public final class MidiInputPort extends android.media.midi.MidiReceiver implements java.io.Closeable {
method public void close() throws java.io.IOException;
method public final int getPortNumber();
- method public void onReceive(byte[], int, int, long) throws java.io.IOException;
+ method public void onSend(byte[], int, int, long) throws java.io.IOException;
}
public final class MidiManager {
- method public android.media.midi.MidiDeviceInfo[] getDeviceList();
- method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.BluetoothOpenCallback, android.os.Handler);
- method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.DeviceOpenCallback, android.os.Handler);
+ method public android.media.midi.MidiDeviceInfo[] getDevices();
+ method public void openBluetoothDevice(android.bluetooth.BluetoothDevice, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
+ method public void openDevice(android.media.midi.MidiDeviceInfo, android.media.midi.MidiManager.OnDeviceOpenedListener, android.os.Handler);
method public void registerDeviceCallback(android.media.midi.MidiManager.DeviceCallback, android.os.Handler);
method public void unregisterDeviceCallback(android.media.midi.MidiManager.DeviceCallback);
}
- public static abstract class MidiManager.BluetoothOpenCallback {
- ctor public MidiManager.BluetoothOpenCallback();
- method public abstract void onDeviceOpened(android.bluetooth.BluetoothDevice, android.media.midi.MidiDevice);
- }
-
public static class MidiManager.DeviceCallback {
ctor public MidiManager.DeviceCallback();
method public void onDeviceAdded(android.media.midi.MidiDeviceInfo);
@@ -18633,31 +18634,34 @@
method public void onDeviceStatusChanged(android.media.midi.MidiDeviceStatus);
}
- public static abstract class MidiManager.DeviceOpenCallback {
- ctor public MidiManager.DeviceOpenCallback();
- method public abstract void onDeviceOpened(android.media.midi.MidiDeviceInfo, android.media.midi.MidiDevice);
+ public static abstract interface MidiManager.OnDeviceOpenedListener {
+ method public abstract void onDeviceOpened(android.media.midi.MidiDevice);
}
public final class MidiOutputPort extends android.media.midi.MidiSender implements java.io.Closeable {
method public void close() throws java.io.IOException;
- method public void connect(android.media.midi.MidiReceiver);
- method public void disconnect(android.media.midi.MidiReceiver);
method public final int getPortNumber();
+ method public void onConnect(android.media.midi.MidiReceiver);
+ method public void onDisconnect(android.media.midi.MidiReceiver);
}
public abstract class MidiReceiver {
ctor public MidiReceiver();
+ ctor public MidiReceiver(int);
method public void flush() throws java.io.IOException;
- method public int getMaxMessageSize();
- method public abstract void onReceive(byte[], int, int, long) throws java.io.IOException;
+ method public final int getMaxMessageSize();
+ method public void onFlush() throws java.io.IOException;
+ method public abstract void onSend(byte[], int, int, long) throws java.io.IOException;
method public void send(byte[], int, int) throws java.io.IOException;
- method public void sendWithTimestamp(byte[], int, int, long) throws java.io.IOException;
+ method public void send(byte[], int, int, long) throws java.io.IOException;
}
public abstract class MidiSender {
ctor public MidiSender();
- method public abstract void connect(android.media.midi.MidiReceiver);
- method public abstract void disconnect(android.media.midi.MidiReceiver);
+ method public void connect(android.media.midi.MidiReceiver);
+ method public void disconnect(android.media.midi.MidiReceiver);
+ method public abstract void onConnect(android.media.midi.MidiReceiver);
+ method public abstract void onDisconnect(android.media.midi.MidiReceiver);
}
}
@@ -19298,7 +19302,7 @@
method public void onTimeShiftPause();
method public void onTimeShiftResume();
method public void onTimeShiftSeekTo(long);
- method public void onTimeShiftSetPlaybackRate(float, int);
+ method public void onTimeShiftSetPlaybackParams(android.media.PlaybackParams);
method public boolean onTouchEvent(android.view.MotionEvent);
method public boolean onTrackballEvent(android.view.MotionEvent);
method public abstract boolean onTune(android.net.Uri);
@@ -19334,7 +19338,7 @@
method public int describeContents();
method public final int getAudioChannelCount();
method public final int getAudioSampleRate();
- method public final java.lang.String getDescription();
+ method public final java.lang.CharSequence getDescription();
method public final android.os.Bundle getExtra();
method public final java.lang.String getId();
method public final java.lang.String getLanguage();
@@ -19355,7 +19359,7 @@
method public android.media.tv.TvTrackInfo build();
method public final android.media.tv.TvTrackInfo.Builder setAudioChannelCount(int);
method public final android.media.tv.TvTrackInfo.Builder setAudioSampleRate(int);
- method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.String);
+ method public final android.media.tv.TvTrackInfo.Builder setDescription(java.lang.CharSequence);
method public final android.media.tv.TvTrackInfo.Builder setExtra(android.os.Bundle);
method public final android.media.tv.TvTrackInfo.Builder setLanguage(java.lang.String);
method public final android.media.tv.TvTrackInfo.Builder setVideoFrameRate(float);
@@ -19388,7 +19392,7 @@
method public void timeShiftPause();
method public void timeShiftResume();
method public void timeShiftSeekTo(long);
- method public void timeShiftSetPlaybackRate(float, int);
+ method public void timeShiftSetPlaybackParams(android.media.PlaybackParams);
method public void tune(java.lang.String, android.net.Uri);
method public void tune(java.lang.String, android.net.Uri, android.os.Bundle);
method public void unblockContent(android.media.tv.TvContentRating);
@@ -19570,7 +19574,7 @@
method public void ignoreNetworkWithCaptivePortal(android.net.Network, java.lang.String);
method public boolean isActiveNetworkMetered();
method public boolean isDefaultNetworkActive();
- method public static boolean isNetworkTypeValid(int);
+ method public static deprecated boolean isNetworkTypeValid(int);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
@@ -28623,7 +28627,7 @@
field public static final java.lang.String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
field public static final deprecated java.lang.String ADB_ENABLED = "adb_enabled";
field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
- field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
+ field public static final deprecated java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
field public static final java.lang.String ANDROID_ID = "android_id";
field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
field public static final deprecated java.lang.String BLUETOOTH_ON = "bluetooth_on";
@@ -29759,7 +29763,7 @@
method public final android.content.Context getApplicationContext();
method public android.renderscript.RenderScript.RSErrorHandler getErrorHandler();
method public android.renderscript.RenderScript.RSMessageHandler getMessageHandler();
- method public static long getMinorID();
+ method public static long getMinorVersion();
method public static void releaseAllContexts();
method public void sendMessage(int, int[]);
method public void setErrorHandler(android.renderscript.RenderScript.RSErrorHandler);
@@ -30333,6 +30337,9 @@
method public java.lang.String getKemKdfAlgorithm();
method public int getKemPointFormat();
field public static final android.security.EcIesParameterSpec DEFAULT;
+ field public static final int POINT_FORMAT_COMPRESSED = 1; // 0x1
+ field public static final int POINT_FORMAT_UNCOMPRESSED = 0; // 0x0
+ field public static final int POINT_FORMAT_UNSPECIFIED = -1; // 0xffffffff
}
public static class EcIesParameterSpec.Builder {
@@ -30346,19 +30353,10 @@
method public android.security.EcIesParameterSpec.Builder setKemPointFormat(int);
}
- public static abstract class EcIesParameterSpec.PointFormat {
- field public static final int COMPRESSED = 1; // 0x1
- field public static final int UNCOMPRESSED = 0; // 0x0
- field public static final int UNSPECIFIED = -1; // 0xffffffff
- }
-
- public static abstract class EcIesParameterSpec.PointFormatEnum implements java.lang.annotation.Annotation {
- }
-
public final class KeyChain {
ctor public KeyChain();
method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String);
- method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], java.lang.String, int, java.lang.String, java.lang.String);
+ method public static void choosePrivateKeyAlias(android.app.Activity, android.security.KeyChainAliasCallback, java.lang.String[], java.security.Principal[], android.net.Uri, java.lang.String);
method public static android.content.Intent createInstallIntent();
method public static java.security.cert.X509Certificate[] getCertificateChain(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
method public static java.security.PrivateKey getPrivateKey(android.content.Context, java.lang.String) throws java.lang.InterruptedException, android.security.KeyChainException;
@@ -30381,186 +30379,104 @@
ctor public KeyChainException(java.lang.Throwable);
}
+ public final deprecated class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
+ method public android.content.Context getContext();
+ method public java.util.Date getEndDate();
+ method public int getKeySize();
+ method public java.lang.String getKeyType();
+ method public java.lang.String getKeystoreAlias();
+ method public java.math.BigInteger getSerialNumber();
+ method public java.util.Date getStartDate();
+ method public javax.security.auth.x500.X500Principal getSubjectDN();
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final deprecated class KeyPairGeneratorSpec.Builder {
+ ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
+ method public android.security.KeyPairGeneratorSpec build();
+ method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+ method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
+ method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
+ method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
+ method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
+ method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
+ method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
+ method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
+ }
+
+ public final deprecated class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ method public android.content.Context getContext();
+ method public boolean isEncryptionRequired();
+ }
+
+ public static final deprecated class KeyStoreParameter.Builder {
+ ctor public KeyStoreParameter.Builder(android.content.Context);
+ method public android.security.KeyStoreParameter build();
+ method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
+ }
+
+ public class NetworkSecurityPolicy {
+ method public static android.security.NetworkSecurityPolicy getInstance();
+ method public boolean isCleartextTrafficPermitted();
+ }
+
+}
+
+package android.security.keystore {
+
public class KeyExpiredException extends java.security.InvalidKeyException {
ctor public KeyExpiredException();
ctor public KeyExpiredException(java.lang.String);
ctor public KeyExpiredException(java.lang.String, java.lang.Throwable);
}
- public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
- method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
- method public java.lang.String[] getEncryptionPaddings();
- method public int getKeySize();
- method public java.util.Date getKeyValidityForConsumptionEnd();
- method public java.util.Date getKeyValidityForOriginationEnd();
- method public java.util.Date getKeyValidityStart();
- method public java.lang.String getKeystoreAlias();
- method public int getPurposes();
- method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isEncryptionRequired();
- method public boolean isRandomizedEncryptionRequired();
- method public boolean isUserAuthenticationRequired();
- }
-
- public static class KeyGeneratorSpec.Builder {
- ctor public KeyGeneratorSpec.Builder(android.content.Context);
- method public android.security.KeyGeneratorSpec build();
- method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String);
- method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired();
- method public android.security.KeyGeneratorSpec.Builder setKeySize(int);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyGeneratorSpec.Builder setPurposes(int);
- method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
- }
-
- public class KeyNotYetValidException extends java.security.InvalidKeyException {
- ctor public KeyNotYetValidException();
- ctor public KeyNotYetValidException(java.lang.String);
- ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
- }
-
- public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec {
+ public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec();
method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
+ method public java.util.Date getCertificateNotAfter();
+ method public java.util.Date getCertificateNotBefore();
+ method public java.math.BigInteger getCertificateSerialNumber();
+ method public javax.security.auth.x500.X500Principal getCertificateSubject();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
- method public java.util.Date getEndDate();
method public int getKeySize();
- method public java.lang.String getKeyType();
method public java.util.Date getKeyValidityForConsumptionEnd();
method public java.util.Date getKeyValidityForOriginationEnd();
method public java.util.Date getKeyValidityStart();
method public java.lang.String getKeystoreAlias();
method public int getPurposes();
- method public java.math.BigInteger getSerialNumber();
method public java.lang.String[] getSignaturePaddings();
- method public java.util.Date getStartDate();
- method public javax.security.auth.x500.X500Principal getSubjectDN();
method public int getUserAuthenticationValidityDurationSeconds();
- method public boolean isEncryptionRequired();
+ method public boolean isDigestsSpecified();
method public boolean isRandomizedEncryptionRequired();
method public boolean isUserAuthenticationRequired();
}
- public static final class KeyPairGeneratorSpec.Builder {
- ctor public KeyPairGeneratorSpec.Builder(android.content.Context);
- method public android.security.KeyPairGeneratorSpec build();
- method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
- method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String);
- method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired();
- method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException;
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int);
- method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger);
- method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...);
- method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date);
- method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal);
- method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
+ public static final class KeyGenParameterSpec.Builder {
+ ctor public KeyGenParameterSpec.Builder(java.lang.String, int);
+ method public android.security.keystore.KeyGenParameterSpec build();
+ method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(java.math.BigInteger);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(javax.security.auth.x500.X500Principal);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeySize(int);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean);
+ method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int);
}
- public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
- ctor public KeyPermanentlyInvalidatedException();
- ctor public KeyPermanentlyInvalidatedException(java.lang.String);
- ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
- }
-
- public abstract class KeyStoreKeyProperties {
- }
-
- public static abstract class KeyStoreKeyProperties.Algorithm {
- field public static final java.lang.String AES = "AES";
- field public static final java.lang.String EC = "EC";
- field public static final java.lang.String HMAC_SHA1 = "HmacSHA1";
- field public static final java.lang.String HMAC_SHA224 = "HmacSHA224";
- field public static final java.lang.String HMAC_SHA256 = "HmacSHA256";
- field public static final java.lang.String HMAC_SHA384 = "HmacSHA384";
- field public static final java.lang.String HMAC_SHA512 = "HmacSHA512";
- field public static final java.lang.String RSA = "RSA";
- }
-
- public static abstract class KeyStoreKeyProperties.AlgorithmEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.BlockMode {
- field public static final java.lang.String CBC = "CBC";
- field public static final java.lang.String CTR = "CTR";
- field public static final java.lang.String ECB = "ECB";
- field public static final java.lang.String GCM = "GCM";
- }
-
- public static abstract class KeyStoreKeyProperties.BlockModeEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Digest {
- field public static final java.lang.String MD5 = "MD5";
- field public static final java.lang.String NONE = "NONE";
- field public static final java.lang.String SHA1 = "SHA-1";
- field public static final java.lang.String SHA224 = "SHA-224";
- field public static final java.lang.String SHA256 = "SHA-256";
- field public static final java.lang.String SHA384 = "SHA-384";
- field public static final java.lang.String SHA512 = "SHA-512";
- }
-
- public static abstract class KeyStoreKeyProperties.DigestEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.EncryptionPadding {
- field public static final java.lang.String NONE = "NoPadding";
- field public static final java.lang.String PKCS7 = "PKCS7Padding";
- field public static final java.lang.String RSA_OAEP = "OAEPPadding";
- field public static final java.lang.String RSA_PKCS1 = "PKCS1Padding";
- }
-
- public static abstract class KeyStoreKeyProperties.EncryptionPaddingEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Origin {
- field public static final int GENERATED = 1; // 0x1
- field public static final int IMPORTED = 2; // 0x2
- field public static final int UNKNOWN = 4; // 0x4
- }
-
- public static abstract class KeyStoreKeyProperties.OriginEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.Purpose {
- field public static final int DECRYPT = 2; // 0x2
- field public static final int ENCRYPT = 1; // 0x1
- field public static final int SIGN = 4; // 0x4
- field public static final int VERIFY = 8; // 0x8
- }
-
- public static abstract class KeyStoreKeyProperties.PurposeEnum implements java.lang.annotation.Annotation {
- }
-
- public static abstract class KeyStoreKeyProperties.SignaturePadding {
- field public static final java.lang.String RSA_PKCS1 = "PKCS1";
- field public static final java.lang.String RSA_PSS = "PSS";
- }
-
- public static abstract class KeyStoreKeyProperties.SignaturePaddingEnum implements java.lang.annotation.Annotation {
- }
-
- public class KeyStoreKeySpec implements java.security.spec.KeySpec {
+ public class KeyInfo implements java.security.spec.KeySpec {
method public java.lang.String[] getBlockModes();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
@@ -30578,9 +30494,55 @@
method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware();
}
- public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter {
+ public class KeyNotYetValidException extends java.security.InvalidKeyException {
+ ctor public KeyNotYetValidException();
+ ctor public KeyNotYetValidException(java.lang.String);
+ ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable);
+ }
+
+ public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException {
+ ctor public KeyPermanentlyInvalidatedException();
+ ctor public KeyPermanentlyInvalidatedException(java.lang.String);
+ ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable);
+ }
+
+ public abstract class KeyProperties {
+ field public static final java.lang.String BLOCK_MODE_CBC = "CBC";
+ field public static final java.lang.String BLOCK_MODE_CTR = "CTR";
+ field public static final java.lang.String BLOCK_MODE_ECB = "ECB";
+ field public static final java.lang.String BLOCK_MODE_GCM = "GCM";
+ field public static final java.lang.String DIGEST_MD5 = "MD5";
+ field public static final java.lang.String DIGEST_NONE = "NONE";
+ field public static final java.lang.String DIGEST_SHA1 = "SHA-1";
+ field public static final java.lang.String DIGEST_SHA224 = "SHA-224";
+ field public static final java.lang.String DIGEST_SHA256 = "SHA-256";
+ field public static final java.lang.String DIGEST_SHA384 = "SHA-384";
+ field public static final java.lang.String DIGEST_SHA512 = "SHA-512";
+ field public static final java.lang.String ENCRYPTION_PADDING_NONE = "NoPadding";
+ field public static final java.lang.String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
+ field public static final java.lang.String ENCRYPTION_PADDING_RSA_OAEP = "OAEPPadding";
+ field public static final java.lang.String ENCRYPTION_PADDING_RSA_PKCS1 = "PKCS1Padding";
+ field public static final java.lang.String KEY_ALGORITHM_AES = "AES";
+ field public static final java.lang.String KEY_ALGORITHM_EC = "EC";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA1 = "HmacSHA1";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA224 = "HmacSHA224";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA256 = "HmacSHA256";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA384 = "HmacSHA384";
+ field public static final java.lang.String KEY_ALGORITHM_HMAC_SHA512 = "HmacSHA512";
+ field public static final java.lang.String KEY_ALGORITHM_RSA = "RSA";
+ field public static final int ORIGIN_GENERATED = 1; // 0x1
+ field public static final int ORIGIN_IMPORTED = 2; // 0x2
+ field public static final int ORIGIN_UNKNOWN = 4; // 0x4
+ field public static final int PURPOSE_DECRYPT = 2; // 0x2
+ field public static final int PURPOSE_ENCRYPT = 1; // 0x1
+ field public static final int PURPOSE_SIGN = 4; // 0x4
+ field public static final int PURPOSE_VERIFY = 8; // 0x8
+ field public static final java.lang.String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
+ field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS";
+ }
+
+ public final class KeyProtection implements java.security.KeyStore.ProtectionParameter {
method public java.lang.String[] getBlockModes();
- method public android.content.Context getContext();
method public java.lang.String[] getDigests();
method public java.lang.String[] getEncryptionPaddings();
method public java.util.Date getKeyValidityForConsumptionEnd();
@@ -30590,32 +30552,24 @@
method public java.lang.String[] getSignaturePaddings();
method public int getUserAuthenticationValidityDurationSeconds();
method public boolean isDigestsSpecified();
- method public boolean isEncryptionRequired();
method public boolean isRandomizedEncryptionRequired();
method public boolean isUserAuthenticationRequired();
}
- public static final class KeyStoreParameter.Builder {
- ctor public KeyStoreParameter.Builder(android.content.Context);
- method public android.security.KeyStoreParameter build();
- method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date);
- method public android.security.KeyStoreParameter.Builder setPurposes(int);
- method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...);
- method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean);
- method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int);
- }
-
- public class NetworkSecurityPolicy {
- method public static android.security.NetworkSecurityPolicy getInstance();
- method public boolean isCleartextTrafficPermitted();
+ public static final class KeyProtection.Builder {
+ ctor public KeyProtection.Builder(int);
+ method public android.security.keystore.KeyProtection build();
+ method public android.security.keystore.KeyProtection.Builder setBlockModes(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setDigests(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setEncryptionPaddings(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityForConsumptionEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
+ method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
+ method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
+ method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
}
public class UserNotAuthenticatedException extends java.security.InvalidKeyException {
@@ -30631,7 +30585,7 @@
public abstract class CarrierConfigService extends android.app.Service {
ctor public CarrierConfigService();
method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.os.Bundle onLoadConfig(android.service.carrier.CarrierIdentifier);
+ method public abstract android.os.PersistableBundle onLoadConfig(android.service.carrier.CarrierIdentifier);
field public static final java.lang.String SERVICE_INTERFACE = "android.service.carrier.CarrierConfigService";
}
@@ -30705,10 +30659,10 @@
package android.service.chooser {
public final class ChooserTarget implements android.os.Parcelable {
- ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent);
- ctor public ChooserTarget(java.lang.CharSequence, android.graphics.Bitmap, float, android.content.IntentSender);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent);
+ ctor public ChooserTarget(java.lang.CharSequence, android.graphics.drawable.Icon, float, android.content.IntentSender);
method public int describeContents();
- method public android.graphics.Bitmap getIcon();
+ method public android.graphics.drawable.Icon getIcon();
method public android.content.IntentSender getIntentSender();
method public float getScore();
method public java.lang.CharSequence getTitle();
@@ -32107,9 +32061,10 @@
package android.telecom {
- public final class AudioState implements android.os.Parcelable {
+ public deprecated class AudioState implements android.os.Parcelable {
ctor public AudioState(boolean, int, int);
ctor public AudioState(android.telecom.AudioState);
+ ctor public AudioState(android.telecom.CallAudioState);
method public static java.lang.String audioRouteToString(int);
method public int describeContents();
method public int getRoute();
@@ -32224,23 +32179,32 @@
ctor public Call.Listener();
}
- public final class CameraCapabilities implements android.os.Parcelable {
- ctor public CameraCapabilities(int, int);
+ public final class CallAudioState implements android.os.Parcelable {
+ ctor public CallAudioState(boolean, int, int);
+ method public static java.lang.String audioRouteToString(int);
method public int describeContents();
- method public int getHeight();
- method public int getWidth();
+ method public int getRoute();
+ method public int getSupportedRouteMask();
+ method public boolean isMuted();
method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.telecom.CameraCapabilities> CREATOR;
+ field public static final android.os.Parcelable.Creator<android.telecom.CallAudioState> CREATOR;
+ field public static final int ROUTE_BLUETOOTH = 2; // 0x2
+ field public static final int ROUTE_EARPIECE = 1; // 0x1
+ field public static final int ROUTE_SPEAKER = 8; // 0x8
+ field public static final int ROUTE_WIRED_HEADSET = 4; // 0x4
+ field public static final int ROUTE_WIRED_OR_EARPIECE = 5; // 0x5
}
- public abstract class Conference implements android.telecom.Conferenceable {
+ public abstract class Conference extends android.telecom.Conferenceable {
ctor public Conference(android.telecom.PhoneAccountHandle);
method public final boolean addConnection(android.telecom.Connection);
method public final void destroy();
- method public final android.telecom.AudioState getAudioState();
+ method public final deprecated android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.util.List<android.telecom.Connection> getConferenceableConnections();
- method public final long getConnectTimeMillis();
+ method public final deprecated long getConnectTimeMillis();
method public final int getConnectionCapabilities();
+ method public final long getConnectionTime();
method public final java.util.List<android.telecom.Connection> getConnections();
method public final android.telecom.DisconnectCause getDisconnectCause();
method public final android.telecom.PhoneAccountHandle getPhoneAccountHandle();
@@ -32249,7 +32213,8 @@
method public final android.telecom.StatusHints getStatusHints();
method public android.telecom.Connection.VideoProvider getVideoProvider();
method public int getVideoState();
- method public void onAudioStateChanged(android.telecom.AudioState);
+ method public deprecated void onAudioStateChanged(android.telecom.AudioState);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onConnectionAdded(android.telecom.Connection);
method public void onDisconnect();
method public void onHold();
@@ -32263,8 +32228,9 @@
method public final void removeConnection(android.telecom.Connection);
method public final void setActive();
method public final void setConferenceableConnections(java.util.List<android.telecom.Connection>);
- method public void setConnectTimeMillis(long);
+ method public final deprecated void setConnectTimeMillis(long);
method public final void setConnectionCapabilities(int);
+ method public final void setConnectionTime(long);
method public final void setDisconnected(android.telecom.DisconnectCause);
method public final void setOnHold();
method public final void setStatusHints(android.telecom.StatusHints);
@@ -32273,10 +32239,10 @@
field public static final long CONNECT_TIME_NOT_SPECIFIED = 0L; // 0x0L
}
- public abstract interface Conferenceable {
+ public abstract class Conferenceable {
}
- public abstract class Connection implements android.telecom.Conferenceable {
+ public abstract class Connection extends android.telecom.Conferenceable {
ctor public Connection();
method public static java.lang.String capabilitiesToString(int);
method public static android.telecom.Connection createCanceledConnection();
@@ -32285,7 +32251,8 @@
method public final android.net.Uri getAddress();
method public final int getAddressPresentation();
method public final boolean getAudioModeIsVoip();
- method public final android.telecom.AudioState getAudioState();
+ method public final deprecated android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.lang.String getCallerDisplayName();
method public final int getCallerDisplayNamePresentation();
method public final android.telecom.Conference getConference();
@@ -32299,7 +32266,8 @@
method public void onAbort();
method public void onAnswer(int);
method public void onAnswer();
- method public void onAudioStateChanged(android.telecom.AudioState);
+ method public deprecated void onAudioStateChanged(android.telecom.AudioState);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onDisconnect();
method public void onHold();
method public void onPlayDtmfTone(char);
@@ -32358,8 +32326,7 @@
public static abstract class Connection.VideoProvider {
ctor public Connection.VideoProvider();
- method public void changeCallDataUsage(long);
- method public void changeCameraCapabilities(android.telecom.CameraCapabilities);
+ method public void changeCameraCapabilities(android.telecom.VideoProfile.CameraCapabilities);
method public void changePeerDimensions(int, int);
method public void changeVideoQuality(int);
method public void handleCallSessionEvent(int);
@@ -32370,11 +32337,12 @@
method public abstract void onSetCamera(java.lang.String);
method public abstract void onSetDeviceOrientation(int);
method public abstract void onSetDisplaySurface(android.view.Surface);
- method public abstract void onSetPauseImage(java.lang.String);
+ method public abstract void onSetPauseImage(android.net.Uri);
method public abstract void onSetPreviewSurface(android.view.Surface);
method public abstract void onSetZoom(float);
method public void receiveSessionModifyRequest(android.telecom.VideoProfile);
method public void receiveSessionModifyResponse(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
+ method public void setCallDataUsage(long);
field public static final int SESSION_EVENT_CAMERA_FAILURE = 5; // 0x5
field public static final int SESSION_EVENT_CAMERA_READY = 6; // 0x6
field public static final int SESSION_EVENT_RX_PAUSE = 1; // 0x1
@@ -32457,13 +32425,13 @@
public abstract class InCallService extends android.app.Service {
ctor public InCallService();
method public final boolean canAddCall();
- method public final android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.util.List<android.telecom.Call> getCalls();
method public deprecated android.telecom.Phone getPhone();
- method public void onAudioStateChanged(android.telecom.AudioState);
method public android.os.IBinder onBind(android.content.Intent);
method public void onBringToForeground(boolean);
method public void onCallAdded(android.telecom.Call);
+ method public void onCallAudioStateChanged(android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Call);
method public void onCanAddCallChanged(boolean);
method public deprecated void onPhoneCreated(android.telecom.Phone);
@@ -32484,7 +32452,7 @@
method public abstract void setCamera(java.lang.String);
method public abstract void setDeviceOrientation(int);
method public abstract void setDisplaySurface(android.view.Surface);
- method public abstract void setPauseImage(java.lang.String);
+ method public abstract void setPauseImage(android.net.Uri);
method public abstract void setPreviewSurface(android.view.Surface);
method public abstract void setZoom(float);
method public abstract void unregisterCallback(android.telecom.InCallService.VideoCall.Callback);
@@ -32494,7 +32462,7 @@
ctor public InCallService.VideoCall.Callback();
method public abstract void onCallDataUsageChanged(long);
method public abstract void onCallSessionEvent(int);
- method public abstract void onCameraCapabilitiesChanged(android.telecom.CameraCapabilities);
+ method public abstract void onCameraCapabilitiesChanged(android.telecom.VideoProfile.CameraCapabilities);
method public abstract void onPeerDimensionsChanged(int, int);
method public abstract void onSessionModifyRequestReceived(android.telecom.VideoProfile);
method public abstract void onSessionModifyResponseReceived(int, android.telecom.VideoProfile, android.telecom.VideoProfile);
@@ -32504,7 +32472,8 @@
public final deprecated class Phone {
method public final void addListener(android.telecom.Phone.Listener);
method public final boolean canAddCall();
- method public final android.telecom.AudioState getAudioState();
+ method public final deprecated android.telecom.AudioState getAudioState();
+ method public final android.telecom.CallAudioState getCallAudioState();
method public final java.util.List<android.telecom.Call> getCalls();
method public final void removeListener(android.telecom.Phone.Listener);
method public final void setAudioRoute(int);
@@ -32513,25 +32482,22 @@
public static abstract class Phone.Listener {
ctor public Phone.Listener();
- method public void onAudioStateChanged(android.telecom.Phone, android.telecom.AudioState);
+ method public deprecated void onAudioStateChanged(android.telecom.Phone, android.telecom.AudioState);
method public void onBringToForeground(android.telecom.Phone, boolean);
method public void onCallAdded(android.telecom.Phone, android.telecom.Call);
+ method public void onCallAudioStateChanged(android.telecom.Phone, android.telecom.CallAudioState);
method public void onCallRemoved(android.telecom.Phone, android.telecom.Call);
method public void onCanAddCallChanged(android.telecom.Phone, boolean);
}
- public class PhoneAccount implements android.os.Parcelable {
+ public final class PhoneAccount implements android.os.Parcelable {
method public static android.telecom.PhoneAccount.Builder builder(android.telecom.PhoneAccountHandle, java.lang.CharSequence);
- method public android.graphics.drawable.Drawable createIconDrawable(android.content.Context);
method public int describeContents();
method public android.telecom.PhoneAccountHandle getAccountHandle();
method public android.net.Uri getAddress();
method public int getCapabilities();
method public int getHighlightColor();
- method public android.graphics.Bitmap getIconBitmap();
- method public java.lang.String getIconPackageName();
- method public int getIconResId();
- method public int getIconTint();
+ method public android.graphics.drawable.Icon getIcon();
method public java.lang.CharSequence getLabel();
method public java.lang.CharSequence getShortDescription();
method public android.net.Uri getSubscriptionAddress();
@@ -32548,7 +32514,6 @@
field public static final int CAPABILITY_VIDEO_CALLING = 8; // 0x8
field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccount> CREATOR;
field public static final int NO_HIGHLIGHT_COLOR = 0; // 0x0
- field public static final int NO_ICON_TINT = 0; // 0x0
field public static final int NO_RESOURCE_ID = -1; // 0xffffffff
field public static final java.lang.String SCHEME_SIP = "sip";
field public static final java.lang.String SCHEME_TEL = "tel";
@@ -32563,17 +32528,13 @@
method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setCapabilities(int);
method public android.telecom.PhoneAccount.Builder setHighlightColor(int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.content.Context, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(java.lang.String, int, int);
- method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.Bitmap);
+ method public android.telecom.PhoneAccount.Builder setIcon(android.graphics.drawable.Icon);
method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence);
method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri);
method public android.telecom.PhoneAccount.Builder setSupportedUriSchemes(java.util.List<java.lang.String>);
}
- public class PhoneAccountHandle implements android.os.Parcelable {
+ public final class PhoneAccountHandle implements android.os.Parcelable {
ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String);
ctor public PhoneAccountHandle(android.content.ComponentName, java.lang.String, android.os.UserHandle);
method public int describeContents();
@@ -32597,7 +32558,8 @@
method public final void registerCallback(android.telecom.RemoteConference.Callback);
method public final void registerCallback(android.telecom.RemoteConference.Callback, android.os.Handler);
method public void separate(android.telecom.RemoteConnection);
- method public void setAudioState(android.telecom.AudioState);
+ method public deprecated void setAudioState(android.telecom.AudioState);
+ method public void setCallAudioState(android.telecom.CallAudioState);
method public void stopDtmfTone();
method public void swap();
method public void unhold();
@@ -32637,7 +32599,8 @@
method public void registerCallback(android.telecom.RemoteConnection.Callback);
method public void registerCallback(android.telecom.RemoteConnection.Callback, android.os.Handler);
method public void reject();
- method public void setAudioState(android.telecom.AudioState);
+ method public deprecated void setAudioState(android.telecom.AudioState);
+ method public void setCallAudioState(android.telecom.CallAudioState);
method public void stopDtmfTone();
method public void unhold();
method public void unregisterCallback(android.telecom.RemoteConnection.Callback);
@@ -32661,13 +32624,15 @@
}
public final class StatusHints implements android.os.Parcelable {
- ctor public StatusHints(android.content.ComponentName, java.lang.CharSequence, int, android.os.Bundle);
+ ctor public deprecated StatusHints(android.content.ComponentName, java.lang.CharSequence, int, android.os.Bundle);
+ ctor public StatusHints(java.lang.CharSequence, android.graphics.drawable.Icon, android.os.Bundle);
method public int describeContents();
method public android.os.Bundle getExtras();
- method public android.graphics.drawable.Drawable getIcon(android.content.Context);
- method public int getIconResId();
+ method public deprecated android.graphics.drawable.Drawable getIcon(android.content.Context);
+ method public android.graphics.drawable.Icon getIcon();
+ method public deprecated int getIconResId();
method public java.lang.CharSequence getLabel();
- method public android.content.ComponentName getPackageName();
+ method public deprecated android.content.ComponentName getPackageName();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telecom.StatusHints> CREATOR;
}
@@ -32748,21 +32713,29 @@
field public static final int QUALITY_HIGH = 1; // 0x1
field public static final int QUALITY_LOW = 3; // 0x3
field public static final int QUALITY_MEDIUM = 2; // 0x2
+ field public static final int STATE_AUDIO_ONLY = 0; // 0x0
+ field public static final int STATE_BIDIRECTIONAL = 3; // 0x3
+ field public static final int STATE_PAUSED = 4; // 0x4
+ field public static final int STATE_RX_ENABLED = 2; // 0x2
+ field public static final int STATE_TX_ENABLED = 1; // 0x1
+ }
+
+ public static final class VideoProfile.CameraCapabilities implements android.os.Parcelable {
+ ctor public VideoProfile.CameraCapabilities(int, int);
+ method public int describeContents();
+ method public int getHeight();
+ method public int getWidth();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile.CameraCapabilities> CREATOR;
}
public static class VideoProfile.VideoState {
- ctor public VideoProfile.VideoState();
method public static boolean isAudioOnly(int);
method public static boolean isBidirectional(int);
method public static boolean isPaused(int);
method public static boolean isReceptionEnabled(int);
method public static boolean isTransmissionEnabled(int);
method public static java.lang.String videoStateToString(int);
- field public static final int AUDIO_ONLY = 0; // 0x0
- field public static final int BIDIRECTIONAL = 3; // 0x3
- field public static final int PAUSED = 4; // 0x4
- field public static final int RX_ENABLED = 2; // 0x2
- field public static final int TX_ENABLED = 1; // 0x1
}
}
@@ -32770,9 +32743,9 @@
package android.telephony {
public class CarrierConfigManager {
- method public android.os.Bundle getConfig();
- method public android.os.Bundle getConfigForSubId(int);
- method public static android.os.Bundle getDefaultConfig();
+ method public android.os.PersistableBundle getConfig();
+ method public android.os.PersistableBundle getConfigForSubId(int);
+ method public static android.os.PersistableBundle getDefaultConfig();
method public void reloadCarrierConfigForSubId(int);
method public void updateConfigForPhoneId(int, java.lang.String);
field public static final java.lang.String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
@@ -32794,7 +32767,7 @@
field public static final java.lang.String BOOL_OPERATOR_SELECTION_EXPAND = "bool_operator_selection_expand";
field public static final java.lang.String BOOL_PREFER_2G = "bool_prefer_2g";
field public static final java.lang.String BOOL_SHOW_APN_SETTING_CDMA = "bool_show_apn_setting_cdma";
- field public static final java.lang.String BOOL_SHOW_CDMA = "bool_show_cdma";
+ field public static final java.lang.String BOOL_SHOW_CDMA_CHOICES = "bool_show_cdma_choices";
field public static final java.lang.String BOOL_SHOW_ONSCREEN_DIAL_BUTTON = "bool_show_onscreen_dial_button";
field public static final java.lang.String BOOL_SIM_NETWORK_UNLOCK_ALLOW_DISMISS = "bool_sim_network_unlock_allow_dismiss";
field public static final java.lang.String BOOL_SUPPORT_PAUSE_IMS_VIDEO_CALLS = "bool_support_pause_ims_video_calls";
@@ -34089,6 +34062,7 @@
method public boolean setDefaultBrowserPackageName(java.lang.String, int);
method public void setInstallerPackageName(java.lang.String, java.lang.String);
method public void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
+ method public void verifyIntentFilter(int, int, java.util.List<java.lang.String>);
method public void verifyPendingInstall(int, int);
}
@@ -34415,6 +34389,9 @@
field public static final int BREAK_STRATEGY_SIMPLE = 0; // 0x0
field public static final int DIR_LEFT_TO_RIGHT = 1; // 0x1
field public static final int DIR_RIGHT_TO_LEFT = -1; // 0xffffffff
+ field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
+ field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
+ field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
}
public static final class Layout.Alignment extends java.lang.Enum {
@@ -34613,6 +34590,7 @@
method public android.text.StaticLayout.Builder setBreakStrategy(int);
method public android.text.StaticLayout.Builder setEllipsize(android.text.TextUtils.TruncateAt);
method public android.text.StaticLayout.Builder setEllipsizedWidth(int);
+ method public android.text.StaticLayout.Builder setHyphenationFrequency(int);
method public android.text.StaticLayout.Builder setIncludePad(boolean);
method public android.text.StaticLayout.Builder setIndents(int[], int[]);
method public android.text.StaticLayout.Builder setLineSpacing(float, float);
@@ -36798,6 +36776,7 @@
method public int getFlags();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
+ method public android.view.Display.Mode getMode();
method public java.lang.String getName();
method public deprecated int getOrientation();
method public deprecated int getPixelFormat();
@@ -36809,7 +36788,8 @@
method public int getRotation();
method public void getSize(android.graphics.Point);
method public int getState();
- method public float[] getSupportedRefreshRates();
+ method public android.view.Display.Mode[] getSupportedModes();
+ method public deprecated float[] getSupportedRefreshRates();
method public deprecated int getWidth();
method public boolean isValid();
field public static final int DEFAULT_DISPLAY = 0; // 0x0
@@ -36824,6 +36804,16 @@
field public static final int STATE_UNKNOWN = 0; // 0x0
}
+ public static final class Display.Mode implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getModeId();
+ method public int getPhysicalHeight();
+ method public int getPhysicalWidth();
+ method public float getRefreshRate();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.view.Display.Mode> CREATOR;
+ }
+
public class DragEvent implements android.os.Parcelable {
method public int describeContents();
method public int getAction();
@@ -37622,6 +37612,7 @@
method public static java.lang.String axisToString(int);
method public final int findPointerIndex(int);
method public final int getAction();
+ method public final int getActionButton();
method public final int getActionIndex();
method public final int getActionMasked();
method public final float getAxisValue(int);
@@ -37685,7 +37676,6 @@
method public final float getY(int);
method public final float getYPrecision();
method public final boolean isButtonPressed(int);
- method public final boolean isStylusButtonPressed();
method public static android.view.MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int);
method public static deprecated android.view.MotionEvent obtain(long, long, int, int, int[], android.view.MotionEvent.PointerCoords[], int, float, float, int, int, int, int);
method public static android.view.MotionEvent obtain(long, long, int, float, float, float, float, int, float, float, int, int);
@@ -37701,6 +37691,8 @@
method public final void setSource(int);
method public final void transform(android.graphics.Matrix);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int ACTION_BUTTON_PRESS = 11; // 0xb
+ field public static final int ACTION_BUTTON_RELEASE = 12; // 0xc
field public static final int ACTION_CANCEL = 3; // 0x3
field public static final int ACTION_DOWN = 0; // 0x0
field public static final int ACTION_HOVER_ENTER = 9; // 0x9
@@ -37769,6 +37761,8 @@
field public static final int BUTTON_FORWARD = 16; // 0x10
field public static final int BUTTON_PRIMARY = 1; // 0x1
field public static final int BUTTON_SECONDARY = 2; // 0x2
+ field public static final int BUTTON_STYLUS_PRIMARY = 32; // 0x20
+ field public static final int BUTTON_STYLUS_SECONDARY = 64; // 0x40
field public static final int BUTTON_TERTIARY = 4; // 0x4
field public static final android.os.Parcelable.Creator<android.view.MotionEvent> CREATOR;
field public static final int EDGE_BOTTOM = 2; // 0x2
@@ -38286,7 +38280,6 @@
method public boolean isSaveEnabled();
method public boolean isSaveFromParentEnabled();
method public boolean isScrollContainer();
- method public boolean isScrollIndicatorEnabled(int);
method public boolean isScrollbarFadingEnabled();
method public boolean isSelected();
method public boolean isShown();
@@ -39617,7 +39610,8 @@
field public float horizontalWeight;
field public deprecated int memoryType;
field public java.lang.String packageName;
- field public float preferredRefreshRate;
+ field public int preferredDisplayModeId;
+ field public deprecated float preferredRefreshRate;
field public int rotationAnimation;
field public float screenBrightness;
field public int screenOrientation;
@@ -41129,7 +41123,7 @@
public abstract class WebResourceError {
ctor public WebResourceError();
- method public abstract java.lang.String getDescription();
+ method public java.lang.CharSequence getDescription();
method public abstract int getErrorCode();
}
@@ -41144,6 +41138,7 @@
public class WebResourceResponse extends android.webkit.WebResourceResponseBase {
ctor public WebResourceResponse(java.lang.String, java.lang.String, java.io.InputStream);
ctor public WebResourceResponse(java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.io.InputStream);
+ ctor public WebResourceResponse(boolean, java.lang.String, java.lang.String, int, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.io.InputStream);
method public java.io.InputStream getData();
method public java.lang.String getEncoding();
method public java.lang.String getMimeType();
@@ -41159,12 +41154,6 @@
public abstract class WebResourceResponseBase {
ctor public WebResourceResponseBase();
- method public abstract java.io.InputStream getData();
- method public abstract java.lang.String getEncoding();
- method public abstract java.lang.String getMimeType();
- method public abstract java.lang.String getReasonPhrase();
- method public abstract java.util.Map<java.lang.String, java.lang.String> getResponseHeaders();
- method public abstract int getStatusCode();
}
public abstract class WebSettings {
@@ -41412,7 +41401,6 @@
method public void goBack();
method public void goBackOrForward(int);
method public void goForward();
- method public void insertVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
method public void invokeZoomPicker();
method public boolean isPrivateBrowsingEnabled();
method public void loadData(java.lang.String, java.lang.String, java.lang.String);
@@ -41429,8 +41417,9 @@
method public boolean pageDown(boolean);
method public boolean pageUp(boolean);
method public void pauseTimers();
- method public void postMessageToMainFrame(android.webkit.WebMessage, android.net.Uri);
method public void postUrl(java.lang.String, byte[]);
+ method public void postVisualStateCallback(long, android.webkit.WebView.VisualStateCallback);
+ method public void postWebMessage(android.webkit.WebMessage, android.net.Uri);
method public void reload();
method public void removeJavascriptInterface(java.lang.String);
method public void requestFocusNodeHref(android.os.Message);
@@ -41541,6 +41530,7 @@
method public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
method public void onReceivedHttpAuthRequest(android.webkit.WebView, android.webkit.HttpAuthHandler, java.lang.String, java.lang.String);
method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponseBase);
+ method public void onReceivedHttpError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceResponse);
method public void onReceivedLoginRequest(android.webkit.WebView, java.lang.String, java.lang.String, java.lang.String);
method public void onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError);
method public void onScaleChanged(android.webkit.WebView, float, float);
@@ -41766,7 +41756,7 @@
method public abstract boolean onKeyUp(int, android.view.KeyEvent);
method public abstract void onMeasure(int, int);
method public abstract void onOverScrolled(int, int, boolean, boolean);
- method public abstract void onProvideVirtualAssistStructure(android.view.ViewStructure);
+ method public abstract void onProvideVirtualAssistStructure(android.view.ViewAssistStructure);
method public abstract void onScrollChanged(int, int, int, int);
method public abstract void onSizeChanged(int, int, int, int);
method public abstract void onStartTemporaryDetach();
@@ -42848,6 +42838,7 @@
method public void setImageAlpha(int);
method public void setImageBitmap(android.graphics.Bitmap);
method public void setImageDrawable(android.graphics.drawable.Drawable);
+ method public void setImageIcon(android.graphics.drawable.Icon);
method public void setImageLevel(int);
method public void setImageMatrix(android.graphics.Matrix);
method public void setImageResource(int);
@@ -43428,7 +43419,9 @@
method public void setDouble(int, java.lang.String, double);
method public void setEmptyView(int, int);
method public void setFloat(int, java.lang.String, float);
+ method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon);
method public void setImageViewBitmap(int, android.graphics.Bitmap);
+ method public void setImageViewIcon(int, android.graphics.drawable.Icon);
method public void setImageViewResource(int, int);
method public void setImageViewUri(int, android.net.Uri);
method public void setInt(int, java.lang.String, int);
@@ -44006,6 +43999,7 @@
method public int getHighlightColor();
method public java.lang.CharSequence getHint();
method public final android.content.res.ColorStateList getHintTextColors();
+ method public int getHyphenationFrequency();
method public int getImeActionId();
method public java.lang.CharSequence getImeActionLabel();
method public int getImeOptions();
@@ -44112,6 +44106,7 @@
method public final void setHintTextColor(int);
method public final void setHintTextColor(android.content.res.ColorStateList);
method public void setHorizontallyScrolling(boolean);
+ method public void setHyphenationFrequency(int);
method public void setImeActionLabel(java.lang.CharSequence, int);
method public void setImeOptions(int);
method public void setIncludeFontPadding(boolean);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index eb834f2..1599459 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1585,7 +1585,7 @@
}
private int runGrantRevokePermission(boolean grant) {
- int userId = UserHandle.USER_CURRENT;
+ int userId = UserHandle.USER_OWNER;
String opt = null;
while ((opt = nextOption()) != null) {
diff --git a/cmds/sm/Android.mk b/cmds/sm/Android.mk
new file mode 100644
index 0000000..7cb1e12
--- /dev/null
+++ b/cmds/sm/Android.mk
@@ -0,0 +1,15 @@
+# Copyright 2015 The Android Open Source Project
+#
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_MODULE := sm
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := sm
+LOCAL_SRC_FILES := sm
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_PREBUILT)
diff --git a/cmds/sm/MODULE_LICENSE_APACHE2 b/cmds/sm/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/sm/MODULE_LICENSE_APACHE2
diff --git a/cmds/sm/NOTICE b/cmds/sm/NOTICE
new file mode 100644
index 0000000..f7bd78d
--- /dev/null
+++ b/cmds/sm/NOTICE
@@ -0,0 +1,189 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/cmds/sm/sm b/cmds/sm/sm
new file mode 100755
index 0000000..8fba007
--- /dev/null
+++ b/cmds/sm/sm
@@ -0,0 +1,6 @@
+# Script to start "sm" on the device, which has a very rudimentary
+# shell.
+#
+base=/system
+export CLASSPATH=$base/framework/sm.jar
+exec app_process $base/bin com.android.commands.sm.Sm "$@"
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
new file mode 100644
index 0000000..0dad4dc
--- /dev/null
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -0,0 +1,198 @@
+/*
+ * 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.commands.sm;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.storage.DiskInfo;
+import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.util.Log;
+
+public final class Sm {
+ private static final String TAG = "Sm";
+
+ IMountService mSm;
+
+ private String[] mArgs;
+ private int mNextArg;
+ private String mCurArgData;
+
+ public static void main(String[] args) {
+ boolean success = false;
+ try {
+ new Sm().run(args);
+ success = true;
+ } catch (Exception e) {
+ if (e instanceof IllegalArgumentException) {
+ showUsage();
+ }
+ Log.e(TAG, "Error", e);
+ System.err.println("Error: " + e);
+ }
+ System.exit(success ? 0 : 1);
+ }
+
+ public void run(String[] args) throws Exception {
+ if (args.length < 1) {
+ throw new IllegalArgumentException();
+ }
+
+ mSm = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
+ if (mSm == null) {
+ throw new RemoteException("Failed to find running mount service");
+ }
+
+ mArgs = args;
+ String op = args[0];
+ mNextArg = 1;
+
+ if ("list-disks".equals(op)) {
+ runListDisks();
+ } else if ("list-volumes".equals(op)) {
+ runListVolumes();
+ } else if ("has-adoptable".equals(op)) {
+ runHasAdoptable();
+ } else if ("get-primary-storage-uuid".equals(op)) {
+ runGetPrimaryStorageUuid();
+ } else if ("set-force-adoptable".equals(op)) {
+ runSetForceAdoptable();
+ } else if ("partition".equals(op)) {
+ runPartition();
+ } else if ("mount".equals(op)) {
+ runMount();
+ } else if ("unmount".equals(op)) {
+ runUnmount();
+ } else if ("format".equals(op)) {
+ runFormat();
+ } else if ("forget".equals(op)) {
+ runForget();
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public void runListDisks() throws RemoteException {
+ final DiskInfo[] disks = mSm.getDisks();
+ for (DiskInfo disk : disks) {
+ System.out.println(disk.getId());
+ }
+ }
+
+ public void runListVolumes() throws RemoteException {
+ final String filter = nextArg();
+ final int filterType;
+ if ("public".equals(filter)) {
+ filterType = VolumeInfo.TYPE_PUBLIC;
+ } else if ("private".equals(filter)) {
+ filterType = VolumeInfo.TYPE_PRIVATE;
+ } else if ("emulated".equals(filter)) {
+ filterType = VolumeInfo.TYPE_EMULATED;
+ } else {
+ filterType = -1;
+ }
+
+ final VolumeInfo[] vols = mSm.getVolumes(0);
+ for (VolumeInfo vol : vols) {
+ if (filterType == -1 || filterType == vol.getType()) {
+ final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
+ System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid());
+ }
+ }
+ }
+
+ public void runHasAdoptable() {
+ System.out.println(SystemProperties.getBoolean(StorageManager.PROP_HAS_ADOPTABLE, false));
+ }
+
+ public void runGetPrimaryStorageUuid() throws RemoteException {
+ System.out.println(mSm.getPrimaryStorageUuid());
+ }
+
+ public void runSetForceAdoptable() throws RemoteException {
+ final boolean forceAdoptable = Boolean.parseBoolean(nextArg());
+ mSm.setDebugFlags(forceAdoptable ? StorageManager.DEBUG_FORCE_ADOPTABLE : 0,
+ StorageManager.DEBUG_FORCE_ADOPTABLE);
+ }
+
+ public void runPartition() throws RemoteException {
+ final String diskId = nextArg();
+ final String type = nextArg();
+ if ("public".equals(type)) {
+ mSm.partitionPublic(diskId);
+ } else if ("private".equals(type)) {
+ mSm.partitionPrivate(diskId);
+ } else if ("mixed".equals(type)) {
+ final int ratio = Integer.parseInt(nextArg());
+ mSm.partitionMixed(diskId, ratio);
+ } else {
+ throw new IllegalArgumentException("Unsupported partition type " + type);
+ }
+ }
+
+ public void runMount() throws RemoteException {
+ final String volId = nextArg();
+ mSm.mount(volId);
+ }
+
+ public void runUnmount() throws RemoteException {
+ final String volId = nextArg();
+ mSm.unmount(volId);
+ }
+
+ public void runFormat() throws RemoteException {
+ final String volId = nextArg();
+ mSm.format(volId);
+ }
+
+ public void runForget() throws RemoteException{
+ final String fsUuid = nextArg();
+ if ("all".equals(fsUuid)) {
+ mSm.forgetAllVolumes();
+ } else {
+ mSm.forgetVolume(fsUuid);
+ }
+ }
+
+ private String nextArg() {
+ if (mNextArg >= mArgs.length) {
+ return null;
+ }
+ String arg = mArgs[mNextArg];
+ mNextArg++;
+ return arg;
+ }
+
+ private static int showUsage() {
+ System.err.println("usage: sm list-disks");
+ System.err.println(" sm list-volumes [public|private|emulated|all]");
+ System.err.println(" sm has-adoptable");
+ System.err.println(" sm get-primary-storage-uuid");
+ System.err.println(" sm set-force-adoptable [true|false]");
+ System.err.println("");
+ System.err.println(" sm partition DISK [public|private|mixed] [ratio]");
+ System.err.println(" sm mount VOLUME");
+ System.err.println(" sm unmount VOLUME");
+ System.err.println(" sm format VOLUME");
+ System.err.println("");
+ System.err.println(" sm forget [UUID|all]");
+ System.err.println("");
+ return 1;
+ }
+}
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 4dcb05e..a6ef25f 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -50,7 +50,7 @@
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
Context.USB_SERVICE));
try {
- usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null), false);
+ usbMgr.setCurrentFunction((args.length >=3 ? args[2] : null));
} catch (RemoteException e) {
System.err.println("Error communicating with UsbManager: " + e);
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9bbb4be..edebc28 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -2320,7 +2320,9 @@
* in {@link RunningAppProcessInfo}, giving you the highest importance of all the
* processes that this package has code running inside of. If there are no processes
* running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned.
+ * @hide
*/
+ @SystemApi
public int getPackageImportance(String packageName) {
try {
int procState = ActivityManagerNative.getDefault().getPackageProcessState(packageName);
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index a71a258..1e9bc54 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2069,6 +2069,13 @@
return true;
}
+ case KEYGUARD_GOING_AWAY_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ keyguardGoingAway(data.readInt() != 0, data.readInt() != 0);
+ reply.writeNoException();
+ return true;
+ }
+
case SHOULD_UP_RECREATE_TASK_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -5179,6 +5186,19 @@
reply.recycle();
}
+ public void keyguardGoingAway(boolean disableWindowAnimations,
+ boolean keyguardGoingToNotificationShade) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(disableWindowAnimations ? 1 : 0);
+ data.writeInt(keyguardGoingToNotificationShade ? 1 : 0);
+ mRemote.transact(KEYGUARD_GOING_AWAY_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f506d59..5dcbe37 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -96,7 +96,7 @@
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.renderscript.RenderScriptCacheDir;
-import android.security.AndroidKeyStoreProvider;
+import android.security.keystore.AndroidKeyStoreProvider;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.ReferrerIntent;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 7104185..e728971 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -227,8 +227,10 @@
public static final int OP_BODY_SENSORS = 56;
/** @hide Read previously received cell broadcast messages. */
public static final int OP_READ_CELL_BROADCASTS = 57;
+ /** @hide Inject mock location into the system. */
+ public static final int OP_MOCK_LOCATION = 58;
/** @hide */
- public static final int _NUM_OP = 58;
+ public static final int _NUM_OP = 59;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -308,6 +310,9 @@
/** @hide Read previously received cell broadcast messages. */
public static final String OPSTR_READ_CELL_BROADCASTS
= "android:read_cell_broadcasts";
+ /** Inject mock location into the system. */
+ public static final String OPSTR_MOCK_LOCATION
+ = "android:mock_location";
/**
* This maps each operation to the operation that serves as the
@@ -375,7 +380,8 @@
OP_PROCESS_OUTGOING_CALLS,
OP_USE_FINGERPRINT,
OP_BODY_SENSORS,
- OP_READ_CELL_BROADCASTS
+ OP_READ_CELL_BROADCASTS,
+ OP_MOCK_LOCATION
};
/**
@@ -440,7 +446,8 @@
null,
OPSTR_USE_FINGERPRINT,
OPSTR_BODY_SENSORS,
- OPSTR_READ_CELL_BROADCASTS
+ OPSTR_READ_CELL_BROADCASTS,
+ OPSTR_MOCK_LOCATION
};
/**
@@ -505,7 +512,8 @@
"PROCESS_OUTGOING_CALLS",
"USE_FINGERPRINT",
"BODY_SENSORS",
- "READ_CELL_BROADCASTS"
+ "READ_CELL_BROADCASTS",
+ "MOCK_LOCATION"
};
/**
@@ -570,7 +578,8 @@
Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.USE_FINGERPRINT,
Manifest.permission.BODY_SENSORS,
- Manifest.permission.READ_CELL_BROADCASTS
+ Manifest.permission.READ_CELL_BROADCASTS,
+ null
};
/**
@@ -636,7 +645,8 @@
null, // PROCESS_OUTGOING_CALLS
null, // USE_FINGERPRINT
null, // BODY_SENSORS
- null // READ_CELL_BROADCASTS
+ null, // READ_CELL_BROADCASTS
+ null // MOCK_LOCATION
};
/**
@@ -701,7 +711,8 @@
false, // PROCESS_OUTGOING_CALLS
false, // USE_FINGERPRINT
false, // BODY_SENSORS
- false // READ_CELL_BROADCASTS
+ false, // READ_CELL_BROADCASTS
+ false // MOCK_LOCATION
};
/**
@@ -765,7 +776,8 @@
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED,
- AppOpsManager.MODE_ALLOWED
+ AppOpsManager.MODE_ALLOWED,
+ AppOpsManager.MODE_ERRORED // OP_MOCK_LOCATION
};
/**
@@ -833,6 +845,7 @@
false,
false,
false,
+ false,
false
};
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 49644a7..1fb88a9 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -577,46 +577,6 @@
return this;
}
- /** TODO: remove this */
- @Override
- public FragmentTransaction setSharedElement(View sharedElement, String name) {
- String transitionName = sharedElement.getTransitionName();
- if (transitionName == null) {
- throw new IllegalArgumentException("Unique transitionNames are required for all" +
- " sharedElements");
- }
- mSharedElementSourceNames = new ArrayList<String>(1);
- mSharedElementSourceNames.add(transitionName);
-
- mSharedElementTargetNames = new ArrayList<String>(1);
- mSharedElementTargetNames.add(name);
- return this;
- }
-
- /** TODO: remove this */
- @Override
- public FragmentTransaction setSharedElements(Pair<View, String>... sharedElements) {
- if (sharedElements == null || sharedElements.length == 0) {
- mSharedElementSourceNames = null;
- mSharedElementTargetNames = null;
- } else {
- ArrayList<String> sourceNames = new ArrayList<String>(sharedElements.length);
- ArrayList<String> targetNames = new ArrayList<String>(sharedElements.length);
- for (int i = 0; i < sharedElements.length; i++) {
- String transitionName = sharedElements[i].first.getTransitionName();
- if (transitionName == null) {
- throw new IllegalArgumentException("Unique transitionNames are required for all"
- + " sharedElements");
- }
- sourceNames.add(transitionName);
- targetNames.add(sharedElements[i].second);
- }
- mSharedElementSourceNames = sourceNames;
- mSharedElementTargetNames = targetNames;
- }
- return this;
- }
-
public FragmentTransaction setTransitionStyle(int styleRes) {
mTransitionStyle = styleRes;
return this;
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 4db4be0..05cf1d4 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -593,7 +593,7 @@
}
private boolean allowOverlappingTransitions() {
- return mIsReturning ? getWindow().getAllowExitTransitionOverlap()
+ return mIsReturning ? getWindow().getAllowReturnTransitionOverlap()
: getWindow().getAllowEnterTransitionOverlap();
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 6b5239d..e0a30ad 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -945,7 +945,7 @@
if (f.mView != null) {
// Need to save the current view state if not
// done already.
- if (!mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
+ if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f);
}
}
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index dc7075c..876c0f6 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -172,14 +172,6 @@
public abstract FragmentTransaction setTransition(int transit);
/**
- * TODO: remove from API
- * @hide
- */
- public FragmentTransaction setCustomTransition(int sceneRootId, int transitionId) {
- return this;
- }
-
- /**
* Used with to map a View from a removed or hidden Fragment to a View from a shown
* or added Fragment.
* @param sharedElement A View in a disappearing Fragment to match with a View in an
@@ -190,18 +182,6 @@
public abstract FragmentTransaction addSharedElement(View sharedElement, String name);
/**
- * TODO: remove from API
- * @hide
- */
- public abstract FragmentTransaction setSharedElement(View sharedElement, String name);
-
- /**
- * TODO: remove from API
- * @hide
- */
- public abstract FragmentTransaction setSharedElements(Pair<View, String>... sharedElements);
-
- /**
* Set a custom style resource that will be used for resolving transit
* animations.
*/
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 5829fbe..05a936c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -403,6 +403,9 @@
public void keyguardWaitingForActivityDrawn() throws RemoteException;
+ public void keyguardGoingAway(boolean disableWindowAnimations,
+ boolean keyguardGoingToNotificationShade) throws RemoteException;
+
public boolean shouldUpRecreateTask(IBinder token, String destAffinity)
throws RemoteException;
@@ -842,4 +845,5 @@
int SHOW_LOCK_TASK_ESCAPE_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+294;
int UPDATE_DEVICE_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+295;
int UPDATE_PREFERRED_SETUP_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+296;
+ int KEYGUARD_GOING_AWAY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+297;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 49b2549..3309443 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -30,6 +30,7 @@
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.session.MediaSession;
@@ -885,6 +886,9 @@
*/
public static final int HEADS_UP_REQUESTED = 2;
+ private Icon mSmallIcon;
+ private Icon mLargeIcon;
+
/**
* Structure to encapsulate a named action that can be shown as part of this notification.
* It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is
@@ -1362,7 +1366,7 @@
int version = parcel.readInt();
when = parcel.readLong();
- icon = parcel.readInt();
+ mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
number = parcel.readInt();
if (parcel.readInt() != 0) {
contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
@@ -1380,7 +1384,7 @@
contentView = RemoteViews.CREATOR.createFromParcel(parcel);
}
if (parcel.readInt() != 0) {
- largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
+ mLargeIcon = Icon.CREATOR.createFromParcel(parcel);
}
defaults = parcel.readInt();
flags = parcel.readInt();
@@ -1445,7 +1449,7 @@
*/
public void cloneInto(Notification that, boolean heavy) {
that.when = this.when;
- that.icon = this.icon;
+ that.mSmallIcon = this.mSmallIcon;
that.number = this.number;
// PendingIntents are global, so there's no reason (or way) to clone them.
@@ -1462,8 +1466,8 @@
if (heavy && this.contentView != null) {
that.contentView = this.contentView.clone();
}
- if (heavy && this.largeIcon != null) {
- that.largeIcon = Bitmap.createBitmap(this.largeIcon);
+ if (heavy && this.mLargeIcon != null) {
+ that.mLargeIcon = this.mLargeIcon;
}
that.iconLevel = this.iconLevel;
that.sound = this.sound; // android.net.Uri is immutable
@@ -1544,7 +1548,7 @@
contentView = null;
bigContentView = null;
headsUpContentView = null;
- largeIcon = null;
+ mLargeIcon = null;
if (extras != null) {
extras.remove(Notification.EXTRA_LARGE_ICON);
extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
@@ -1586,7 +1590,7 @@
parcel.writeInt(1);
parcel.writeLong(when);
- parcel.writeInt(icon);
+ mSmallIcon.writeToParcel(parcel, 0);
parcel.writeInt(number);
if (contentIntent != null) {
parcel.writeInt(1);
@@ -1618,9 +1622,9 @@
} else {
parcel.writeInt(0);
}
- if (largeIcon != null) {
+ if (mLargeIcon != null) {
parcel.writeInt(1);
- largeIcon.writeToParcel(parcel, 0);
+ mLargeIcon.writeToParcel(parcel, 0);
} else {
parcel.writeInt(0);
}
@@ -1865,6 +1869,35 @@
}
/**
+ * The small icon representing this notification in the status bar and content view.
+ *
+ * @return the small icon representing this notification.
+ *
+ * @see Builder#getSmallIcon()
+ * @see Builder#setSmallIcon(Icon)
+ */
+ public Icon getSmallIcon() {
+ return mSmallIcon;
+ }
+
+ /**
+ * Used when notifying to clean up legacy small icons.
+ * @hide
+ */
+ public void setSmallIcon(Icon icon) {
+ mSmallIcon = icon;
+ }
+
+ /**
+ * The large icon shown in this notification's content view.
+ * @see Builder#getLargeIcon()
+ * @see Builder#setLargeIcon(Icon)
+ */
+ public Icon getLargeIcon() {
+ return mLargeIcon;
+ }
+
+ /**
* @hide
*/
public boolean isValid() {
@@ -1966,7 +1999,7 @@
private Context mContext;
private long mWhen;
- private int mSmallIcon;
+ private Icon mSmallIcon, mLargeIcon;
private int mSmallIconLevel;
private int mNumber;
private CharSequence mContentTitle;
@@ -1979,7 +2012,6 @@
private PendingIntent mFullScreenIntent;
private CharSequence mTickerText;
private RemoteViews mTickerView;
- private Bitmap mLargeIcon;
private Uri mSound;
private int mAudioStreamType;
private AudioAttributes mAudioAttributes;
@@ -2160,8 +2192,9 @@
* @see Notification#icon
*/
public Builder setSmallIcon(@DrawableRes int icon) {
- mSmallIcon = icon;
- return this;
+ return setSmallIcon(icon != 0
+ ? Icon.createWithResource(mContext, icon)
+ : null);
}
/**
@@ -2176,8 +2209,20 @@
* @see Notification#iconLevel
*/
public Builder setSmallIcon(@DrawableRes int icon, int level) {
- mSmallIcon = icon;
mSmallIconLevel = level;
+ return setSmallIcon(icon);
+ }
+
+ /**
+ * Set the small icon, which will be used to represent the notification in the
+ * status bar and content view (unless overriden there by a
+ * {@link #setLargeIcon(Bitmap) large icon}).
+ *
+ * @param icon An Icon object to use.
+ * @see Notification#icon
+ */
+ public Builder setSmallIcon(Icon icon) {
+ mSmallIcon = icon;
return this;
}
@@ -2324,14 +2369,24 @@
}
/**
- * Add a large icon to the notification (and the ticker on some devices).
+ * Add a large icon to the notification content view.
*
* In the platform template, this image will be shown on the left of the notification view
- * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side).
- *
- * @see Notification#largeIcon
+ * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small
+ * badge atop the large icon).
*/
- public Builder setLargeIcon(Bitmap icon) {
+ public Builder setLargeIcon(Bitmap b) {
+ return setLargeIcon(b != null ? Icon.createWithBitmap(b) : null);
+ }
+
+ /**
+ * Add a large icon to the notification content view.
+ *
+ * In the platform template, this image will be shown on the left of the notification view
+ * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small
+ * badge atop the large icon).
+ */
+ public Builder setLargeIcon(Icon icon) {
mLargeIcon = icon;
return this;
}
@@ -2840,13 +2895,13 @@
boolean contentTextInLine2 = false;
if (mLargeIcon != null) {
- contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
+ contentView.setImageViewIcon(R.id.icon, mLargeIcon);
processLargeLegacyIcon(mLargeIcon, contentView);
- contentView.setImageViewResource(R.id.right_icon, mSmallIcon);
+ contentView.setImageViewIcon(R.id.right_icon, mSmallIcon);
contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
processSmallRightIcon(mSmallIcon, contentView);
} else { // small icon at left
- contentView.setImageViewResource(R.id.icon, mSmallIcon);
+ contentView.setImageViewIcon(R.id.icon, mSmallIcon);
contentView.setViewVisibility(R.id.icon, View.VISIBLE);
processSmallIconAsLarge(mSmallIcon, contentView);
}
@@ -3086,14 +3141,16 @@
/**
* Apply any necessary background to smallIcons being used in the largeIcon spot.
*/
- private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) {
+ private void processSmallIconAsLarge(Icon largeIcon, RemoteViews contentView) {
if (!isLegacy()) {
contentView.setDrawableParameters(R.id.icon, false, -1,
0xFFFFFFFF,
PorterDuff.Mode.SRC_ATOP, -1);
- }
- if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) {
applyLargeIconBackground(contentView);
+ } else {
+ if (mColorUtil.isGrayscaleIcon(mContext, largeIcon)) {
+ applyLargeIconBackground(contentView);
+ }
}
}
@@ -3102,8 +3159,9 @@
* if it's grayscale).
*/
// TODO: also check bounds, transparency, that sort of thing.
- private void processLargeLegacyIcon(Bitmap largeIcon, RemoteViews contentView) {
- if (isLegacy() && mColorUtil.isGrayscaleIcon(largeIcon)) {
+ private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) {
+ if (largeIcon != null && isLegacy()
+ && mColorUtil.isGrayscaleIcon(mContext, largeIcon)) {
applyLargeIconBackground(contentView);
} else {
removeLargeIconBackground(contentView);
@@ -3137,14 +3195,16 @@
/**
* Recolor small icons when used in the R.id.right_icon slot.
*/
- private void processSmallRightIcon(int smallIconDrawableId,
- RemoteViews contentView) {
+ private void processSmallRightIcon(Icon smallIcon, RemoteViews contentView) {
if (!isLegacy()) {
contentView.setDrawableParameters(R.id.right_icon, false, -1,
0xFFFFFFFF,
PorterDuff.Mode.SRC_ATOP, -1);
}
- if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
+ final boolean gray = isLegacy()
+ && smallIcon.getType() == Icon.TYPE_RESOURCE
+ && mColorUtil.isGrayscaleIcon(mContext, smallIcon.getResId());
+ if (!isLegacy() || gray) {
contentView.setInt(R.id.right_icon,
"setBackgroundResource",
R.drawable.notification_icon_legacy_bg);
@@ -3180,7 +3240,10 @@
public Notification buildUnstyled() {
Notification n = new Notification();
n.when = mWhen;
- n.icon = mSmallIcon;
+ n.mSmallIcon = mSmallIcon;
+ if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
+ n.icon = mSmallIcon.getResId();
+ }
n.iconLevel = mSmallIconLevel;
n.number = mNumber;
@@ -3192,7 +3255,10 @@
n.fullScreenIntent = mFullScreenIntent;
n.tickerText = mTickerText;
n.tickerView = makeTickerView();
- n.largeIcon = mLargeIcon;
+ n.mLargeIcon = mLargeIcon;
+ if (mLargeIcon != null && mLargeIcon.getType() == Icon.TYPE_BITMAP) {
+ n.largeIcon = mLargeIcon.getBitmap();
+ }
n.sound = mSound;
n.audioStreamType = mAudioStreamType;
n.audioAttributes = mAudioAttributes;
@@ -3242,7 +3308,7 @@
extras.putCharSequence(EXTRA_TEXT, mContentText);
extras.putCharSequence(EXTRA_SUB_TEXT, mSubText);
extras.putCharSequence(EXTRA_INFO_TEXT, mContentInfo);
- extras.putInt(EXTRA_SMALL_ICON, mSmallIcon);
+ extras.putParcelable(EXTRA_SMALL_ICON, mSmallIcon);
extras.putInt(EXTRA_PROGRESS, mProgress);
extras.putInt(EXTRA_PROGRESS_MAX, mProgressMax);
extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
@@ -3430,7 +3496,7 @@
// Notification fields.
mWhen = n.when;
- mSmallIcon = n.icon;
+ mSmallIcon = n.mSmallIcon;
mSmallIconLevel = n.iconLevel;
mNumber = n.number;
@@ -3441,7 +3507,7 @@
mFullScreenIntent = n.fullScreenIntent;
mTickerText = n.tickerText;
mTickerView = n.tickerView;
- mLargeIcon = n.largeIcon;
+ mLargeIcon = n.mLargeIcon;
mSound = n.sound;
mAudioStreamType = n.audioStreamType;
mAudioAttributes = n.audioAttributes;
@@ -3472,7 +3538,7 @@
mContentText = extras.getCharSequence(EXTRA_TEXT);
mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT);
- mSmallIcon = extras.getInt(EXTRA_SMALL_ICON);
+ mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON);
mProgress = extras.getInt(EXTRA_PROGRESS);
mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX);
mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
@@ -3764,7 +3830,7 @@
*/
public static class BigPictureStyle extends Style {
private Bitmap mPicture;
- private Bitmap mBigLargeIcon;
+ private Icon mBigLargeIcon;
private boolean mBigLargeIconSet = false;
public BigPictureStyle() {
@@ -3803,8 +3869,15 @@
* Override the large icon when the big notification is shown.
*/
public BigPictureStyle bigLargeIcon(Bitmap b) {
+ return bigLargeIcon(b != null ? Icon.createWithBitmap(b) : null);
+ }
+
+ /**
+ * Override the large icon when the big notification is shown.
+ */
+ public BigPictureStyle bigLargeIcon(Icon icon) {
mBigLargeIconSet = true;
- mBigLargeIcon = b;
+ mBigLargeIcon = icon;
return this;
}
@@ -3815,7 +3888,7 @@
// 1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides
// mLargeIcon
// 2. !mBigLargeIconSet -> mLargeIcon applies
- Bitmap oldLargeIcon = null;
+ Icon oldLargeIcon = null;
if (mBigLargeIconSet) {
oldLargeIcon = mBuilder.mLargeIcon;
mBuilder.mLargeIcon = mBigLargeIcon;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index e4bbe27..557964b 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -23,6 +23,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ParceledListSlice;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -204,6 +205,7 @@
notification.sound.checkFileUriExposed("Notification.sound");
}
}
+ fixLegacySmallIcon(notification, pkg);
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
Notification stripped = notification.clone();
Builder.stripForDelivery(stripped);
@@ -231,6 +233,7 @@
notification.sound.checkFileUriExposed("Notification.sound");
}
}
+ fixLegacySmallIcon(notification, pkg);
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
Notification stripped = notification.clone();
Builder.stripForDelivery(stripped);
@@ -244,6 +247,12 @@
}
}
+ private void fixLegacySmallIcon(Notification n, String pkg) {
+ if (n.getSmallIcon() == null && n.icon != 0) {
+ n.setSmallIcon(Icon.createWithResource(pkg, n.icon));
+ }
+ }
+
/**
* Cancel a previously shown notification. If it's transient, the view
* will be hidden. If it's persistent, it will be removed from the status
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 470804d..87e2f9a 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -24,6 +24,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.security.KeyChain;
@@ -249,13 +250,7 @@
public static final String EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID = "android.app.extra.CHOOSE_PRIVATE_KEY_SENDER_UID";
/** @hide */
- public static final String EXTRA_CHOOSE_PRIVATE_KEY_HOST = "android.app.extra.CHOOSE_PRIVATE_KEY_HOST";
-
- /** @hide */
- public static final String EXTRA_CHOOSE_PRIVATE_KEY_PORT = "android.app.extra.CHOOSE_PRIVATE_KEY_PORT";
-
- /** @hide */
- public static final String EXTRA_CHOOSE_PRIVATE_KEY_URL = "android.app.extra.CHOOSE_PRIVATE_KEY_URL";
+ public static final String EXTRA_CHOOSE_PRIVATE_KEY_URI = "android.app.extra.CHOOSE_PRIVATE_KEY_URI";
/** @hide */
public static final String EXTRA_CHOOSE_PRIVATE_KEY_ALIAS = "android.app.extra.CHOOSE_PRIVATE_KEY_ALIAS";
@@ -487,15 +482,13 @@
* @param context The running context as per {@link #onReceive}.
* @param intent The received intent as per {@link #onReceive}.
* @param uid The uid asking for the private key and certificate pair.
- * @param host The authentication host, may be null.
- * @param port The authentication port, or -1.
- * @param url The URL to authenticate, may be null.
+ * @param uri The URI to authenticate, may be null.
* @param alias The alias preselected by the client, or null.
* @return The private key alias to return and grant access to.
* @see KeyChain#choosePrivateKeyAlias
*/
- public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, String host,
- int port, String url, String alias) {
+ public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
+ String alias) {
return null;
}
@@ -546,12 +539,9 @@
onProfileProvisioningComplete(context, intent);
} else if (ACTION_CHOOSE_PRIVATE_KEY_ALIAS.equals(action)) {
int uid = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, -1);
- String host = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_HOST);
- int port = intent.getIntExtra(EXTRA_CHOOSE_PRIVATE_KEY_PORT, -1);
- String url = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_URL);
+ Uri uri = intent.getParcelableExtra(EXTRA_CHOOSE_PRIVATE_KEY_URI);
String alias = intent.getStringExtra(EXTRA_CHOOSE_PRIVATE_KEY_ALIAS);
- String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, host, port, url,
- alias);
+ String chosenAlias = onChoosePrivateKeyAlias(context, intent, uid, uri, alias);
setResultData(chosenAlias);
} else if (ACTION_LOCK_TASK_ENTERING.equals(action)) {
String pkg = intent.getStringExtra(EXTRA_LOCK_TASK_PACKAGE);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3fb7059..55ff85a 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -402,7 +402,7 @@
* has completed successfully.
*
* <p>The broadcast is limited to the primary profile, to the app specified in the provisioning
- * intent (@see #ACTION_PROVISION_MANAGED_PROFILE).
+ * intent with action {@link #ACTION_PROVISION_MANAGED_PROFILE}.
*
* <p>This intent will contain the extra {@link #EXTRA_PROVISIONING_ACCOUNT_TO_MIGRATE} which
* corresponds to the account requested to be migrated at provisioning time, if any.
@@ -2523,13 +2523,26 @@
* {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call
* this method; if it has not, a security exception will be thrown.
*
- * <p>Calling this from a managed profile will throw a security exception.
+ * <p>Calling this from a managed profile before version
+ * {@link android.os.Build.VERSION_CODES#MNC} will throw a security exception.
+ *
+ * <p>From version {@link android.os.Build.VERSION_CODES#MNC} a profile owner can set:
+ * <ul>
+ * <li>{@link #KEYGUARD_DISABLE_TRUST_AGENTS}, {@link #KEYGUARD_DISABLE_FINGERPRINT}
+ * these will affect the profile's parent user.
+ * <li>{@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS} this will affect notifications
+ * generated by applications in the managed profile.
+ * </ul>
+ * <p>Requests to disable other features on a managed profile will be ignored. The admin
+ * can check which features have been disabled by calling
+ * {@link #getKeyguardDisabledFeatures(ComponentName)}
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param which {@link #KEYGUARD_DISABLE_FEATURES_NONE} (default),
* {@link #KEYGUARD_DISABLE_WIDGETS_ALL}, {@link #KEYGUARD_DISABLE_SECURE_CAMERA},
* {@link #KEYGUARD_DISABLE_SECURE_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_TRUST_AGENTS},
- * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FEATURES_ALL}
+ * {@link #KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS}, {@link #KEYGUARD_DISABLE_FINGERPRINT},
+ * {@link #KEYGUARD_DISABLE_FEATURES_ALL}
*/
public void setKeyguardDisabledFeatures(ComponentName admin, int which) {
if (mService != null) {
@@ -2793,17 +2806,16 @@
* @param who Which {@link DeviceAdminReceiver} this request is associated with, or null if not
* called by the device owner.
* @param initializer Which {@link DeviceAdminReceiver} to make device initializer.
- * @param initializerName The user-visible name of the device initializer.
* @return whether the component was successfully registered as the device initializer.
* @throws IllegalArgumentException if the componentname is null or invalid
* @throws IllegalStateException if the caller is not device owner or the device has
* already been provisioned or a device initializer already exists.
*/
- public boolean setDeviceInitializer(ComponentName who, ComponentName initializer,
- String initializerName) throws IllegalArgumentException, IllegalStateException {
+ public boolean setDeviceInitializer(ComponentName who, ComponentName initializer)
+ throws IllegalArgumentException, IllegalStateException {
if (mService != null) {
try {
- return mService.setDeviceInitializer(who, initializer, initializerName);
+ return mService.setDeviceInitializer(who, initializer);
} catch (RemoteException re) {
Log.w(TAG, "Failed to set device initializer");
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 481ff62..24ef604 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -23,6 +23,7 @@
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.net.ProxyInfo;
+import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.RemoteCallback;
@@ -131,7 +132,7 @@
void enforceCanManageCaCerts(in ComponentName admin);
boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);
- void choosePrivateKeyAlias(int uid, in String host, int port, in String url, in String alias, IBinder aliasCallback);
+ void choosePrivateKeyAlias(int uid, in Uri uri, in String alias, IBinder aliasCallback);
void setCertInstallerPackage(in ComponentName who, String installerPackage);
String getCertInstallerPackage(in ComponentName who);
@@ -213,7 +214,7 @@
boolean setUserEnabled(in ComponentName who);
boolean isDeviceInitializer(String packageName);
void clearDeviceInitializer(in ComponentName who);
- boolean setDeviceInitializer(in ComponentName who, in ComponentName initializer, String initializerName);
+ boolean setDeviceInitializer(in ComponentName who, in ComponentName initializer);
String getDeviceInitializer();
ComponentName getDeviceInitializerComponent();
diff --git a/core/java/android/app/backup/BackupTransport.java b/core/java/android/app/backup/BackupTransport.java
index 9540eb1..4d2158f 100644
--- a/core/java/android/app/backup/BackupTransport.java
+++ b/core/java/android/app/backup/BackupTransport.java
@@ -162,8 +162,17 @@
* this is called, {@link #finishBackup} will be called to ensure the request
* is sent and received successfully.
*
+ * <p>If the transport returns anything other than TRANSPORT_OK from this method,
+ * the OS will halt the current initialize operation and schedule a retry in the
+ * near future. Even if the transport is in a state such that attempting to
+ * "initialize" the backend storage is meaningless -- for example, if there is
+ * no current live dataset at all, or there is no authenticated account under which
+ * to store the data remotely -- the transport should return TRANSPORT_OK here
+ * and treat the initializeDevice() / finishBackup() pair as a graceful no-op.
+ *
* @return One of {@link BackupTransport#TRANSPORT_OK} (OK so far) or
- * {@link BackupTransport#TRANSPORT_ERROR} (on network error or other failure).
+ * {@link BackupTransport#TRANSPORT_ERROR} (to retry following network error
+ * or other failure).
*/
public int initializeDevice() {
return BackupTransport.TRANSPORT_ERROR;
diff --git a/core/java/android/app/usage/NetworkUsageStats.java b/core/java/android/app/usage/NetworkStats.java
similarity index 92%
rename from core/java/android/app/usage/NetworkUsageStats.java
rename to core/java/android/app/usage/NetworkStats.java
index 990d231..5193563 100644
--- a/core/java/android/app/usage/NetworkUsageStats.java
+++ b/core/java/android/app/usage/NetworkStats.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.net.INetworkStatsService;
import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
@@ -33,7 +32,7 @@
* Class providing enumeration over buckets of network usage statistics. NetworkUsageStats objects
* are returned as results to various queries in {@link NetworkStatsManager}.
*/
-public final class NetworkUsageStats implements AutoCloseable {
+public final class NetworkStats implements AutoCloseable {
private final static String TAG = "NetworkUsageStats";
private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -70,7 +69,7 @@
/**
* Results of a summary query.
*/
- private NetworkStats mSummary = null;
+ private android.net.NetworkStats mSummary = null;
/**
* Results of detail queries.
@@ -85,11 +84,11 @@
/**
* Recycling entry objects to prevent heap fragmentation.
*/
- private NetworkStats.Entry mRecycledSummaryEntry = null;
+ private android.net.NetworkStats.Entry mRecycledSummaryEntry = null;
private NetworkStatsHistory.Entry mRecycledHistoryEntry = null;
/** @hide */
- NetworkUsageStats(Context context, NetworkTemplate template, long startTimestamp,
+ NetworkStats(Context context, NetworkTemplate template, long startTimestamp,
long endTimestamp) throws RemoteException, SecurityException {
final INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
@@ -136,14 +135,19 @@
public static final int STATE_FOREGROUND = 0x2;
/**
+ * Special UID value for aggregate/unspecified.
+ */
+ public static final int UID_ALL = android.net.NetworkStats.UID_ALL;
+
+ /**
* Special UID value for removed apps.
*/
- public static final int UID_REMOVED = -4;
+ public static final int UID_REMOVED = TrafficStats.UID_REMOVED;
/**
* Special UID value for data usage by tethering.
*/
- public static final int UID_TETHERING = -5;
+ public static final int UID_TETHERING = TrafficStats.UID_TETHERING;
private int mUid;
private int mState;
@@ -156,9 +160,9 @@
private static int convertState(int networkStatsSet) {
switch (networkStatsSet) {
- case NetworkStats.SET_ALL : return STATE_ALL;
- case NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
- case NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND;
+ case android.net.NetworkStats.SET_ALL : return STATE_ALL;
+ case android.net.NetworkStats.SET_DEFAULT : return STATE_DEFAULT;
+ case android.net.NetworkStats.SET_FOREGROUND : return STATE_FOREGROUND;
}
return 0;
}
@@ -337,8 +341,8 @@
void startHistoryEnumeration(int uid) {
mHistory = null;
try {
- mHistory = mSession.getHistoryForUid(mTemplate, uid, NetworkStats.SET_ALL,
- NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
+ mHistory = mSession.getHistoryForUid(mTemplate, uid, android.net.NetworkStats.SET_ALL,
+ android.net.NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
setSingleUid(uid);
} catch (RemoteException e) {
Log.w(TAG, e);
@@ -364,8 +368,9 @@
stepUid();
mHistory = null;
try {
- mHistory = mSession.getHistoryForUid(mTemplate, getUid(), NetworkStats.SET_ALL,
- NetworkStats.TAG_NONE, NetworkStatsHistory.FIELD_ALL);
+ mHistory = mSession.getHistoryForUid(mTemplate, getUid(),
+ android.net.NetworkStats.SET_ALL, android.net.NetworkStats.TAG_NONE,
+ NetworkStatsHistory.FIELD_ALL);
} catch (RemoteException e) {
Log.w(TAG, e);
// Leaving mHistory null
@@ -405,7 +410,7 @@
}
Bucket bucket = new Bucket();
if (mRecycledSummaryEntry == null) {
- mRecycledSummaryEntry = new NetworkStats.Entry();
+ mRecycledSummaryEntry = new android.net.NetworkStats.Entry();
}
mSummary.getTotal(mRecycledSummaryEntry);
fillBucketFromSummaryEntry(bucket);
diff --git a/core/java/android/app/usage/NetworkStatsManager.java b/core/java/android/app/usage/NetworkStatsManager.java
index af7c053..2ae0181 100644
--- a/core/java/android/app/usage/NetworkStatsManager.java
+++ b/core/java/android/app/usage/NetworkStatsManager.java
@@ -16,18 +16,17 @@
package android.app.usage;
-import android.app.usage.NetworkUsageStats.Bucket;
+import android.app.usage.NetworkStats.Bucket;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkIdentity;
import android.net.NetworkTemplate;
import android.os.RemoteException;
-import android.os.UserHandle;
import android.util.Log;
/**
* Provides access to network usage history and statistics. Usage data is collected in
- * discrete bins of time called 'Buckets'. See {@link NetworkUsageStats.Bucket} for details.
+ * discrete bins of time called 'Buckets'. See {@link NetworkStats.Bucket} for details.
* <p />
* Queries can define a time interval in the form of start and end timestamps (Long.MIN_VALUE and
* Long.MAX_VALUE can be used to simulate open ended intervals). All queries (except
@@ -37,15 +36,20 @@
* <h3>
* Summary queries
* </h3>
+ * {@link #querySummaryForDevice} <p />
+ * {@link #querySummaryForUser} <p />
+ * {@link #querySummary} <p />
* These queries aggregate network usage across the whole interval. Therefore there will be only one
* bucket for a particular key and state combination. In case of the user-wide and device-wide
* summaries a single bucket containing the totalised network usage is returned.
* <h3>
* History queries
* </h3>
+ * {@link #queryDetailsForUid} <p />
+ * {@link #queryDetails} <p />
* These queries do not aggregate over time but do aggregate over state. Therefore there can be
* multiple buckets for a particular key but all Bucket's state is going to be
- * {@link NetworkUsageStats.Bucket#STATE_ALL}.
+ * {@link NetworkStats.Bucket#STATE_ALL}.
* <p />
* <b>NOTE:</b> This API requires the permission
* {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, which is a system-level permission and
@@ -68,7 +72,10 @@
}
/**
* Query network usage statistics summaries. Result is summarised data usage for the whole
- * device. Result is a single Bucket aggregated over time, state and uid.
+ * device. Result is a single Bucket aggregated over time, state and uid. This means the
+ * bucket's start and end timestamp are going to be the same as the 'startTime' and 'endTime'
+ * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
+ * {@link NetworkStats.Bucket#UID_ALL}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -89,7 +96,7 @@
}
Bucket bucket = null;
- NetworkUsageStats stats = new NetworkUsageStats(mContext, template, startTime, endTime);
+ NetworkStats stats = new NetworkStats(mContext, template, startTime, endTime);
bucket = stats.getDeviceSummaryForNetwork(startTime, endTime);
stats.close();
@@ -99,6 +106,9 @@
/**
* Query network usage statistics summaries. Result is summarised data usage for all uids
* belonging to calling user. Result is a single Bucket aggregated over time, state and uid.
+ * This means the bucket's start and end timestamp are going to be the same as the 'startTime'
+ * and 'endTime' parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid
+ * {@link NetworkStats.Bucket#UID_ALL}.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -118,8 +128,8 @@
return null;
}
- NetworkUsageStats stats;
- stats = new NetworkUsageStats(mContext, template, startTime, endTime);
+ NetworkStats stats;
+ stats = new NetworkStats(mContext, template, startTime, endTime);
stats.startSummaryEnumeration(startTime, endTime);
stats.close();
@@ -129,7 +139,9 @@
/**
* Query network usage statistics summaries. Result filtered to include only uids belonging to
* calling user. Result is aggregated over time, hence all buckets will have the same start and
- * end timestamps. Not aggregated over state or uid.
+ * end timestamps. Not aggregated over state or uid. This means buckets' start and end
+ * timestamps are going to be the same as the 'startTime' and 'endTime' parameters, state and
+ * uid are going to vary.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -142,15 +154,15 @@
* @return Statistics object or null if permissions are insufficient or error happened during
* statistics collection.
*/
- public NetworkUsageStats querySummary(int networkType, String subscriberId, long startTime,
+ public NetworkStats querySummary(int networkType, String subscriberId, long startTime,
long endTime) throws SecurityException, RemoteException {
NetworkTemplate template = createTemplate(networkType, subscriberId);
if (template == null) {
return null;
}
- NetworkUsageStats result;
- result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ NetworkStats result;
+ result = new NetworkStats(mContext, template, startTime, endTime);
result.startSummaryEnumeration(startTime, endTime);
return result;
@@ -158,7 +170,9 @@
/**
* Query network usage statistics details. Only usable for uids belonging to calling user.
- * Result is aggregated over state but not aggregated over time.
+ * Result is aggregated over state but not aggregated over time. This means buckets' start and
+ * end timestamps are going to be between 'startTime' and 'endTime' parameters, state is going
+ * to be {@link NetworkStats.Bucket#STATE_ALL} and uid the same as the 'uid' parameter.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -172,15 +186,15 @@
* @return Statistics object or null if permissions are insufficient or error happened during
* statistics collection.
*/
- public NetworkUsageStats queryDetailsForUid(int networkType, String subscriberId,
+ public NetworkStats queryDetailsForUid(int networkType, String subscriberId,
long startTime, long endTime, int uid) throws SecurityException, RemoteException {
NetworkTemplate template = createTemplate(networkType, subscriberId);
if (template == null) {
return null;
}
- NetworkUsageStats result;
- result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ NetworkStats result;
+ result = new NetworkStats(mContext, template, startTime, endTime);
result.startHistoryEnumeration(uid);
return result;
@@ -188,7 +202,9 @@
/**
* Query network usage statistics details. Result filtered to include only uids belonging to
- * calling user. Result is aggregated over state but not aggregated over time or uid.
+ * calling user. Result is aggregated over state but not aggregated over time or uid. This means
+ * buckets' start and end timestamps are going to be between 'startTime' and 'endTime'
+ * parameters, state is going to be {@link NetworkStats.Bucket#STATE_ALL} and uid will vary.
*
* @param networkType As defined in {@link ConnectivityManager}, e.g.
* {@link ConnectivityManager#TYPE_MOBILE}, {@link ConnectivityManager#TYPE_WIFI}
@@ -201,14 +217,14 @@
* @return Statistics object or null if permissions are insufficient or error happened during
* statistics collection.
*/
- public NetworkUsageStats queryDetails(int networkType, String subscriberId, long startTime,
+ public NetworkStats queryDetails(int networkType, String subscriberId, long startTime,
long endTime) throws SecurityException, RemoteException {
NetworkTemplate template = createTemplate(networkType, subscriberId);
if (template == null) {
return null;
}
- NetworkUsageStats result;
- result = new NetworkUsageStats(mContext, template, startTime, endTime);
+ NetworkStats result;
+ result = new NetworkStats(mContext, template, startTime, endTime);
result.startUserUidEnumeration();
return result;
}
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index c74bbdd..34699d8 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -234,4 +234,15 @@
}
return false;
}
+
+ /**
+ * @hide
+ */
+ public void setAppInactive(String packageName, boolean inactive) {
+ try {
+ mService.setAppInactive(packageName, inactive, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ // fall through
+ }
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 767f59e..f66b5ff 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
@@ -380,6 +382,7 @@
* @return priority of the device
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getPriority(BluetoothDevice device) {
if (VDBG) log("getPriority(" + device + ")");
if (mService != null && isEnabled()
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ec6f18d..8768f40 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -17,6 +17,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.IntDef;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -37,6 +40,8 @@
import android.util.Pair;
import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -133,6 +138,12 @@
public static final String EXTRA_PREVIOUS_STATE =
"android.bluetooth.adapter.extra.PREVIOUS_STATE";
+ /** @hide */
+ @IntDef({STATE_OFF, STATE_TURNING_ON, STATE_ON, STATE_TURNING_OFF, STATE_BLE_TURNING_ON,
+ STATE_BLE_ON, STATE_BLE_TURNING_OFF})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AdapterState {}
+
/**
* Indicates the local Bluetooth adapter is off.
*/
@@ -273,6 +284,11 @@
public static final String EXTRA_PREVIOUS_SCAN_MODE =
"android.bluetooth.adapter.extra.PREVIOUS_SCAN_MODE";
+ /** @hide */
+ @IntDef({SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE, SCAN_MODE_CONNECTABLE_DISCOVERABLE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ScanMode {}
+
/**
* Indicates that both inquiry scan and page scan are disabled on the local
* Bluetooth adapter. Therefore this device is neither discoverable
@@ -578,6 +594,7 @@
*
* @return true if the local adapter is turned on
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean isEnabled() {
try {
synchronized(mManagerCallback) {
@@ -752,6 +769,8 @@
*
* @return current state of Bluetooth adapter
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @AdapterState
public int getState() {
try {
synchronized(mManagerCallback) {
@@ -792,6 +811,8 @@
* @return current state of Bluetooth adapter
* @hide
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @AdapterState
public int getLeState() {
try {
synchronized(mManagerCallback) {
@@ -845,6 +866,7 @@
* @return true to indicate adapter startup has begun, or false on
* immediate error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean enable() {
int state = STATE_OFF;
if (isEnabled() == true){
@@ -893,6 +915,7 @@
* @return true to indicate adapter shutdown has begun, or false on
* immediate error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean disable() {
try {
return mManagerService.disable(true);
@@ -925,6 +948,7 @@
*
* @return Bluetooth hardware address as string
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public String getAddress() {
try {
return mManagerService.getAddress();
@@ -998,6 +1022,7 @@
* @param name a valid Bluetooth name
* @return true if the name was set, false otherwise
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setName(String name) {
if (getState() != STATE_ON) return false;
try {
@@ -1024,6 +1049,8 @@
*
* @return scan mode
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
+ @ScanMode
public int getScanMode() {
if (getState() != STATE_ON) return SCAN_MODE_NONE;
try {
@@ -1062,7 +1089,7 @@
* @return true if the scan mode was set, false otherwise
* @hide
*/
- public boolean setScanMode(int mode, int duration) {
+ public boolean setScanMode(@ScanMode int mode, int duration) {
if (getState() != STATE_ON) return false;
try {
synchronized(mManagerCallback) {
@@ -1130,6 +1157,7 @@
*
* @return true on success, false on error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startDiscovery() {
if (getState() != STATE_ON) return false;
try {
@@ -1157,6 +1185,7 @@
*
* @return true on success, false on error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean cancelDiscovery() {
if (getState() != STATE_ON) return false;
try {
@@ -1186,6 +1215,7 @@
*
* @return true if discovering
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean isDiscovering() {
if (getState() != STATE_ON) return false;
try {
@@ -1345,6 +1375,7 @@
*
* @return unmodifiable set of {@link BluetoothDevice}, or null on error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public Set<BluetoothDevice> getBondedDevices() {
if (getState() != STATE_ON) {
return toDeviceSet(new BluetoothDevice[0]);
@@ -1396,6 +1427,7 @@
* {@link BluetoothProfile#STATE_CONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING}
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getProfileConnectionState(int profile) {
if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED;
try {
@@ -1460,6 +1492,7 @@
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions, or channel in use.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothServerSocket listenUsingRfcommWithServiceRecord(String name, UUID uuid)
throws IOException {
return createNewRfcommSocketAndRecord(name, uuid, true, true);
@@ -1491,6 +1524,7 @@
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions, or channel in use.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String name, UUID uuid)
throws IOException {
return createNewRfcommSocketAndRecord(name, uuid, false, false);
@@ -2032,6 +2066,7 @@
* instead.
*/
@Deprecated
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startLeScan(LeScanCallback callback) {
return startLeScan(null, callback);
}
@@ -2052,6 +2087,7 @@
* instead.
*/
@Deprecated
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean startLeScan(final UUID[] serviceUuids, final LeScanCallback callback) {
if (DBG) Log.d(TAG, "startLeScan(): " + serviceUuids);
if (callback == null) {
@@ -2138,6 +2174,7 @@
* @deprecated Use {@link BluetoothLeScanner#stopScan(ScanCallback)} instead.
*/
@Deprecated
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void stopLeScan(LeScanCallback callback) {
if (DBG) Log.d(TAG, "stopLeScan()");
BluetoothLeScanner scanner = getBluetoothLeScanner();
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index bfc374fb..26a91e4 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -709,6 +711,7 @@
*
* @return the Bluetooth name, or null if there was a problem.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public String getName() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
@@ -729,6 +732,7 @@
* {@link #DEVICE_TYPE_DUAL}.
* {@link #DEVICE_TYPE_UNKNOWN} if it's not available
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getType() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
@@ -807,6 +811,7 @@
*
* @return false on immediate error, true if bonding will begin
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean createBond() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
@@ -948,6 +953,7 @@
*
* @return the bond state
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getBondState() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot get bond state");
@@ -1014,6 +1020,7 @@
*
* @return Bluetooth class object, or null on error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothClass getBluetoothClass() {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
@@ -1039,6 +1046,7 @@
* @return the supported features (UUIDs) of the remote device,
* or null on error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public ParcelUuid[] getUuids() {
if (sService == null || isBluetoothEnabled() == false) {
Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
@@ -1065,6 +1073,7 @@
* of initiating an ACL connection to the remote device
* was started.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public boolean fetchUuidsWithSdp() {
IBluetooth service = sService;
if (service == null || isBluetoothEnabled() == false) {
@@ -1144,6 +1153,7 @@
* @return true confirmation has been sent out
* false for error
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public boolean setPairingConfirmation(boolean confirm) {
if (sService == null) {
Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
@@ -1405,6 +1415,7 @@
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
if (isBluetoothEnabled() == false) {
Log.e(TAG, "Bluetooth is not enabled");
@@ -1443,6 +1454,7 @@
* @throws IOException on error, for example Bluetooth not available, or
* insufficient permissions
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
if (isBluetoothEnabled() == false) {
Log.e(TAG, "Bluetooth is not enabled");
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index b1618cf3..e355a1c 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -16,6 +16,8 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
@@ -89,6 +91,7 @@
* {@link BluetoothProfile#STATE_DISCONNECTED},
* {@link BluetoothProfile#STATE_DISCONNECTING}
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getConnectionState(BluetoothDevice device, int profile) {
if (DBG) Log.d(TAG,"getConnectionState()");
@@ -117,6 +120,7 @@
* @param profile GATT or GATT_SERVER
* @return List of devices. The list will be empty on error.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getConnectedDevices(int profile) {
if (DBG) Log.d(TAG,"getConnectedDevices");
if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
@@ -161,6 +165,7 @@
* {@link BluetoothProfile#STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates");
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index eecb073..cbce22c 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -17,6 +17,9 @@
package android.bluetooth;
+import android.Manifest;
+import android.annotation.RequiresPermission;
+
import java.util.List;
/**
@@ -163,6 +166,7 @@
*
* @return List of devices. The list will be empty on error.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getConnectedDevices();
/**
@@ -179,6 +183,7 @@
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING},
* @return List of devices. The list will be empty on error.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states);
/**
@@ -191,6 +196,7 @@
* {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING},
* {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH)
public int getConnectionState(BluetoothDevice device);
/**
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 687bd5d..2e6c4f0 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -16,6 +16,8 @@
package android.bluetooth.le;
+import android.Manifest;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
@@ -80,6 +82,7 @@
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code callback} is null.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(final ScanCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback is null");
@@ -97,6 +100,7 @@
* @param callback Callback used to deliver scan results.
* @throws IllegalArgumentException If {@code settings} or {@code callback} is null.
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void startScan(List<ScanFilter> filters, ScanSettings settings,
final ScanCallback callback) {
startScan(filters, settings, callback, null);
@@ -151,6 +155,7 @@
*
* @param callback
*/
+ @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
public void stopScan(ScanCallback callback) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
synchronized (mLeScanClients) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6a98950..a434c7b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -134,7 +134,15 @@
* explicitly set if desired.
*
* @see #getSharedPreferences
+ *
+ * @deprecated MODE_MULTI_PROCESS does not work reliably in
+ * some versions of Android, and furthermore does not provide any
+ * mechanism for reconciling concurrent modifications across
+ * processes. Applications should not attempt to use it. Instead,
+ * they should use an explicit cross-process data management
+ * approach such as {@link android.content.ContentProvider ContentProvider}.
*/
+ @Deprecated
public static final int MODE_MULTI_PROCESS = 0x0004;
/**
@@ -604,11 +612,7 @@
* editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
* @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
* default operation, {@link #MODE_WORLD_READABLE}
- * and {@link #MODE_WORLD_WRITEABLE} to control permissions. The bit
- * {@link #MODE_MULTI_PROCESS} can also be used if multiple processes
- * are mutating the same SharedPreferences file. {@link #MODE_MULTI_PROCESS}
- * is always on in apps targeting Gingerbread (Android 2.3) and below, and
- * off by default in later versions.
+ * and {@link #MODE_WORLD_WRITEABLE} to control permissions.
*
* @return The single {@link SharedPreferences} instance that can be used
* to retrieve and modify the preference values.
@@ -616,7 +620,6 @@
* @see #MODE_PRIVATE
* @see #MODE_WORLD_READABLE
* @see #MODE_WORLD_WRITEABLE
- * @see #MODE_MULTI_PROCESS
*/
public abstract SharedPreferences getSharedPreferences(String name,
int mode);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 7d76760..2db623b 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1535,6 +1535,22 @@
"android.intent.action.MANAGE_APP_PERMISSIONS";
/**
+ * Activity action: Launch UI to manage permissions.
+ * <p>
+ * Input: Nothing.
+ * </p>
+ * <p>
+ * Output: Nothing.
+ * </p>
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_MANAGE_PERMISSIONS =
+ "android.intent.action.MANAGE_PERMISSIONS";
+
+ /**
* Intent extra: An app package name.
* <p>
* Type: String
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 707ef30..96bb2ee 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -107,6 +107,8 @@
*
* @see {@link android.content.Context#getNoBackupFilesDir}
* @see {@link #FLAG_ALLOW_BACKUP}
+ *
+ * @hide
*/
public int fullBackupContent = 0;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 6401fe6..2ca0306 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -653,6 +653,16 @@
public static final int INSTALL_FAILED_VERSION_DOWNGRADE = -25;
/**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the old package has target SDK high enough to support runtime permission and
+ * the new package has target SDK low enough to not support runtime permissions.
+ * @hide
+ */
+ @SystemApi
+ public static final int INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE = -26;
+
+ /**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser was given a path that is not a file, or does not end with the expected
@@ -1930,6 +1940,14 @@
@SystemApi
public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 1 << 3;
+ /**
+ * Permission flag: The permission is set in its current state
+ * because the app is a component that is a part of the system.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_SYSTEM_FIXED = 1 << 4;
/**
* Mask for all permission flags.
@@ -1937,7 +1955,7 @@
* @hide
*/
@SystemApi
- public static final int MASK_PERMISSION_FLAGS = 0xF;
+ public static final int MASK_PERMISSION_FLAGS = 0xFF;
/**
* Retrieve overall information about an application package that is
@@ -2435,7 +2453,8 @@
@IntDef({FLAG_PERMISSION_USER_SET,
FLAG_PERMISSION_USER_FIXED,
FLAG_PERMISSION_POLICY_FIXED,
- FLAG_PERMISSION_REVOKE_ON_UPGRADE})
+ FLAG_PERMISSION_REVOKE_ON_UPGRADE,
+ FLAG_PERMISSION_SYSTEM_FIXED})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionFlags {}
@@ -3730,6 +3749,7 @@
*
* @hide
*/
+ @SystemApi
public abstract void verifyIntentFilter(int verificationId, int verificationCode,
List<String> outFailedDomains);
@@ -4502,6 +4522,7 @@
case INSTALL_FAILED_PACKAGE_CHANGED: return PackageInstaller.STATUS_FAILURE_INVALID;
case INSTALL_FAILED_UID_CHANGED: return PackageInstaller.STATUS_FAILURE_INVALID;
case INSTALL_FAILED_VERSION_DOWNGRADE: return PackageInstaller.STATUS_FAILURE_INVALID;
+ case INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE: return PackageInstaller.STATUS_FAILURE_INVALID;
case INSTALL_PARSE_FAILED_NOT_APK: return PackageInstaller.STATUS_FAILURE_INVALID;
case INSTALL_PARSE_FAILED_BAD_MANIFEST: return PackageInstaller.STATUS_FAILURE_INVALID;
case INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: return PackageInstaller.STATUS_FAILURE_INVALID;
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index c2d2f65..0bd2a3b 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -52,6 +52,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -573,7 +574,7 @@
private void readPersistentServicesLocked(InputStream is)
throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(is, null);
+ parser.setInput(is, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG
&& eventType != XmlPullParser.END_DOCUMENT) {
@@ -663,7 +664,7 @@
try {
fos = atomicFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "services");
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 7b96e20..9201b614 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -81,5 +81,5 @@
*
* Callers require the android.permission.CAMERA_SEND_SYSTEM_EVENTS permission.
*/
- oneway void notifySystemEvent(int eventId, int arg0);
+ oneway void notifySystemEvent(int eventId, in int[] args);
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index ef71c42..c6f622c 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -29,11 +29,11 @@
* <p>A CameraCaptureSession is created by providing a set of target output surfaces to
* {@link CameraDevice#createCaptureSession createCaptureSession}, or by providing an
* {@link android.hardware.camera2.params.InputConfiguration} and a set of target output surfaces to
- * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} for a
- * reprocessible capture session. Once created, the session is active until a new session is
+ * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} for a
+ * reprocessable capture session. Once created, the session is active until a new session is
* created by the camera device, or the camera device is closed.</p>
*
- * <p>All capture sessions can be used for capturing images from the camera but only reprocessible
+ * <p>All capture sessions can be used for capturing images from the camera but only reprocessable
* capture sessions can reprocess images captured from the camera in the same session previously.
* </p>
*
@@ -41,7 +41,7 @@
* it requires configuring the camera device's internal pipelines and allocating memory buffers for
* sending images to the desired targets. Therefore the setup is done asynchronously, and
* {@link CameraDevice#createCaptureSession createCaptureSession} and
- * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession} will
+ * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession} will
* send the ready-to-use CameraCaptureSession to the provided listener's
* {@link CameraCaptureSession.StateCallback#onConfigured onConfigured} callback. If configuration
* cannot be completed, then the
@@ -156,7 +156,7 @@
*
* <p>All capture sessions can be used for capturing images from the camera but only capture
* sessions created by
- * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession}
+ * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession}
* can submit reprocess capture requests. Submitting a reprocess request to a regular capture
* session will result in an {@link IllegalArgumentException}.</p>
*
@@ -177,19 +177,22 @@
* was explicitly closed, a new session has been created
* or the camera device has been closed.
* @throws IllegalArgumentException if the request targets no Surfaces or Surfaces that are not
- * configured as outputs for this session; or a reprocess
- * capture request is submitted in a non-reprocessible capture
- * session; or the reprocess capture request was created with
- * a {@link TotalCaptureResult} from a different session; or
- * the capture targets a Surface in the middle of being
- * {@link #prepare prepared}; or the handler is null, the
- * listener is not null, and the calling thread has no looper.
+ * configured as outputs for this session; or the request
+ * targets a set of Surfaces that cannot be submitted
+ * simultaneously in a reprocessable capture session; or a
+ * reprocess capture request is submitted in a
+ * non-reprocessable capture session; or the reprocess capture
+ * request was created with a {@link TotalCaptureResult} from
+ * a different session; or the capture targets a Surface in
+ * the middle of being {@link #prepare prepared}; or the
+ * handler is null, the listener is not null, and the calling
+ * thread has no looper.
*
* @see #captureBurst
* @see #setRepeatingRequest
* @see #setRepeatingBurst
* @see #abortCaptures
- * @see CameraDevice#createReprocessibleCaptureSession
+ * @see CameraDevice#createReprocessableCaptureSession
*/
public abstract int capture(CaptureRequest request, CaptureCallback listener, Handler handler)
throws CameraAccessException;
@@ -211,7 +214,7 @@
*
* <p>All capture sessions can be used for capturing images from the camera but only capture
* sessions created by
- * {@link CameraDevice#createReprocessibleCaptureSession createReprocessibleCaptureSession}
+ * {@link CameraDevice#createReprocessableCaptureSession createReprocessableCaptureSession}
* can submit reprocess capture requests. Submitting a reprocess request to a regular
* capture session will result in an {@link IllegalArgumentException}.</p>
*
@@ -233,14 +236,16 @@
* was explicitly closed, a new session has been created
* or the camera device has been closed.
* @throws IllegalArgumentException If the requests target no Surfaces, or the requests target
- * Surfaces not currently configured as outputs; or a reprocess
- * capture request is submitted in a non-reprocessible capture
- * session; or one of the reprocess capture requests was
- * created with a {@link TotalCaptureResult} from a different
- * session; or one of the captures targets a Surface in the
- * middle of being {@link #prepare prepared}; or if the handler
- * is null, the listener is not null, and the calling thread
- * has no looper.
+ * Surfaces not currently configured as outputs; or one of the
+ * requests targets a set of Surfaces that cannot be submitted
+ * simultaneously in a reprocessable capture session; or a
+ * reprocess capture request is submitted in a
+ * non-reprocessable capture session; or one of the reprocess
+ * capture requests was created with a
+ * {@link TotalCaptureResult} from a different session; or one
+ * of the captures targets a Surface in the middle of being
+ * {@link #prepare prepared}; or if the handler is null, the
+ * listener is not null, and the calling thread has no looper.
*
* @see #capture
* @see #setRepeatingRequest
@@ -420,7 +425,7 @@
*
* <p>This method is the fastest way to switch the camera device to a new session with
* {@link CameraDevice#createCaptureSession} or
- * {@link CameraDevice#createReprocessibleCaptureSession}, at the cost of discarding in-progress
+ * {@link CameraDevice#createReprocessableCaptureSession}, at the cost of discarding in-progress
* work. It must be called before the new session is created. Once all pending requests are
* either completed or thrown away, the {@link StateCallback#onReady} callback will be called,
* if the session has not been closed. Otherwise, the {@link StateCallback#onClosed}
@@ -443,7 +448,7 @@
* @see #setRepeatingRequest
* @see #setRepeatingBurst
* @see CameraDevice#createCaptureSession
- * @see CameraDevice#createReprocessibleCaptureSession
+ * @see CameraDevice#createReprocessableCaptureSession
*/
public abstract void abortCaptures() throws CameraAccessException;
@@ -454,14 +459,14 @@
* @return {@code true} if the application can submit reprocess capture requests with this
* camera capture session. {@code false} otherwise.
*
- * @see CameraDevice#createReprocessibleCaptureSession
+ * @see CameraDevice#createReprocessableCaptureSession
*/
- public abstract boolean isReprocessible();
+ public abstract boolean isReprocessable();
/**
- * Get the input Surface associated with a reprocessible capture session.
+ * Get the input Surface associated with a reprocessable capture session.
*
- * <p>Each reprocessible capture session has an input {@link Surface} where the reprocess
+ * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess
* capture requests get the input images from, rather than the camera device. The application
* can create a {@link android.media.ImageWriter} with this input {@link Surface} and use it to
* provide input images for reprocess capture requests.</p>
@@ -469,7 +474,7 @@
* @return The {@link Surface} where reprocessing capture requests get the input images from. If
* this is not a reprocess capture session, {@code null} will be returned.
*
- * @see CameraDevice#createReprocessibleCaptureSession
+ * @see CameraDevice#createReprocessableCaptureSession
* @see android.media.ImageWriter
* @see android.media.ImageReader
*/
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 19e821c..d3b63f9 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1239,7 +1239,7 @@
* only the input buffer will be used to produce these output stream buffers, and a
* new sensor image will not be captured.</p>
* <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
- * stream image format will be OPAQUE, the associated output stream image format
+ * stream image format will be PRIVATE, the associated output stream image format
* should be JPEG.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>0 or 1.</p>
@@ -1326,7 +1326,7 @@
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING MANUAL_POST_PROCESSING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}</li>
- * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}</li>
+ * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING PRIVATE_REPROCESSING}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS READ_SENSOR_SETTINGS}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}</li>
* <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}</li>
@@ -1339,7 +1339,7 @@
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
* @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_RAW
- * @see #REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING
+ * @see #REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING
* @see #REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS
* @see #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE
* @see #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING
@@ -1536,12 +1536,12 @@
* <tr>
* <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
* <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
- * <td align="left">OPAQUE_REPROCESSING</td>
+ * <td align="left">PRIVATE_REPROCESSING</td>
* </tr>
* <tr>
* <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
* <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
- * <td align="left">OPAQUE_REPROCESSING</td>
+ * <td align="left">PRIVATE_REPROCESSING</td>
* </tr>
* <tr>
* <td align="left">{@link android.graphics.ImageFormat#YUV_420_888 }</td>
@@ -1556,8 +1556,9 @@
* </tbody>
* </table>
* <p>PRIVATE refers to a device-internal format that is not directly application-visible. A
- * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newOpaqueInstance }.</p>
- * <p>For a OPAQUE_REPROCESSING-capable camera device, using the PRIVATE format as either input
+ * PRIVATE input surface can be acquired by {@link android.media.ImageReader#newInstance }
+ * with {@link android.graphics.ImageFormat#PRIVATE } as the format.</p>
+ * <p>For a PRIVATE_REPROCESSING-capable camera device, using the PRIVATE format as either input
* or output will never hurt maximum frame rate (i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p>
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
@@ -2647,8 +2648,8 @@
* formats/sizes combination.</p>
* <p>If this key reports 0, it means a reprocess request doesn't introduce any glitch to the
* ongoing camera repeating request outputs, as if this reprocess request is never issued.</p>
- * <p>This key is supported if the camera device supports OPAQUE or YUV reprocessing (
- * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains OPAQUE_REPROCESSING or
+ * <p>This key is supported if the camera device supports PRIVATE or YUV reprocessing (
+ * i.e. {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains PRIVATE_REPROCESSING or
* YUV_REPROCESSING).</p>
* <p><b>Units</b>: Number of frames.</p>
* <p><b>Range of valid values:</b><br>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index e9564b3..dad4fb6 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -100,7 +100,7 @@
* means maximizing image quality without compromising preview frame rate.
* AE/AWB/AF should be on auto mode.
* This template is guaranteed to be supported on camera devices that support the
- * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING OPAQUE_REPROCESSING}
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING PRIVATE_REPROCESSING}
* capability or the
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}
* capability.
@@ -409,31 +409,34 @@
CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException;
/**
- * Create a new reprocessible camera capture session by providing the desired reprocessing
+ * Create a new reprocessable camera capture session by providing the desired reprocessing
* input Surface configuration and the target output set of Surfaces to the camera device.
*
* <p>If a camera device supports YUV reprocessing
- * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING}) or OPAQUE
+ * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING}) or PRIVATE
* reprocessing
- * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING}), besides
- * the capture session created via {@link #createCaptureSession}, the application can also
- * create a reprocessible capture session to submit reprocess capture requests in addition to
- * regular capture requests. A reprocess capture request takes the next available buffer from
- * the session's input Surface, and sends it through the camera device's processing pipeline
- * again, to produce buffers for the request's target output Surfaces. No new image data is
- * captured for a reprocess request. However the input buffer provided by
+ * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING}), besides
+ * the capture session created via {@link #createCaptureSession createCaptureSession}, the
+ * application can also create a reprocessable capture session to submit reprocess capture
+ * requests in addition to regular capture requests. A reprocess capture request takes the next
+ * available buffer from the session's input Surface, and sends it through the camera device's
+ * processing pipeline again, to produce buffers for the request's target output Surfaces. No
+ * new image data is captured for a reprocess request. However the input buffer provided by
* the application must be captured previously by the same camera device in the same session
* directly (e.g. for Zero-Shutter-Lag use case) or indirectly (e.g. combining multiple output
* images).</p>
*
- * <p>The active reprocessible capture session determines an input {@link Surface} and the set
+ * <p>The active reprocessable capture session determines an input {@link Surface} and the set
* of potential output Surfaces for the camera devices for each capture request. The application
- * can use {@link #createCaptureRequest} to create regular capture requests to capture new
- * images from the camera device, and use {@link #createReprocessCaptureRequest} to create
- * reprocess capture requests to process buffers from the input {@link Surface}. A request may
- * use all or only some of the outputs. All the output Surfaces in one capture request will come
- * from the same source, either from a new capture by the camera device, or from the input
- * Surface depending on if the request is a reprocess capture request.</p>
+ * can use {@link #createCaptureRequest createCaptureRequest} to create regular capture requests
+ * to capture new images from the camera device, and use {@link #createReprocessCaptureRequest
+ * createReprocessCaptureRequest} to create reprocess capture requests to process buffers from
+ * the input {@link Surface}. Some combinations of output Surfaces in a session may not be used
+ * in a request simultaneously. The guaranteed combinations of output Surfaces that can be used
+ * in a request simultaneously are listed in the tables under {@link #createCaptureSession
+ * createCaptureSession}. All the output Surfaces in one capture request will come from the
+ * same source, either from a new capture by the camera device, or from the input Surface
+ * depending on if the request is a reprocess capture request.</p>
*
* <p>Input formats and sizes supported by the camera device can be queried via
* {@link StreamConfigurationMap#getInputFormats} and
@@ -445,11 +448,93 @@
* they cannot be used as targets for a reprocessing request.</p>
*
* <p>Since the application cannot access {@link android.graphics.ImageFormat#PRIVATE} images
- * directly, an output Surface created by {@link android.media.ImageReader#newOpaqueInstance}
- * will be considered as intended to be used for reprocessing input and thus the
- * {@link android.media.ImageReader} size must match one of the supported input sizes for
- * {@link android.graphics.ImageFormat#PRIVATE} format. Otherwise, creating a reprocessible
- * capture session will fail.</p>
+ * directly, an output Surface created by {@link android.media.ImageReader#newInstance} with
+ * {@link android.graphics.ImageFormat#PRIVATE} as the format will be considered as intended to
+ * be used for reprocessing input and thus the {@link android.media.ImageReader} size must
+ * match one of the supported input sizes for {@link android.graphics.ImageFormat#PRIVATE}
+ * format. Otherwise, creating a reprocessable capture session will fail.</p>
+ *
+ * <p>The guaranteed stream configurations listed in
+ * {@link #createCaptureSession createCaptureSession} are also guaranteed to work for
+ * {@link #createReprocessableCaptureSession createReprocessableCaptureSession}. In addition,
+ * the configurations in the tables below are also guaranteed for creating a reprocessable
+ * capture session if the camera device supports YUV reprocessing or PRIVATE reprocessing.
+ * However, not all output targets used to create a reprocessable session may be used in a
+ * {@link CaptureRequest} simultaneously. The guaranteed output targets that can be included
+ * in a {@link CaptureRequest} simultaneously are listed in the tables under
+ * {@link #createCaptureSession createCaptureSession}. For example, with a FULL-capability
+ * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} {@code == }
+ * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) device that supports PRIVATE
+ * reprocessing, an application can create a reprocessable capture session with 1 input,
+ * ({@code PRIV}, {@code MAXIMUM}), and 3 outputs, ({@code PRIV}, {@code MAXIMUM}),
+ * ({@code PRIV}, {@code PREVIEW}), and ({@code YUV}, {@code MAXIMUM}). However, it's not
+ * guaranteed that an application can submit a regular or reprocess capture with ({@code PRIV},
+ * {@code MAXIMUM}) and ({@code YUV}, {@code MAXIMUM}) outputs based on the table listed under
+ * {@link #createCaptureSession createCaptureSession}. In other words, use the tables below to
+ * determine the guaranteed stream configurations for creating a reprocessable capture session,
+ * and use the tables under {@link #createCaptureSession createCaptureSession} to determine the
+ * guaranteed output targets that can be submitted in a regular or reprocess
+ * {@link CaptureRequest} simultaneously.</p>
+ *
+ * <style scoped>
+ * #rb { border-right-width: thick; }
+ * </style>
+ *
+ * <p>Limited-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED}) devices
+ * support at least the following stream combinations for creating a reprocessable capture
+ * session in addition to those listed in {@link #createCaptureSession createCaptureSession} for
+ * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices:
+ *
+ * <table>
+ * <tr><th colspan="11">LIMITED-level additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr>
+ * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr>
+ * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>No-viewfinder still image reprocessing.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>ZSL(Zero-Shutter-Lag) still imaging.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>ZSL still and in-app processing imaging.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>ZSL in-app processing with still capture.</td> </tr>
+ * </table><br>
+ * </p>
+ *
+ * <p>FULL-capability ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
+ * {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) devices
+ * support at least the following stream combinations for creating a reprocessable capture
+ * session in addition to those for
+ * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices:
+ *
+ * <table>
+ * <tr><th colspan="11">FULL-capability additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr>
+ * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr>
+ * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
+ * <tr> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>Maximum-resolution multi-frame image fusion in-app processing with regular preview.</td> </tr>
+ * <tr> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td></td><td id="rb"></td> <td></td><td id="rb"></td> <td>Maximum-resolution multi-frame image fusion two-input in-app processing.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code RECORD}</td> <td></td><td id="rb"></td> <td>High-resolution ZSL in-app video processing with regular preview.</td> </tr>
+ * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Maximum-resolution ZSL in-app processing with regular preview.</td> </tr>
+ * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Maximum-resolution two-input ZSL in-app processing.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code RECORD}</td> <td>{@code JPEG}</td><td id="rb">{@code RECORD}</td> <td>High-resolution ZSL in-app video processing and video snapshot with regular preview.</td> </tr>
+ * <tr> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution two-input ZSL in-app processing with regular preview.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>ZSL still capture and in-app processing.</td> </tr>
+ * </table><br>
+ * </p>
+ *
+ * <p>RAW-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} includes
+ * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_RAW RAW}) devices additionally support
+ * at least the following stream combinations for creating a reprocessable capture session
+ * on both {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL} and
+ * {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED LIMITED} devices
+ *
+ * <table>
+ * <tr><th colspan="11">RAW-capability additional guaranteed configurations for creating a reprocessable capture session<br>({@code PRIV} input is guaranteed only if PRIVATE reprocessing is supported. {@code YUV} input is guaranteed only if YUV reprocessing is supported)</th></tr>
+ * <tr><th colspan="2" id="rb">Input</th><th colspan="2" id="rb">Target 1</th><th colspan="2" id="rb">Target 2</th><th colspan="2" id="rb">Target 3</th><th colspan="2" id="rb">Target 4</th><th rowspan="2">Sample use case(s)</th> </tr>
+ * <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th></tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td></td><td id="rb"></td> <td>Mutually exclusive ZSL in-app processing and DNG capture.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>Mutually exclusive ZSL in-app processing and preview with DNG capture.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>Mutually exclusive ZSL two-input in-app processing and DNG capture.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>Mutually exclusive ZSL still capture and preview with DNG capture.</td> </tr>
+ * <tr> <td>{@code PRIV}/{@code YUV}</td><td id="rb">{@code MAXIMUM}</td> <td>Same as input</td><td id="rb">{@code MAXIMUM}</td> <td>{@code YUV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>{@code RAW}</td><td id="rb">{@code MAXIMUM}</td> <td>Mutually exclusive ZSL in-app processing with still capture and DNG capture.</td> </tr>
+ * </table><br>
+ * </p>
*
* @param inputConfig The configuration for the input {@link Surface}
* @param outputs The new set of Surfaces that should be made available as
@@ -466,6 +551,7 @@
* encountered a fatal error
* @throws IllegalStateException if the camera device has been closed
*
+ * @see #createCaptureSession
* @see CameraCaptureSession
* @see StreamConfigurationMap#getInputFormats
* @see StreamConfigurationMap#getInputSizes
@@ -474,7 +560,7 @@
* @see android.media.ImageWriter
* @see android.media.ImageReader
*/
- public abstract void createReprocessibleCaptureSession(InputConfiguration inputConfig,
+ public abstract void createReprocessableCaptureSession(InputConfiguration inputConfig,
List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException;
@@ -516,8 +602,7 @@
* {@link CameraCaptureSession}'s input {@link Surface} to all output {@link Surface Surfaces}
* included in the reprocess capture request. The reprocess input images must be generated from
* one or multiple output images captured from the same camera device. The application can
- * provide input images to camera device via
- * {{@link android.media.ImageWriter#queueInputImage ImageWriter#queueInputImage}}.
+ * provide input images to camera device via {@link android.media.ImageWriter#queueInputImage}.
* The application must use the capture result of one of those output images to create a
* reprocess capture request so that the camera device can use the information to achieve
* optimal reprocess image quality.
@@ -532,7 +617,7 @@
*
* @see CaptureRequest.Builder
* @see TotalCaptureResult
- * @see CameraDevice#createReprocessibleCaptureSession
+ * @see CameraDevice#createReprocessableCaptureSession
* @see android.media.ImageWriter
*/
public abstract CaptureRequest.Builder createReprocessCaptureRequest(
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 9327f00..d99cce7 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -556,7 +556,7 @@
* {@link CameraManager#registerTorchCallback} to be notified of such status changes.
* </p>
*
- * @see registerTorchCallback
+ * @see #registerTorchCallback
*/
public static abstract class TorchCallback {
/**
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index ca9439b..6baa660 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -388,8 +388,8 @@
* <li>{@link CaptureRequest#TONEMAP_CURVE android.tonemap.curve}</li>
* <li>{@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}</li>
* <li>{@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</li>
- * <li>android.tonemap.gamma</li>
- * <li>android.tonemap.presetCurve</li>
+ * <li>{@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma}</li>
+ * <li>{@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve}</li>
* </ul>
* </li>
* <li>
@@ -429,8 +429,10 @@
* @see CaptureRequest#SHADING_MODE
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @see CaptureRequest#TONEMAP_CURVE
+ * @see CaptureRequest#TONEMAP_GAMMA
* @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
* @see CaptureRequest#TONEMAP_MODE
+ * @see CaptureRequest#TONEMAP_PRESET_CURVE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2;
@@ -472,7 +474,7 @@
* <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both
* {@link android.graphics.ImageFormat#YUV_420_888 } and
* {@link android.graphics.ImageFormat#JPEG } formats.</li>
- * <li>The maximum available resolution for OPAQUE streams
+ * <li>The maximum available resolution for PRIVATE streams
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
* <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
@@ -492,7 +494,7 @@
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
- public static final int REQUEST_AVAILABLE_CAPABILITIES_OPAQUE_REPROCESSING = 4;
+ public static final int REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING = 4;
/**
* <p>The camera device supports accurately reporting the sensor settings for many of
@@ -565,7 +567,7 @@
/**
* <p>The camera device supports the YUV_420_888 reprocessing use case, similar as
- * OPAQUE_REPROCESSING, This capability requires the camera device to support the
+ * PRIVATE_REPROCESSING, This capability requires the camera device to support the
* following:</p>
* <ul>
* <li>One input stream is supported, that is, <code>{@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} == 1</code>.</li>
@@ -2185,22 +2187,26 @@
public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
/**
- * <p>Use the gamma value specified in android.tonemap.gamma to peform
+ * <p>Use the gamma value specified in {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma} to peform
* tonemapping.</p>
* <p>All color enhancement and tonemapping must be disabled, except
- * for applying the tonemapping curve specified by android.tonemap.gamma.</p>
+ * for applying the tonemapping curve specified by {@link CaptureRequest#TONEMAP_GAMMA android.tonemap.gamma}.</p>
* <p>Must not slow down frame rate relative to raw sensor output.</p>
+ *
+ * @see CaptureRequest#TONEMAP_GAMMA
* @see CaptureRequest#TONEMAP_MODE
*/
public static final int TONEMAP_MODE_GAMMA_VALUE = 3;
/**
* <p>Use the preset tonemapping curve specified in
- * android.tonemap.presetCurve to peform tonemapping.</p>
+ * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve} to peform tonemapping.</p>
* <p>All color enhancement and tonemapping must be disabled, except
* for applying the tonemapping curve specified by
- * android.tonemap.presetCurve.</p>
+ * {@link CaptureRequest#TONEMAP_PRESET_CURVE android.tonemap.presetCurve}.</p>
* <p>Must not slow down frame rate relative to raw sensor output.</p>
+ *
+ * @see CaptureRequest#TONEMAP_PRESET_CURVE
* @see CaptureRequest#TONEMAP_MODE
*/
public static final int TONEMAP_MODE_PRESET_CURVE = 4;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index ab6ce91..5fb9abc 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -158,9 +158,9 @@
private final HashSet<Surface> mSurfaceSet;
private final CameraMetadataNative mSettings;
private boolean mIsReprocess;
- // Each reprocess request must be tied to a reprocessible session ID.
+ // Each reprocess request must be tied to a reprocessable session ID.
// Valid only for reprocess requests (mIsReprocess == true).
- private int mReprocessibleSessionId;
+ private int mReprocessableSessionId;
private Object mUserTag;
@@ -173,7 +173,7 @@
mSettings = new CameraMetadataNative();
mSurfaceSet = new HashSet<Surface>();
mIsReprocess = false;
- mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE;
+ mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
}
/**
@@ -186,7 +186,7 @@
mSettings = new CameraMetadataNative(source.mSettings);
mSurfaceSet = (HashSet<Surface>) source.mSurfaceSet.clone();
mIsReprocess = source.mIsReprocess;
- mReprocessibleSessionId = source.mReprocessibleSessionId;
+ mReprocessableSessionId = source.mReprocessableSessionId;
mUserTag = source.mUserTag;
}
@@ -199,30 +199,30 @@
* @param isReprocess Indicates whether to create a reprocess capture request. {@code true}
* to create a reprocess capture request. {@code false} to create a regular
* capture request.
- * @param reprocessibleSessionId The ID of the camera capture session this capture is created
+ * @param reprocessableSessionId The ID of the camera capture session this capture is created
* for. This is used to validate if the application submits a
* reprocess capture request to the same session where
* the {@link TotalCaptureResult}, used to create the reprocess
* capture, came from.
*
* @throws IllegalArgumentException If creating a reprocess capture request with an invalid
- * reprocessibleSessionId.
+ * reprocessableSessionId.
*
* @see CameraDevice#createReprocessCaptureRequest
*/
private CaptureRequest(CameraMetadataNative settings, boolean isReprocess,
- int reprocessibleSessionId) {
+ int reprocessableSessionId) {
mSettings = CameraMetadataNative.move(settings);
mSurfaceSet = new HashSet<Surface>();
mIsReprocess = isReprocess;
if (isReprocess) {
- if (reprocessibleSessionId == CameraCaptureSession.SESSION_ID_NONE) {
+ if (reprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) {
throw new IllegalArgumentException("Create a reprocess capture request with an " +
- "invalid session ID: " + reprocessibleSessionId);
+ "invalid session ID: " + reprocessableSessionId);
}
- mReprocessibleSessionId = reprocessibleSessionId;
+ mReprocessableSessionId = reprocessableSessionId;
} else {
- mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE;
+ mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
}
}
@@ -307,20 +307,20 @@
}
/**
- * Get the reprocessible session ID this reprocess capture request is associated with.
+ * Get the reprocessable session ID this reprocess capture request is associated with.
*
- * @return the reprocessible session ID this reprocess capture request is associated with
+ * @return the reprocessable session ID this reprocess capture request is associated with
*
* @throws IllegalStateException if this capture request is not a reprocess capture request.
* @hide
*/
- public int getReprocessibleSessionId() {
+ public int getReprocessableSessionId() {
if (mIsReprocess == false ||
- mReprocessibleSessionId == CameraCaptureSession.SESSION_ID_NONE) {
- throw new IllegalStateException("Getting the reprocessible session ID for a "+
+ mReprocessableSessionId == CameraCaptureSession.SESSION_ID_NONE) {
+ throw new IllegalStateException("Getting the reprocessable session ID for a "+
"non-reprocess capture request is illegal.");
}
- return mReprocessibleSessionId;
+ return mReprocessableSessionId;
}
/**
@@ -346,7 +346,7 @@
&& mSurfaceSet.equals(other.mSurfaceSet)
&& mSettings.equals(other.mSettings)
&& mIsReprocess == other.mIsReprocess
- && mReprocessibleSessionId == other.mReprocessibleSessionId;
+ && mReprocessableSessionId == other.mReprocessableSessionId;
}
@Override
@@ -395,7 +395,7 @@
}
mIsReprocess = (in.readInt() == 0) ? false : true;
- mReprocessibleSessionId = CameraCaptureSession.SESSION_ID_NONE;
+ mReprocessableSessionId = CameraCaptureSession.SESSION_ID_NONE;
}
@Override
@@ -450,19 +450,19 @@
* @param reprocess Indicates whether to create a reprocess capture request. {@code true}
* to create a reprocess capture request. {@code false} to create a regular
* capture request.
- * @param reprocessibleSessionId The ID of the camera capture session this capture is
+ * @param reprocessableSessionId The ID of the camera capture session this capture is
* created for. This is used to validate if the application
* submits a reprocess capture request to the same session
* where the {@link TotalCaptureResult}, used to create the
* reprocess capture, came from.
*
* @throws IllegalArgumentException If creating a reprocess capture request with an invalid
- * reprocessibleSessionId.
+ * reprocessableSessionId.
* @hide
*/
public Builder(CameraMetadataNative template, boolean reprocess,
- int reprocessibleSessionId) {
- mRequest = new CaptureRequest(template, reprocess, reprocessibleSessionId);
+ int reprocessableSessionId) {
+ mRequest = new CaptureRequest(template, reprocess, reprocessableSessionId);
}
/**
@@ -1275,7 +1275,7 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * contains PRIVATE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
* {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
* always supported.</p>
* <p><b>Possible values:</b>
@@ -1355,7 +1355,7 @@
* android.control.* are mostly disabled, and the camera device implements
* one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
* as it wishes. The camera device scene mode 3A settings are provided by
- * android.control.sceneModeOverrides.</p>
+ * {@link android.hardware.camera2.CaptureResult capture results}.</p>
* <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
* is that this frame will not be used by camera device background 3A statistics
* update, as if this frame is never captured. This mode can be used in the scenario
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 3dc8970..0277c5b 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1698,7 +1698,7 @@
* <p>This control (except for MANUAL) is only effective if
* <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code> and any 3A routine is active.</p>
* <p>ZERO_SHUTTER_LAG will be supported if {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
- * contains OPAQUE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
+ * contains PRIVATE_REPROCESSING or YUV_REPROCESSING. MANUAL will be supported if
* {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} contains MANUAL_SENSOR. Other intent values are
* always supported.</p>
* <p><b>Possible values:</b>
@@ -1921,7 +1921,7 @@
* android.control.* are mostly disabled, and the camera device implements
* one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
* as it wishes. The camera device scene mode 3A settings are provided by
- * android.control.sceneModeOverrides.</p>
+ * {@link android.hardware.camera2.CaptureResult capture results}.</p>
* <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
* is that this frame will not be used by camera device background 3A statistics
* update, as if this frame is never captured. This mode can be used in the scenario
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index dff6227..d08c52b 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -153,10 +153,10 @@
Handler handler) throws CameraAccessException {
if (request == null) {
throw new IllegalArgumentException("request must not be null");
- } else if (request.isReprocess() && !isReprocessible()) {
+ } else if (request.isReprocess() && !isReprocessable()) {
throw new IllegalArgumentException("this capture session cannot handle reprocess " +
"requests");
- } else if (request.isReprocess() && request.getReprocessibleSessionId() != mId) {
+ } else if (request.isReprocess() && request.getReprocessableSessionId() != mId) {
throw new IllegalArgumentException("capture request was created for another session");
}
@@ -184,10 +184,10 @@
for (CaptureRequest request : requests) {
if (request.isReprocess()) {
- if (!isReprocessible()) {
+ if (!isReprocessable()) {
throw new IllegalArgumentException("This capture session cannot handle " +
"reprocess requests");
- } else if (request.getReprocessibleSessionId() != mId) {
+ } else if (request.getReprocessableSessionId() != mId) {
throw new IllegalArgumentException("Capture request was created for another " +
"session");
}
@@ -293,7 +293,7 @@
}
@Override
- public boolean isReprocessible() {
+ public boolean isReprocessable() {
return mInput != null;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
index e84b46a..4508dc8 100644
--- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java
@@ -480,16 +480,16 @@
}
@Override
- public void createReprocessibleCaptureSession(InputConfiguration inputConfig,
+ public void createReprocessableCaptureSession(InputConfiguration inputConfig,
List<Surface> outputs, CameraCaptureSession.StateCallback callback, Handler handler)
throws CameraAccessException {
if (DEBUG) {
- Log.d(TAG, "createReprocessibleCaptureSession");
+ Log.d(TAG, "createReprocessableCaptureSession");
}
if (inputConfig == null) {
throw new IllegalArgumentException("inputConfig cannot be null when creating a " +
- "reprocessible capture session");
+ "reprocessable capture session");
}
List<OutputConfiguration> outConfigurations = new ArrayList<>(outputs.size());
for (Surface surface : outputs) {
diff --git a/core/java/android/hardware/camera2/legacy/ParameterUtils.java b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
index 9e9a6fe..32bbc51 100644
--- a/core/java/android/hardware/camera2/legacy/ParameterUtils.java
+++ b/core/java/android/hardware/camera2/legacy/ParameterUtils.java
@@ -61,6 +61,8 @@
public static final Rect RECTANGLE_EMPTY =
new Rect(/*left*/0, /*top*/0, /*right*/0, /*bottom*/0);
+ private static final double ASPECT_RATIO_TOLERANCE = 0.05f;
+
/**
* Calculate effective/reported zoom data from a user-specified crop region.
*/
@@ -498,7 +500,10 @@
float aspectRatioPreview = previewSize.getWidth() * 1.0f / previewSize.getHeight();
float cropH, cropW;
- if (aspectRatioPreview < aspectRatioArray) {
+ if (Math.abs(aspectRatioPreview - aspectRatioArray) < ASPECT_RATIO_TOLERANCE) {
+ cropH = activeArray.height();
+ cropW = activeArray.width();
+ } else if (aspectRatioPreview < aspectRatioArray) {
// The new width must be smaller than the height, so scale the width by AR
cropH = activeArray.height();
cropW = cropH * aspectRatioPreview;
diff --git a/core/java/android/hardware/camera2/params/InputConfiguration.java b/core/java/android/hardware/camera2/params/InputConfiguration.java
index dea1c5c..0c642cf 100644
--- a/core/java/android/hardware/camera2/params/InputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/InputConfiguration.java
@@ -19,11 +19,11 @@
import android.hardware.camera2.utils.HashCodeHelpers;
/**
- * Immutable class to store an input configuration that is used to create a reprocessible capture
+ * Immutable class to store an input configuration that is used to create a reprocessable capture
* session.
*
- * @see CameraDevice#createReprocessibleCaptureSession
- * @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
+ * @see android.hardware.camera2.CameraDevice#createReprocessableCaptureSession
+ * @see android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
*/
public final class InputConfiguration {
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java
index 02793f1..aa697ea 100644
--- a/core/java/android/hardware/display/DisplayManagerInternal.java
+++ b/core/java/android/hardware/display/DisplayManagerInternal.java
@@ -125,11 +125,13 @@
* mirroring.
* @param requestedRefreshRate The preferred refresh rate for the top-most visible window that
* has a preference.
+ * @param requestedModeId The preferred mode id for the top-most visible window that has a
+ * preference.
* @param inTraversal True if called from WindowManagerService during a window traversal
* prior to call to performTraversalInTransactionFromWindowManager.
*/
public abstract void setDisplayProperties(int displayId, boolean hasContent,
- float requestedRefreshRate, boolean inTraversal);
+ float requestedRefreshRate, int requestedModeId, boolean inTraversal);
/**
* Applies an offset to the contents of a display, for example to avoid burn-in.
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index cf96145..338bd76 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -32,7 +32,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.hardware.fingerprint.FingerprintManager.EnrollmentCallback;
-import android.security.AndroidKeyStoreProvider;
+import android.security.keystore.AndroidKeyStoreProvider;
import android.util.Log;
import android.util.Slog;
@@ -686,7 +686,7 @@
private void sendAuthenticatedResult(Fingerprint fp) {
if (mAuthenticationCallback != null) {
- if (fp.getFingerId() == 0 && fp.getGroupId() == 0) {
+ if (fp.getFingerId() == 0) {
// Fingerprint template valid but doesn't match one in database
mAuthenticationCallback.onAuthenticationFailed();
} else {
diff --git a/core/java/android/hardware/fingerprint/FingerprintUtils.java b/core/java/android/hardware/fingerprint/FingerprintUtils.java
deleted file mode 100644
index 525f254..0000000
--- a/core/java/android/hardware/fingerprint/FingerprintUtils.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.fingerprint;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.os.Vibrator;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Utility class for dealing with fingerprints and fingerprint settings.
- * @hide
- */
-public
-class FingerprintUtils {
- private static final boolean DEBUG = true;
- private static final String TAG = "FingerprintUtils";
- private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
- private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
-
- private static int[] toIntArray(List<Integer> list) {
- if (list == null) {
- return null;
- }
- int[] arr = new int[list.size()];
- int i = 0;
- for (int elem : list) {
- arr[i] = elem;
- i++;
- }
- return arr;
- }
-
- public static int[] getFingerprintIdsForUser(ContentResolver res, int userId) {
- String fingerIdsRaw = Settings.Secure.getStringForUser(res,
- Settings.Secure.USER_FINGERPRINT_IDS, userId);
- ArrayList<Integer> tmp = new ArrayList<Integer>();
- if (!TextUtils.isEmpty(fingerIdsRaw)) {
- String[] fingerStringIds = fingerIdsRaw.replace("[","").replace("]","").split(", ");
- int length = fingerStringIds.length;
- for (int i = 0; i < length; i++) {
- try {
- tmp.add(Integer.decode(fingerStringIds[i]));
- } catch (NumberFormatException e) {
- if (DEBUG) Log.w(TAG, "Error parsing finger id: '" + fingerStringIds[i] + "'");
- }
- }
- }
- return toIntArray(tmp);
- }
-
- public static void addFingerprintIdForUser(ContentResolver res, int fingerId, int userId) {
- // FingerId 0 has special meaning.
- if (fingerId == 0) {
- Log.w(TAG, "Tried to add fingerId 0");
- return;
- }
-
- int[] fingerIds = getFingerprintIdsForUser(res, userId);
-
- // Don't allow dups
- if (ArrayUtils.contains(fingerIds, fingerId)) {
- Log.w(TAG, "finger already added " + fingerId);
- return;
- }
- int[] newList = Arrays.copyOf(fingerIds, fingerIds.length + 1);
- newList[fingerIds.length] = fingerId;
- Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
- Arrays.toString(newList), userId);
- }
-
- public static boolean removeFingerprintIdForUser(int fingerId, ContentResolver res, int userId)
- {
- // FingerId 0 has special meaning. The HAL layer is supposed to remove each finger one
- // at a time and invoke notify() for each fingerId. If we get called with 0 here, it means
- // something bad has happened.
- if (fingerId == 0) throw new IllegalArgumentException("fingerId can't be 0");
-
- final int[] fingerIds = getFingerprintIdsForUser(res, userId);
- if (ArrayUtils.contains(fingerIds, fingerId)) {
- final int[] result = ArrayUtils.removeInt(fingerIds, fingerId);
- Settings.Secure.putStringForUser(res, Settings.Secure.USER_FINGERPRINT_IDS,
- Arrays.toString(result), userId);
- return true;
- }
- return false;
- }
-
- public static void vibrateFingerprintError(Context context) {
- Vibrator vibrator = context.getSystemService(Vibrator.class);
- if (vibrator != null) {
- vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
- }
- }
-
- public static void vibrateFingerprintSuccess(Context context) {
- Vibrator vibrator = context.getSystemService(Vibrator.class);
- if (vibrator != null) {
- vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
- }
- }
-
-};
-
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index e4ab3f2..881dc0f 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -83,7 +83,7 @@
void clearDefaults(String packageName, int userId);
/* Sets the current USB function. */
- void setCurrentFunction(String function, boolean makeDefault);
+ void setCurrentFunction(String function);
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
* the public key to list of host keys that the user has approved.
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index a45d4ca..000d41f 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -228,6 +228,23 @@
*/
public static final String EXTRA_PERMISSION_GRANTED = "permission";
+ /**
+ * The persistent property which stores whether adb is enabled or not. Other values are ignored.
+ * Previously this value stored non-adb settings, but not anymore.
+ * TODO: rename this to something adb specific, rather than using usb.
+ *
+ * {@hide}
+ */
+ public static final String ADB_PERSISTENT_PROPERTY = "persist.sys.usb.config";
+
+ /**
+ * The non-persistent property which stores the current USB settings.
+ *
+ * {@hide}
+ */
+ public static final String USB_SETTINGS_PROPERTY = "sys.usb.config";
+
+
private final Context mContext;
private final IUsbManager mService;
@@ -410,21 +427,26 @@
}
}
+ private static boolean propertyContainsFunction(String property, String function) {
+ String functions = SystemProperties.get(property, "");
+ int index = functions.indexOf(function);
+ if (index < 0) return false;
+ if (index > 0 && functions.charAt(index - 1) != ',') return false;
+ int charAfter = index + function.length();
+ if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
+ return true;
+ }
+
/**
- * Returns the current default USB function.
+ * Returns true if the specified USB function is currently enabled.
*
- * @return name of the default function.
+ * @param function name of the USB function
+ * @return true if the USB function is enabled.
*
* {@hide}
*/
- public String getDefaultFunction() {
- String functions = SystemProperties.get("persist.sys.usb.config", "");
- int commaIndex = functions.indexOf(',');
- if (commaIndex > 0) {
- return functions.substring(0, commaIndex);
- } else {
- return functions;
- }
+ public boolean isFunctionEnabled(String function) {
+ return propertyContainsFunction(USB_SETTINGS_PROPERTY, function);
}
/**
@@ -432,13 +454,12 @@
* If function is null, then the current function is set to the default function.
*
* @param function name of the USB function, or null to restore the default function
- * @param makeDefault true if the function should be set as the new default function
*
* {@hide}
*/
- public void setCurrentFunction(String function, boolean makeDefault) {
+ public void setCurrentFunction(String function) {
try {
- mService.setCurrentFunction(function, makeDefault);
+ mService.setCurrentFunction(function);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in setCurrentFunction", e);
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d8c3361..26878c0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -496,6 +496,8 @@
* Tests if a given integer represents a valid network type.
* @param networkType the type to be tested
* @return a boolean. {@code true} if the type is valid, else {@code false}
+ * @deprecated All APIs accepting a network type are deprecated. There should be no need to
+ * validate a network type.
*/
public static boolean isNetworkTypeValid(int networkType) {
return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
diff --git a/core/java/android/net/IpReachabilityMonitor.java b/core/java/android/net/IpReachabilityMonitor.java
new file mode 100644
index 0000000..7e1c05b
--- /dev/null
+++ b/core/java/android/net/IpReachabilityMonitor.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.ProxyInfo;
+import android.net.RouteInfo;
+import android.net.netlink.NetlinkConstants;
+import android.net.netlink.NetlinkErrorMessage;
+import android.net.netlink.NetlinkMessage;
+import android.net.netlink.NetlinkSocket;
+import android.net.netlink.RtNetlinkNeighborMessage;
+import android.net.netlink.StructNdaCacheInfo;
+import android.net.netlink.StructNdMsg;
+import android.net.netlink.StructNlMsgHdr;
+import android.os.SystemClock;
+import android.system.ErrnoException;
+import android.system.NetlinkSocketAddress;
+import android.system.OsConstants;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.InterruptedIOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * IpReachabilityMonitor.
+ *
+ * Monitors on-link IP reachability and notifies callers whenever any on-link
+ * addresses of interest appear to have become unresponsive.
+ *
+ * @hide
+ */
+public class IpReachabilityMonitor {
+ private static final String TAG = "IpReachabilityMonitor";
+ private static final boolean DBG = true;
+ private static final boolean VDBG = false;
+
+ public interface Callback {
+ public void notifyLost(InetAddress ip, String logMsg);
+ }
+
+ private final Object mLock = new Object();
+ private final String mInterfaceName;
+ private final int mInterfaceIndex;
+ private final Callback mCallback;
+ private final Set<InetAddress> mIpWatchList;
+ private int mIpWatchListVersion;
+ private boolean mRunning;
+ final private Thread mObserverThread;
+
+ // TODO: consider passing in a NetworkInterface object from the caller.
+ public IpReachabilityMonitor(String ifName, Callback callback) throws IllegalArgumentException {
+ mInterfaceName = ifName;
+ int ifIndex = -1;
+ try {
+ NetworkInterface netIf = NetworkInterface.getByName(ifName);
+ mInterfaceIndex = netIf.getIndex();
+ } catch (SocketException | NullPointerException e) {
+ throw new IllegalArgumentException("invalid interface '" + ifName + "': ", e);
+ }
+ mCallback = callback;
+ mIpWatchList = new HashSet<InetAddress>();
+ mIpWatchListVersion = 0;
+ mRunning = false;
+ mObserverThread = new Thread(new NetlinkSocketObserver());
+ mObserverThread.start();
+ }
+
+ public void stop() {
+ synchronized (mLock) {
+ mRunning = false;
+ mIpWatchList.clear();
+ }
+ }
+
+ // TODO: add a public dump() method that can be called during a bug report.
+
+ private static Set<InetAddress> getOnLinkNeighbors(LinkProperties lp) {
+ Set<InetAddress> allIps = new HashSet<InetAddress>();
+
+ final List<RouteInfo> routes = lp.getRoutes();
+ for (RouteInfo route : routes) {
+ if (route.hasGateway()) {
+ allIps.add(route.getGateway());
+ }
+ }
+
+ for (InetAddress nameserver : lp.getDnsServers()) {
+ allIps.add(nameserver);
+ }
+
+ try {
+ // Don't block here for DNS lookups. If the proxy happens to be an
+ // IP literal then we add it the list, but otherwise skip it.
+ allIps.add(NetworkUtils.numericToInetAddress(lp.getHttpProxy().getHost()));
+ } catch (NullPointerException|IllegalArgumentException e) {
+ // No proxy, PAC proxy, or proxy is not a literal IP address.
+ }
+
+ Set<InetAddress> neighbors = new HashSet<InetAddress>();
+ for (InetAddress ip : allIps) {
+ // TODO: consider using the prefixes of the LinkAddresses instead
+ // of the routes--it may be more accurate.
+ for (RouteInfo route : routes) {
+ if (route.hasGateway()) {
+ continue; // Not directly connected.
+ }
+ if (route.matches(ip)) {
+ neighbors.add(ip);
+ break;
+ }
+ }
+ }
+ return neighbors;
+ }
+
+ private String describeWatchList() {
+ synchronized (mLock) {
+ return "version{" + mIpWatchListVersion + "}, " +
+ "ips=[" + TextUtils.join(",", mIpWatchList) + "]";
+ }
+ }
+
+ private boolean isWatching(InetAddress ip) {
+ synchronized (mLock) {
+ return mRunning && mIpWatchList.contains(ip);
+ }
+ }
+
+ public void updateLinkProperties(LinkProperties lp) {
+ if (!mInterfaceName.equals(lp.getInterfaceName())) {
+ // TODO: figure out how to cope with interface changes.
+ Log.wtf(TAG, "requested LinkProperties interface '" + lp.getInterfaceName() +
+ "' does not match: " + mInterfaceName);
+ return;
+ }
+
+ // We rely upon the caller to determine when LinkProperties have actually
+ // changed and call this at the appropriate time. Note that even though
+ // the LinkProperties may change, the set of on-link neighbors might not.
+ //
+ // Nevertheless, just clear and re-add everything.
+ final Set<InetAddress> neighbors = getOnLinkNeighbors(lp);
+ if (neighbors.isEmpty()) {
+ return;
+ }
+
+ synchronized (mLock) {
+ mIpWatchList.clear();
+ mIpWatchList.addAll(neighbors);
+ mIpWatchListVersion++;
+ }
+ if (DBG) { Log.d(TAG, "watch: " + describeWatchList()); }
+ }
+
+ public void clearLinkProperties() {
+ synchronized (mLock) {
+ mIpWatchList.clear();
+ mIpWatchListVersion++;
+ }
+ if (DBG) { Log.d(TAG, "clear: " + describeWatchList()); }
+ }
+
+ private void notifyLost(InetAddress ip, String msg) {
+ if (!isWatching(ip)) {
+ // Ignore stray notifications. This can happen when, for example,
+ // several neighbors are reported unreachable or deleted
+ // back-to-back. Because these messages are parsed serially, and
+ // this method is called for each notification, the caller above us
+ // may have already processed an earlier lost notification and
+ // cleared the watch list as it moves to handle the situation.
+ return;
+ }
+ Log.w(TAG, "ALERT: " + ip.getHostAddress() + " -- " + msg);
+ if (mCallback != null) {
+ mCallback.notifyLost(ip, msg);
+ }
+ }
+
+
+ private final class NetlinkSocketObserver implements Runnable {
+ private static final String TAG = "NetlinkSocketObserver";
+ private NetlinkSocket mSocket;
+
+ @Override
+ public void run() {
+ if (VDBG) { Log.d(TAG, "Starting observing thread."); }
+ synchronized (mLock) { mRunning = true; }
+
+ try {
+ setupNetlinkSocket();
+ } catch (ErrnoException | SocketException e) {
+ Log.e(TAG, "Failed to suitably initialize a netlink socket", e);
+ synchronized (mLock) { mRunning = false; }
+ }
+
+ ByteBuffer byteBuffer;
+ while (stillRunning()) {
+ try {
+ byteBuffer = recvKernelReply();
+ } catch (ErrnoException e) {
+ Log.w(TAG, "ErrnoException: ", e);
+ break;
+ }
+ final long whenMs = SystemClock.elapsedRealtime();
+ if (byteBuffer == null) {
+ continue;
+ }
+ parseNetlinkMessageBuffer(byteBuffer, whenMs);
+ }
+
+ clearNetlinkSocket();
+
+ synchronized (mLock) { mRunning = false; }
+ if (VDBG) { Log.d(TAG, "Finishing observing thread."); }
+ }
+
+ private boolean stillRunning() {
+ synchronized (mLock) {
+ return mRunning;
+ }
+ }
+
+ private void clearNetlinkSocket() {
+ if (mSocket != null) {
+ mSocket.close();
+ }
+ mSocket = null;
+ }
+
+ // TODO: Refactor the main loop to recreate the socket upon recoverable errors.
+ private void setupNetlinkSocket() throws ErrnoException, SocketException {
+ clearNetlinkSocket();
+ mSocket = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
+
+ final NetlinkSocketAddress listenAddr = new NetlinkSocketAddress(
+ 0, OsConstants.RTMGRP_NEIGH);
+ mSocket.bind(listenAddr);
+
+ if (VDBG) {
+ final NetlinkSocketAddress nlAddr = mSocket.getLocalAddress();
+ Log.d(TAG, "bound to sockaddr_nl{"
+ + ((long) (nlAddr.getPortId() & 0xffffffff)) + ", "
+ + nlAddr.getGroupsMask()
+ + "}");
+ }
+ }
+
+ private ByteBuffer recvKernelReply() throws ErrnoException {
+ try {
+ return mSocket.recvMessage(0);
+ } catch (InterruptedIOException e) {
+ // Interruption or other error, e.g. another thread closed our file descriptor.
+ } catch (ErrnoException e) {
+ if (e.errno != OsConstants.EAGAIN) {
+ throw e;
+ }
+ }
+ return null;
+ }
+
+ private void parseNetlinkMessageBuffer(ByteBuffer byteBuffer, long whenMs) {
+ while (byteBuffer.remaining() > 0) {
+ final int position = byteBuffer.position();
+ final NetlinkMessage nlMsg = NetlinkMessage.parse(byteBuffer);
+ if (nlMsg == null || nlMsg.getHeader() == null) {
+ byteBuffer.position(position);
+ Log.e(TAG, "unparsable netlink msg: " + NetlinkConstants.hexify(byteBuffer));
+ break;
+ }
+
+ final int srcPortId = nlMsg.getHeader().nlmsg_pid;
+ if (srcPortId != 0) {
+ Log.e(TAG, "non-kernel source portId: " + ((long) (srcPortId & 0xffffffff)));
+ break;
+ }
+
+ if (nlMsg instanceof NetlinkErrorMessage) {
+ Log.e(TAG, "netlink error: " + nlMsg);
+ continue;
+ } else if (!(nlMsg instanceof RtNetlinkNeighborMessage)) {
+ if (DBG) {
+ Log.d(TAG, "non-rtnetlink neighbor msg: " + nlMsg);
+ }
+ continue;
+ }
+
+ evaluateRtNetlinkNeighborMessage((RtNetlinkNeighborMessage) nlMsg, whenMs);
+ }
+ }
+
+ private void evaluateRtNetlinkNeighborMessage(
+ RtNetlinkNeighborMessage neighMsg, long whenMs) {
+ final StructNdMsg ndMsg = neighMsg.getNdHeader();
+ if (ndMsg == null || ndMsg.ndm_ifindex != mInterfaceIndex) {
+ return;
+ }
+
+ final InetAddress destination = neighMsg.getDestination();
+ if (!isWatching(destination)) {
+ return;
+ }
+
+ final short msgType = neighMsg.getHeader().nlmsg_type;
+ final short nudState = ndMsg.ndm_state;
+ final String eventMsg = "NeighborEvent{"
+ + "elapsedMs=" + whenMs + ", "
+ + destination.getHostAddress() + ", "
+ + "[" + NetlinkConstants.hexify(neighMsg.getLinkLayerAddress()) + "], "
+ + NetlinkConstants.stringForNlMsgType(msgType) + ", "
+ + StructNdMsg.stringForNudState(nudState)
+ + "}";
+
+ if (VDBG) {
+ Log.d(TAG, neighMsg.toString());
+ } else if (DBG) {
+ Log.d(TAG, eventMsg);
+ }
+
+ if ((msgType == NetlinkConstants.RTM_DELNEIGH) ||
+ (nudState == StructNdMsg.NUD_FAILED)) {
+ final String logMsg = "FAILURE: " + eventMsg;
+ notifyLost(destination, logMsg);
+ }
+ }
+ }
+}
diff --git a/core/java/android/net/netlink/NetlinkConstants.java b/core/java/android/net/netlink/NetlinkConstants.java
new file mode 100644
index 0000000..e331701
--- /dev/null
+++ b/core/java/android/net/netlink/NetlinkConstants.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.system.OsConstants;
+import com.android.internal.util.HexDump;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Various constants and static helper methods for netlink communications.
+ *
+ * Values taken from:
+ *
+ * <linux_src>/include/uapi/linux/netlink.h
+ * <linux_src>/include/uapi/linux/rtnetlink.h
+ *
+ * @hide
+ */
+public class NetlinkConstants {
+ private NetlinkConstants() {}
+
+ public static final int NLA_ALIGNTO = 4;
+
+ public static final int alignedLengthOf(short length) {
+ final int intLength = (int) length & 0xffff;
+ return alignedLengthOf(intLength);
+ }
+
+ public static final int alignedLengthOf(int length) {
+ if (length <= 0) { return 0; }
+ return (((length + NLA_ALIGNTO - 1) / NLA_ALIGNTO) * NLA_ALIGNTO);
+ }
+
+ public static String stringForAddressFamily(int family) {
+ if (family == OsConstants.AF_INET) { return "AF_INET"; }
+ if (family == OsConstants.AF_INET6) { return "AF_INET6"; }
+ if (family == OsConstants.AF_NETLINK) { return "AF_NETLINK"; }
+ return String.valueOf(family);
+ }
+
+ public static String hexify(byte[] bytes) {
+ if (bytes == null) { return "(null)"; }
+ return HexDump.toHexString(bytes);
+ }
+
+ public static String hexify(ByteBuffer buffer) {
+ if (buffer == null) { return "(null)"; }
+ return HexDump.toHexString(
+ buffer.array(), buffer.position(), buffer.remaining());
+ }
+
+ // Known values for struct nlmsghdr nlm_type.
+ public static final short NLMSG_NOOP = 1; // Nothing
+ public static final short NLMSG_ERROR = 2; // Error
+ public static final short NLMSG_DONE = 3; // End of a dump
+ public static final short NLMSG_OVERRUN = 4; // Data lost
+ public static final short NLMSG_MAX_RESERVED = 15; // Max reserved value
+
+ public static final short RTM_NEWLINK = 16;
+ public static final short RTM_DELLINK = 17;
+ public static final short RTM_GETLINK = 18;
+ public static final short RTM_SETLINK = 19;
+ public static final short RTM_NEWADDR = 20;
+ public static final short RTM_DELADDR = 21;
+ public static final short RTM_GETADDR = 22;
+ public static final short RTM_NEWROUTE = 24;
+ public static final short RTM_DELROUTE = 25;
+ public static final short RTM_GETROUTE = 26;
+ public static final short RTM_NEWNEIGH = 28;
+ public static final short RTM_DELNEIGH = 29;
+ public static final short RTM_GETNEIGH = 30;
+ public static final short RTM_NEWRULE = 32;
+ public static final short RTM_DELRULE = 33;
+ public static final short RTM_GETRULE = 34;
+ public static final short RTM_NEWNDUSEROPT = 68;
+
+ public static String stringForNlMsgType(short nlm_type) {
+ switch (nlm_type) {
+ case NLMSG_NOOP: return "NLMSG_NOOP";
+ case NLMSG_ERROR: return "NLMSG_ERROR";
+ case NLMSG_DONE: return "NLMSG_DONE";
+ case NLMSG_OVERRUN: return "NLMSG_OVERRUN";
+ case RTM_NEWLINK: return "RTM_NEWLINK";
+ case RTM_DELLINK: return "RTM_DELLINK";
+ case RTM_GETLINK: return "RTM_GETLINK";
+ case RTM_SETLINK: return "RTM_SETLINK";
+ case RTM_NEWADDR: return "RTM_NEWADDR";
+ case RTM_DELADDR: return "RTM_DELADDR";
+ case RTM_GETADDR: return "RTM_GETADDR";
+ case RTM_NEWROUTE: return "RTM_NEWROUTE";
+ case RTM_DELROUTE: return "RTM_DELROUTE";
+ case RTM_GETROUTE: return "RTM_GETROUTE";
+ case RTM_NEWNEIGH: return "RTM_NEWNEIGH";
+ case RTM_DELNEIGH: return "RTM_DELNEIGH";
+ case RTM_GETNEIGH: return "RTM_GETNEIGH";
+ case RTM_NEWRULE: return "RTM_NEWRULE";
+ case RTM_DELRULE: return "RTM_DELRULE";
+ case RTM_GETRULE: return "RTM_GETRULE";
+ case RTM_NEWNDUSEROPT: return "RTM_NEWNDUSEROPT";
+ default:
+ return "unknown RTM type: " + String.valueOf(nlm_type);
+ }
+ }
+}
diff --git a/core/java/android/net/netlink/NetlinkErrorMessage.java b/core/java/android/net/netlink/NetlinkErrorMessage.java
new file mode 100644
index 0000000..dbc10d6
--- /dev/null
+++ b/core/java/android/net/netlink/NetlinkErrorMessage.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.StructNlMsgHdr;
+import android.net.netlink.NetlinkMessage;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * A NetlinkMessage subclass for netlink error messages.
+ *
+ * @hide
+ */
+public class NetlinkErrorMessage extends NetlinkMessage {
+
+ public static NetlinkErrorMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
+ final NetlinkErrorMessage errorMsg = new NetlinkErrorMessage(header);
+
+ errorMsg.mNlMsgErr = StructNlMsgErr.parse(byteBuffer);
+ if (errorMsg.mNlMsgErr == null) {
+ return null;
+ }
+
+ return errorMsg;
+ }
+
+ private StructNlMsgErr mNlMsgErr;
+
+ NetlinkErrorMessage(StructNlMsgHdr header) {
+ super(header);
+ mNlMsgErr = null;
+ }
+
+ public StructNlMsgErr getNlMsgError() {
+ return mNlMsgErr;
+ }
+
+ @Override
+ public String toString() {
+ return "NetlinkErrorMessage{ "
+ + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
+ + "nlmsgerr{" + (mNlMsgErr == null ? "" : mNlMsgErr.toString()) + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/NetlinkMessage.java b/core/java/android/net/netlink/NetlinkMessage.java
new file mode 100644
index 0000000..bc04a16
--- /dev/null
+++ b/core/java/android/net/netlink/NetlinkMessage.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import android.net.netlink.NetlinkErrorMessage;
+import android.net.netlink.RtNetlinkNeighborMessage;
+import android.net.netlink.StructNlAttr;
+import android.net.netlink.StructNlMsgHdr;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * NetlinkMessage base class for other, more specific netlink message types.
+ *
+ * Classes that extend NetlinkMessage should:
+ * - implement a public static parse(StructNlMsgHdr, ByteBuffer) method
+ * - returning either null (parse errors) or a new object of the subclass
+ * type (cast-able to NetlinkMessage)
+ *
+ * NetlinkMessage.parse() should be updated to know which nlmsg_type values
+ * correspond with which message subclasses.
+ *
+ * @hide
+ */
+public class NetlinkMessage {
+ private final static String TAG = "NetlinkMessage";
+
+ public static NetlinkMessage parse(ByteBuffer byteBuffer) {
+ final int startPosition = (byteBuffer != null) ? byteBuffer.position() : -1;
+ final StructNlMsgHdr nlmsghdr = StructNlMsgHdr.parse(byteBuffer);
+ if (nlmsghdr == null) {
+ return null;
+ }
+
+ int payloadLength = NetlinkConstants.alignedLengthOf(nlmsghdr.nlmsg_len);
+ payloadLength -= StructNlMsgHdr.STRUCT_SIZE;
+ if (payloadLength < 0 || payloadLength > byteBuffer.remaining()) {
+ // Malformed message or runt buffer. Pretend the buffer was consumed.
+ byteBuffer.position(byteBuffer.limit());
+ return null;
+ }
+
+ switch (nlmsghdr.nlmsg_type) {
+ //case NetlinkConstants.NLMSG_NOOP:
+ case NetlinkConstants.NLMSG_ERROR:
+ return (NetlinkMessage) NetlinkErrorMessage.parse(byteBuffer);
+ case NetlinkConstants.NLMSG_DONE:
+ byteBuffer.position(byteBuffer.position() + payloadLength);
+ return new NetlinkMessage(nlmsghdr);
+ //case NetlinkConstants.NLMSG_OVERRUN:
+ case NetlinkConstants.RTM_NEWNEIGH:
+ case NetlinkConstants.RTM_DELNEIGH:
+ case NetlinkConstants.RTM_GETNEIGH:
+ return (NetlinkMessage) RtNetlinkNeighborMessage.parse(nlmsghdr, byteBuffer);
+ default:
+ if (nlmsghdr.nlmsg_type <= NetlinkConstants.NLMSG_MAX_RESERVED) {
+ // Netlink control message. Just parse the header for now,
+ // pretending the whole message was consumed.
+ byteBuffer.position(byteBuffer.position() + payloadLength);
+ return new NetlinkMessage(nlmsghdr);
+ }
+ return null;
+ }
+ }
+
+ protected StructNlMsgHdr mHeader;
+
+ public NetlinkMessage(StructNlMsgHdr nlmsghdr) {
+ mHeader = nlmsghdr;
+ }
+
+ public StructNlMsgHdr getHeader() {
+ return mHeader;
+ }
+
+ @Override
+ public String toString() {
+ return "NetlinkMessage{" + (mHeader == null ? "" : mHeader.toString()) + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/NetlinkSocket.java b/core/java/android/net/netlink/NetlinkSocket.java
new file mode 100644
index 0000000..657d48c
--- /dev/null
+++ b/core/java/android/net/netlink/NetlinkSocket.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.system.ErrnoException;
+import android.system.NetlinkSocketAddress;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructTimeval;
+import android.util.Log;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.InterruptedIOException;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+
+/**
+ * NetlinkSocket
+ *
+ * A small wrapper class to assist with AF_NETLINK socket operations.
+ *
+ * @hide
+ */
+public class NetlinkSocket implements Closeable {
+ private static final String TAG = "NetlinkSocket";
+ private static final int SOCKET_RECV_BUFSIZE = 64 * 1024;
+ private static final int DEFAULT_RECV_BUFSIZE = 8 * 1024;
+
+ final private FileDescriptor mDescriptor;
+ private NetlinkSocketAddress mAddr;
+ private long mLastRecvTimeoutMs;
+ private long mLastSendTimeoutMs;
+
+ public NetlinkSocket(int nlProto) throws ErrnoException {
+ mDescriptor = Os.socket(
+ OsConstants.AF_NETLINK, OsConstants.SOCK_DGRAM, nlProto);
+
+ Libcore.os.setsockoptInt(
+ mDescriptor, OsConstants.SOL_SOCKET,
+ OsConstants.SO_RCVBUF, SOCKET_RECV_BUFSIZE);
+ }
+
+ public NetlinkSocketAddress getLocalAddress() throws ErrnoException {
+ return (NetlinkSocketAddress) Os.getsockname(mDescriptor);
+ }
+
+ public void bind(NetlinkSocketAddress localAddr) throws ErrnoException, SocketException {
+ Os.bind(mDescriptor, (SocketAddress)localAddr);
+ }
+
+ public void connectTo(NetlinkSocketAddress peerAddr)
+ throws ErrnoException, SocketException {
+ Os.connect(mDescriptor, (SocketAddress) peerAddr);
+ }
+
+ public void connectToKernel() throws ErrnoException, SocketException {
+ connectTo(new NetlinkSocketAddress(0, 0));
+ }
+
+ /**
+ * Wait indefinitely (or until underlying socket error) for a
+ * netlink message of at most DEFAULT_RECV_BUFSIZE size.
+ */
+ public ByteBuffer recvMessage()
+ throws ErrnoException, InterruptedIOException {
+ return recvMessage(DEFAULT_RECV_BUFSIZE, 0);
+ }
+
+ /**
+ * Wait up to |timeoutMs| (or until underlying socket error) for a
+ * netlink message of at most DEFAULT_RECV_BUFSIZE size.
+ */
+ public ByteBuffer recvMessage(long timeoutMs) throws ErrnoException, InterruptedIOException {
+ return recvMessage(DEFAULT_RECV_BUFSIZE, timeoutMs);
+ }
+
+ private void checkTimeout(long timeoutMs) {
+ if (timeoutMs < 0) {
+ throw new IllegalArgumentException("Negative timeouts not permitted");
+ }
+ }
+
+ /**
+ * Wait up to |timeoutMs| (or until underlying socket error) for a
+ * netlink message of at most |bufsize| size.
+ *
+ * Multi-threaded calls with different timeouts will cause unexpected results.
+ */
+ public ByteBuffer recvMessage(int bufsize, long timeoutMs)
+ throws ErrnoException, IllegalArgumentException, InterruptedIOException {
+ checkTimeout(timeoutMs);
+
+ synchronized (mDescriptor) {
+ if (mLastRecvTimeoutMs != timeoutMs) {
+ Os.setsockoptTimeval(mDescriptor,
+ OsConstants.SOL_SOCKET, OsConstants.SO_RCVTIMEO,
+ StructTimeval.fromMillis(timeoutMs));
+ mLastRecvTimeoutMs = timeoutMs;
+ }
+ }
+
+ ByteBuffer byteBuffer = ByteBuffer.allocate(bufsize);
+ int length = Os.read(mDescriptor, byteBuffer);
+ if (length == bufsize) {
+ Log.w(TAG, "maximum read");
+ }
+ byteBuffer.position(0);
+ byteBuffer.limit(length);
+ byteBuffer.order(ByteOrder.nativeOrder());
+ return byteBuffer;
+ }
+
+ /**
+ * Send a message to a peer to which this socket has previously connected.
+ *
+ * This blocks until completion or an error occurs.
+ */
+ public boolean sendMessage(byte[] bytes, int offset, int count)
+ throws ErrnoException, InterruptedIOException {
+ return sendMessage(bytes, offset, count, 0);
+ }
+
+ /**
+ * Send a message to a peer to which this socket has previously connected,
+ * waiting at most |timeoutMs| milliseconds for the send to complete.
+ *
+ * Multi-threaded calls with different timeouts will cause unexpected results.
+ */
+ public boolean sendMessage(byte[] bytes, int offset, int count, long timeoutMs)
+ throws ErrnoException, IllegalArgumentException, InterruptedIOException {
+ checkTimeout(timeoutMs);
+
+ synchronized (mDescriptor) {
+ if (mLastSendTimeoutMs != timeoutMs) {
+ Os.setsockoptTimeval(mDescriptor,
+ OsConstants.SOL_SOCKET, OsConstants.SO_SNDTIMEO,
+ StructTimeval.fromMillis(timeoutMs));
+ mLastSendTimeoutMs = timeoutMs;
+ }
+ }
+
+ return (count == Os.write(mDescriptor, bytes, offset, count));
+ }
+
+ @Override
+ public void close() {
+ IoUtils.closeQuietly(mDescriptor);
+ }
+}
diff --git a/core/java/android/net/netlink/RtNetlinkNeighborMessage.java b/core/java/android/net/netlink/RtNetlinkNeighborMessage.java
new file mode 100644
index 0000000..d4b572c
--- /dev/null
+++ b/core/java/android/net/netlink/RtNetlinkNeighborMessage.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.StructNdaCacheInfo;
+import android.net.netlink.StructNdMsg;
+import android.net.netlink.StructNlAttr;
+import android.net.netlink.StructNlMsgHdr;
+import android.net.netlink.NetlinkMessage;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+
+/**
+ * A NetlinkMessage subclass for netlink error messages.
+ *
+ * see also: <linux_src>/include/uapi/linux/neighbour.h
+ *
+ * @hide
+ */
+public class RtNetlinkNeighborMessage extends NetlinkMessage {
+ public static final short NDA_UNSPEC = 0;
+ public static final short NDA_DST = 1;
+ public static final short NDA_LLADDR = 2;
+ public static final short NDA_CACHEINFO = 3;
+ public static final short NDA_PROBES = 4;
+ public static final short NDA_VLAN = 5;
+ public static final short NDA_PORT = 6;
+ public static final short NDA_VNI = 7;
+ public static final short NDA_IFINDEX = 8;
+ public static final short NDA_MASTER = 9;
+
+ private static StructNlAttr findNextAttrOfType(short attrType, ByteBuffer byteBuffer) {
+ while (byteBuffer != null && byteBuffer.remaining() > 0) {
+ final StructNlAttr nlAttr = StructNlAttr.peek(byteBuffer);
+ if (nlAttr == null) {
+ break;
+ }
+ if (nlAttr.nla_type == attrType) {
+ return StructNlAttr.parse(byteBuffer);
+ }
+ if (byteBuffer.remaining() < nlAttr.getAlignedLength()) {
+ break;
+ }
+ byteBuffer.position(byteBuffer.position() + nlAttr.getAlignedLength());
+ }
+ return null;
+ }
+
+ public static RtNetlinkNeighborMessage parse(StructNlMsgHdr header, ByteBuffer byteBuffer) {
+ final RtNetlinkNeighborMessage neighMsg = new RtNetlinkNeighborMessage(header);
+
+ neighMsg.mNdmsg = StructNdMsg.parse(byteBuffer);
+ if (neighMsg.mNdmsg == null) {
+ return null;
+ }
+
+ // Some of these are message-type dependent, and not always present.
+ final int baseOffset = byteBuffer.position();
+ StructNlAttr nlAttr = findNextAttrOfType(NDA_DST, byteBuffer);
+ if (nlAttr != null) {
+ neighMsg.mDestination = nlAttr.getValueAsInetAddress();
+ }
+
+ byteBuffer.position(baseOffset);
+ nlAttr = findNextAttrOfType(NDA_LLADDR, byteBuffer);
+ if (nlAttr != null) {
+ neighMsg.mLinkLayerAddr = nlAttr.nla_value;
+ }
+
+ byteBuffer.position(baseOffset);
+ nlAttr = findNextAttrOfType(NDA_PROBES, byteBuffer);
+ if (nlAttr != null) {
+ neighMsg.mNumProbes = nlAttr.getValueAsInt(0);
+ }
+
+ byteBuffer.position(baseOffset);
+ nlAttr = findNextAttrOfType(NDA_CACHEINFO, byteBuffer);
+ if (nlAttr != null) {
+ neighMsg.mCacheInfo = StructNdaCacheInfo.parse(nlAttr.getValueAsByteBuffer());
+ }
+
+ final int kMinConsumed = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE;
+ final int kAdditionalSpace = NetlinkConstants.alignedLengthOf(
+ neighMsg.mHeader.nlmsg_len - kMinConsumed);
+ if (byteBuffer.remaining() < kAdditionalSpace) {
+ byteBuffer.position(byteBuffer.limit());
+ } else {
+ byteBuffer.position(baseOffset + kAdditionalSpace);
+ }
+
+ return neighMsg;
+ }
+
+ /**
+ * A convenience method to create an RTM_GETNEIGH request message.
+ */
+ public static byte[] newGetNeighborsRequest(int seqNo) {
+ final int length = StructNlMsgHdr.STRUCT_SIZE + StructNdMsg.STRUCT_SIZE;
+ final byte[] bytes = new byte[length];
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+ byteBuffer.order(ByteOrder.nativeOrder());
+
+ final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
+ nlmsghdr.nlmsg_len = length;
+ nlmsghdr.nlmsg_type = NetlinkConstants.RTM_GETNEIGH;
+ nlmsghdr.nlmsg_flags = StructNlMsgHdr.NLM_F_REQUEST|StructNlMsgHdr.NLM_F_DUMP;
+ nlmsghdr.nlmsg_seq = seqNo;
+ nlmsghdr.pack(byteBuffer);
+
+ final StructNdMsg ndmsg = new StructNdMsg();
+ ndmsg.pack(byteBuffer);
+
+ return bytes;
+ }
+
+ private StructNdMsg mNdmsg;
+ private InetAddress mDestination;
+ private byte[] mLinkLayerAddr;
+ private int mNumProbes;
+ private StructNdaCacheInfo mCacheInfo;
+
+ private RtNetlinkNeighborMessage(StructNlMsgHdr header) {
+ super(header);
+ mNdmsg = null;
+ mDestination = null;
+ mLinkLayerAddr = null;
+ mNumProbes = 0;
+ mCacheInfo = null;
+ }
+
+ public StructNdMsg getNdHeader() {
+ return mNdmsg;
+ }
+
+ public InetAddress getDestination() {
+ return mDestination;
+ }
+
+ public byte[] getLinkLayerAddress() {
+ return mLinkLayerAddr;
+ }
+
+ public int getProbes() {
+ return mNumProbes;
+ }
+
+ public StructNdaCacheInfo getCacheInfo() {
+ return mCacheInfo;
+ }
+
+ @Override
+ public String toString() {
+ final String ipLiteral = (mDestination == null) ? "" : mDestination.getHostAddress();
+ return "RtNetlinkNeighborMessage{ "
+ + "nlmsghdr{" + (mHeader == null ? "" : mHeader.toString()) + "}, "
+ + "ndmsg{" + (mNdmsg == null ? "" : mNdmsg.toString()) + "}, "
+ + "destination{" + ipLiteral + "} "
+ + "linklayeraddr{" + NetlinkConstants.hexify(mLinkLayerAddr) + "} "
+ + "probes{" + mNumProbes + "} "
+ + "cacheinfo{" + (mCacheInfo == null ? "" : mCacheInfo.toString()) + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/StructNdMsg.java b/core/java/android/net/netlink/StructNdMsg.java
new file mode 100644
index 0000000..e66d45d
--- /dev/null
+++ b/core/java/android/net/netlink/StructNdMsg.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import android.system.OsConstants;
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct ndmsg
+ *
+ * see: <linux_src>/include/uapi/linux/neighbour.h
+ *
+ * @hide
+ */
+public class StructNdMsg {
+ // Already aligned.
+ public static final int STRUCT_SIZE = 12;
+
+ // Neighbor Cache Entry States
+ public static final short NUD_INCOMPLETE = 0x01;
+ public static final short NUD_REACHABLE = 0x02;
+ public static final short NUD_STALE = 0x04;
+ public static final short NUD_DELAY = 0x08;
+ public static final short NUD_PROBE = 0x10;
+ public static final short NUD_FAILED = 0x20;
+ public static final short NUD_NOARP = 0x40;
+ public static final short NUD_PERMANENT = 0x80;
+
+ public static String stringForNudState(short nudState) {
+ switch (nudState) {
+ case NUD_INCOMPLETE: return "NUD_INCOMPLETE";
+ case NUD_REACHABLE: return "NUD_REACHABLE";
+ case NUD_STALE: return "NUD_STALE";
+ case NUD_DELAY: return "NUD_DELAY";
+ case NUD_PROBE: return "NUD_PROBE";
+ case NUD_FAILED: return "NUD_FAILED";
+ case NUD_NOARP: return "NUD_NOARP";
+ case NUD_PERMANENT: return "NUD_PERMANENT";
+ default:
+ return "unknown NUD state: " + String.valueOf(nudState);
+ }
+ }
+
+ public static boolean isNudStateConnected(short nudState) {
+ return ((nudState & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE)) != 0);
+ }
+
+ // Neighbor Cache Entry Flags
+ public static byte NTF_USE = (byte) 0x01;
+ public static byte NTF_SELF = (byte) 0x02;
+ public static byte NTF_MASTER = (byte) 0x04;
+ public static byte NTF_PROXY = (byte) 0x08;
+ public static byte NTF_ROUTER = (byte) 0x80;
+
+ public static String stringForNudFlags(byte flags) {
+ final StringBuilder sb = new StringBuilder();
+ if ((flags & NTF_USE) != 0) {
+ sb.append("NTF_USE");
+ }
+ if ((flags & NTF_SELF) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NTF_SELF");
+ }
+ if ((flags & NTF_MASTER) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NTF_MASTER");
+ }
+ if ((flags & NTF_PROXY) != 0) {
+ if (sb.length() > 0) { sb.append("|");
+ }
+ sb.append("NTF_PROXY"); }
+ if ((flags & NTF_ROUTER) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NTF_ROUTER");
+ }
+ return sb.toString();
+ }
+
+ private static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
+ return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
+ }
+
+ public static StructNdMsg parse(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return null; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the possible
+ // exception of usage within unittests.
+ final StructNdMsg struct = new StructNdMsg();
+ struct.ndm_family = byteBuffer.get();
+ final byte pad1 = byteBuffer.get();
+ final short pad2 = byteBuffer.getShort();
+ struct.ndm_ifindex = byteBuffer.getInt();
+ struct.ndm_state = byteBuffer.getShort();
+ struct.ndm_flags = byteBuffer.get();
+ struct.ndm_type = byteBuffer.get();
+ return struct;
+ }
+
+ public byte ndm_family;
+ public int ndm_ifindex;
+ public short ndm_state;
+ public byte ndm_flags;
+ public byte ndm_type;
+
+ public StructNdMsg() {
+ ndm_family = (byte) OsConstants.AF_UNSPEC;
+ }
+
+ public boolean pack(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return false; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the exception
+ // of usage within unittests.
+ byteBuffer.put(ndm_family);
+ byteBuffer.put((byte) 0); // pad1
+ byteBuffer.putShort((short) 0); // pad2
+ byteBuffer.putInt(ndm_ifindex);
+ byteBuffer.putShort(ndm_state);
+ byteBuffer.put(ndm_flags);
+ byteBuffer.put(ndm_type);
+ return true;
+ }
+
+ public boolean nudConnected() {
+ return isNudStateConnected(ndm_state);
+ }
+
+ public boolean nudValid() {
+ return (nudConnected() || ((ndm_state & (NUD_PROBE|NUD_STALE|NUD_DELAY)) != 0));
+ }
+
+ @Override
+ public String toString() {
+ final String stateStr = "" + ndm_state + " (" + stringForNudState(ndm_state) + ")";
+ final String flagsStr = "" + ndm_flags + " (" + stringForNudFlags(ndm_flags) + ")";
+ return "StructNdMsg{ "
+ + "family{" + NetlinkConstants.stringForAddressFamily((int) ndm_family) + "}, "
+ + "ifindex{" + ndm_ifindex + "}, "
+ + "state{" + stateStr + "}, "
+ + "flags{" + flagsStr + "}, "
+ + "type{" + ndm_type + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/StructNdaCacheInfo.java b/core/java/android/net/netlink/StructNdaCacheInfo.java
new file mode 100644
index 0000000..16cf563
--- /dev/null
+++ b/core/java/android/net/netlink/StructNdaCacheInfo.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.system.Os;
+import android.system.OsConstants;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct nda_cacheinfo
+ *
+ * see: <linux_src>/include/uapi/linux/neighbour.h
+ *
+ * @hide
+ */
+public class StructNdaCacheInfo {
+ // Already aligned.
+ public static final int STRUCT_SIZE = 16;
+
+ private static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
+ return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
+ }
+
+ public static StructNdaCacheInfo parse(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return null; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the possible
+ // exception of usage within unittests.
+ final StructNdaCacheInfo struct = new StructNdaCacheInfo();
+ struct.ndm_used = byteBuffer.getInt();
+ struct.ndm_confirmed = byteBuffer.getInt();
+ struct.ndm_updated = byteBuffer.getInt();
+ struct.ndm_refcnt = byteBuffer.getInt();
+ return struct;
+ }
+
+ // TODO: investigate whether this can change during device runtime and
+ // decide what (if anything) should be done about that.
+ private static final long CLOCK_TICKS_PER_SECOND = Os.sysconf(OsConstants._SC_CLK_TCK);
+
+ private static long ticksToMilliSeconds(int intClockTicks) {
+ final long longClockTicks = (long) intClockTicks & 0xffffffff;
+ return (longClockTicks * 1000) / CLOCK_TICKS_PER_SECOND;
+ }
+
+ /**
+ * Explanatory notes, for reference.
+ *
+ * Before being returned to user space, the neighbor entry times are
+ * converted to clock_t's like so:
+ *
+ * ndm_used = jiffies_to_clock_t(now - neigh->used);
+ * ndm_confirmed = jiffies_to_clock_t(now - neigh->confirmed);
+ * ndm_updated = jiffies_to_clock_t(now - neigh->updated);
+ *
+ * meaning that these values are expressed as "clock ticks ago". To
+ * convert these clock ticks to seconds divide by sysconf(_SC_CLK_TCK).
+ * When _SC_CLK_TCK is 100, for example, the ndm_* times are expressed
+ * in centiseconds.
+ *
+ * These values are unsigned, but fortunately being expressed as "some
+ * clock ticks ago", these values are typically very small (and
+ * 2^31 centiseconds = 248 days).
+ *
+ * By observation, it appears that:
+ * ndm_used: the last time ARP/ND took place for this neighbor
+ * ndm_confirmed: the last time ARP/ND succeeded for this neighbor OR
+ * higher layer confirmation (TCP or MSG_CONFIRM)
+ * was received
+ * ndm_updated: the time when the current NUD state was entered
+ */
+ public int ndm_used;
+ public int ndm_confirmed;
+ public int ndm_updated;
+ public int ndm_refcnt;
+
+ public StructNdaCacheInfo() {}
+
+ public long lastUsed() {
+ return ticksToMilliSeconds(ndm_used);
+ }
+
+ public long lastConfirmed() {
+ return ticksToMilliSeconds(ndm_confirmed);
+ }
+
+ public long lastUpdated() {
+ return ticksToMilliSeconds(ndm_updated);
+ }
+
+ @Override
+ public String toString() {
+ return "NdaCacheInfo{ "
+ + "ndm_used{" + lastUsed() + "}, "
+ + "ndm_confirmed{" + lastConfirmed() + "}, "
+ + "ndm_updated{" + lastUpdated() + "}, "
+ + "ndm_refcnt{" + ndm_refcnt + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/StructNlAttr.java b/core/java/android/net/netlink/StructNlAttr.java
new file mode 100644
index 0000000..9aef4c7
--- /dev/null
+++ b/core/java/android/net/netlink/StructNlAttr.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import libcore.io.SizeOf;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteOrder;
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct nlattr
+ *
+ * see: <linux_src>/include/uapi/linux/netlink.h
+ *
+ * @hide
+ */
+public class StructNlAttr {
+ // Already aligned.
+ public static final int NLA_HEADERLEN = 4;
+
+ // Return a (length, type) object only, without consuming any bytes in
+ // |byteBuffer| and without copying or interpreting any value bytes.
+ // This is used for scanning over a packed set of struct nlattr's,
+ // looking for instances of a particular type.
+ public static StructNlAttr peek(ByteBuffer byteBuffer) {
+ if (byteBuffer == null || byteBuffer.remaining() < NLA_HEADERLEN) {
+ return null;
+ }
+ final int baseOffset = byteBuffer.position();
+
+ final StructNlAttr struct = new StructNlAttr();
+ struct.nla_len = byteBuffer.getShort();
+ struct.nla_type = byteBuffer.getShort();
+ struct.mByteOrder = byteBuffer.order();
+
+ byteBuffer.position(baseOffset);
+ if (struct.nla_len < NLA_HEADERLEN) {
+ // Malformed.
+ return null;
+ }
+ return struct;
+ }
+
+ public static StructNlAttr parse(ByteBuffer byteBuffer) {
+ final StructNlAttr struct = peek(byteBuffer);
+ if (struct == null || byteBuffer.remaining() < struct.getAlignedLength()) {
+ return null;
+ }
+
+ final int baseOffset = byteBuffer.position();
+ byteBuffer.position(baseOffset + NLA_HEADERLEN);
+
+ int valueLen = ((int) struct.nla_len) & 0xffff;
+ valueLen -= NLA_HEADERLEN;
+ if (valueLen > 0) {
+ struct.nla_value = new byte[valueLen];
+ byteBuffer.get(struct.nla_value, 0, valueLen);
+ byteBuffer.position(baseOffset + struct.getAlignedLength());
+ }
+ return struct;
+ }
+
+ public short nla_len;
+ public short nla_type;
+ public byte[] nla_value;
+ public ByteOrder mByteOrder;
+
+ public StructNlAttr() {
+ mByteOrder = ByteOrder.nativeOrder();
+ }
+
+ public int getAlignedLength() {
+ return NetlinkConstants.alignedLengthOf(nla_len);
+ }
+
+ public ByteBuffer getValueAsByteBuffer() {
+ if (nla_value == null) { return null; }
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(nla_value);
+ byteBuffer.order(mByteOrder);
+ return byteBuffer;
+ }
+
+ public int getValueAsInt(int defaultValue) {
+ final ByteBuffer byteBuffer = getValueAsByteBuffer();
+ if (byteBuffer == null || byteBuffer.remaining() != SizeOf.INT) {
+ return defaultValue;
+ }
+ return getValueAsByteBuffer().getInt();
+ }
+
+ public InetAddress getValueAsInetAddress() {
+ if (nla_value == null) { return null; }
+
+ try {
+ return InetAddress.getByAddress(nla_value);
+ } catch (UnknownHostException ignored) {
+ return null;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "StructNlAttr{ "
+ + "nla_len{" + nla_len + "}, "
+ + "nla_type{" + nla_type + "}, "
+ + "nla_value{" + NetlinkConstants.hexify(nla_value) + "}, "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/StructNlMsgErr.java b/core/java/android/net/netlink/StructNlMsgErr.java
new file mode 100644
index 0000000..5da19a2
--- /dev/null
+++ b/core/java/android/net/netlink/StructNlMsgErr.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import android.net.netlink.StructNlMsgHdr;
+import libcore.io.SizeOf;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct nlmsgerr
+ *
+ * see <linux_src>/include/uapi/linux/netlink.h
+ *
+ * @hide
+ */
+public class StructNlMsgErr {
+ public static final int STRUCT_SIZE = SizeOf.INT + StructNlMsgHdr.STRUCT_SIZE;
+
+ public static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
+ return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
+ }
+
+ public static StructNlMsgErr parse(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return null; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the exception
+ // of usage within unittests.
+ final StructNlMsgErr struct = new StructNlMsgErr();
+ struct.error = byteBuffer.getInt();
+ struct.msg = StructNlMsgHdr.parse(byteBuffer);
+ return struct;
+ }
+
+ public int error;
+ public StructNlMsgHdr msg;
+
+ public StructNlMsgErr() {
+ error = 0;
+ msg = null;
+ }
+
+ public boolean pack(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return false; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the possible
+ // exception of usage within unittests.
+ byteBuffer.putInt(error);
+ if (msg != null) {
+ msg.pack(byteBuffer);
+ }
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "StructNlMsgErr{ "
+ + "error{" + error + "}, "
+ + "msg{" + (msg == null ? "" : msg.toString()) + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/net/netlink/StructNlMsgHdr.java b/core/java/android/net/netlink/StructNlMsgHdr.java
new file mode 100644
index 0000000..67925ac
--- /dev/null
+++ b/core/java/android/net/netlink/StructNlMsgHdr.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import java.nio.ByteBuffer;
+
+
+/**
+ * struct nlmsghdr
+ *
+ * see <linux_src>/include/uapi/linux/netlink.h
+ *
+ * @hide
+ */
+public class StructNlMsgHdr {
+ // Already aligned.
+ public static final int STRUCT_SIZE = 16;
+
+ public static final short NLM_F_REQUEST = 0x0001;
+ public static final short NLM_F_MULTI = 0x0002;
+ public static final short NLM_F_ACK = 0x0004;
+ public static final short NLM_F_ECHO = 0x0008;
+ // Flags for a GET request.
+ public static final short NLM_F_ROOT = 0x0100;
+ public static final short NLM_F_MATCH = 0x0200;
+ public static final short NLM_F_DUMP = NLM_F_ROOT|NLM_F_MATCH;
+
+ public static String stringForNlMsgFlags(short flags) {
+ final StringBuilder sb = new StringBuilder();
+ if ((flags & NLM_F_REQUEST) != 0) {
+ sb.append("NLM_F_REQUEST");
+ }
+ if ((flags & NLM_F_MULTI) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NLM_F_MULTI");
+ }
+ if ((flags & NLM_F_ACK) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NLM_F_ACK");
+ }
+ if ((flags & NLM_F_ECHO) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NLM_F_ECHO");
+ }
+ if ((flags & NLM_F_ROOT) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NLM_F_ROOT");
+ }
+ if ((flags & NLM_F_MATCH) != 0) {
+ if (sb.length() > 0) { sb.append("|"); }
+ sb.append("NLM_F_MATCH");
+ }
+ return sb.toString();
+ }
+
+ public static boolean hasAvailableSpace(ByteBuffer byteBuffer) {
+ return byteBuffer != null && byteBuffer.remaining() >= STRUCT_SIZE;
+ }
+
+ public static StructNlMsgHdr parse(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return null; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the exception
+ // of usage within unittests.
+ final StructNlMsgHdr struct = new StructNlMsgHdr();
+ struct.nlmsg_len = byteBuffer.getInt();
+ struct.nlmsg_type = byteBuffer.getShort();
+ struct.nlmsg_flags = byteBuffer.getShort();
+ struct.nlmsg_seq = byteBuffer.getInt();
+ struct.nlmsg_pid = byteBuffer.getInt();
+
+ if (struct.nlmsg_len < STRUCT_SIZE) {
+ // Malformed.
+ return null;
+ }
+ return struct;
+ }
+
+ public int nlmsg_len;
+ public short nlmsg_type;
+ public short nlmsg_flags;
+ public int nlmsg_seq;
+ public int nlmsg_pid;
+
+ public StructNlMsgHdr() {
+ nlmsg_len = 0;
+ nlmsg_type = 0;
+ nlmsg_flags = 0;
+ nlmsg_seq = 0;
+ nlmsg_pid = 0;
+ }
+
+ public boolean pack(ByteBuffer byteBuffer) {
+ if (!hasAvailableSpace(byteBuffer)) { return false; }
+
+ // The ByteOrder must have already been set by the caller. In most
+ // cases ByteOrder.nativeOrder() is correct, with the possible
+ // exception of usage within unittests.
+ byteBuffer.putInt(nlmsg_len);
+ byteBuffer.putShort(nlmsg_type);
+ byteBuffer.putShort(nlmsg_flags);
+ byteBuffer.putInt(nlmsg_seq);
+ byteBuffer.putInt(nlmsg_pid);
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ final String typeStr = "" + nlmsg_type
+ + "(" + NetlinkConstants.stringForNlMsgType(nlmsg_type) + ")";
+ final String flagsStr = "" + nlmsg_flags
+ + "(" + stringForNlMsgFlags(nlmsg_flags) + ")";
+ return "StructNlMsgHdr{ "
+ + "nlmsg_len{" + nlmsg_len + "}, "
+ + "nlmsg_type{" + typeStr + "}, "
+ + "nlmsg_flags{" + flagsStr + ")}, "
+ + "nlmsg_seq{" + nlmsg_seq + "}, "
+ + "nlmsg_pid{" + nlmsg_pid + "} "
+ + "}";
+ }
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 4dfe0de..5f515eb 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -425,6 +425,24 @@
public abstract long getMobileRadioActiveTime(int which);
public abstract int getMobileRadioActiveCount(int which);
+ /**
+ * Get the total cpu time (in microseconds) this UID had processes executing in userspace.
+ */
+ public abstract long getUserCpuTimeUs(int which);
+
+ /**
+ * Get the total cpu time (in microseconds) this UID had processes executing kernel syscalls.
+ */
+ public abstract long getSystemCpuTimeUs(int which);
+
+ /**
+ * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
+ * @param speedStep the index of the CPU speed. This is not the actual speed of the CPU.
+ * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
+ * @see BatteryStats#getCpuSpeedSteps()
+ */
+ public abstract long getTimeAtCpuSpeed(int step, int which);
+
public static abstract class Sensor {
/*
* FIXME: it's not correct to use this magic value because it
@@ -506,15 +524,6 @@
*/
public abstract long getForegroundTime(int which);
- /**
- * Returns the approximate cpu time (in milliseconds) spent at a certain CPU speed.
- * @param speedStep the index of the CPU speed. This is not the actual speed of the
- * CPU.
- * @param which one of STATS_SINCE_CHARGED, STATS_SINCE_UNPLUGGED, or STATS_CURRENT.
- * @see BatteryStats#getCpuSpeedSteps()
- */
- public abstract long getTimeAtCpuSpeedStep(int speedStep, int which);
-
public abstract int countExcessivePowers();
public abstract ExcessivePower getExcessivePower(int i);
@@ -3873,6 +3882,16 @@
}
}
+ final long userCpuTimeUs = u.getUserCpuTimeUs(which);
+ final long systemCpuTimeUs = u.getSystemCpuTimeUs(which);
+ if (userCpuTimeUs > 0 || systemCpuTimeUs > 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Total cpu time: ");
+ formatTimeMs(sb, (userCpuTimeUs + systemCpuTimeUs) / 1000);
+ pw.println(sb.toString());
+ }
+
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats
= u.getProcessStats();
for (int ipr=processStats.size()-1; ipr>=0; ipr--) {
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 021e5e4..917271d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -528,7 +528,7 @@
* {@code /after/foo/bar.txt}.
*/
public static File rewriteAfterRename(File beforeDir, File afterDir, File file) {
- if (file == null) return null;
+ if (file == null || beforeDir == null || afterDir == null) return null;
if (contains(beforeDir, file)) {
final String splice = file.getAbsolutePath().substring(
beforeDir.getAbsolutePath().length());
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 0b55998..1cc2d33 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -476,8 +476,18 @@
}
/**
- * Enable detection of mismatches between defined resource types
+ * Enables detection of mismatches between defined resource types
* and getter calls.
+ * <p>
+ * This helps detect accidental type mismatches and potentially
+ * expensive type conversions when obtaining typed resources.
+ * <p>
+ * For example, a strict mode violation would be thrown when
+ * calling {@link android.content.res.TypedArray#getInt(int, int)}
+ * on an index that contains a String-type resource. If the string
+ * value can be parsed as an integer, this method call will return
+ * a value without crashing; however, the developer should format
+ * the resource as an integer to avoid unnecessary type conversion.
*/
public Builder detectResourceMismatches() {
return enable(DETECT_RESOURCE_MISMATCH);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index cc37d5e..3dee68c 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -936,7 +936,7 @@
* Returns list of the profiles of userHandle including
* userHandle itself.
* Note that this returns both enabled and not enabled profiles. See
- * {@link #getUserProfiles()} if you need only the enabled ones.
+ * {@link #getEnabledProfiles(int)} if you need only the enabled ones.
*
* Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
* @param userHandle profiles of this user will be returned.
@@ -953,6 +953,25 @@
}
/**
+ * Returns list of the profiles of userHandle including
+ * userHandle itself.
+ * Note that this returns only enabled.
+ *
+ * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+ * @param userHandle profiles of this user will be returned.
+ * @return the list of profiles.
+ * @hide
+ */
+ public List<UserInfo> getEnabledProfiles(int userHandle) {
+ try {
+ return mService.getProfiles(userHandle, true /* enabledOnly */);
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not get user list", re);
+ return null;
+ }
+ }
+
+ /**
* Returns a list of UserHandles for profiles associated with the user that the calling process
* is running on, including the user itself.
*
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index fcde3f4..e55ae99 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -1005,6 +1005,22 @@
}
@Override
+ public long benchmark(String volId) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeString(volId);
+ mRemote.transact(Stub.TRANSACTION_benchmark, _data, _reply, 0);
+ _reply.readException();
+ return _reply.readLong();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
public void partitionPublic(String diskId) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1099,6 +1115,36 @@
}
@Override
+ public void forgetAllVolumes() throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ mRemote.transact(Stub.TRANSACTION_forgetAllVolumes, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
+ public void setDebugFlags(int _flags, int _mask) throws RemoteException {
+ Parcel _data = Parcel.obtain();
+ Parcel _reply = Parcel.obtain();
+ try {
+ _data.writeInterfaceToken(DESCRIPTOR);
+ _data.writeInt(_flags);
+ _data.writeInt(_mask);
+ mRemote.transact(Stub.TRANSACTION_setDebugFlags, _data, _reply, 0);
+ _reply.readException();
+ } finally {
+ _reply.recycle();
+ _data.recycle();
+ }
+ }
+
+ @Override
public String getPrimaryStorageUuid() throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
@@ -1238,9 +1284,13 @@
static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 53;
static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 54;
static final int TRANSACTION_forgetVolume = IBinder.FIRST_CALL_TRANSACTION + 55;
+ static final int TRANSACTION_forgetAllVolumes = IBinder.FIRST_CALL_TRANSACTION + 56;
- static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 56;
- static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
+ static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
+ static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58;
+
+ static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
+ static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
/**
* Cast an IBinder object into an IMountService interface, generating a
@@ -1711,6 +1761,14 @@
reply.writeNoException();
return true;
}
+ case TRANSACTION_benchmark: {
+ data.enforceInterface(DESCRIPTOR);
+ String volId = data.readString();
+ long res = benchmark(volId);
+ reply.writeNoException();
+ reply.writeLong(res);
+ return true;
+ }
case TRANSACTION_partitionPublic: {
data.enforceInterface(DESCRIPTOR);
String diskId = data.readString();
@@ -1757,6 +1815,20 @@
reply.writeNoException();
return true;
}
+ case TRANSACTION_forgetAllVolumes: {
+ data.enforceInterface(DESCRIPTOR);
+ forgetAllVolumes();
+ reply.writeNoException();
+ return true;
+ }
+ case TRANSACTION_setDebugFlags: {
+ data.enforceInterface(DESCRIPTOR);
+ int _flags = data.readInt();
+ int _mask = data.readInt();
+ setDebugFlags(_flags, _mask);
+ reply.writeNoException();
+ return true;
+ }
case TRANSACTION_getPrimaryStorageUuid: {
data.enforceInterface(DESCRIPTOR);
String volumeUuid = getPrimaryStorageUuid();
@@ -2067,6 +2139,7 @@
public void mount(String volId) throws RemoteException;
public void unmount(String volId) throws RemoteException;
public void format(String volId) throws RemoteException;
+ public long benchmark(String volId) throws RemoteException;
public void partitionPublic(String diskId) throws RemoteException;
public void partitionPrivate(String diskId) throws RemoteException;
@@ -2075,6 +2148,8 @@
public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException;
public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
public void forgetVolume(String fsUuid) throws RemoteException;
+ public void forgetAllVolumes() throws RemoteException;
+ public void setDebugFlags(int flags, int mask) throws RemoteException;
public String getPrimaryStorageUuid() throws RemoteException;
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 3fdabee..8ff56f8 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -73,6 +73,8 @@
/** {@hide} */
public static final String PROP_PRIMARY_PHYSICAL = "ro.vold.primary_physical";
/** {@hide} */
+ public static final String PROP_HAS_ADOPTABLE = "vold.has_adoptable";
+ /** {@hide} */
public static final String PROP_FORCE_ADOPTABLE = "persist.fw.force_adoptable";
/** {@hide} */
@@ -80,6 +82,9 @@
/** {@hide} */
public static final String UUID_PRIMARY_PHYSICAL = "primary_physical";
+ /** {@hide} */
+ public static final int DEBUG_FORCE_ADOPTABLE = 1 << 0;
+
private final Context mContext;
private final ContentResolver mResolver;
@@ -639,6 +644,15 @@
}
/** {@hide} */
+ public long benchmark(String volId) {
+ try {
+ return mMountService.benchmark(volId);
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /** {@hide} */
public void partitionPublic(String diskId) {
try {
mMountService.partitionPublic(diskId);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d3a5561..ef0dc3e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3102,7 +3102,16 @@
public static final String EGG_MODE = "egg_mode";
/** @hide */
- public static final Validator EGG_MODE_VALIDATOR = sBooleanValidator;
+ public static final Validator EGG_MODE_VALIDATOR = new Validator() {
+ @Override
+ public boolean validate(String value) {
+ try {
+ return Long.parseLong(value) >= 0;
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
+ };
/**
* IMPORTANT: If you add a new public settings you also have to add it to
@@ -4133,7 +4142,10 @@
* LocationManager service for testing purposes during application development. These
* locations and status values override actual location and status information generated
* by network, gps, or other location providers.
+ *
+ * @deprecated This settings is not used anymore.
*/
+ @Deprecated
public static final String ALLOW_MOCK_LOCATION = "mock_location";
/**
@@ -4363,12 +4375,6 @@
"lock_screen_appwidget_ids";
/**
- * List of enrolled fingerprint identifiers (comma-delimited).
- * @hide
- */
- public static final String USER_FINGERPRINT_IDS = "user_fingerprint_ids";
-
- /**
* Id of the appwidget shown on the lock screen when appwidgets are disabled.
* @hide
*/
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 879f26c..89668c1 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -306,6 +306,13 @@
contentValues.put(Voicemails.SOURCE_PACKAGE, voicemail.getSourcePackage());
contentValues.put(Voicemails.SOURCE_DATA, voicemail.getSourceData());
contentValues.put(Voicemails.IS_READ, voicemail.isRead() ? 1 : 0);
+
+ PhoneAccountHandle phoneAccount = voicemail.getPhoneAccount();
+ if (voicemail.getPhoneAccount() != null) {
+ contentValues.put(Voicemails.PHONE_ACCOUNT_COMPONENT_NAME,
+ phoneAccount.getComponentName().flattenToString());
+ contentValues.put(Voicemails.PHONE_ACCOUNT_ID, phoneAccount.getId());
+ }
return contentValues;
}
}
diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl
index 4809050..b0779c0 100644
--- a/core/java/android/security/IKeystoreService.aidl
+++ b/core/java/android/security/IKeystoreService.aidl
@@ -75,4 +75,6 @@
int abort(IBinder handle);
boolean isOperationAuthorized(IBinder token);
int addAuthToken(in byte[] authToken);
+ int onUserAdded(int userId, int parentId);
+ int onUserRemoved(int userId);
}
diff --git a/core/java/android/service/carrier/CarrierConfigService.java b/core/java/android/service/carrier/CarrierConfigService.java
index 1880d16..bf33ad5 100644
--- a/core/java/android/service/carrier/CarrierConfigService.java
+++ b/core/java/android/service/carrier/CarrierConfigService.java
@@ -16,21 +16,21 @@
import android.app.Service;
import android.content.Intent;
-import android.os.Bundle;
import android.os.IBinder;
+import android.os.PersistableBundle;
/**
* A service that sets carrier configuration for telephony services.
* <p>
* To extend this class, you must declare the service in your manifest file to require the
- * {@link android.Manifest.permission#BIND_CARRIER_CONFIG_SERVICE} permission and include an intent
+ * {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission and include an intent
* filter with the {@link #SERVICE_INTERFACE} action. For example:
* </p>
*
* <pre>{@code
* <service android:name=".MyCarrierConfigService"
* android:label="@string/service_name"
- * android:permission="android.permission.BIND_CARRIER_CONFIG_SERVICE">
+ * android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
* <action android:name="android.service.carrier.CarrierConfigService" />
* </intent-filter>
@@ -68,16 +68,16 @@
* </p>
* <p>
* Implementations should use the keys defined in {@link android.telephony.CarrierConfigManager
- * CarrierConfigManager}. Any configuration values not set in the returned {@link Bundle} may be
- * overridden by the system's default configuration service.
+ * CarrierConfigManager}. Any configuration values not set in the returned {@link
+ * PersistableBundle} may be overridden by the system's default configuration service.
* </p>
*
* @param id contains details about the current carrier that can be used do decide what
* configuration values to return.
- * @return a {@link Bundle} object containing the configuration or null if default values should
- * be used.
+ * @return a {@link PersistableBundle} object containing the configuration or null if default
+ * values should be used.
*/
- public abstract Bundle onLoadConfig(CarrierIdentifier id);
+ public abstract PersistableBundle onLoadConfig(CarrierIdentifier id);
/** @hide */
@Override
@@ -97,7 +97,7 @@
private class ICarrierConfigServiceWrapper extends ICarrierConfigService.Stub {
@Override
- public Bundle getCarrierConfig(CarrierIdentifier id) {
+ public PersistableBundle getCarrierConfig(CarrierIdentifier id) {
return CarrierConfigService.this.onLoadConfig(id);
}
}
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index d7bf10c..f5396a3 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -31,12 +31,12 @@
* A service that receives calls from the system when new SMS and MMS are
* sent or received.
* <p>To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE} permission
+ * the {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission
* and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
* <pre>
* <service android:name=".MyMessagingService"
* android:label="@string/service_name"
- * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE">
+ * android:permission="android.permission.BIND_CARRIER_SERVICES">
* <intent-filter>
* <action android:name="android.service.carrier.CarrierMessagingService" />
* </intent-filter>
diff --git a/core/java/android/service/carrier/ICarrierConfigService.aidl b/core/java/android/service/carrier/ICarrierConfigService.aidl
index d8390b6..abbc000 100644
--- a/core/java/android/service/carrier/ICarrierConfigService.aidl
+++ b/core/java/android/service/carrier/ICarrierConfigService.aidl
@@ -16,7 +16,7 @@
package android.service.carrier;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.service.carrier.CarrierIdentifier;
/**
@@ -28,5 +28,5 @@
interface ICarrierConfigService {
/** @see android.service.carrier.CarrierConfigService#onLoadConfig */
- Bundle getCarrierConfig(in CarrierIdentifier id);
-}
\ No newline at end of file
+ PersistableBundle getCarrierConfig(in CarrierIdentifier id);
+}
diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java
index 4c94ee7..50c435a 100644
--- a/core/java/android/service/chooser/ChooserTarget.java
+++ b/core/java/android/service/chooser/ChooserTarget.java
@@ -25,6 +25,7 @@
import android.content.IntentFilter;
import android.content.IntentSender;
import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -34,6 +35,16 @@
/**
* A ChooserTarget represents a deep-link into an application as returned by a
* {@link android.service.chooser.ChooserTargetService}.
+ *
+ * <p>A chooser target represents a specific deep link target into an application exposed
+ * for selection by the user. This might be a frequently emailed contact, a recently active
+ * group messaging conversation, a folder in a cloud storage app, a collection of related
+ * items published on a social media service or any other contextually relevant grouping
+ * of target app + relevant metadata.</p>
+ *
+ * <p>Creators of chooser targets should consult the relevant design guidelines for the type
+ * of target they are presenting. For example, targets involving people should be presented
+ * with a circular icon.</p>
*/
public final class ChooserTarget implements Parcelable {
private static final String TAG = "ChooserTarget";
@@ -48,7 +59,7 @@
* The icon that will be shown to the user to represent this target.
* The system may resize this icon as appropriate.
*/
- private Bitmap mIcon;
+ private Icon mIcon;
/**
* The IntentSender that will be used to deliver the intent to the target.
@@ -93,7 +104,7 @@
* @param score ranking score for this target between 0.0f and 1.0f, inclusive
* @param pendingIntent PendingIntent to fill in and send if the user chooses this target
*/
- public ChooserTarget(CharSequence title, Bitmap icon, float score,
+ public ChooserTarget(CharSequence title, Icon icon, float score,
PendingIntent pendingIntent) {
this(title, icon, score, pendingIntent.getIntentSender());
}
@@ -129,7 +140,7 @@
* @param score ranking score for this target between 0.0f and 1.0f, inclusive
* @param intentSender IntentSender to fill in and send if the user chooses this target
*/
- public ChooserTarget(CharSequence title, Bitmap icon, float score, IntentSender intentSender) {
+ public ChooserTarget(CharSequence title, Icon icon, float score, IntentSender intentSender) {
mTitle = title;
mIcon = icon;
if (score > 1.f || score < 0.f) {
@@ -143,7 +154,7 @@
ChooserTarget(Parcel in) {
mTitle = in.readCharSequence();
if (in.readInt() != 0) {
- mIcon = Bitmap.CREATOR.createFromParcel(in);
+ mIcon = Icon.CREATOR.createFromParcel(in);
} else {
mIcon = null;
}
@@ -167,7 +178,7 @@
*
* @return the icon representing this target, intended to be shown to a user
*/
- public Bitmap getIcon() {
+ public Icon getIcon() {
return mIcon;
}
diff --git a/core/java/android/service/chooser/ChooserTargetService.java b/core/java/android/service/chooser/ChooserTargetService.java
index 699bd0a..0d1834a 100644
--- a/core/java/android/service/chooser/ChooserTargetService.java
+++ b/core/java/android/service/chooser/ChooserTargetService.java
@@ -107,7 +107,7 @@
* <p>The returned list should be sorted such that the most relevant targets appear first.
* Any PendingIntents used to construct the resulting ChooserTargets should always be prepared
* to have the relevant data fields filled in by the sender. See
- * {@link ChooserTarget#ChooserTarget(CharSequence, android.graphics.Bitmap, float, android.app.PendingIntent) ChooserTarget}.</p>
+ * {@link ChooserTarget#ChooserTarget(CharSequence, android.graphics.drawable.Icon, float, android.app.PendingIntent) ChooserTarget}.</p>
*
* <p><em>Important:</em> Calls to this method from other applications will occur on
* a binder thread, not on your app's main thread. Make sure that access to relevant data
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 599ac74..1e42913 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -573,24 +573,34 @@
}
public static Condition toTimeCondition(Context context, int minutesFromNow, int userHandle) {
+ return toTimeCondition(context, minutesFromNow, userHandle, false /*shortVersion*/);
+ }
+
+ public static Condition toTimeCondition(Context context, int minutesFromNow, int userHandle,
+ boolean shortVersion) {
final long now = System.currentTimeMillis();
final long millis = minutesFromNow == 0 ? ZERO_VALUE_MS : minutesFromNow * MINUTES_MS;
- return toTimeCondition(context, now + millis, minutesFromNow, now, userHandle);
+ return toTimeCondition(context, now + millis, minutesFromNow, now, userHandle,
+ shortVersion);
}
public static Condition toTimeCondition(Context context, long time, int minutes, long now,
- int userHandle) {
+ int userHandle, boolean shortVersion) {
final int num, summaryResId, line1ResId;
if (minutes < 60) {
// display as minutes
num = minutes;
- summaryResId = R.plurals.zen_mode_duration_minutes_summary;
- line1ResId = R.plurals.zen_mode_duration_minutes;
+ summaryResId = shortVersion ? R.plurals.zen_mode_duration_minutes_summary_short
+ : R.plurals.zen_mode_duration_minutes_summary;
+ line1ResId = shortVersion ? R.plurals.zen_mode_duration_minutes_short
+ : R.plurals.zen_mode_duration_minutes;
} else {
// display as hours
num = Math.round(minutes / 60f);
- summaryResId = com.android.internal.R.plurals.zen_mode_duration_hours_summary;
- line1ResId = com.android.internal.R.plurals.zen_mode_duration_hours;
+ summaryResId = shortVersion ? R.plurals.zen_mode_duration_hours_summary_short
+ : R.plurals.zen_mode_duration_hours_summary;
+ line1ResId = shortVersion ? R.plurals.zen_mode_duration_hours_short
+ : R.plurals.zen_mode_duration_hours;
}
final String skeleton = DateFormat.is24HourFormat(context, userHandle) ? "Hm" : "hma";
final String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton);
@@ -793,17 +803,17 @@
}
public static String getConditionLine1(Context context, ZenModeConfig config,
- int userHandle) {
- return getConditionLine(context, config, userHandle, true /*useLine1*/);
+ int userHandle, boolean shortVersion) {
+ return getConditionLine(context, config, userHandle, true /*useLine1*/, shortVersion);
}
public static String getConditionSummary(Context context, ZenModeConfig config,
- int userHandle) {
- return getConditionLine(context, config, userHandle, false /*useLine1*/);
+ int userHandle, boolean shortVersion) {
+ return getConditionLine(context, config, userHandle, false /*useLine1*/, shortVersion);
}
private static String getConditionLine(Context context, ZenModeConfig config,
- int userHandle, boolean useLine1) {
+ int userHandle, boolean useLine1, boolean shortVersion) {
if (config == null) return "";
if (config.manualRule != null) {
final Uri id = config.manualRule.conditionId;
@@ -816,7 +826,7 @@
final long now = System.currentTimeMillis();
final long span = time - now;
c = toTimeCondition(context,
- time, Math.round(span / (float) MINUTES_MS), now, userHandle);
+ time, Math.round(span / (float) MINUTES_MS), now, userHandle, shortVersion);
}
final String rt = c == null ? "" : useLine1 ? c.line1 : c.summary;
return TextUtils.isEmpty(rt) ? "" : rt;
diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java
index 2a2589a..7ea9da1 100644
--- a/core/java/android/text/BidiFormatter.java
+++ b/core/java/android/text/BidiFormatter.java
@@ -25,7 +25,7 @@
/**
* Utility class for formatting text for display in a potentially opposite-directionality context
* without garbling. The directionality of the context is set at formatter creation and the
- * directionality of the text can be either estimated or passed in when known.
+ * directionality of the text can be either estimated or passed in when known.
*
* <p>To support versions lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2},
* you can use the support library's {@link android.support.v4.text.BidiFormatter} class.
@@ -377,9 +377,11 @@
* See {@link TextDirectionHeuristics} for pre-defined heuristics.
* @param isolate Whether to directionally isolate the string to prevent it from garbling the
* content around it
- * @return Input string after applying the above processing.
+ * @return Input string after applying the above processing. {@code null} if {@code str} is
+ * {@code null}.
*/
public String unicodeWrap(String str, TextDirectionHeuristic heuristic, boolean isolate) {
+ if (str == null) return null;
final boolean isRtl = heuristic.isRtl(str, 0, str.length());
StringBuilder result = new StringBuilder();
if (getStereoReset() && isolate) {
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index fc65f63..e99a960 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -79,7 +79,8 @@
boolean includepad,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
- spacingmult, spacingadd, includepad, StaticLayout.BREAK_STRATEGY_SIMPLE,
+ spacingmult, spacingadd, includepad,
+ StaticLayout.BREAK_STRATEGY_SIMPLE, StaticLayout.HYPHENATION_FREQUENCY_NONE,
ellipsize, ellipsizedWidth);
}
@@ -96,7 +97,7 @@
TextPaint paint,
int width, Alignment align, TextDirectionHeuristic textDir,
float spacingmult, float spacingadd,
- boolean includepad, int breakStrategy,
+ boolean includepad, int breakStrategy, int hyphenationFrequency,
TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
super((ellipsize == null)
? display
@@ -122,6 +123,7 @@
mIncludePad = includepad;
mBreakStrategy = breakStrategy;
+ mHyphenationFrequency = hyphenationFrequency;
/*
* This is annoying, but we can't refer to the layout until
@@ -293,7 +295,8 @@
.setLineSpacing(getSpacingAdd(), getSpacingMultiplier())
.setEllipsizedWidth(mEllipsizedWidth)
.setEllipsize(mEllipsizeAt)
- .setBreakStrategy(mBreakStrategy);
+ .setBreakStrategy(mBreakStrategy)
+ .setHyphenationFrequency(mHyphenationFrequency);
reflowed.generate(b, false, true);
int n = reflowed.getLineCount();
@@ -719,6 +722,7 @@
private int mEllipsizedWidth;
private TextUtils.TruncateAt mEllipsizeAt;
private int mBreakStrategy;
+ private int mHyphenationFrequency;
private PackedIntVector mInts;
private PackedObjectVector<Directions> mObjects;
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 60de02a..f176240 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -71,6 +71,35 @@
*/
public static final int BREAK_STRATEGY_BALANCED = 2;
+ /** @hide */
+ @IntDef({HYPHENATION_FREQUENCY_NORMAL, HYPHENATION_FREQUENCY_FULL,
+ HYPHENATION_FREQUENCY_NONE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface HyphenationFrequency {}
+
+ /**
+ * Value for hyphenation frequency indicating no automatic hyphenation. Useful
+ * for backward compatibility, and for cases where the automatic hyphenation algorithm results
+ * in incorrect hyphenation. Mid-word breaks may still happen when a word is wider than the
+ * layout and there is otherwise no valid break. Soft hyphens are ignored and will not be used
+ * as suggestions for potential line breaks.
+ */
+ public static final int HYPHENATION_FREQUENCY_NONE = 0;
+
+ /**
+ * Value for hyphenation frequency indicating a light amount of automatic hyphenation, which
+ * is a conservative default. Useful for informal cases, such as short sentences or chat
+ * messages.
+ */
+ public static final int HYPHENATION_FREQUENCY_NORMAL = 1;
+
+ /**
+ * Value for hyphenation frequency indicating the full amount of automatic hyphenation, typical
+ * in typography. Useful for running text and where it's important to put the maximum amount of
+ * text in a screen with limited space.
+ */
+ public static final int HYPHENATION_FREQUENCY_FULL = 2;
+
private static final ParagraphStyle[] NO_PARA_SPANS =
ArrayUtils.emptyArray(ParagraphStyle.class);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 59c7c6d..d6d046b 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -92,6 +92,7 @@
b.mEllipsize = null;
b.mMaxLines = Integer.MAX_VALUE;
b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
+ b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
b.mMeasuredText = MeasuredText.obtain();
return b;
@@ -276,6 +277,19 @@
}
/**
+ * Set hyphenation frequency, to control the amount of automatic hyphenation used. The
+ * default is {@link Layout#HYPHENATION_FREQUENCY_NONE}.
+ *
+ * @param hyphenationFrequency hyphenation frequency for the paragraph
+ * @return this builder, useful for chaining
+ * @see android.widget.TextView#setHyphenationFrequency
+ */
+ public Builder setHyphenationFrequency(@HyphenationFrequency int hyphenationFrequency) {
+ mHyphenationFrequency = hyphenationFrequency;
+ return this;
+ }
+
+ /**
* Set indents. Arguments are arrays holding an indent amount, one per line, measured in
* pixels. For lines past the last element in the array, the last element repeats.
*
@@ -302,7 +316,8 @@
* the native code is as follows.
*
* For each paragraph, do a nSetupParagraph, which sets paragraph text, line width, tab
- * stops, break strategy (and possibly other parameters in the future).
+ * stops, break strategy, and hyphenation frequency (and possibly other parameters in the
+ * future).
*
* Then, for each run within the paragraph:
* - setLocale (this must be done at least for the first run, optional afterwards)
@@ -377,6 +392,7 @@
TextUtils.TruncateAt mEllipsize;
int mMaxLines;
int mBreakStrategy;
+ int mHyphenationFrequency;
Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
@@ -644,7 +660,7 @@
nSetupParagraph(b.mNativePtr, chs, paraEnd - paraStart,
firstWidth, firstWidthLineCount, restWidth,
- variableTabStops, TAB_INCREMENT, b.mBreakStrategy);
+ variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency);
// measurement has to be done before performing line breaking
// but we don't want to recompute fontmetrics or span ranges the
@@ -1153,7 +1169,7 @@
// Set up paragraph text and settings; done as one big method to minimize jni crossings
private static native void nSetupParagraph(long nativePtr, char[] text, int length,
float firstWidth, int firstWidthLineCount, float restWidth,
- int[] variableTabStops, int defaultTabStop, int breakStrategy);
+ int[] variableTabStops, int defaultTabStop, int breakStrategy, int hyphenationFrequency);
private static native float nAddStyleRun(long nativePtr, long nativePaint,
long nativeTypeface, int start, int end, boolean isRtl);
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index c4dc5ed..5dda8a7 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -194,6 +194,87 @@
return BreakIterator.DONE;
}
+ /**
+ * If <code>offset</code> is within a group of punctuation as defined
+ * by {@link #isPunctuation(int)}, returns the index of the first character
+ * of that group, otherwise returns BreakIterator.DONE.
+ *
+ * @param offset the offset to search from.
+ */
+ public int getPunctuationBeginning(int offset) {
+ while (offset != BreakIterator.DONE && !isPunctuationStartBoundary(offset)) {
+ offset = prevBoundary(offset);
+ }
+ // No need to shift offset, prevBoundary handles that.
+ return offset;
+ }
+
+ /**
+ * If <code>offset</code> is within a group of punctuation as defined
+ * by {@link #isPunctuation(int)}, returns the index of the last character
+ * of that group plus one, otherwise returns BreakIterator.DONE.
+ *
+ * @param offset the offset to search from.
+ */
+ public int getPunctuationEnd(int offset) {
+ while (offset != BreakIterator.DONE && !isPunctuationEndBoundary(offset)) {
+ offset = nextBoundary(offset);
+ }
+ // No need to shift offset, nextBoundary handles that.
+ return offset;
+ }
+
+ /**
+ * Indicates if the provided offset is after a punctuation character
+ * as defined by {@link #isPunctuation(int)}.
+ *
+ * @param offset the offset to check from.
+ * @return Whether the offset is after a punctuation character.
+ */
+ public boolean isAfterPunctuation(int offset) {
+ final int shiftedOffset = offset - mOffsetShift;
+ if (shiftedOffset >= 1 && shiftedOffset <= mString.length()) {
+ final int codePoint = mString.codePointBefore(shiftedOffset);
+ return isPunctuation(codePoint);
+ }
+ return false;
+ }
+
+ /**
+ * Indicates if the provided offset is at a punctuation character
+ * as defined by {@link #isPunctuation(int)}.
+ *
+ * @param offset the offset to check from.
+ * @return Whether the offset is at a punctuation character.
+ */
+ public boolean isOnPunctuation(int offset) {
+ final int shiftedOffset = offset - mOffsetShift;
+ if (shiftedOffset >= 0 && shiftedOffset < mString.length()) {
+ final int codePoint = mString.codePointAt(shiftedOffset);
+ return isPunctuation(codePoint);
+ }
+ return false;
+ }
+
+ private boolean isPunctuationStartBoundary(int offset) {
+ return isOnPunctuation(offset) && !isAfterPunctuation(offset);
+ }
+
+ private boolean isPunctuationEndBoundary(int offset) {
+ return !isOnPunctuation(offset) && isAfterPunctuation(offset);
+ }
+
+ private boolean isPunctuation(int cp) {
+ int type = Character.getType(cp);
+ return (type == Character.CONNECTOR_PUNCTUATION ||
+ type == Character.DASH_PUNCTUATION ||
+ type == Character.END_PUNCTUATION ||
+ type == Character.FINAL_QUOTE_PUNCTUATION ||
+ type == Character.INITIAL_QUOTE_PUNCTUATION ||
+ type == Character.OTHER_PUNCTUATION ||
+ type == Character.START_PUNCTUATION);
+ }
+
private boolean isAfterLetterOrDigit(int shiftedOffset) {
if (shiftedOffset >= 1 && shiftedOffset <= mString.length()) {
final int codePoint = mString.codePointBefore(shiftedOffset);
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 79a8489..d2b6533 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -209,7 +209,7 @@
private static float getRefreshRate() {
DisplayInfo di = DisplayManagerGlobal.getInstance().getDisplayInfo(
Display.DEFAULT_DISPLAY);
- return di.refreshRate;
+ return di.getMode().getRefreshRate();
}
/**
diff --git a/telecomm/java/android/telecom/CameraCapabilities.aidl b/core/java/android/view/Display.aidl
similarity index 68%
copy from telecomm/java/android/telecom/CameraCapabilities.aidl
copy to core/java/android/view/Display.aidl
index c8e0c5e..42bba44 100644
--- a/telecomm/java/android/telecom/CameraCapabilities.aidl
+++ b/core/java/android/view/Display.aidl
@@ -1,22 +1,19 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
+/**
+ * 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
+ * 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
+ * limitations under the License.
*/
-package android.telecom;
+package android.view;
-/**
- * {@hide}
- */
-parcelable CameraCapabilities;
+parcelable Display.Mode;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 71e2251..d4b971a 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -21,6 +21,8 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.display.DisplayManagerGlobal;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.Process;
import android.os.SystemClock;
import android.util.DisplayMetrics;
@@ -619,18 +621,44 @@
public float getRefreshRate() {
synchronized (this) {
updateDisplayInfoLocked();
- return mDisplayInfo.refreshRate;
+ return mDisplayInfo.getMode().getRefreshRate();
}
}
/**
* Get the supported refresh rates of this display in frames per second.
+ * <p>
+ * This method only returns refresh rates for the display's default modes. For more options, use
+ * {@link #getSupportedModes()}.
+ *
+ * @deprecated use {@link #getSupportedModes()} instead
*/
+ @Deprecated
public float[] getSupportedRefreshRates() {
synchronized (this) {
updateDisplayInfoLocked();
- final float[] refreshRates = mDisplayInfo.supportedRefreshRates;
- return Arrays.copyOf(refreshRates, refreshRates.length);
+ return mDisplayInfo.getDefaultRefreshRates();
+ }
+ }
+
+ /**
+ * Returns the active mode of the display.
+ */
+ public Mode getMode() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.getMode();
+ }
+ }
+
+ /**
+ * Gets the supported modes of this display.
+ */
+ public Mode[] getSupportedModes() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ final Display.Mode[] modes = mDisplayInfo.supportedModes;
+ return Arrays.copyOf(modes, modes.length);
}
}
@@ -862,4 +890,152 @@
public static boolean isSuspendedState(int state) {
return state == STATE_OFF || state == STATE_DOZE_SUSPEND;
}
+
+ /**
+ * A mode supported by a given display.
+ *
+ * @see Display#getSupportedModes()
+ */
+ public static final class Mode implements Parcelable {
+ /**
+ * @hide
+ */
+ public static final Mode[] EMPTY_ARRAY = new Mode[0];
+
+ private final int mModeId;
+ private final int mWidth;
+ private final int mHeight;
+ private final float mRefreshRate;
+
+ /**
+ * @hide
+ */
+ public Mode(int modeId, int width, int height, float refreshRate) {
+ mModeId = modeId;
+ mWidth = width;
+ mHeight = height;
+ mRefreshRate = refreshRate;
+ }
+
+ /**
+ * Returns this mode's id.
+ */
+ public int getModeId() {
+ return mModeId;
+ }
+
+ /**
+ * Returns the physical width of the display in pixels when configured in this mode's
+ * resolution.
+ * <p>
+ * Note that due to application UI scaling, the number of pixels made available to
+ * applications when the mode is active (as reported by {@link Display#getWidth()} may
+ * differ from the mode's actual resolution (as reported by this function).
+ * <p>
+ * For example, applications running on a 4K display may have their UI laid out and rendered
+ * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
+ * rendering content through a {@link android.view.SurfaceView} using full size buffers.
+ */
+ public int getPhysicalWidth() {
+ return mWidth;
+ }
+
+ /**
+ * Returns the physical height of the display in pixels when configured in this mode's
+ * resolution.
+ * <p>
+ * Note that due to application UI scaling, the number of pixels made available to
+ * applications when the mode is active (as reported by {@link Display#getHeight()} may
+ * differ from the mode's actual resolution (as reported by this function).
+ * <p>
+ * For example, applications running on a 4K display may have their UI laid out and rendered
+ * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
+ * rendering content through a {@link android.view.SurfaceView} using full size buffers.
+ */
+ public int getPhysicalHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Returns the refresh rate in frames per second.
+ */
+ public float getRefreshRate() {
+ return mRefreshRate;
+ }
+
+ /**
+ * Returns {@code true} if this mode matches the given parameters.
+ *
+ * @hide
+ */
+ public boolean matches(int width, int height, float refreshRate) {
+ return mWidth == width &&
+ mHeight == height &&
+ Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Mode)) {
+ return false;
+ }
+ Mode that = (Mode) other;
+ return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate);
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ hash = hash * 17 + mModeId;
+ hash = hash * 17 + mWidth;
+ hash = hash * 17 + mHeight;
+ hash = hash * 17 + Float.floatToIntBits(mRefreshRate);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{")
+ .append("id=").append(mModeId)
+ .append(", width=").append(mWidth)
+ .append(", height=").append(mHeight)
+ .append(", fps=").append(mRefreshRate)
+ .append("}")
+ .toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ private Mode(Parcel in) {
+ this(in.readInt(), in.readInt(), in.readInt(), in.readFloat());
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int parcelableFlags) {
+ out.writeInt(mModeId);
+ out.writeInt(mWidth);
+ out.writeInt(mHeight);
+ out.writeFloat(mRefreshRate);
+ }
+
+ @SuppressWarnings("hiding")
+ public static final Parcelable.Creator<Mode> CREATOR
+ = new Parcelable.Creator<Mode>() {
+ @Override
+ public Mode createFromParcel(Parcel in) {
+ return new Mode(in);
+ }
+
+ @Override
+ public Mode[] newArray(int size) {
+ return new Mode[size];
+ }
+ };
+ }
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 243961c..b9fde8a 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -20,11 +20,11 @@
import android.content.res.Configuration;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArraySet;
import android.util.DisplayMetrics;
import java.util.Arrays;
-import libcore.util.EmptyArray;
import libcore.util.Objects;
/**
@@ -155,18 +155,19 @@
public int rotation;
/**
- * The refresh rate of this display in frames per second.
- * <p>
- * The value of this field is indeterminate if the logical display is presented on
- * more than one physical display.
- * </p>
+ * The active display mode.
*/
- public float refreshRate;
+ public int modeId;
/**
- * The supported refresh rates of this display at the current resolution in frames per second.
+ * The default display mode.
*/
- public float[] supportedRefreshRates = EmptyArray.FLOAT;
+ public int defaultModeId;
+
+ /**
+ * The supported modes of this display.
+ */
+ public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
/**
* The logical display density which is the basis for density-independent
@@ -276,7 +277,8 @@
&& overscanRight == other.overscanRight
&& overscanBottom == other.overscanBottom
&& rotation == other.rotation
- && refreshRate == other.refreshRate
+ && modeId == other.modeId
+ && defaultModeId == other.defaultModeId
&& logicalDensityDpi == other.logicalDensityDpi
&& physicalXDpi == other.physicalXDpi
&& physicalYDpi == other.physicalYDpi
@@ -312,9 +314,9 @@
overscanRight = other.overscanRight;
overscanBottom = other.overscanBottom;
rotation = other.rotation;
- refreshRate = other.refreshRate;
- supportedRefreshRates = Arrays.copyOf(
- other.supportedRefreshRates, other.supportedRefreshRates.length);
+ modeId = other.modeId;
+ defaultModeId = other.defaultModeId;
+ supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
logicalDensityDpi = other.logicalDensityDpi;
physicalXDpi = other.physicalXDpi;
physicalYDpi = other.physicalYDpi;
@@ -344,8 +346,13 @@
overscanRight = source.readInt();
overscanBottom = source.readInt();
rotation = source.readInt();
- refreshRate = source.readFloat();
- supportedRefreshRates = source.createFloatArray();
+ modeId = source.readInt();
+ defaultModeId = source.readInt();
+ int nModes = source.readInt();
+ supportedModes = new Display.Mode[nModes];
+ for (int i = 0; i < nModes; i++) {
+ supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
+ }
logicalDensityDpi = source.readInt();
physicalXDpi = source.readFloat();
physicalYDpi = source.readFloat();
@@ -377,8 +384,12 @@
dest.writeInt(overscanRight);
dest.writeInt(overscanBottom);
dest.writeInt(rotation);
- dest.writeFloat(refreshRate);
- dest.writeFloatArray(supportedRefreshRates);
+ dest.writeInt(modeId);
+ dest.writeInt(defaultModeId);
+ dest.writeInt(supportedModes.length);
+ for (int i = 0; i < supportedModes.length; i++) {
+ supportedModes[i].writeToParcel(dest, flags);
+ }
dest.writeInt(logicalDensityDpi);
dest.writeFloat(physicalXDpi);
dest.writeFloat(physicalYDpi);
@@ -395,6 +406,61 @@
return 0;
}
+ public Display.Mode getMode() {
+ return findMode(modeId);
+ }
+
+ public Display.Mode getDefaultMode() {
+ return findMode(defaultModeId);
+ }
+
+ private Display.Mode findMode(int id) {
+ for (int i = 0; i < supportedModes.length; i++) {
+ if (supportedModes[i].getModeId() == id) {
+ return supportedModes[i];
+ }
+ }
+ throw new IllegalStateException("Unable to locate mode " + id);
+ }
+
+ /**
+ * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
+ * mode could be found.
+ */
+ public int findDefaultModeByRefreshRate(float refreshRate) {
+ Display.Mode[] modes = supportedModes;
+ Display.Mode defaultMode = getDefaultMode();
+ for (int i = 0; i < modes.length; i++) {
+ if (modes[i].matches(
+ defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
+ return modes[i].getModeId();
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the list of supported refresh rates in the default mode.
+ */
+ public float[] getDefaultRefreshRates() {
+ Display.Mode[] modes = supportedModes;
+ ArraySet<Float> rates = new ArraySet<>();
+ Display.Mode defaultMode = getDefaultMode();
+ for (int i = 0; i < modes.length; i++) {
+ Display.Mode mode = modes[i];
+ if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
+ && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
+ rates.add(mode.getRefreshRate());
+ }
+ }
+ float[] result = new float[rates.size()];
+ int i = 0;
+ for (Float rate : rates) {
+ result[i++] = rate;
+ }
+ return result;
+ }
+
public void getAppMetrics(DisplayMetrics outMetrics) {
getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
}
@@ -490,10 +556,12 @@
sb.append(smallestNominalAppWidth);
sb.append(" x ");
sb.append(smallestNominalAppHeight);
- sb.append(", ");
- sb.append(refreshRate);
- sb.append(" fps, supportedRefreshRates ");
- sb.append(Arrays.toString(supportedRefreshRates));
+ sb.append(", mode ");
+ sb.append(modeId);
+ sb.append(", defaultMode ");
+ sb.append(defaultModeId);
+ sb.append(", modes ");
+ sb.append(Arrays.toString(supportedModes));
sb.append(", rotation ");
sb.append(rotation);
sb.append(", density ");
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 6632f39..5e58250 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -260,7 +260,7 @@
/**
* Gets the current width of the surface. This is the width that the surface
- * was last set to in a call to {@link #setup(int, int, Rect)}.
+ * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
*
* @return the current width of the surface
*/
@@ -268,7 +268,7 @@
/**
* Gets the current height of the surface. This is the height that the surface
- * was last set to in a call to {@link #setup(int, int, Rect)}.
+ * was last set to in a call to {@link #setup(int, int, View.AttachInfo, Rect)}.
*
* @return the current width of the surface
*/
@@ -373,19 +373,20 @@
*
* @param width The width of the drawing surface.
* @param height The height of the drawing surface.
+ * @param attachInfo Information about the window.
* @param surface The surface to hardware accelerate
* @param surfaceInsets The drawing surface insets to apply
*
* @return true if the surface was initialized, false otherwise. Returning
* false might mean that the surface was already initialized.
*/
- boolean initializeIfNeeded(int width, int height, Surface surface, Rect surfaceInsets)
- throws OutOfResourcesException {
+ boolean initializeIfNeeded(int width, int height, View.AttachInfo attachInfo,
+ Surface surface, Rect surfaceInsets) throws OutOfResourcesException {
if (isRequested()) {
// We lost the gl context, so recreate it.
if (!isEnabled()) {
if (initialize(surface)) {
- setup(width, height, surfaceInsets);
+ setup(width, height, attachInfo, surfaceInsets);
return true;
}
}
@@ -398,9 +399,17 @@
*
* @param width The width of the drawing surface.
* @param height The height of the drawing surface.
+ * @param attachInfo Information about the window.
* @param surfaceInsets The drawing surface insets to apply
*/
- abstract void setup(int width, int height, Rect surfaceInsets);
+ abstract void setup(int width, int height, View.AttachInfo attachInfo, Rect surfaceInsets);
+
+ /**
+ * Updates the light position based on the position of the window.
+ *
+ * @param attachInfo Information about the window.
+ */
+ abstract void setLightCenter(View.AttachInfo attachInfo);
/**
* Optional, sets the name of the renderer. Useful for debugging purposes.
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 9fc80fc..0fefdc7 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -80,11 +80,17 @@
int localValue, int localChanges);
/**
- * If the window manager returned RELAYOUT_RES_ANIMATING
- * from relayout(), this method will be called when the animation
- * is done.
+ * The window is beginning to animate. The application should stop drawing frames until the
+ * window is not animating anymore, indicated by being called {@link #windowEndAnimating}.
+ *
+ * @param remainingFrameCount how many frames the app might still draw before stopping drawing
*/
- void doneAnimating();
+ void onAnimationStarted(int remainingFrameCount);
+
+ /**
+ * The window has ended animating. See {@link #onAnimationStarted}.
+ */
+ void onAnimationStopped();
/**
* Called for non-application windows when the enter animation has completed.
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index c5e4c21..46ef379 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -97,6 +97,9 @@
// Set to true if we received hover enter.
private boolean mHoverEntered;
+ // The bitset of buttons which we've received ACTION_BUTTON_PRESS for.
+ private int mButtonsPressed;
+
// The current violation message.
private StringBuilder mViolationMessage;
@@ -148,6 +151,7 @@
mTouchEventStreamIsTainted = false;
mTouchEventStreamUnhandled = false;
mHoverEntered = false;
+ mButtonsPressed = 0;
while (mKeyStateList != null) {
final KeyState state = mKeyStateList;
@@ -466,6 +470,8 @@
final int action = event.getAction();
final int source = event.getSource();
+ final int buttonState = event.getButtonState();
+ final int actionButton = event.getActionButton();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
switch (action) {
case MotionEvent.ACTION_HOVER_ENTER:
@@ -486,6 +492,62 @@
ensureHistorySizeIsZeroForThisAction(event);
ensurePointerCountIsOneForThisAction(event);
break;
+ case MotionEvent.ACTION_BUTTON_PRESS:
+ ensureActionButtonIsNonZeroForThisAction(event);
+ if ((mButtonsPressed & actionButton) != 0) {
+ problem("Action button for ACTION_BUTTON_PRESS event is " +
+ actionButton + ", but it has already been pressed and " +
+ "has yet to be released.");
+ }
+
+ mButtonsPressed |= actionButton;
+ // The system will automatically mirror the stylus buttons onto the button
+ // state as the old set of generic buttons for apps targeting pre-M. If
+ // it looks this has happened, go ahead and set the generic buttons as
+ // pressed to prevent spurious errors.
+ if (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY &&
+ (buttonState & MotionEvent.BUTTON_SECONDARY) != 0) {
+ mButtonsPressed |= MotionEvent.BUTTON_SECONDARY;
+ } else if (actionButton == MotionEvent.BUTTON_STYLUS_SECONDARY &&
+ (buttonState & MotionEvent.BUTTON_TERTIARY) != 0) {
+ mButtonsPressed |= MotionEvent.BUTTON_TERTIARY;
+ }
+
+ if (mButtonsPressed != buttonState) {
+ problem(String.format("Reported button state differs from " +
+ "expected button state based on press and release events. " +
+ "Is 0x%08x but expected 0x%08x.",
+ buttonState, mButtonsPressed));
+ }
+ break;
+ case MotionEvent.ACTION_BUTTON_RELEASE:
+ ensureActionButtonIsNonZeroForThisAction(event);
+ if ((mButtonsPressed & actionButton) != actionButton) {
+ problem("Action button for ACTION_BUTTON_RELEASE event is " +
+ actionButton + ", but it was either never pressed or has " +
+ "already been released.");
+ }
+
+ mButtonsPressed &= ~actionButton;
+ // The system will automatically mirror the stylus buttons onto the button
+ // state as the old set of generic buttons for apps targeting pre-M. If
+ // it looks this has happened, go ahead and set the generic buttons as
+ // released to prevent spurious errors.
+ if (actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY &&
+ (buttonState & MotionEvent.BUTTON_SECONDARY) == 0) {
+ mButtonsPressed &= ~MotionEvent.BUTTON_SECONDARY;
+ } else if (actionButton == MotionEvent.BUTTON_STYLUS_SECONDARY &&
+ (buttonState & MotionEvent.BUTTON_TERTIARY) == 0) {
+ mButtonsPressed &= ~MotionEvent.BUTTON_TERTIARY;
+ }
+
+ if (mButtonsPressed != buttonState) {
+ problem(String.format("Reported button state differs from " +
+ "expected button state based on press and release events. " +
+ "Is 0x%08x but expected 0x%08x.",
+ buttonState, mButtonsPressed));
+ }
+ break;
default:
problem("Invalid action for generic pointer event.");
break;
@@ -563,6 +625,15 @@
}
}
+ private void ensureActionButtonIsNonZeroForThisAction(MotionEvent event) {
+ final int actionButton = event.getActionButton();
+ if (actionButton == 0) {
+ problem("No action button set. Action button should always be non-zero for " +
+ MotionEvent.actionToString(event.getAction()));
+
+ }
+ }
+
private void ensureHistorySizeIsZeroForThisAction(MotionEvent event) {
final int historySize = event.getHistorySize();
if (historySize != 0) {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 5df596a..4394cd8 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -303,6 +303,32 @@
public static final int ACTION_HOVER_EXIT = 10;
/**
+ * Constant for {@link #getActionMasked}: A button has been pressed.
+ *
+ * <p>
+ * Use {@link #getActionButton()} to get which button was pressed.
+ * </p><p>
+ * This action is not a touch event so it is delivered to
+ * {@link View#onGenericMotionEvent(MotionEvent)} rather than
+ * {@link View#onTouchEvent(MotionEvent)}.
+ * </p>
+ */
+ public static final int ACTION_BUTTON_PRESS = 11;
+
+ /**
+ * Constant for {@link #getActionMasked}: A button has been released.
+ *
+ * <p>
+ * Use {@link #getActionButton()} to get which button was released.
+ * </p><p>
+ * This action is not a touch event so it is delivered to
+ * {@link View#onGenericMotionEvent(MotionEvent)} rather than
+ * {@link View#onTouchEvent(MotionEvent)}.
+ * </p>
+ */
+ public static final int ACTION_BUTTON_RELEASE = 12;
+
+ /**
* Bits in the action code that represent a pointer index, used with
* {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting
* down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer
@@ -1174,14 +1200,14 @@
public static final int BUTTON_PRIMARY = 1 << 0;
/**
- * Button constant: Secondary button (right mouse button, stylus first button).
+ * Button constant: Secondary button (right mouse button).
*
* @see #getButtonState
*/
public static final int BUTTON_SECONDARY = 1 << 1;
/**
- * Button constant: Tertiary button (middle mouse button, stylus second button).
+ * Button constant: Tertiary button (middle mouse button).
*
* @see #getButtonState
*/
@@ -1209,6 +1235,20 @@
*/
public static final int BUTTON_FORWARD = 1 << 4;
+ /**
+ * Button constant: Primary stylus button pressed.
+ *
+ * @see #getButtonState
+ */
+ public static final int BUTTON_STYLUS_PRIMARY = 1 << 5;
+
+ /**
+ * Button constant: Secondary stylus button pressed.
+ *
+ * @see #getButtonState
+ */
+ public static final int BUTTON_STYLUS_SECONDARY = 1 << 6;
+
// NOTE: If you add a new axis here you must also add it to:
// native/include/android/input.h
@@ -1220,8 +1260,8 @@
"BUTTON_TERTIARY",
"BUTTON_BACK",
"BUTTON_FORWARD",
- "0x00000020",
- "0x00000040",
+ "BUTTON_STYLUS_PRIMARY",
+ "BUTTON_STYLUS_SECONDARY",
"0x00000080",
"0x00000100",
"0x00000200",
@@ -1357,6 +1397,8 @@
private static native void nativeSetEdgeFlags(long nativePtr, int action);
private static native int nativeGetMetaState(long nativePtr);
private static native int nativeGetButtonState(long nativePtr);
+ private static native void nativeSetButtonState(long nativePtr, int buttonState);
+ private static native int nativeGetActionButton(long nativePtr);
private static native void nativeOffsetLocation(long nativePtr, float deltaX, float deltaY);
private static native float nativeGetXOffset(long nativePtr);
private static native float nativeGetYOffset(long nativePtr);
@@ -2212,12 +2254,36 @@
* @see #BUTTON_TERTIARY
* @see #BUTTON_FORWARD
* @see #BUTTON_BACK
+ * @see #BUTTON_STYLUS_PRIMARY
+ * @see #BUTTON_STYLUS_SECONDARY
*/
public final int getButtonState() {
return nativeGetButtonState(mNativePtr);
}
/**
+ * Sets the bitfield indicating which buttons are pressed.
+ *
+ * @see #getButtonState()
+ * @hide
+ */
+ public final void setButtonState(int buttonState) {
+ nativeSetButtonState(mNativePtr, buttonState);
+ }
+
+ /**
+ * Gets which button has been modified during a press or release action.
+ *
+ * For actions other than {@link #ACTION_BUTTON_PRESS} and {@link #ACTION_BUTTON_RELEASE}
+ * the returned value is undefined.
+ *
+ * @see #getButtonState()
+ */
+ public final int getActionButton() {
+ return nativeGetActionButton(mNativePtr);
+ }
+
+ /**
* Returns the original raw X coordinate of this event. For touch
* events on the screen, this is the original location of the event
* on the screen, before it had been adjusted for the containing window
@@ -3013,6 +3079,7 @@
public String toString() {
StringBuilder msg = new StringBuilder();
msg.append("MotionEvent { action=").append(actionToString(getAction()));
+ msg.append(", actionButton=").append(buttonStateToString(getActionButton()));
final int pointerCount = getPointerCount();
for (int i = 0; i < pointerCount; i++) {
@@ -3066,6 +3133,10 @@
return "ACTION_HOVER_ENTER";
case ACTION_HOVER_EXIT:
return "ACTION_HOVER_EXIT";
+ case ACTION_BUTTON_PRESS:
+ return "ACTION_BUTTON_PRESS";
+ case ACTION_BUTTON_RELEASE:
+ return "ACTION_BUTTON_RELEASE";
}
int index = (action & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
switch (action & ACTION_MASK) {
@@ -3172,6 +3243,8 @@
* @see #BUTTON_TERTIARY
* @see #BUTTON_FORWARD
* @see #BUTTON_BACK
+ * @see #BUTTON_STYLUS_PRIMARY
+ * @see #BUTTON_STYLUS_SECONDARY
*/
public final boolean isButtonPressed(int button) {
if (button == 0) {
@@ -3180,18 +3253,6 @@
return (getButtonState() & button) == button;
}
- /**
- * Checks if a stylus is being used and if the first stylus button is
- * pressed.
- *
- * @return True if the tool is a stylus and if the first stylus button is
- * pressed.
- * @see #BUTTON_SECONDARY
- */
- public final boolean isStylusButtonPressed() {
- return (isButtonPressed(BUTTON_SECONDARY) && getToolType(0) == TOOL_TYPE_STYLUS);
- }
-
public static final Parcelable.Creator<MotionEvent> CREATOR
= new Parcelable.Creator<MotionEvent>() {
public MotionEvent createFromParcel(Parcel in) {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 85b22fb..d70712a 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -717,6 +717,14 @@
if (surfaceTexture == null) {
throw new NullPointerException("surfaceTexture must not be null");
}
+ if (surfaceTexture == mSurface) {
+ throw new IllegalArgumentException("Trying to setSurfaceTexture to " +
+ "the same SurfaceTexture that's already set.");
+ }
+ if (surfaceTexture.isReleased()) {
+ throw new IllegalArgumentException("Cannot setSurfaceTexture to a " +
+ "released SurfaceTexture");
+ }
if (mSurface != null) {
mSurface.release();
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 1fd7109..7f243d3 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -19,11 +19,10 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
-import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.Binder;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
@@ -31,7 +30,6 @@
import android.os.ServiceManager;
import android.os.Trace;
import android.util.Log;
-import android.util.LongSparseArray;
import android.view.Surface.OutOfResourcesException;
import android.view.View.AttachInfo;
@@ -41,8 +39,6 @@
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.HashSet;
/**
* Hardware renderer that proxies the rendering to a render thread. Most calls
@@ -197,10 +193,10 @@
}
@Override
- void setup(int width, int height, Rect surfaceInsets) {
- final float lightX = width / 2.0f;
+ void setup(int width, int height, AttachInfo attachInfo, Rect surfaceInsets) {
mWidth = width;
mHeight = height;
+
if (surfaceInsets != null && (surfaceInsets.left != 0 || surfaceInsets.right != 0
|| surfaceInsets.top != 0 || surfaceInsets.bottom != 0)) {
mHasInsets = true;
@@ -218,10 +214,23 @@
mSurfaceWidth = width;
mSurfaceHeight = height;
}
+
mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
- nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight,
- lightX, mLightY, mLightZ, mLightRadius,
+ nSetup(mNativeProxy, mSurfaceWidth, mSurfaceHeight, mLightRadius,
mAmbientShadowAlpha, mSpotShadowAlpha);
+
+ setLightCenter(attachInfo);
+ }
+
+ @Override
+ void setLightCenter(AttachInfo attachInfo) {
+ // Adjust light position for window offsets.
+ final Point displaySize = attachInfo.mPoint;
+ attachInfo.mDisplay.getRealSize(displaySize);
+ final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
+ final float lightY = mLightY - attachInfo.mWindowTop;
+
+ nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
}
@Override
@@ -500,8 +509,9 @@
private static native void nUpdateSurface(long nativeProxy, Surface window);
private static native boolean nPauseSurface(long nativeProxy, Surface window);
private static native void nSetup(long nativeProxy, int width, int height,
- float lightX, float lightY, float lightZ, float lightRadius,
- int ambientShadowAlpha, int spotShadowAlpha);
+ float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
+ private static native void nSetLightCenter(long nativeProxy,
+ float lightX, float lightY, float lightZ);
private static native void nSetOpaque(long nativeProxy, boolean opaque);
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e1f1816..6ca320a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4265,12 +4265,13 @@
}
mForegroundInfo.mInsidePadding = a.getBoolean(attr,
mForegroundInfo.mInsidePadding);
+ break;
case R.styleable.View_scrollIndicators:
final int scrollIndicators =
- a.getInt(attr, SCROLL_INDICATORS_NONE) & SCROLL_INDICATORS_PFLAG3_MASK;
+ (a.getInt(attr, 0) << SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT)
+ & SCROLL_INDICATORS_PFLAG3_MASK;
if (scrollIndicators != 0) {
- viewFlagValues |= scrollIndicators;
- viewFlagMasks |= SCROLL_INDICATORS_PFLAG3_MASK;
+ mPrivateFlags3 |= scrollIndicators;
initializeScrollIndicators = true;
}
break;
@@ -4884,7 +4885,8 @@
* @attr ref android.R.styleable#View_scrollIndicators
*/
public void setScrollIndicators(@ScrollIndicators int indicators) {
- setScrollIndicators(indicators, SCROLL_INDICATORS_PFLAG3_MASK);
+ setScrollIndicators(indicators,
+ SCROLL_INDICATORS_PFLAG3_MASK >>> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT);
}
/**
@@ -4954,36 +4956,6 @@
>>> SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
}
- /**
- * Returns whether the specified scroll indicator is enabled.
- * <p>
- * Multiple indicator types may be queried by passing the logical OR of the
- * desired types. If multiple types are specified, the return value
- * represents whether they are all enabled.
- *
- * @param direction the indicator direction, or the logical OR of multiple
- * indicator directions. One or more of:
- * <ul>
- * <li>{@link #SCROLL_INDICATOR_TOP}</li>
- * <li>{@link #SCROLL_INDICATOR_BOTTOM}</li>
- * <li>{@link #SCROLL_INDICATOR_LEFT}</li>
- * <li>{@link #SCROLL_INDICATOR_RIGHT}</li>
- * <li>{@link #SCROLL_INDICATOR_START}</li>
- * <li>{@link #SCROLL_INDICATOR_END}</li>
- * </ul>
- * @return {@code true} if the specified indicator(s) are enabled,
- * {@code false} otherwise
- * @attr ref android.R.styleable#View_scrollIndicators
- */
- public boolean isScrollIndicatorEnabled(int direction) {
- // Shift and sanitize input.
- direction <<= SCROLL_INDICATORS_TO_PFLAGS3_LSHIFT;
- direction &= SCROLL_INDICATORS_PFLAG3_MASK;
-
- // All of the flags must be set.
- return (mPrivateFlags3 & direction) == direction;
- }
-
ListenerInfo getListenerInfo() {
if (mListenerInfo != null) {
return mListenerInfo;
@@ -5249,8 +5221,8 @@
* @return True if the event was consumed.
*/
private boolean performStylusActionOnButtonPress(MotionEvent event) {
- if (isStylusButtonPressable() && !mInStylusButtonPress
- && !mHasPerformedLongPress && event.isStylusButtonPressed()) {
+ if (isStylusButtonPressable() && !mInStylusButtonPress && !mHasPerformedLongPress
+ && event.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY)) {
if (performStylusButtonPress()) {
mInStylusButtonPress = true;
setPressed(true, event.getX(), event.getY());
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 57c6cbf..b7d902c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -40,6 +40,7 @@
import android.hardware.display.DisplayManager.DisplayListener;
import android.media.AudioManager;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -220,6 +221,9 @@
boolean mLastWasImTarget;
boolean mWindowsAnimating;
boolean mDrawDuringWindowsAnimating;
+
+ /** How many frames the app is still allowed to draw when a window animation is happening. */
+ private int mRemainingFrameCount;
boolean mIsDrawing;
int mLastSystemUiVisibility;
int mClientWindowLayoutFlags;
@@ -962,6 +966,12 @@
}
}
+ invalidateRectOnScreen(dirty);
+
+ return null;
+ }
+
+ private void invalidateRectOnScreen(Rect dirty) {
final Rect localDirty = mDirty;
if (!localDirty.isEmpty() && !localDirty.contains(dirty)) {
mAttachInfo.mSetIgnoreDirtyState = true;
@@ -981,8 +991,6 @@
if (!mWillDrawSoon && (intersected || mIsAnimating)) {
scheduleTraversals();
}
-
- return null;
}
void setWindowStopped(boolean stopped) {
@@ -1569,10 +1577,6 @@
}
final int surfaceGenerationId = mSurface.getGenerationId();
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
- if (!mDrawDuringWindowsAnimating &&
- (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) {
- mWindowsAnimating = true;
- }
if (DEBUG_LAYOUT) Log.v(TAG, "relayout: frame=" + frame.toShortString()
+ " overscan=" + mPendingOverscanInsets.toShortString()
@@ -1813,15 +1817,15 @@
}
}
- if (mAttachInfo.mHardwareRenderer != null &&
- mAttachInfo.mHardwareRenderer.isEnabled()) {
- if (hwInitialized ||
- mWidth != mAttachInfo.mHardwareRenderer.getWidth() ||
- mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
- mAttachInfo.mHardwareRenderer.setup(
- mWidth, mHeight, mWindowAttributes.surfaceInsets);
+ final HardwareRenderer hardwareRenderer = mAttachInfo.mHardwareRenderer;
+ if (hardwareRenderer != null && hardwareRenderer.isEnabled()) {
+ if (hwInitialized
+ || mWidth != hardwareRenderer.getWidth()
+ || mHeight != hardwareRenderer.getHeight()) {
+ hardwareRenderer.setup(mWidth, mHeight, mAttachInfo,
+ mWindowAttributes.surfaceInsets);
if (!hwInitialized) {
- mAttachInfo.mHardwareRenderer.invalidate(mSurface);
+ hardwareRenderer.invalidate(mSurface);
mFullRedrawNeeded = true;
}
}
@@ -1897,6 +1901,11 @@
}
mAttachInfo.mWindowLeft = frame.left;
mAttachInfo.mWindowTop = frame.top;
+
+ // Update the light position for the new window offsets.
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.setLightCenter(mAttachInfo);
+ }
}
}
@@ -1996,14 +2005,11 @@
+ mView.findFocus());
}
}
- if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) {
- // The first time we relayout the window, if the system is
- // doing window animations, we want to hold of on any future
- // draws until the animation is done.
- mWindowsAnimating = true;
- }
} else if (mWindowsAnimating) {
- skipDraw = true;
+ if (mRemainingFrameCount <= 0) {
+ skipDraw = true;
+ }
+ mRemainingFrameCount--;
}
mFirst = false;
@@ -2608,7 +2614,7 @@
try {
mAttachInfo.mHardwareRenderer.initializeIfNeeded(
- mWidth, mHeight, mSurface, surfaceInsets);
+ mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
} catch (OutOfResourcesException e) {
handleOutOfResourcesException(e);
return;
@@ -2800,7 +2806,7 @@
public void setDrawDuringWindowsAnimating(boolean value) {
mDrawDuringWindowsAnimating = value;
if (value) {
- handleDispatchDoneAnimating();
+ handleDispatchWindowAnimationStopped();
}
}
@@ -3152,11 +3158,12 @@
private final static int MSG_UPDATE_CONFIGURATION = 18;
private final static int MSG_PROCESS_INPUT_EVENTS = 19;
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 21;
- private final static int MSG_DISPATCH_DONE_ANIMATING = 22;
- private final static int MSG_INVALIDATE_WORLD = 23;
- private final static int MSG_WINDOW_MOVED = 24;
- private final static int MSG_SYNTHESIZE_INPUT_EVENT = 25;
- private final static int MSG_DISPATCH_WINDOW_SHOWN = 26;
+ private final static int MSG_INVALIDATE_WORLD = 22;
+ private final static int MSG_WINDOW_MOVED = 23;
+ private final static int MSG_SYNTHESIZE_INPUT_EVENT = 24;
+ private final static int MSG_DISPATCH_WINDOW_SHOWN = 25;
+ private final static int MSG_DISPATCH_WINDOW_ANIMATION_STOPPED = 26;
+ private final static int MSG_DISPATCH_WINDOW_ANIMATION_STARTED = 27;
final class ViewRootHandler extends Handler {
@Override
@@ -3200,8 +3207,10 @@
return "MSG_PROCESS_INPUT_EVENTS";
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST:
return "MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST";
- case MSG_DISPATCH_DONE_ANIMATING:
- return "MSG_DISPATCH_DONE_ANIMATING";
+ case MSG_DISPATCH_WINDOW_ANIMATION_STARTED:
+ return "MSG_DISPATCH_WINDOW_ANIMATION_STARTED";
+ case MSG_DISPATCH_WINDOW_ANIMATION_STOPPED:
+ return "MSG_DISPATCH_WINDOW_ANIMATION_STOPPED";
case MSG_WINDOW_MOVED:
return "MSG_WINDOW_MOVED";
case MSG_SYNTHESIZE_INPUT_EVENT:
@@ -3300,7 +3309,7 @@
final WindowManager.LayoutParams lp = mWindowAttributes;
final Rect surfaceInsets = lp != null ? lp.surfaceInsets : null;
mAttachInfo.mHardwareRenderer.initializeIfNeeded(
- mWidth, mHeight, mSurface, surfaceInsets);
+ mWidth, mHeight, mAttachInfo, mSurface, surfaceInsets);
} catch (OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException locking surface", e);
try {
@@ -3421,8 +3430,12 @@
case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: {
setAccessibilityFocus(null, null);
} break;
- case MSG_DISPATCH_DONE_ANIMATING: {
- handleDispatchDoneAnimating();
+ case MSG_DISPATCH_WINDOW_ANIMATION_STARTED: {
+ int remainingFrameCount = msg.arg1;
+ handleDispatchWindowAnimationStarted(remainingFrameCount);
+ } break;
+ case MSG_DISPATCH_WINDOW_ANIMATION_STOPPED: {
+ handleDispatchWindowAnimationStopped();
} break;
case MSG_INVALIDATE_WORLD: {
if (mView != null) {
@@ -4038,7 +4051,7 @@
} else {
// If delivering a new non-key event, make sure the window is
// now allowed to start updating.
- handleDispatchDoneAnimating();
+ handleDispatchWindowAnimationStopped();
final int source = q.mEvent.getSource();
if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
return processPointerEvent(q);
@@ -4068,7 +4081,7 @@
if (event.getAction() != KeyEvent.ACTION_UP) {
// If delivering a new key event, make sure the window is
// now allowed to start updating.
- handleDispatchDoneAnimating();
+ handleDispatchWindowAnimationStopped();
}
// Deliver the key to the view hierarchy.
@@ -5285,7 +5298,14 @@
}
}
- public void handleDispatchDoneAnimating() {
+ public void handleDispatchWindowAnimationStarted(int remainingFrameCount) {
+ if (!mDrawDuringWindowsAnimating) {
+ mRemainingFrameCount = remainingFrameCount;
+ mWindowsAnimating = true;
+ }
+ }
+
+ public void handleDispatchWindowAnimationStopped() {
if (mWindowsAnimating) {
mWindowsAnimating = false;
if (!mDirty.isEmpty() || mIsAnimating || mFullRedrawNeeded) {
@@ -5347,7 +5367,7 @@
//Log.d(TAG, ">>>>>> CALLING relayout");
if (params != null && mOrigWindowType != params.type) {
// For compatibility with old apps, don't crash here.
- if (mTargetSdkVersion < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
Slog.w(TAG, "Window type can not be changed after "
+ "the window is added; ignoring change of " + mView);
params.type = mOrigWindowType;
@@ -5772,6 +5792,7 @@
void enqueueInputEvent(InputEvent event,
InputEventReceiver receiver, int flags, boolean processImmediately) {
+ adjustInputEventForCompatibility(event);
QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);
// Always enqueue the input event in order, regardless of its time stamp.
@@ -5877,6 +5898,19 @@
recycleQueuedInputEvent(q);
}
+ private void adjustInputEventForCompatibility(InputEvent e) {
+ if (mTargetSdkVersion < Build.VERSION_CODES.MNC && e instanceof MotionEvent) {
+ MotionEvent motion = (MotionEvent) e;
+ final int mask =
+ MotionEvent.BUTTON_STYLUS_PRIMARY | MotionEvent.BUTTON_STYLUS_SECONDARY;
+ final int buttonState = motion.getButtonState();
+ final int compatButtonState = (buttonState & mask) >> 4;
+ if (compatButtonState != 0) {
+ motion.setButtonState(buttonState | compatButtonState);
+ }
+ }
+ }
+
static boolean isTerminalInputEvent(InputEvent event) {
if (event instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent)event;
@@ -6189,8 +6223,13 @@
mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, args));
}
- public void dispatchDoneAnimating() {
- mHandler.sendEmptyMessage(MSG_DISPATCH_DONE_ANIMATING);
+ public void dispatchWindowAnimationStarted(int remainingFrameCount) {
+ mHandler.obtainMessage(MSG_DISPATCH_WINDOW_ANIMATION_STARTED,
+ remainingFrameCount, 0 /* unused */).sendToTarget();
+ }
+
+ public void dispatchWindowAnimationStopped() {
+ mHandler.sendEmptyMessage(MSG_DISPATCH_WINDOW_ANIMATION_STOPPED);
}
public void dispatchCheckFocus() {
@@ -6363,7 +6402,14 @@
}
// Refresh the node for the focused virtual view.
+ final Rect oldBounds = mTempRect;
+ mAccessibilityFocusedVirtualView.getBoundsInScreen(oldBounds);
mAccessibilityFocusedVirtualView = provider.createAccessibilityNodeInfo(focusedChildId);
+ final Rect newBounds = mAccessibilityFocusedVirtualView.getBoundsInScreen();
+ if (!oldBounds.equals(newBounds)) {
+ oldBounds.union(newBounds);
+ invalidateRectOnScreen(oldBounds);
+ }
}
@Override
@@ -6713,10 +6759,18 @@
}
@Override
- public void doneAnimating() {
+ public void onAnimationStarted(int remainingFrameCount) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
- viewAncestor.dispatchDoneAnimating();
+ viewAncestor.dispatchWindowAnimationStarted(remainingFrameCount);
+ }
+ }
+
+ @Override
+ public void onAnimationStopped() {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchWindowAnimationStopped();
}
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 49a72ce..07984e9 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1784,14 +1784,6 @@
public void setAllowReturnTransitionOverlap(boolean allow) {}
/**
- * TODO: remove this.
- * @hide
- */
- public void setAllowExitTransitionOverlap(boolean allow) {
- setAllowReturnTransitionOverlap(allow);
- }
-
- /**
* Returns how the transition set in
* {@link #setExitTransition(android.transition.Transition)} overlaps with the exit
* transition of the called Activity when reentering after if finishes. When true,
@@ -1805,12 +1797,6 @@
public boolean getAllowReturnTransitionOverlap() { return true; }
/**
- * TODO: remove this.
- * @hide
- */
- public boolean getAllowExitTransitionOverlap() { return getAllowReturnTransitionOverlap(); }
-
- /**
* Returns the duration, in milliseconds, of the window background fade
* when transitioning into or away from an Activity when called with an Activity Transition.
* <p>When executing the enter transition, the background starts transparent
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2797b6e..7976ca4 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -101,7 +101,7 @@
* the given view hierarchy's {@link View#onDetachedFromWindow()
* View.onDetachedFromWindow()} methods before returning. This is not
* for normal applications; using it correctly requires great care.
- *
+ *
* @param view The view to be removed.
*/
public void removeViewImmediate(View view);
@@ -115,7 +115,7 @@
*/
@ViewDebug.ExportedProperty
public int x;
-
+
/**
* Y position for this window. With the default gravity it is ignored.
* When using {@link Gravity#TOP} or {@link Gravity#BOTTOM} it provides
@@ -228,12 +228,12 @@
@ViewDebug.IntToString(from = TYPE_VOICE_INTERACTION_STARTING, to = "TYPE_VOICE_INTERACTION_STARTING"),
})
public int type;
-
+
/**
* Start of window types that represent normal application windows.
*/
public static final int FIRST_APPLICATION_WINDOW = 1;
-
+
/**
* Window type: an application window that serves as the "base" window
* of the overall application; all other application windows will
@@ -241,14 +241,14 @@
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_BASE_APPLICATION = 1;
-
+
/**
* Window type: a normal application window. The {@link #token} must be
* an Activity token identifying who the window belongs to.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_APPLICATION = 2;
-
+
/**
* Window type: special application window that is displayed while the
* application is starting. Not for use by applications themselves;
@@ -257,7 +257,7 @@
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_APPLICATION_STARTING = 3;
-
+
/**
* End of types of application windows.
*/
@@ -330,14 +330,14 @@
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW;
-
+
/**
* Window type: the search bar. There can be only one search bar
* window; it is placed at the top of the screen.
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;
-
+
/**
* Window type: phone. These are non-application windows providing
* user interaction with the phone (in particular incoming calls).
@@ -346,7 +346,7 @@
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;
-
+
/**
* Window type: system window, such as low power alert. These windows
* are always on top of application windows.
@@ -366,7 +366,7 @@
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW+5;
-
+
/**
* Window type: system overlay windows, which need to be displayed
* on top of everything else. These windows must not take input
@@ -374,7 +374,7 @@
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;
-
+
/**
* Window type: priority phone UI, which needs to be displayed even if
* the keyguard is active. These windows must not take input
@@ -382,26 +382,26 @@
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;
-
+
/**
* Window type: panel that slides out from the status bar
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8;
-
+
/**
* Window type: dialogs that the keyguard shows
* In multiuser systems shows on all users' windows.
*/
public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9;
-
+
/**
* Window type: internal system error windows, appear on top of
* everything they can.
* In multiuser systems shows only on the owning user's window.
*/
public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10;
-
+
/**
* Window type: internal input methods windows, which appear above
* the normal UI. Application windows may be resized or panned to keep
@@ -581,16 +581,16 @@
/** @deprecated this is ignored, this value is set automatically when needed. */
@Deprecated
public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;
-
+
/**
* @deprecated this is ignored
*/
@Deprecated
public int memoryType;
-
+
/** Window flag: as long as this window is visible to the user, allow
- * the lock screen to activate while the screen is on.
- * This can be used independently, or in combination with
+ * the lock screen to activate while the screen is on.
+ * This can be used independently, or in combination with
* {@link #FLAG_KEEP_SCREEN_ON} and/or {@link #FLAG_SHOW_WHEN_LOCKED} */
public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001;
@@ -608,26 +608,26 @@
* instead go to whatever focusable window is behind it. This flag
* will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that
* is explicitly set.
- *
+ *
* <p>Setting this flag also implies that the window will not need to
* interact with
- * a soft input method, so it will be Z-ordered and positioned
+ * a soft input method, so it will be Z-ordered and positioned
* independently of any active input method (typically this means it
* gets Z-ordered on top of the input method, so it can use the full
* screen for its content and cover the input method if needed. You
* can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;
-
+
/** Window flag: this window can never receive touch events. */
public static final int FLAG_NOT_TOUCHABLE = 0x00000010;
-
+
/** Window flag: even when this window is focusable (its
* {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events
* outside of the window to be sent to the windows behind it. Otherwise
* it will consume all pointer events itself, regardless of whether they
* are inside of the window. */
public static final int FLAG_NOT_TOUCH_MODAL = 0x00000020;
-
+
/** Window flag: when set, if the device is asleep when the touch
* screen is pressed, you will receive this first touch event. Usually
* the first touch event is consumed by the system since the user can
@@ -637,21 +637,21 @@
*/
@Deprecated
public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
-
+
/** Window flag: as long as this window is visible to the user, keep
* the device's screen turned on and bright. */
public static final int FLAG_KEEP_SCREEN_ON = 0x00000080;
-
+
/** Window flag: place the window within the entire screen, ignoring
* decorations around the border (such as the status bar). The
* window must correctly position its contents to take the screen
* decoration into account. This flag is normally set for you
* by Window as described in {@link Window#setFlags}. */
public static final int FLAG_LAYOUT_IN_SCREEN = 0x00000100;
-
+
/** Window flag: allow window to extend outside of the screen. */
public static final int FLAG_LAYOUT_NO_LIMITS = 0x00000200;
-
+
/**
* Window flag: hide all screen decorations (such as the status bar) while
* this window is displayed. This allows the window to use the entire
@@ -673,17 +673,17 @@
* {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_Fullscreen}.</p>
*/
public static final int FLAG_FULLSCREEN = 0x00000400;
-
+
/** Window flag: override {@link #FLAG_FULLSCREEN} and force the
* screen decorations (such as the status bar) to be shown. */
public static final int FLAG_FORCE_NOT_FULLSCREEN = 0x00000800;
-
+
/** Window flag: turn on dithering when compositing this window to
* the screen.
* @deprecated This flag is no longer used. */
@Deprecated
public static final int FLAG_DITHER = 0x00001000;
-
+
/** Window flag: treat the content of the window as secure, preventing
* it from appearing in screenshots or from being viewed on non-secure
* displays.
@@ -692,21 +692,21 @@
* secure surfaces and secure displays.
*/
public static final int FLAG_SECURE = 0x00002000;
-
+
/** Window flag: a special mode where the layout parameters are used
* to perform scaling of the surface when it is composited to the
* screen. */
public static final int FLAG_SCALED = 0x00004000;
-
+
/** Window flag: intended for windows that will often be used when the user is
* holding the screen against their face, it will aggressively filter the event
* stream to prevent unintended presses in this situation that may not be
- * desired for a particular window, when such an event stream is detected, the
+ * desired for a particular window, when such an event stream is detected, the
* application will receive a CANCEL motion event to indicate this so applications
- * can handle this accordingly by taking no action on the event
+ * can handle this accordingly by taking no action on the event
* until the finger is released. */
public static final int FLAG_IGNORE_CHEEK_PRESSES = 0x00008000;
-
+
/** Window flag: a special option only for use in combination with
* {@link #FLAG_LAYOUT_IN_SCREEN}. When requesting layout in the
* screen your window may appear on top of or behind screen decorations
@@ -715,7 +715,7 @@
* content is not covered by screen decorations. This flag is normally
* set for you by Window as described in {@link Window#setFlags}.*/
public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
-
+
/** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with
* respect to how this window interacts with the current method. That
* is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the
@@ -726,7 +726,7 @@
* to use more space and cover the input method.
*/
public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
-
+
/** Window flag: if you have set {@link #FLAG_NOT_TOUCH_MODAL}, you
* can set this flag to receive a single special MotionEvent with
* the action
@@ -736,7 +736,7 @@
* first down as an ACTION_OUTSIDE.
*/
public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
-
+
/** Window flag: special flag to let windows be shown when the screen
* is locked. This will let application windows take precedence over
* key guard or any other lock screens. Can be used with
@@ -766,13 +766,13 @@
* {@link android.R.style#Theme_DeviceDefault_Wallpaper_NoTitleBar}.</p>
*/
public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
-
+
/** Window flag: when set as a window is being added or made
* visible, once the window has been shown then the system will
* poke the power manager's user activity (as if the user had woken
* up the device) to turn the screen on. */
public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
-
+
/** Window flag: when set the window will cause the keyguard to
* be dismissed, only if it is not a secure lock keyguard. Because such
* a keyguard is not needed for security, it will never re-appear if
@@ -786,7 +786,7 @@
* also been set.
*/
public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
-
+
/** Window flag: when set the window will accept for touch events
* outside of its bounds to be sent to other windows that also
* support split touch. When this flag is not set, the first pointer
@@ -798,7 +798,7 @@
* to be split across multiple windows.
*/
public static final int FLAG_SPLIT_TOUCH = 0x00800000;
-
+
/**
* <p>Indicates whether this window should be hardware accelerated.
* Requesting hardware acceleration does not guarantee it will happen.</p>
@@ -940,7 +940,7 @@
/**
* Various behavioral options/flags. Default is none.
- *
+ *
* @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
* @see #FLAG_DIM_BEHIND
* @see #FLAG_NOT_FOCUSABLE
@@ -1041,10 +1041,10 @@
* as if it was.
* Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
* that need hardware acceleration (e.g. LockScreen), where hardware acceleration
- * is generally disabled. This flag must be specified in addition to
+ * is generally disabled. This flag must be specified in addition to
* {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
* windows.
- *
+ *
* @hide
*/
public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
@@ -1055,7 +1055,7 @@
* If certain parts of the UI that really do want to use hardware
* acceleration, this flag can be set to force it. This is basically
* for the lock screen. Anyone else using it, you are probably wrong.
- *
+ *
* @hide
*/
public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
@@ -1194,63 +1194,63 @@
}
return false;
}
-
+
/**
* Mask for {@link #softInputMode} of the bits that determine the
* desired visibility state of the soft input area for this window.
*/
public static final int SOFT_INPUT_MASK_STATE = 0x0f;
-
+
/**
* Visibility state for {@link #softInputMode}: no state has been specified.
*/
public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
-
+
/**
* Visibility state for {@link #softInputMode}: please don't change the state of
* the soft input area.
*/
public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
-
+
/**
* Visibility state for {@link #softInputMode}: please hide any soft input
* area when normally appropriate (when the user is navigating
* forward to your window).
*/
public static final int SOFT_INPUT_STATE_HIDDEN = 2;
-
+
/**
* Visibility state for {@link #softInputMode}: please always hide any
* soft input area when this window receives focus.
*/
public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
-
+
/**
* Visibility state for {@link #softInputMode}: please show the soft
* input area when normally appropriate (when the user is navigating
* forward to your window).
*/
public static final int SOFT_INPUT_STATE_VISIBLE = 4;
-
+
/**
* Visibility state for {@link #softInputMode}: please always make the
* soft input area visible when this window receives input focus.
*/
public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
-
+
/**
* Mask for {@link #softInputMode} of the bits that determine the
* way that the window should be adjusted to accommodate the soft
* input window.
*/
public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
-
+
/** Adjustment option for {@link #softInputMode}: nothing specified.
* The system will try to pick one or
* the other depending on the contents of the window.
*/
public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;
-
+
/** Adjustment option for {@link #softInputMode}: set to allow the
* window to be resized when an input
* method is shown, so that its contents are not covered by the input
@@ -1263,7 +1263,7 @@
* not resize, but will stay fullscreen.
*/
public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
-
+
/** Adjustment option for {@link #softInputMode}: set to have a window
* pan when an input method is
* shown, so it doesn't need to deal with resizing but just panned
@@ -1273,7 +1273,7 @@
* the other depending on the contents of the window.
*/
public static final int SOFT_INPUT_ADJUST_PAN = 0x20;
-
+
/** Adjustment option for {@link #softInputMode}: set to have a window
* not adjust for a shown input method. The window will not be resized,
* and it will not be panned to make its focus visible.
@@ -1292,7 +1292,7 @@
/**
* Desired operating mode for any soft input area. May be any combination
* of:
- *
+ *
* <ul>
* <li> One of the visibility states
* {@link #SOFT_INPUT_STATE_UNSPECIFIED}, {@link #SOFT_INPUT_STATE_UNCHANGED},
@@ -1309,7 +1309,7 @@
* {@link android.R.attr#windowSoftInputMode} attribute.</p>
*/
public int softInputMode;
-
+
/**
* Placement of window within the screen as per {@link Gravity}. Both
* {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int,
@@ -1326,7 +1326,7 @@
* @see Gravity
*/
public int gravity;
-
+
/**
* The horizontal margin, as a percentage of the container's width,
* between the container and the widget. See
@@ -1335,7 +1335,7 @@
* field is added with {@link #x} to supply the <var>xAdj</var> parameter.
*/
public float horizontalMargin;
-
+
/**
* The vertical margin, as a percentage of the container's height,
* between the container and the widget. See
@@ -1361,26 +1361,26 @@
* @hide
*/
public boolean hasManualSurfaceInsets;
-
+
/**
* The desired bitmap format. May be one of the constants in
* {@link android.graphics.PixelFormat}. Default is OPAQUE.
*/
public int format;
-
+
/**
* A style resource defining the animations to use for this window.
* This must be a system resource; it can not be an application resource
* because the window manager does not have access to applications.
*/
public int windowAnimations;
-
+
/**
* An alpha value to apply to this entire window.
* An alpha of 1.0 means fully opaque and 0.0 means fully transparent
*/
public float alpha = 1.0f;
-
+
/**
* When {@link #FLAG_DIM_BEHIND} is set, this is the amount of dimming
* to apply. Range is from 1.0 for completely opaque to 0.0 for no
@@ -1408,7 +1408,7 @@
* to the hightest value when this window is in front.
*/
public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
-
+
/**
* This can be used to override the user's preferred brightness of
* the screen. A value of less than 0, the default, means to use the
@@ -1416,7 +1416,7 @@
* dark to full bright.
*/
public float screenBrightness = BRIGHTNESS_OVERRIDE_NONE;
-
+
/**
* This can be used to override the standard behavior of the button and
* keyboard backlights. A value of less than 0, the default, means to
@@ -1450,7 +1450,7 @@
* opaque windows have the #FLAG_FULLSCREEN bit set and are not covered
* by other windows. All other situations default to the
* {@link #ROTATION_ANIMATION_ROTATE} behavior.
- *
+ *
* @see #ROTATION_ANIMATION_ROTATE
* @see #ROTATION_ANIMATION_CROSSFADE
* @see #ROTATION_ANIMATION_JUMPCUT
@@ -1462,18 +1462,18 @@
* you.
*/
public IBinder token = null;
-
+
/**
* Name of the package owning this window.
*/
public String packageName = null;
-
+
/**
* Specific orientation value for a window.
* May be any of the same values allowed
- * for {@link android.content.pm.ActivityInfo#screenOrientation}.
- * If not set, a default value of
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
+ * for {@link android.content.pm.ActivityInfo#screenOrientation}.
+ * If not set, a default value of
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
* will be used.
*/
public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1482,13 +1482,28 @@
* The preferred refresh rate for the window.
*
* This must be one of the supported refresh rates obtained for the display(s) the window
- * is on.
+ * is on. The selected refresh rate will be applied to the display's default mode.
+ *
+ * This value is ignored if {@link #preferredDisplayModeId} is set.
*
* @see Display#getSupportedRefreshRates()
+ * @deprecated use {@link #preferredDisplayModeId} instead
*/
+ @Deprecated
public float preferredRefreshRate;
/**
+ * Id of the preferred display mode for the window.
+ * <p>
+ * This must be one of the supported modes obtained for the display(s) the window is on.
+ * A value of {@code 0} means no preference.
+ *
+ * @see Display#getSupportedModes()
+ * @see Display.Mode#getModeId()
+ */
+ public int preferredDisplayModeId;
+
+ /**
* Control the visibility of the status bar.
*
* @see View#STATUS_BAR_VISIBLE
@@ -1505,7 +1520,7 @@
/**
* Get callbacks about the system ui visibility changing.
- *
+ *
* TODO: Maybe there should be a bitfield of optional callbacks that we need.
*
* @hide
@@ -1571,34 +1586,34 @@
type = TYPE_APPLICATION;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type, int _flags) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
flags = _flags;
format = PixelFormat.OPAQUE;
}
-
+
public LayoutParams(int _type, int _flags, int _format) {
super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
type = _type;
flags = _flags;
format = _format;
}
-
+
public LayoutParams(int w, int h, int _type, int _flags, int _format) {
super(w, h);
type = _type;
flags = _flags;
format = _format;
}
-
+
public LayoutParams(int w, int h, int xpos, int ypos, int _type,
int _flags, int _format) {
super(w, h);
@@ -1608,14 +1623,14 @@
flags = _flags;
format = _format;
}
-
+
public final void setTitle(CharSequence title) {
if (null == title)
title = "";
-
+
mTitle = TextUtils.stringOrSpannedString(title);
}
-
+
public final CharSequence getTitle() {
return mTitle;
}
@@ -1660,6 +1675,7 @@
TextUtils.writeToParcel(mTitle, out, parcelableFlags);
out.writeInt(screenOrientation);
out.writeFloat(preferredRefreshRate);
+ out.writeInt(preferredDisplayModeId);
out.writeInt(systemUiVisibility);
out.writeInt(subtreeSystemUiVisibility);
out.writeInt(hasSystemUiListeners ? 1 : 0);
@@ -1683,8 +1699,8 @@
return new LayoutParams[size];
}
};
-
-
+
+
public LayoutParams(Parcel in) {
width = in.readInt();
height = in.readInt();
@@ -1709,6 +1725,7 @@
mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
screenOrientation = in.readInt();
preferredRefreshRate = in.readFloat();
+ preferredDisplayModeId = in.readInt();
systemUiVisibility = in.readInt();
subtreeSystemUiVisibility = in.readInt();
hasSystemUiListeners = in.readInt() != 0;
@@ -1757,6 +1774,8 @@
/** {@hide} */
public static final int NEEDS_MENU_KEY_CHANGED = 1 << 22;
/** {@hide} */
+ public static final int PREFERRED_DISPLAY_MODE_ID = 1 << 23;
+ /** {@hide} */
public static final int EVERYTHING_CHANGED = 0xffffffff;
// internal buffer to backup/restore parameters under compatibility mode.
@@ -1863,7 +1882,7 @@
rotationAnimation = o.rotationAnimation;
changes |= ROTATION_ANIMATION_CHANGED;
}
-
+
if (screenOrientation != o.screenOrientation) {
screenOrientation = o.screenOrientation;
changes |= SCREEN_ORIENTATION_CHANGED;
@@ -1874,6 +1893,11 @@
changes |= PREFERRED_REFRESH_RATE_CHANGED;
}
+ if (preferredDisplayModeId != o.preferredDisplayModeId) {
+ preferredDisplayModeId = o.preferredDisplayModeId;
+ changes |= PREFERRED_DISPLAY_MODE_ID;
+ }
+
if (systemUiVisibility != o.systemUiVisibility
|| subtreeSystemUiVisibility != o.subtreeSystemUiVisibility) {
systemUiVisibility = o.systemUiVisibility;
@@ -1924,7 +1948,7 @@
Log.d("Debug", "WindowManager.LayoutParams={title=" + mTitle + "}");
return "";
}
-
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(256);
@@ -1996,6 +2020,10 @@
sb.append(" preferredRefreshRate=");
sb.append(preferredRefreshRate);
}
+ if (preferredDisplayModeId != 0) {
+ sb.append(" preferredDisplayMode=");
+ sb.append(preferredDisplayModeId);
+ }
if (systemUiVisibility != 0) {
sb.append(" sysui=0x");
sb.append(Integer.toHexString(systemUiVisibility));
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index e7a7ba8..c16578e 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -69,12 +69,6 @@
public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
/**
- * The window manager is currently animating. It will call
- * IWindow.doneAnimating() when done.
- */
- public static final int RELAYOUT_RES_ANIMATING = 0x8;
-
- /**
* Flag for relayout: the client will be later giving
* internal insets; as a result, the window will not impact other window
* layouts until the insets are given.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index c785149..901a32d 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -1011,6 +1011,10 @@
public void addAction(AccessibilityAction action) {
enforceNotSealed();
+ addActionUnchecked(action);
+ }
+
+ private void addActionUnchecked(AccessibilityAction action) {
if (action == null) {
return;
}
@@ -1491,6 +1495,15 @@
}
/**
+ * Returns the actual rect containing the node bounds in screen coordinates.
+ *
+ * @hide Not safe to expose outside the framework.
+ */
+ public Rect getBoundsInScreen() {
+ return mBoundsInScreen;
+ }
+
+ /**
* Sets the node bounds in screen coordinates.
* <p>
* <strong>Note:</strong> Cannot be called from an
@@ -2846,9 +2859,9 @@
addLegacyStandardActions(legacyStandardActions);
final int nonLegacyActionCount = actionCount - Integer.bitCount(legacyStandardActions);
for (int i = 0; i < nonLegacyActionCount; i++) {
- AccessibilityAction action = new AccessibilityAction(
+ final AccessibilityAction action = new AccessibilityAction(
parcel.readInt(), parcel.readCharSequence());
- addAction(action);
+ addActionUnchecked(action);
}
}
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 040fd37..568e160 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -350,16 +350,6 @@
*/
private CursorAnchorInfo mCursorAnchorInfo = null;
- /**
- * The buffer to retrieve the view location in screen coordinates in {@link #updateCursor}.
- */
- private final int[] mViewTopLeft = new int[2];
-
- /**
- * The matrix to convert the view location into screen coordinates in {@link #updateCursor}.
- */
- private final Matrix mViewToScreenMatrix = new Matrix();
-
// -----------------------------------------------------------
/**
diff --git a/core/java/android/webkit/ViewAssistStructure.java b/core/java/android/webkit/ViewAssistStructure.java
new file mode 100644
index 0000000..6f7a645
--- /dev/null
+++ b/core/java/android/webkit/ViewAssistStructure.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.webkit;
+
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.text.TextPaint;
+import android.view.ViewStructure;
+
+
+/**
+ * TODO This class is temporary. It will be deleted once we update Webview APK to use the
+ * new ViewStructure method.
+ * @hide
+ */
+public class ViewAssistStructure extends android.view.ViewAssistStructure {
+
+ private ViewStructure mV;
+
+ public ViewAssistStructure(ViewStructure v) {
+ mV = v;
+ }
+
+ @Override
+ public void setId(int id, String packageName, String typeName, String entryName) {
+ mV.setId(id, packageName, typeName, entryName);
+ }
+
+ @Override
+ public void setDimens(int left, int top, int scrollX, int scrollY, int width,
+ int height) {
+ mV.setDimens(left, top, scrollX, scrollY, width, height);
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ mV.setVisibility(visibility);
+ }
+
+ @Override
+ public void setAssistBlocked(boolean state) {
+ mV.setAssistBlocked(state);
+ }
+
+ @Override
+ public void setEnabled(boolean state) {
+ mV.setEnabled(state);
+ }
+
+ @Override
+ public void setClickable(boolean state) {
+ mV.setClickable(state);
+ }
+
+ @Override
+ public void setLongClickable(boolean state) {
+ mV.setLongClickable(state);
+ }
+
+ @Override
+ public void setStylusButtonPressable(boolean state) {
+ mV.setStylusButtonPressable(state);
+ }
+
+ @Override
+ public void setFocusable(boolean state) {
+ mV.setFocusable(state);
+ }
+
+ @Override
+ public void setFocused(boolean state) {
+ mV.setFocused(state);
+ }
+
+ @Override
+ public void setAccessibilityFocused(boolean state) {
+ mV.setAccessibilityFocused(state);
+ }
+
+ @Override
+ public void setCheckable(boolean state) {
+ mV.setCheckable(state);
+ }
+
+ @Override
+ public void setChecked(boolean state) {
+ mV.setChecked(state);
+ }
+
+ @Override
+ public void setSelected(boolean state) {
+ mV.setSelected(state);
+ }
+
+ @Override
+ public void setActivated(boolean state) {
+ mV.setActivated(state);
+ }
+
+ @Override
+ public void setClassName(String className) {
+ mV.setClassName(className);
+ }
+
+ @Override
+ public void setContentDescription(CharSequence contentDescription) {
+ mV.setContentDescription(contentDescription);
+ }
+
+ @Override
+ public void setText(CharSequence text) {
+ mV.setText(text);
+ }
+
+ @Override
+ public void setText(CharSequence text, int selectionStart, int selectionEnd) {
+ mV.setText(text, selectionStart, selectionEnd);
+ }
+
+ @Override
+ public void setTextPaint(TextPaint paint) {
+ mV.setTextPaint(paint);
+ }
+
+ @Override
+ public void setHint(CharSequence hint) {
+ mV.setHint(hint);
+ }
+
+ @Override
+ public CharSequence getText() {
+ return mV.getText();
+ }
+
+ @Override
+ public int getTextSelectionStart() {
+ return mV.getTextSelectionStart();
+ }
+
+ @Override
+ public int getTextSelectionEnd() {
+ return mV.getTextSelectionEnd();
+ }
+
+ @Override
+ public CharSequence getHint() {
+ return mV.getHint();
+ }
+
+ @Override
+ public Bundle getExtras() {
+ return mV.getExtras();
+ }
+
+ @Override
+ public boolean hasExtras() {
+ return mV.hasExtras();
+ }
+
+ @Override
+ public void setChildCount(int num) {
+ mV.setChildCount(num);
+ }
+
+ @Override
+ public int getChildCount() {
+ return mV.getChildCount();
+ }
+
+ @Override
+ public android.view.ViewAssistStructure newChild(int index) {
+ return mV.newChild(index);
+ }
+
+ @Override
+ public android.view.ViewAssistStructure asyncNewChild(int index) {
+ return mV.asyncNewChild(index);
+ }
+
+ @Override
+ public void asyncCommit() {
+ mV.asyncCommit();
+ }
+
+ @Override
+ public Rect getTempRect() {
+ return mV.getTempRect();
+ }
+}
diff --git a/core/java/android/webkit/WebMessagePort.java b/core/java/android/webkit/WebMessagePort.java
index eab27bd..5f33c7b 100644
--- a/core/java/android/webkit/WebMessagePort.java
+++ b/core/java/android/webkit/WebMessagePort.java
@@ -16,12 +16,13 @@
package android.webkit;
+import android.annotation.SystemApi;
import android.os.Handler;
/**
- * The Java representation of the HTML5 Message Port. See
- * https://html.spec.whatwg.org/multipage/comms.html#messageport
- * for definition of MessagePort in HTML5.
+ * The Java representation of the
+ * <a href="https://html.spec.whatwg.org/multipage/comms.html#messageport">
+ * HTML5 message ports.</a>
*
* A Message port represents one endpoint of a Message Channel. In Android
* webview, there is no separate Message Channel object. When a message channel
@@ -32,6 +33,19 @@
* When a message port is first created or received via transfer, it does not
* have a WebMessageCallback to receive web messages. The messages are queued until
* a WebMessageCallback is set.
+ *
+ * A message port should be closed when it is not used by the embedder application
+ * anymore. A closed port cannot be transferred or cannot be reopened to send
+ * messages. Close can be called multiple times.
+ *
+ * When a port is transferred to JS, it cannot be used to send or receive messages
+ * at the Java side anymore. Different from HTML5 Spec, a port cannot be transferred
+ * if one of these has ever happened: i. a message callback was set, ii. a message was
+ * posted on it. A transferred port cannot be closed by the application, since
+ * the ownership is also transferred.
+ *
+ * It is possible to transfer both ports of a channel to JS, for example for
+ * communication between subframes.
*/
public abstract class WebMessagePort {
@@ -55,6 +69,13 @@
}
/**
+ * Constructor.
+ * @hide
+ */
+ @SystemApi
+ public WebMessagePort() { }
+
+ /**
* Post a WebMessage to the entangled port.
*
* @param message the message from Java to JS.
diff --git a/core/java/android/webkit/WebResourceError.java b/core/java/android/webkit/WebResourceError.java
index 080d174..90693f3 100644
--- a/core/java/android/webkit/WebResourceError.java
+++ b/core/java/android/webkit/WebResourceError.java
@@ -16,6 +16,8 @@
package android.webkit;
+import android.annotation.SystemApi;
+
/**
* Encapsulates information about errors occured during loading of web resources. See
* {@link WebViewClient#onReceivedError(WebView, WebResourceRequest, WebResourceError) WebViewClient.onReceivedError(WebView, WebResourceRequest, WebResourceError)}
@@ -34,6 +36,16 @@
* and thus can be used for communicating the problem to the user.
*
* @return The description of the error
+ *
+ * Will become abstract after updated WebView.apk will be submitted
+ * into the Android tree.
*/
- public abstract String getDescription();
+ public CharSequence getDescription() { return ""; }
+
+ /**
+ * This class can not be subclassed by applications.
+ * @hide
+ */
+ @SystemApi
+ public WebResourceError() {}
}
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index a42aaa7..3a925c8 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -20,12 +20,15 @@
import java.io.StringBufferInputStream;
import java.util.Map;
+import android.annotation.SystemApi;
+
/**
* Encapsulates a resource response. Applications can return an instance of this
* class from {@link WebViewClient#shouldInterceptRequest} to provide a custom
* response when the WebView requests a particular resource.
*/
public class WebResourceResponse extends WebResourceResponseBase {
+ private boolean mImmutable;
private String mMimeType;
private String mEncoding;
private int mStatusCode;
@@ -80,13 +83,15 @@
* @param mimeType The resource response's MIME type
*/
public void setMimeType(String mimeType) {
+ checkImmutable();
mMimeType = mimeType;
}
/**
- * {@inheritDoc}
+ * Gets the resource response's MIME type.
+ *
+ * @return The resource response's MIME type
*/
- @Override
public String getMimeType() {
return mMimeType;
}
@@ -98,13 +103,15 @@
* @param encoding The resource response's encoding
*/
public void setEncoding(String encoding) {
+ checkImmutable();
mEncoding = encoding;
}
/**
- * {@inheritDoc}
+ * Gets the resource response's encoding.
+ *
+ * @return The resource response's encoding
*/
- @Override
public String getEncoding() {
return mEncoding;
}
@@ -118,6 +125,7 @@
* and not empty.
*/
public void setStatusCodeAndReasonPhrase(int statusCode, String reasonPhrase) {
+ checkImmutable();
if (statusCode < 100)
throw new IllegalArgumentException("statusCode can't be less than 100.");
if (statusCode > 599)
@@ -140,17 +148,19 @@
}
/**
- * {@inheritDoc}
+ * Gets the resource response's status code.
+ *
+ * @return The resource response's status code.
*/
- @Override
public int getStatusCode() {
return mStatusCode;
}
/**
- * {@inheritDoc}
+ * Gets the description of the resource response's status code.
+ *
+ * @return The description of the resource response's status code.
*/
- @Override
public String getReasonPhrase() {
return mReasonPhrase;
}
@@ -161,13 +171,15 @@
* @param headers Mapping of header name -> header value.
*/
public void setResponseHeaders(Map<String, String> headers) {
+ checkImmutable();
mResponseHeaders = headers;
}
/**
- * {@inheritDoc}
+ * Gets the headers for the resource response.
+ *
+ * @return The headers for the resource response.
*/
- @Override
public Map<String, String> getResponseHeaders() {
return mResponseHeaders;
}
@@ -180,6 +192,7 @@
* StringBufferInputStream.
*/
public void setData(InputStream data) {
+ checkImmutable();
// If data is (or is a subclass of) StringBufferInputStream
if (data != null && StringBufferInputStream.class.isAssignableFrom(data.getClass())) {
throw new IllegalArgumentException("StringBufferInputStream is deprecated and must " +
@@ -189,10 +202,32 @@
}
/**
- * {@inheritDoc}
+ * Gets the input stream that provides the resource response's data.
+ *
+ * @return The input stream that provides the resource response's data
*/
- @Override
public InputStream getData() {
return mInputStream;
}
+
+ /**
+ * The internal version of the constructor that doesn't perform arguments checks.
+ * @hide
+ */
+ @SystemApi
+ public WebResourceResponse(boolean immutable, String mimeType, String encoding, int statusCode,
+ String reasonPhrase, Map<String, String> responseHeaders, InputStream data) {
+ mImmutable = immutable;
+ mMimeType = mimeType;
+ mEncoding = encoding;
+ mStatusCode = statusCode;
+ mReasonPhrase = reasonPhrase;
+ mResponseHeaders = responseHeaders;
+ mInputStream = data;
+ }
+
+ private void checkImmutable() {
+ if (mImmutable)
+ throw new IllegalStateException("This WebResourceResponse instance is immutable");
+ }
}
diff --git a/core/java/android/webkit/WebResourceResponseBase.java b/core/java/android/webkit/WebResourceResponseBase.java
index cffde82..69eb397 100644
--- a/core/java/android/webkit/WebResourceResponseBase.java
+++ b/core/java/android/webkit/WebResourceResponseBase.java
@@ -16,53 +16,9 @@
package android.webkit;
-import java.io.InputStream;
-import java.util.Map;
-
/**
- * Encapsulates a resource response received from the server.
- * This is an abstract class used by WebView callbacks.
+ * This class will be deleted after updated WebView.apk will be submitted
+ * into the Android tree.
*/
public abstract class WebResourceResponseBase {
- /**
- * Gets the resource response's MIME type.
- *
- * @return The resource response's MIME type
- */
- public abstract String getMimeType();
-
- /**
- * Gets the resource response's encoding.
- *
- * @return The resource response's encoding
- */
- public abstract String getEncoding();
-
- /**
- * Gets the resource response's status code.
- *
- * @return The resource response's status code.
- */
- public abstract int getStatusCode();
-
- /**
- * Gets the description of the resource response's status code.
- *
- * @return The description of the resource response's status code.
- */
- public abstract String getReasonPhrase();
-
- /**
- * Gets the headers for the resource response.
- *
- * @return The headers for the resource response.
- */
- public abstract Map<String, String> getResponseHeaders();
-
- /**
- * Gets the input stream that provides the resource response's data.
- *
- * @return The input stream that provides the resource response's data
- */
- public abstract InputStream getData();
}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 453e4f5..cfa347f 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1340,11 +1340,13 @@
* offscreen but attached to a window. Turning this on can avoid
* rendering artifacts when animating an offscreen WebView on-screen.
* Offscreen WebViews in this mode use more memory. The default value is
- * false.
+ * false.<br>
* Please follow these guidelines to limit memory usage:
- * - WebView size should be not be larger than the device screen size.
- * - Limit use of this mode to a small number of WebViews. Use it for
+ * <ul>
+ * <li> WebView size should be not be larger than the device screen size.
+ * <li> Limit use of this mode to a small number of WebViews. Use it for
* visible WebViews and WebViews about to be animated to visible.
+ * </ul>
*/
public abstract void setOffscreenPreRaster(boolean enabled);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e27e253..ccb98b4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -366,15 +366,15 @@
}
/**
- * Callback interface supplied to {@link #insertVisualStateCallback} for receiving
+ * Callback interface supplied to {@link #postVisualStateCallback} for receiving
* notifications about the visual state.
*/
public static abstract class VisualStateCallback {
/**
* Invoked when the visual state is ready to be drawn in the next {@link #onDraw}.
*
- * @param requestId the id supplied to the corresponding {@link #insertVisualStateCallback}
- * request
+ * @param requestId The identifier passed to {@link #postVisualStateCallback} when this
+ * callback was posted.
*/
public abstract void onComplete(long requestId);
}
@@ -1125,15 +1125,18 @@
}
/**
- * Inserts a {@link VisualStateCallback}.
+ * Posts a {@link VisualStateCallback}, which will be called when
+ * the current state of the WebView is ready to be drawn.
*
- * <p>Updates to the the DOM are reflected asynchronously such that when the DOM is updated the
- * subsequent {@link WebView#onDraw} invocation might not reflect those updates. The
+ * <p>Because updates to the the DOM are processed asynchronously, updates to the DOM may not
+ * immediately be reflected visually by subsequent {@link WebView#onDraw} invocations. The
* {@link VisualStateCallback} provides a mechanism to notify the caller when the contents of
- * the DOM at the current time are ready to be drawn the next time the {@link WebView} draws.
- * By current time we mean the time at which this API was called. The next draw after the
- * callback completes is guaranteed to reflect all the updates to the DOM applied before the
- * current time, but it may also contain updates applied after the current time.</p>
+ * the DOM at the current time are ready to be drawn the next time the {@link WebView}
+ * draws.</p>
+ *
+ * <p>The next draw after the callback completes is guaranteed to reflect all the updates to the
+ * DOM up to the the point at which the {@link VisualStateCallback} was posted, but it may also
+ * contain updates applied after the callback was posted.</p>
*
* <p>The state of the DOM covered by this API includes the following:
* <ul>
@@ -1164,15 +1167,15 @@
* {@link VisualStateCallback#onComplete} method.</li>
* </ul></p>
*
- * <p>When using this API it is also recommended to enable pre-rasterization if the
- * {@link WebView} is offscreen to avoid flickering. See WebSettings#setOffscreenPreRaster for
+ * <p>When using this API it is also recommended to enable pre-rasterization if the {@link
+ * WebView} is offscreen to avoid flickering. See {@link WebSettings#setOffscreenPreRaster} for
* more details and do consider its caveats.</p>
*
- * @param requestId an id that will be returned in the callback to allow callers to match
- * requests with callbacks.
- * @param callback the callback to be invoked.
+ * @param requestId An id that will be returned in the callback to allow callers to match
+ * requests with callbacks.
+ * @param callback The callback to be invoked.
*/
- public void insertVisualStateCallback(long requestId, VisualStateCallback callback) {
+ public void postVisualStateCallback(long requestId, VisualStateCallback callback) {
checkThread();
mProvider.insertVisualStateCallback(requestId, callback);
}
@@ -1835,8 +1838,9 @@
/**
* Creates a message channel to communicate with JS and returns the message
* ports that represent the endpoints of this message channel. The HTML5 message
- * channel functionality is described here:
- * https://html.spec.whatwg.org/multipage/comms.html#messagechannel
+ * channel functionality is described
+ * <a href="https://html.spec.whatwg.org/multipage/comms.html#messagechannel">here
+ * </a>
*
* The returned message channels are entangled and already in started state.
*
@@ -1850,13 +1854,16 @@
/**
* Post a message to main frame. The embedded application can restrict the
* messages to a certain target origin. See
- * https://html.spec.whatwg.org/multipage/comms.html#posting-messages
- * for how target origin can be used.
+ * <a href="https://html.spec.whatwg.org/multipage/comms.html#posting-messages">
+ * HTML5 spec</a> for how target origin can be used.
*
* @param message the WebMessage
- * @param targetOrigin the target origin.
+ * @param targetOrigin the target origin. This is the origin of the page
+ * that is intended to receive the message. For best security
+ * practices, the user should not specify a wildcard (*) when
+ * specifying the origin.
*/
- public void postMessageToMainFrame(WebMessage message, Uri targetOrigin) {
+ public void postWebMessage(WebMessage message, Uri targetOrigin) {
checkThread();
mProvider.postMessageToMainFrame(message, targetOrigin);
}
@@ -2429,7 +2436,8 @@
@Override
public void onProvideVirtualStructure(ViewStructure structure) {
- mProvider.getViewDelegate().onProvideVirtualAssistStructure(structure);
+ ViewAssistStructure s = new ViewAssistStructure(structure);
+ mProvider.getViewDelegate().onProvideVirtualAssistStructure(s);
}
/** @hide */
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 8a2b3fa..feed2b8 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -83,27 +83,31 @@
}
/**
- * Notify the host application that the page commit is visible.
+ * Notify the host application that {@link android.webkit.WebView} content left over from
+ * previous page navigations will no longer be drawn.
*
- * <p>This is the earliest point at which we can guarantee that the contents of the previously
- * loaded page will not longer be drawn in the next {@link WebView#onDraw}. The next draw will
- * render the {@link WebView#setBackgroundColor background color} of the WebView or some of the
- * contents from the committed page already. This callback may be useful when reusing
- * {@link WebView}s to ensure that no stale content is shown. This method is only called for
- * the main frame.</p>
+ * <p>This callback can be used to determine the point at which it is safe to make a recycled
+ * {@link android.webkit.WebView} visible, ensuring that no stale content is shown. It is called
+ * at the earliest point at which it can be guaranteed that {@link WebView#onDraw} will no
+ * longer draw any content from previous navigations. The next draw will display either the
+ * {@link WebView#setBackgroundColor background color} of the {@link WebView}, or some of the
+ * contents of the newly loaded page.
*
- * <p>This method is called when the state of the DOM at the point at which the
- * body of the HTTP response (commonly the string of html) had started loading will be visible.
- * If you set a background color for the page in the HTTP response body this will most likely
- * be visible and perhaps some other elements. At that point no other resources had usually
- * been loaded, so you can expect images for example to not be visible. If you want
- * a finer level of granularity consider calling {@link WebView#insertVisualStateCallback}
- * directly.</p>
+ * <p>This method is called when the body of the HTTP response has started loading, is reflected
+ * in the DOM, and will be visible in subsequent draws. This callback occurs early in the
+ * document loading process, and as such you should expect that linked resources (for example,
+ * css and images) may not be available.</p>
*
- * <p>Please note that all the conditions and recommendations presented in
- * {@link WebView#insertVisualStateCallback} also apply to this API.<p>
+ * <p>For more fine-grained notification of visual state updates, see {@link
+ * WebView#postVisualStateCallback}.</p>
*
- * @param url the url of the committed page
+ * <p>Please note that all the conditions and recommendations applicable to
+ * {@link WebView#postVisualStateCallback} also apply to this API.<p>
+ *
+ * <p>This callback is only called for main frame navigations.</p>
+ *
+ * @param view The {@link android.webkit.WebView} for which the navigation occurred.
+ * @param url The URL corresponding to the page navigation that triggered this callback.
*/
public void onPageCommitVisible(WebView view, String url) {
}
@@ -229,11 +233,20 @@
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
if (request.isForMainFrame()) {
onReceivedError(view,
- error.getErrorCode(), error.getDescription(), request.getUrl().toString());
+ error.getErrorCode(), error.getDescription().toString(),
+ request.getUrl().toString());
}
}
/**
+ * This method will be deleted after updated WebView.apk will be submitted
+ * into the Android tree.
+ */
+ public void onReceivedHttpError(
+ WebView view, WebResourceRequest request, WebResourceResponseBase errorResponse) {
+ }
+
+ /**
* Notify the host application that an HTTP error has been received from the server while
* loading a resource. HTTP errors have status codes >= 400. This callback will be called
* for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to
@@ -244,7 +257,7 @@
* @param errorResponse Information about the error occured.
*/
public void onReceivedHttpError(
- WebView view, WebResourceRequest request, WebResourceResponseBase errorResponse) {
+ WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
}
/**
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 9782d72..b7d529e 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -40,7 +40,10 @@
import dalvik.system.VMRuntime;
import java.io.File;
+import java.io.IOException;
import java.util.Arrays;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
/**
* Top level factory, used creating all the main WebView implementation classes.
@@ -323,15 +326,30 @@
long newVmSize = 0L;
for (String path : nativeLibs) {
+ if (path == null || TextUtils.isEmpty(path)) continue;
if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path);
- if (path == null) continue;
File f = new File(path);
if (f.exists()) {
- long length = f.length();
- if (length > newVmSize) {
- newVmSize = length;
+ newVmSize = Math.max(newVmSize, f.length());
+ continue;
+ }
+ if (path.contains("!")) {
+ String[] split = TextUtils.split(path, "!");
+ if (split.length == 2) {
+ try {
+ ZipFile z = new ZipFile(split[0]);
+ ZipEntry e = z.getEntry(split[1]);
+ if (e != null && e.getMethod() == ZipEntry.STORED) {
+ newVmSize = Math.max(newVmSize, e.getSize());
+ continue;
+ }
+ }
+ catch (IOException e) {
+ Log.e(LOGTAG, "error reading APK file " + split[0] + ", ", e);
+ }
}
}
+ Log.e(LOGTAG, "error sizing load for " + path);
}
if (DEBUG) {
@@ -355,6 +373,27 @@
}
// throws MissingWebViewPackageException
+ private static String getLoadFromApkPath(String apkPath,
+ String[] abiList,
+ String nativeLibFileName) {
+ // Search the APK for a native library conforming to a listed ABI.
+ try {
+ ZipFile z = new ZipFile(apkPath);
+ for (String abi : abiList) {
+ final String entry = "lib/" + abi + "/" + nativeLibFileName;
+ ZipEntry e = z.getEntry(entry);
+ if (e != null && e.getMethod() == ZipEntry.STORED) {
+ // Return a path formatted for dlopen() load from APK.
+ return apkPath + "!" + entry;
+ }
+ }
+ } catch (IOException e) {
+ throw new MissingWebViewPackageException(e);
+ }
+ return "";
+ }
+
+ // throws MissingWebViewPackageException
private static String[] getWebViewNativeLibraryPaths() {
ApplicationInfo ai = getWebViewApplicationInfo();
final String NATIVE_LIB_FILE_NAME = getWebViewLibrary(ai);
@@ -382,8 +421,29 @@
path32 = ai.nativeLibraryDir;
path64 = "";
}
- if (!TextUtils.isEmpty(path32)) path32 += "/" + NATIVE_LIB_FILE_NAME;
- if (!TextUtils.isEmpty(path64)) path64 += "/" + NATIVE_LIB_FILE_NAME;
+
+ // Form the full paths to the extracted native libraries.
+ // If libraries were not extracted, try load from APK paths instead.
+ if (!TextUtils.isEmpty(path32)) {
+ path32 += "/" + NATIVE_LIB_FILE_NAME;
+ File f = new File(path32);
+ if (!f.exists()) {
+ path32 = getLoadFromApkPath(ai.sourceDir,
+ Build.SUPPORTED_32_BIT_ABIS,
+ NATIVE_LIB_FILE_NAME);
+ }
+ }
+ if (!TextUtils.isEmpty(path64)) {
+ path64 += "/" + NATIVE_LIB_FILE_NAME;
+ File f = new File(path64);
+ if (!f.exists()) {
+ path64 = getLoadFromApkPath(ai.sourceDir,
+ Build.SUPPORTED_64_BIT_ABIS,
+ NATIVE_LIB_FILE_NAME);
+ }
+ }
+
+ if (DEBUG) Log.v(LOGTAG, "Native 32-bit lib: " + path32 + ", 64-bit lib: " + path64);
return new String[] { path32, path64 };
}
diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java
index e367192..00aba2a 100644
--- a/core/java/android/webkit/WebViewProvider.java
+++ b/core/java/android/webkit/WebViewProvider.java
@@ -32,7 +32,6 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewStructure;
import android.view.ViewGroup.LayoutParams;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -299,7 +298,7 @@
interface ViewDelegate {
public boolean shouldDelayChildPressedState();
- public void onProvideVirtualAssistStructure(ViewStructure structure);
+ public void onProvideVirtualAssistStructure(android.view.ViewAssistStructure structure);
public AccessibilityNodeProvider getAccessibilityNodeProvider();
diff --git a/core/java/android/widget/ActivityChooserModel.java b/core/java/android/widget/ActivityChooserModel.java
index 51174c3..75c857c 100644
--- a/core/java/android/widget/ActivityChooserModel.java
+++ b/core/java/android/widget/ActivityChooserModel.java
@@ -40,6 +40,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -991,7 +992,7 @@
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type = XmlPullParser.START_DOCUMENT;
while (type != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
@@ -1074,7 +1075,7 @@
try {
serializer.setOutput(fos, null);
- serializer.startDocument("UTF-8", true);
+ serializer.startDocument(StandardCharsets.UTF_8.name(), true);
serializer.startTag(null, TAG_HISTORICAL_RECORDS);
final int recordCount = historicalRecords.size();
diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java
index d271af2..8fe8252 100644
--- a/core/java/android/widget/DayPickerPagerAdapter.java
+++ b/core/java/android/widget/DayPickerPagerAdapter.java
@@ -186,11 +186,12 @@
}
private int getMonthForPosition(int position) {
- return position % MONTHS_IN_YEAR + mMinDate.get(Calendar.MONTH);
+ return (position + mMinDate.get(Calendar.MONTH)) % MONTHS_IN_YEAR;
}
private int getYearForPosition(int position) {
- return position / MONTHS_IN_YEAR + mMinDate.get(Calendar.YEAR);
+ final int yearOffset = (position + mMinDate.get(Calendar.MONTH)) / MONTHS_IN_YEAR;
+ return yearOffset + mMinDate.get(Calendar.YEAR);
}
private int getPositionForDay(@Nullable Calendar day) {
@@ -198,8 +199,8 @@
return -1;
}
- final int yearOffset = (day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR));
- final int monthOffset = (day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH));
+ final int yearOffset = day.get(Calendar.YEAR) - mMinDate.get(Calendar.YEAR);
+ final int monthOffset = day.get(Calendar.MONTH) - mMinDate.get(Calendar.MONTH);
final int position = yearOffset * MONTHS_IN_YEAR + monthOffset;
return position;
}
diff --git a/core/java/android/widget/DayPickerView.java b/core/java/android/widget/DayPickerView.java
index 334afab..dc772fb 100644
--- a/core/java/android/widget/DayPickerView.java
+++ b/core/java/android/widget/DayPickerView.java
@@ -344,6 +344,8 @@
// Changing the min/max date changes the selection position since we
// don't really have stable IDs. Jumps immediately to the new position.
setDate(mSelectedDay.getTimeInMillis(), false, false);
+
+ updateButtonVisibility(mViewPager.getCurrentItem());
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 2e36cee..c829783 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -209,6 +209,10 @@
// Set when this TextView gained focus with some text selected. Will start selection mode.
boolean mCreatedWithASelection;
+ boolean mDoubleTap = false;
+
+ private Runnable mSelectionModeWithoutSelectionRunnable;
+
// The span controller helps monitoring the changes to which the Editor needs to react:
// - EasyEditSpans, for which we have some UI to display on attach and on hide
// - SelectionSpans, for which we need to call updateSelection if an IME is attached
@@ -286,6 +290,13 @@
mUndoManager.redo(owners, 1); // Redo 1 action.
}
+ void replace() {
+ int middle = (mTextView.getSelectionStart() + mTextView.getSelectionEnd()) / 2;
+ stopSelectionActionMode();
+ Selection.setSelection((Spannable) mTextView.getText(), middle);
+ showSuggestions();
+ }
+
void onAttachedToWindow() {
if (mShowErrorAfterAttach) {
showError();
@@ -342,6 +353,11 @@
mTextView.removeCallbacks(mShowSuggestionRunnable);
}
+ // Cancel the single tap delayed runnable.
+ if (mSelectionModeWithoutSelectionRunnable != null) {
+ mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
+ }
+
destroyDisplayListsData();
if (mSpellChecker != null) {
@@ -689,14 +705,12 @@
// FIXME - For this and similar methods we're not doing anything to check if there's
// a LocaleSpan in the text, this may be something we should try handling or checking for.
int retOffset = getWordIteratorWithText().prevBoundary(offset);
- if (isPunctBoundaryBehind(retOffset, true /* isStart */)) {
- // If we're on a punctuation boundary we should continue to get the
- // previous offset until we're not longer on a punctuation boundary.
- retOffset = getWordIteratorWithText().prevBoundary(retOffset);
- while (!isPunctBoundaryBehind(retOffset, false /* isStart */)
- && retOffset != BreakIterator.DONE) {
- retOffset = getWordIteratorWithText().prevBoundary(retOffset);
- }
+ if (getWordIteratorWithText().isOnPunctuation(retOffset)) {
+ // On punctuation boundary or within group of punctuation, find punctuation start.
+ retOffset = getWordIteratorWithText().getPunctuationBeginning(offset);
+ } else {
+ // Not on a punctuation boundary, find the word start.
+ retOffset = getWordIteratorWithText().getBeginning(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -706,14 +720,12 @@
private int getWordEnd(int offset) {
int retOffset = getWordIteratorWithText().nextBoundary(offset);
- if (isPunctBoundaryForward(retOffset, true /* isStart */)) {
- // If we're on a punctuation boundary we should continue to get the
- // next offset until we're no longer on a punctuation boundary.
- retOffset = getWordIteratorWithText().nextBoundary(retOffset);
- while (!isPunctBoundaryForward(retOffset, false /* isStart */)
- && retOffset != BreakIterator.DONE) {
- retOffset = getWordIteratorWithText().nextBoundary(retOffset);
- }
+ if (getWordIteratorWithText().isAfterPunctuation(retOffset)) {
+ // On punctuation boundary or within group of punctuation, find punctuation end.
+ retOffset = getWordIteratorWithText().getPunctuationEnd(offset);
+ } else {
+ // Not on a punctuation boundary, find the word end.
+ retOffset = getWordIteratorWithText().getEnd(offset);
}
if (retOffset == BreakIterator.DONE) {
return offset;
@@ -722,70 +734,6 @@
}
/**
- * Checks for punctuation boundaries for the provided offset and the
- * previous character.
- *
- * @param offset The offset to check from.
- * @param isStart Whether the boundary being checked for is at the start or
- * end of a punctuation sequence.
- * @return Whether this is a punctuation boundary.
- */
- private boolean isPunctBoundaryBehind(int offset, boolean isStart) {
- CharSequence text = mTextView.getText();
- if (offset == BreakIterator.DONE || offset > text.length() || offset == 0) {
- return false;
- }
- int cp = Character.codePointAt(text, offset);
- int prevCp = Character.codePointBefore(text, offset);
-
- if (isPunctuation(cp)) {
- // If it's the start, the current cp and the prev cp are
- // punctuation. If it's at the end of a punctuation sequence the
- // current is punctuation and the prev is not.
- return isStart ? isPunctuation(prevCp) : !isPunctuation(prevCp);
- }
- return false;
- }
-
- /**
- * Checks for punctuation boundaries for the provided offset and the next
- * character.
- *
- * @param offset The offset to check from.
- * @param isStart Whether the boundary being checked for is at the start or
- * end of a punctuation sequence.
- * @return Whether this is a punctuation boundary.
- */
- private boolean isPunctBoundaryForward(int offset, boolean isStart) {
- CharSequence text = mTextView.getText();
- if (offset == BreakIterator.DONE || offset > text.length() || offset == 0) {
- return false;
- }
- int cp = Character.codePointBefore(text, offset);
- int nextCpOffset = Math.min(offset + Character.charCount(cp), text.length() - 1);
- int nextCp = Character.codePointBefore(text, nextCpOffset);
-
- if (isPunctuation(cp)) {
- // If it's the start, the current cp and the next cp are
- // punctuation. If it's at the end of a punctuation sequence the
- // current is punctuation and the next is not.
- return isStart ? isPunctuation(nextCp) : !isPunctuation(nextCp);
- }
- return false;
- }
-
- private boolean isPunctuation(int cp) {
- int type = Character.getType(cp);
- return (type == Character.CONNECTOR_PUNCTUATION ||
- type == Character.DASH_PUNCTUATION ||
- type == Character.END_PUNCTUATION ||
- type == Character.FINAL_QUOTE_PUNCTUATION ||
- type == Character.INITIAL_QUOTE_PUNCTUATION ||
- type == Character.OTHER_PUNCTUATION ||
- type == Character.START_PUNCTUATION);
- }
-
- /**
* Adjusts selection to the word under last touch offset. Return true if the operation was
* successfully performed.
*/
@@ -1867,6 +1815,7 @@
// When the cursor moves, the word that was typed may need spell check
mSpellChecker.onSelectionChanged();
}
+
if (!extractedTextModeWillBeStarted()) {
if (isCursorInsideEasyCorrectionSpan()) {
mShowSuggestionRunnable = new Runnable() {
@@ -3185,10 +3134,6 @@
mCustomSelectionActionModeCallback.onActionItemClicked(mode, item)) {
return true;
}
- if (item.getItemId() == TextView.ID_REPLACE) {
- onReplace();
- return true;
- }
return mTextView.onTextContextMenuItem(item.getItemId());
}
@@ -3262,13 +3207,6 @@
}
}
- private void onReplace() {
- int middle = (mTextView.getSelectionStart() + mTextView.getSelectionEnd()) / 2;
- stopSelectionActionMode();
- Selection.setSelection((Spannable) mTextView.getText(), middle);
- showSuggestions();
- }
-
/**
* A listener to call {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}
* while the input method is requesting the cursor/anchor position. Does nothing as long as
@@ -3488,9 +3426,13 @@
protected void updateDrawable() {
final int offset = getCurrentCursorOffset();
final boolean isRtlCharAtOffset = mTextView.getLayout().isRtlCharAt(offset);
+ final Drawable oldDrawable = mDrawable;
mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr;
mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset);
mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset);
+ if (oldDrawable != mDrawable) {
+ postInvalidate();
+ }
}
protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun);
@@ -3794,9 +3736,27 @@
super.show();
final long durationSinceCutOrCopy =
- SystemClock.uptimeMillis() - TextView.LAST_CUT_OR_COPY_TIME;
- if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
- startSelectionActionModeWithoutSelection();
+ SystemClock.uptimeMillis() - TextView.sLastCutCopyOrTextChangedTime;
+
+ // Cancel the single tap delayed runnable.
+ if (mDoubleTap && mSelectionModeWithoutSelectionRunnable != null) {
+ mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable);
+ }
+
+ // Prepare and schedule the single tap runnable to run exactly after the double tap
+ // timeout has passed.
+ if (!mDoubleTap && (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION)) {
+ if (mSelectionModeWithoutSelectionRunnable == null) {
+ mSelectionModeWithoutSelectionRunnable = new Runnable() {
+ public void run() {
+ startSelectionActionModeWithoutSelection();
+ }
+ };
+ }
+
+ mTextView.postDelayed(
+ mSelectionModeWithoutSelectionRunnable,
+ ViewConfiguration.getDoubleTapTimeout() + 1);
}
hideAfterDelay();
@@ -3923,8 +3883,8 @@
private class SelectionStartHandleView extends HandleView {
// Indicates whether the cursor is making adjustments within a word.
private boolean mInWord = false;
- // Offset to track difference between touch and word boundary.
- protected int mTouchWordOffset;
+ // Difference between touch position and word boundary position.
+ private float mTouchWordDelta;
public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -3937,7 +3897,7 @@
@Override
protected int getHorizontalGravity(boolean isRtlRun) {
- return isRtlRun ? Gravity.RIGHT : Gravity.LEFT;
+ return isRtlRun ? Gravity.LEFT : Gravity.RIGHT;
}
@Override
@@ -3957,10 +3917,20 @@
@Override
public void updatePosition(float x, float y) {
- final int trueOffset = mTextView.getOffsetForPosition(x, y);
- final int currLine = mTextView.getLineAtCoordinate(y);
+ final int selectionEnd = mTextView.getSelectionEnd();
+ final Layout layout = mTextView.getLayout();
+ int initialOffset = mTextView.getOffsetForPosition(x, y);
+ int currLine = mTextView.getLineAtCoordinate(y);
boolean positionCursor = false;
- int offset = trueOffset;
+
+ if (initialOffset >= selectionEnd) {
+ // Handles have crossed, bound it to the last selected line and
+ // adjust by word / char as normal.
+ currLine = layout != null ? layout.getLineForOffset(selectionEnd) : mPrevLine;
+ initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+ }
+
+ int offset = initialOffset;
int end = getWordEnd(offset);
int start = getWordStart(offset);
@@ -3976,33 +3946,41 @@
offset = mPreviousOffset;
}
}
- mTouchWordOffset = Math.max(trueOffset - offset, 0);
- positionCursor = true;
- } else if (offset - mTouchWordOffset > mPreviousOffset || currLine > mPrevLine) {
- // User is shrinking the selection.
- if (currLine > mPrevLine) {
- // We're on a different line, so we'll snap to word boundaries.
- offset = start;
- mTouchWordOffset = Math.max(trueOffset - offset, 0);
+ if (layout != null && offset < initialOffset) {
+ final float adjustedX = layout.getPrimaryHorizontal(offset);
+ mTouchWordDelta =
+ mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
} else {
- offset -= mTouchWordOffset;
+ mTouchWordDelta = 0.0f;
}
positionCursor = true;
+ } else {
+ final int adjustedOffset =
+ mTextView.getOffsetAtCoordinate(currLine, x - mTouchWordDelta);
+ if (adjustedOffset > mPreviousOffset || currLine > mPrevLine) {
+ // User is shrinking the selection.
+ if (currLine > mPrevLine) {
+ // We're on a different line, so we'll snap to word boundaries.
+ offset = start;
+ if (layout != null && offset < initialOffset) {
+ final float adjustedX = layout.getPrimaryHorizontal(offset);
+ mTouchWordDelta =
+ mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
+ } else {
+ mTouchWordDelta = 0.0f;
+ }
+ } else {
+ offset = adjustedOffset;
+ }
+ positionCursor = true;
+ }
}
- // Handles can not cross and selection is at least one character.
if (positionCursor) {
- final int selectionEnd = mTextView.getSelectionEnd();
+ // Handles can not cross and selection is at least one character.
if (offset >= selectionEnd) {
- // We can't cross the handles so let's just constrain the Y value.
- int alteredOffset = mTextView.getOffsetAtCoordinate(mPrevLine, x);
- if (alteredOffset >= selectionEnd) {
- // Can't pass the other drag handle.
- offset = getNextCursorOffset(selectionEnd, false);
- } else {
- offset = alteredOffset;
- }
- mTouchWordOffset = 0;
+ offset = getNextCursorOffset(selectionEnd, false);
+ mTouchWordDelta = 0.0f;
}
mInWord = !getWordIteratorWithText().isBoundary(offset);
positionAtCursorOffset(offset, false);
@@ -4014,7 +3992,7 @@
boolean superResult = super.onTouchEvent(event);
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
- mTouchWordOffset = 0;
+ mTouchWordDelta = 0.0f;
}
return superResult;
}
@@ -4023,8 +4001,8 @@
private class SelectionEndHandleView extends HandleView {
// Indicates whether the cursor is making adjustments within a word.
private boolean mInWord = false;
- // Offset to track difference between touch and word boundary.
- protected int mTouchWordOffset;
+ // Difference between touch position and word boundary position.
+ private float mTouchWordDelta;
public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
super(drawableLtr, drawableRtl);
@@ -4037,7 +4015,7 @@
@Override
protected int getHorizontalGravity(boolean isRtlRun) {
- return isRtlRun ? Gravity.LEFT : Gravity.RIGHT;
+ return isRtlRun ? Gravity.RIGHT : Gravity.LEFT;
}
@Override
@@ -4057,10 +4035,20 @@
@Override
public void updatePosition(float x, float y) {
- final int trueOffset = mTextView.getOffsetForPosition(x, y);
- final int currLine = mTextView.getLineAtCoordinate(y);
- int offset = trueOffset;
+ final int selectionStart = mTextView.getSelectionStart();
+ final Layout layout = mTextView.getLayout();
+ int initialOffset = mTextView.getOffsetForPosition(x, y);
+ int currLine = mTextView.getLineAtCoordinate(y);
boolean positionCursor = false;
+
+ if (initialOffset <= selectionStart) {
+ // Handles have crossed, bound it to the first selected line and
+ // adjust by word / char as normal.
+ currLine = layout != null ? layout.getLineForOffset(selectionStart) : mPrevLine;
+ initialOffset = mTextView.getOffsetAtCoordinate(currLine, x);
+ }
+
+ int offset = initialOffset;
int end = getWordEnd(offset);
int start = getWordStart(offset);
@@ -4076,33 +4064,41 @@
offset = mPreviousOffset;
}
}
- mTouchWordOffset = Math.max(offset - trueOffset, 0);
- positionCursor = true;
- } else if (offset + mTouchWordOffset < mPreviousOffset || currLine < mPrevLine) {
- // User is shrinking the selection.
- if (currLine < mPrevLine) {
- // We're on a different line, so we'll snap to word boundaries.
- offset = end;
- mTouchWordOffset = Math.max(offset - trueOffset, 0);
+ if (layout != null && offset > initialOffset) {
+ final float adjustedX = layout.getPrimaryHorizontal(offset);
+ mTouchWordDelta =
+ adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
} else {
- offset += mTouchWordOffset;
+ mTouchWordDelta = 0.0f;
}
positionCursor = true;
+ } else {
+ final int adjustedOffset =
+ mTextView.getOffsetAtCoordinate(currLine, x + mTouchWordDelta);
+ if (adjustedOffset < mPreviousOffset || currLine < mPrevLine) {
+ // User is shrinking the selection.
+ if (currLine < mPrevLine) {
+ // We're on a different line, so we'll snap to word boundaries.
+ offset = end;
+ if (layout != null && offset > initialOffset) {
+ final float adjustedX = layout.getPrimaryHorizontal(offset);
+ mTouchWordDelta =
+ adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
+ } else {
+ mTouchWordDelta = 0.0f;
+ }
+ } else {
+ offset = adjustedOffset;
+ }
+ positionCursor = true;
+ }
}
if (positionCursor) {
- final int selectionStart = mTextView.getSelectionStart();
+ // Handles can not cross and selection is at least one character.
if (offset <= selectionStart) {
- // We can't cross the handles so let's just constrain the Y value.
- int alteredOffset = mTextView.getOffsetAtCoordinate(mPrevLine, x);
- int length = mTextView.getText().length();
- if (alteredOffset <= selectionStart) {
- // Can't pass the other drag handle.
- offset = getNextCursorOffset(selectionStart, true);
- } else {
- offset = Math.min(alteredOffset, length);
- }
- mTouchWordOffset = 0;
+ offset = getNextCursorOffset(selectionStart, true);
+ mTouchWordDelta = 0.0f;
}
mInWord = !getWordIteratorWithText().isBoundary(offset);
positionAtCursorOffset(offset, false);
@@ -4114,7 +4110,7 @@
boolean superResult = super.onTouchEvent(event);
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
// Reset the touch word offset when the user has lifted their finger.
- mTouchWordOffset = 0;
+ mTouchWordDelta = 0.0f;
}
return superResult;
}
@@ -4149,6 +4145,10 @@
public void show() {
getHandle().show();
+
+ if (mSelectionModifierCursorController != null) {
+ mSelectionModifierCursorController.hide();
+ }
}
public void hide() {
@@ -4190,8 +4190,6 @@
// The offsets of that last touch down event. Remembered to start selection there.
private int mMinTouchOffset, mMaxTouchOffset;
- // Double tap detection
- private long mPreviousTapUpTime = 0;
private float mDownPositionX, mDownPositionY;
private boolean mGestureStayedInTapRegion;
@@ -4273,8 +4271,7 @@
// Double tap detection
if (mGestureStayedInTapRegion) {
- long duration = SystemClock.uptimeMillis() - mPreviousTapUpTime;
- if (duration <= ViewConfiguration.getDoubleTapTimeout()) {
+ if (mDoubleTap) {
final float deltaX = x - mDownPositionX;
final float deltaY = y - mDownPositionY;
final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
@@ -4383,7 +4380,6 @@
break;
case MotionEvent.ACTION_UP:
- mPreviousTapUpTime = SystemClock.uptimeMillis();
if (mDragAcceleratorActive) {
// No longer dragging to select text, let the parent intercept events.
mTextView.getParent().requestDisallowInterceptTouchEvent(false);
@@ -4475,7 +4471,7 @@
private class CorrectionHighlighter {
private final Path mPath = new Path();
- private final Paint mPaint = new Paint();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int mStart, mEnd;
private long mFadingStartTime;
private RectF mTempRectF;
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 05059bc..73a873a 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -36,8 +36,10 @@
import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
+import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -462,6 +464,21 @@
}
/**
+ * Sets the content of this ImageView to the specified Icon.
+ *
+ * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding
+ * on the UI thread, which can cause UI jank. If that's a concern, consider using
+ * {@link Icon#loadDrawableAsync(Context, Icon.OnDrawableLoadedListener, Handler)}
+ * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p>
+ *
+ * @param icon an Icon holding the desired image
+ */
+ @android.view.RemotableViewMethod
+ public void setImageIcon(Icon icon) {
+ setImageDrawable(icon.loadDrawable(mContext));
+ }
+
+ /**
* Applies a tint to the image drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
* <p>
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a10be11..dc75fd0 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -35,6 +35,7 @@
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -1072,6 +1073,7 @@
static final int BUNDLE = 13;
static final int INTENT = 14;
static final int COLOR_STATE_LIST = 15;
+ static final int ICON = 16;
String methodName;
int type;
@@ -1150,6 +1152,10 @@
this.value = ColorStateList.CREATOR.createFromParcel(in);
}
break;
+ case ICON:
+ if (in.readInt() != 0) {
+ this.value = Icon.CREATOR.createFromParcel(in);
+ }
default:
break;
}
@@ -1225,6 +1231,13 @@
if (this.value != null) {
((ColorStateList)this.value).writeToParcel(out, flags);
}
+ break;
+ case ICON:
+ out.writeInt(this.value != null ? 1 : 0);
+ if (this.value != null) {
+ ((Icon)this.value).writeToParcel(out, flags);
+ }
+ break;
default:
break;
}
@@ -1262,6 +1275,8 @@
return Intent.class;
case COLOR_STATE_LIST:
return ColorStateList.class;
+ case ICON:
+ return Icon.class;
default:
return null;
}
@@ -2082,6 +2097,16 @@
}
/**
+ * Equivalent to calling ImageView.setImageIcon
+ *
+ * @param viewId The id of the view whose bitmap should change
+ * @param icon The new Icon for the ImageView
+ */
+ public void setImageViewIcon(int viewId, Icon icon) {
+ setIcon(viewId, "setImageIcon", icon);
+ }
+
+ /**
* Equivalent to calling AdapterView.setEmptyView
*
* @param viewId The id of the view on which to set the empty view
@@ -2519,6 +2544,17 @@
}
/**
+ * Call a method taking one Icon on a view in the layout for this RemoteViews.
+ *
+ * @param viewId The id of the view on which to call the method.
+ * @param methodName The name of the method to call.
+ * @param value The {@link android.graphics.drawable.Icon} to pass the method.
+ */
+ public void setIcon(int viewId, String methodName, Icon value) {
+ addAction(new ReflectionAction(viewId, methodName, ReflectionAction.ICON, value));
+ }
+
+ /**
* Equivalent to calling View.setContentDescription(CharSequence).
*
* @param viewId The id of the view whose content description should change.
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index ff587c2..f42959f 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -26,6 +26,7 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Insets;
+import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
@@ -214,7 +215,7 @@
public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
- mTextPaint = new TextPaint();
+ mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
final Resources res = getResources();
mTextPaint.density = res.getDisplayMetrics().density;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 68c49cd..5acd79f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -238,6 +238,7 @@
* @attr ref android.R.styleable#TextView_letterSpacing
* @attr ref android.R.styleable#TextView_fontFeatureSettings
* @attr ref android.R.styleable#TextView_breakStrategy
+ * @attr ref android.R.styleable#TextView_hyphenationFrequency
* @attr ref android.R.styleable#TextView_leftIndents
* @attr ref android.R.styleable#TextView_rightIndents
*/
@@ -291,8 +292,8 @@
// New state used to change background based on whether this TextView is multiline.
private static final int[] MULTILINE_STATE_SET = { R.attr.state_multiline };
- // System wide time for last cut or copy action.
- static long LAST_CUT_OR_COPY_TIME;
+ // System wide time for last cut, copy or text changed action.
+ static long sLastCutCopyOrTextChangedTime;
/**
* @hide
@@ -555,6 +556,7 @@
private float mSpacingAdd = 0.0f;
private int mBreakStrategy;
+ private int mHyphenationFrequency;
private int[] mLeftIndents;
private int[] mRightIndents;
@@ -597,6 +599,9 @@
private final Paint mHighlightPaint;
private boolean mHighlightPathBogus = true;
+ private boolean mFirstTouch = false;
+ private long mLastTouchUpTime = 0;
+
// Although these fields are specific to editable text, they are not added to Editor because
// they are defined by the TextView's style and are theme-dependent.
int mCursorDrawableRes;
@@ -669,11 +674,11 @@
final Resources res = getResources();
final CompatibilityInfo compat = res.getCompatibilityInfo();
- mTextPaint = new TextPaint();
+ mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.density = res.getDisplayMetrics().density;
mTextPaint.setCompatibilityScaling(compat.applicationScale);
- mHighlightPaint = new Paint();
+ mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHighlightPaint.setCompatibilityScaling(compat.applicationScale);
mMovement = getDefaultMovementMethod();
@@ -696,6 +701,7 @@
float letterSpacing = 0;
String fontFeatureSettings = null;
mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
+ mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
final Resources.Theme theme = context.getTheme();
@@ -1154,6 +1160,10 @@
mBreakStrategy = a.getInt(attr, Layout.BREAK_STRATEGY_SIMPLE);
break;
+ case com.android.internal.R.styleable.TextView_hyphenationFrequency:
+ mHyphenationFrequency = a.getInt(attr, Layout.HYPHENATION_FREQUENCY_NONE);
+ break;
+
case com.android.internal.R.styleable.TextView_leftIndents:
TypedArray margins = res.obtainTypedArray(a.getResourceId(attr, View.NO_ID));
mLeftIndents = parseDimensionArray(margins);
@@ -3050,6 +3060,33 @@
}
/**
+ * Sets the hyphenation frequency. The default value for both TextView and EditText, which is set
+ * from the theme, is {@link Layout#HYPHENATION_FREQUENCY_NORMAL}.
+ *
+ * @attr ref android.R.styleable#TextView_hyphenationFrequency
+ * @see #getHyphenationFrequency()
+ */
+ public void setHyphenationFrequency(@Layout.HyphenationFrequency int hyphenationFrequency) {
+ mHyphenationFrequency = hyphenationFrequency;
+ if (mLayout != null) {
+ nullLayouts();
+ requestLayout();
+ invalidate();
+ }
+ }
+
+ /**
+ * @return the currently set hyphenation frequency.
+ *
+ * @attr ref android.R.styleable#TextView_hyphenationFrequency
+ * @see #setHyphenationFrequency(int)
+ */
+ @Layout.HyphenationFrequency
+ public int getHyphenationFrequency() {
+ return mHyphenationFrequency;
+ }
+
+ /**
* Set indents. Arguments are arrays holding an indent amount, one per line, measured in
* pixels. For lines past the last element in the array, the last element repeats.
*
@@ -6637,7 +6674,8 @@
.setTextDir(mTextDir)
.setLineSpacing(mSpacingAdd, mSpacingMult)
.setIncludePad(mIncludePad)
- .setBreakStrategy(mBreakStrategy);
+ .setBreakStrategy(mBreakStrategy)
+ .setHyphenationFrequency(mHyphenationFrequency);
if (mLeftIndents != null || mRightIndents != null) {
builder.setIndents(mLeftIndents, mRightIndents);
}
@@ -6678,7 +6716,8 @@
Layout result = null;
if (mText instanceof Spannable) {
result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth,
- alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad, mBreakStrategy,
+ alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad,
+ mBreakStrategy, mHyphenationFrequency,
getKeyListener() == null ? effectiveEllipsize : null, ellipsisWidth);
} else {
if (boring == UNKNOWN_BORING) {
@@ -6726,7 +6765,8 @@
.setTextDir(mTextDir)
.setLineSpacing(mSpacingAdd, mSpacingMult)
.setIncludePad(mIncludePad)
- .setBreakStrategy(mBreakStrategy);
+ .setBreakStrategy(mBreakStrategy)
+ .setHyphenationFrequency(mHyphenationFrequency);
if (mLeftIndents != null || mRightIndents != null) {
builder.setIndents(mLeftIndents, mRightIndents);
}
@@ -7968,6 +8008,8 @@
* through a thunk.
*/
void sendAfterTextChanged(Editable text) {
+ sLastCutCopyOrTextChangedTime = 0;
+
if (mListeners != null) {
final ArrayList<TextWatcher> list = mListeners;
final int count = list.size();
@@ -8240,6 +8282,22 @@
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getActionMasked();
+ if (mEditor != null && action == MotionEvent.ACTION_DOWN) {
+ // Detect double tap and inform the Editor.
+ if (mFirstTouch && (SystemClock.uptimeMillis() - mLastTouchUpTime) <=
+ ViewConfiguration.getDoubleTapTimeout()) {
+ mEditor.mDoubleTap = true;
+ mFirstTouch = false;
+ } else {
+ mEditor.mDoubleTap = false;
+ mFirstTouch = true;
+ }
+ }
+
+ if (action == MotionEvent.ACTION_UP) {
+ mLastTouchUpTime = SystemClock.uptimeMillis();
+ }
+
if (mEditor != null) {
mEditor.onTouchEvent(event);
@@ -9014,6 +9072,12 @@
stopSelectionActionMode();
return true;
+ case ID_REPLACE:
+ if (mEditor != null) {
+ mEditor.replace();
+ }
+ return true;
+
case ID_SHARE:
shareSelectedText();
return true;
@@ -9248,7 +9312,7 @@
}
}
stopSelectionActionMode();
- LAST_CUT_OR_COPY_TIME = 0;
+ sLastCutCopyOrTextChangedTime = 0;
}
}
@@ -9268,7 +9332,7 @@
ClipboardManager clipboard = (ClipboardManager) getContext().
getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setPrimaryClip(clip);
- LAST_CUT_OR_COPY_TIME = SystemClock.uptimeMillis();
+ sLastCutCopyOrTextChangedTime = SystemClock.uptimeMillis();
}
/**
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 83fa967..ea18c12 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -29,8 +29,8 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.database.DataSetObserver;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -51,10 +51,8 @@
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
-import android.widget.LinearLayout;
import android.widget.ListView;
import com.android.internal.R;
@@ -74,6 +72,8 @@
private IntentSender mRefinementIntentSender;
private RefinementResultReceiver mRefinementResultReceiver;
+ private Intent mReferrerFillInIntent;
+
private ChooserListAdapter mChooserListAdapter;
private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
@@ -81,7 +81,7 @@
private static final int CHOOSER_TARGET_SERVICE_RESULT = 1;
private static final int CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT = 2;
- private Handler mTargetResultHandler = new Handler() {
+ private final Handler mChooserHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -176,6 +176,8 @@
}
}
+ mReferrerFillInIntent = new Intent().putExtra(Intent.EXTRA_REFERRER, getReferrer());
+
mChosenComponentSender = intent.getParcelableExtra(
Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
mRefinementIntentSender = intent.getParcelableExtra(
@@ -346,7 +348,7 @@
if (!mServiceConnections.isEmpty()) {
if (DEBUG) Log.d(TAG, "queryTargets setting watchdog timer for "
+ WATCHDOG_TIMEOUT_MILLIS + "ms");
- mTargetResultHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
+ mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
WATCHDOG_TIMEOUT_MILLIS);
}
}
@@ -379,7 +381,7 @@
unbindService(conn);
}
mServiceConnections.clear();
- mTargetResultHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
}
void onRefinementResult(TargetInfo selectedTarget, Intent matchingIntent) {
@@ -435,7 +437,7 @@
private final ResolveInfo mBackupResolveInfo;
private final ChooserTarget mChooserTarget;
private Drawable mBadgeIcon = null;
- private final Drawable mDisplayIcon;
+ private Drawable mDisplayIcon;
private final Intent mFillInIntent;
private final int mFillInFlags;
@@ -451,7 +453,9 @@
}
}
}
- mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
+ final Icon icon = chooserTarget.getIcon();
+ // TODO do this in the background
+ mDisplayIcon = icon != null ? icon.loadDrawable(ChooserActivity.this) : null;
if (sourceInfo != null) {
mBackupResolveInfo = null;
@@ -497,9 +501,12 @@
? mSourceInfo.getResolvedIntent() : getTargetIntent();
if (result == null) {
Log.e(TAG, "ChooserTargetInfo#getFillInIntent: no fillIn intent available");
- } else if (mFillInIntent != null) {
+ } else {
result = new Intent(result);
- result.fillIn(mFillInIntent, mFillInFlags);
+ if (mFillInIntent != null) {
+ result.fillIn(mFillInIntent, mFillInFlags);
+ }
+ result.fillIn(mReferrerFillInIntent, 0);
}
return result;
}
@@ -867,7 +874,7 @@
msg.what = CHOOSER_TARGET_SERVICE_RESULT;
msg.obj = new ServiceResultInfo(mOriginalTarget, targets,
ChooserTargetServiceConnection.this);
- mTargetResultHandler.sendMessage(msg);
+ mChooserHandler.sendMessage(msg);
}
};
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 80bc5fe..49230c1 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -45,33 +45,11 @@
import android.widget.ImageView;
public class PlatLogoActivity extends Activity {
- final static int[] FLAVORS = {
- 0xFF9C27B0, 0xFFBA68C8, // grape
- 0xFFFF9800, 0xFFFFB74D, // orange
- 0xFFF06292, 0xFFF8BBD0, // bubblegum
- 0xFFAFB42B, 0xFFCDDC39, // lime
- 0xFFFFEB3B, 0xFFFFF176, // lemon
- 0xFF795548, 0xFFA1887F, // mystery flavor
- };
FrameLayout mLayout;
int mTapCount;
int mKeyCount;
PathInterpolator mInterpolator = new PathInterpolator(0f, 0f, 0.5f, 1f);
- static int newColorIndex() {
- return 2*((int) (Math.random()*FLAVORS.length/2));
- }
-
- Drawable makeRipple() {
- final int idx = newColorIndex();
- final ShapeDrawable popbg = new ShapeDrawable(new OvalShape());
- popbg.getPaint().setColor(FLAVORS[idx]);
- final RippleDrawable ripple = new RippleDrawable(
- ColorStateList.valueOf(FLAVORS[idx+1]),
- popbg, null);
- return ripple;
- }
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -87,120 +65,62 @@
final int size = (int)
(Math.min(Math.min(dm.widthPixels, dm.heightPixels), 600*dp) - 100*dp);
- final View stick = new View(this) {
- Paint mPaint = new Paint();
- Path mShadow = new Path();
-
- @Override
- public void onAttachedToWindow() {
- super.onAttachedToWindow();
- setWillNotDraw(false);
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRect(0, getHeight() / 2, getWidth(), getHeight());
- }
- });
- }
- @Override
- public void onDraw(Canvas c) {
- final int w = c.getWidth();
- final int h = c.getHeight() / 2;
- c.translate(0, h);
- final GradientDrawable g = new GradientDrawable();
- g.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);
- g.setGradientCenter(w * 0.75f, 0);
- g.setColors(new int[] { 0xFFFFFFFF, 0xFFAAAAAA });
- g.setBounds(0, 0, w, h);
- g.draw(c);
- mPaint.setColor(0xFFAAAAAA);
- mShadow.reset();
- mShadow.moveTo(0,0);
- mShadow.lineTo(w, 0);
- mShadow.lineTo(w, size/2 + 1.5f*w);
- mShadow.lineTo(0, size/2);
- mShadow.close();
- c.drawPath(mShadow, mPaint);
- }
- };
- mLayout.addView(stick, new FrameLayout.LayoutParams((int) (32 * dp),
- ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL));
- stick.setAlpha(0f);
-
- final ImageView im = new ImageView(this);
+ final View im = new View(this);
im.setTranslationZ(20);
- im.setScaleX(0);
- im.setScaleY(0);
+ im.setScaleX(0.5f);
+ im.setScaleY(0.5f);
+ im.setAlpha(0f);
+ im.setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ final int pad = (int) (8*dp);
+ outline.setOval(pad, pad, view.getWidth()-pad, view.getHeight()-pad);
+ }
+ });
final Drawable platlogo = getDrawable(com.android.internal.R.drawable.platlogo);
- platlogo.setAlpha(0);
- im.setImageDrawable(platlogo);
- im.setBackground(makeRipple());
+ im.setBackground(new RippleDrawable(
+ ColorStateList.valueOf(0xFFFFFFFF),
+ platlogo,
+ null));
im.setClickable(true);
- final ShapeDrawable highlight = new ShapeDrawable(new OvalShape());
- highlight.getPaint().setColor(0x10FFFFFF);
- highlight.setBounds((int)(size*.15f), (int)(size*.15f),
- (int)(size*.6f), (int)(size*.6f));
- im.getOverlay().add(highlight);
im.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mTapCount == 0) {
- im.animate()
- .translationZ(40)
- .scaleX(1)
- .scaleY(1)
- .setInterpolator(mInterpolator)
- .setDuration(700)
- .setStartDelay(500)
- .start();
+ im.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (mTapCount < 5) return false;
- final ObjectAnimator a = ObjectAnimator.ofInt(platlogo, "alpha", 0, 255);
- a.setInterpolator(mInterpolator);
- a.setStartDelay(1000);
- a.start();
-
- stick.animate()
- .translationZ(20)
- .alpha(1)
- .setInterpolator(mInterpolator)
- .setDuration(700)
- .setStartDelay(750)
- .start();
-
- im.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- if (mTapCount < 5) return false;
-
- final ContentResolver cr = getContentResolver();
- if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
- == 0) {
- // For posterity: the moment this user unlocked the easter egg
+ final ContentResolver cr = getContentResolver();
+ if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
+ == 0) {
+ // For posterity: the moment this user unlocked the easter egg
+ try {
Settings.System.putLong(cr,
Settings.System.EGG_MODE,
System.currentTimeMillis());
+ } catch (RuntimeException e) {
+ Log.e("PlatLogoActivity", "Can't write settings", e);
}
- im.post(new Runnable() {
- @Override
- public void run() {
- try {
- startActivity(new Intent(Intent.ACTION_MAIN)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK
- | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
- .addCategory("com.android.internal.category.PLATLOGO"));
- } catch (ActivityNotFoundException ex) {
- Log.e("PlatLogoActivity", "No more eggs.");
- }
- finish();
- }
- });
- return true;
}
- });
- } else {
- im.setBackground(makeRipple());
- }
+ im.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ startActivity(new Intent(Intent.ACTION_MAIN)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK
+ | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
+ .addCategory("com.android.internal.category.PLATLOGO"));
+ } catch (ActivityNotFoundException ex) {
+ Log.e("PlatLogoActivity", "No more eggs.");
+ }
+ finish();
+ }
+ });
+ return true;
+ }
+ });
mTapCount++;
}
});
@@ -229,7 +149,7 @@
mLayout.addView(im, new FrameLayout.LayoutParams(size, size, Gravity.CENTER));
- im.animate().scaleX(0.3f).scaleY(0.3f)
+ im.animate().scaleX(1f).scaleY(1f).alpha(1f)
.setInterpolator(mInterpolator)
.setDuration(500)
.setStartDelay(800)
diff --git a/core/java/com/android/internal/logging/MetricsConstants.java b/core/java/com/android/internal/logging/MetricsConstants.java
index 6aa81ce..65dc743 100644
--- a/core/java/com/android/internal/logging/MetricsConstants.java
+++ b/core/java/com/android/internal/logging/MetricsConstants.java
@@ -21,7 +21,9 @@
* @hide
*/
public interface MetricsConstants {
- // These constants must match those in the analytic pipeline.
+ // These constants must match those in the analytic pipeline, do not edit.
+ public static final int VIEW_UNKNOWN = 0;
+ public static final int MAIN_SETTINGS = 1;
public static final int ACCESSIBILITY = 2;
public static final int ACCESSIBILITY_CAPTION_PROPERTIES = 3;
public static final int ACCESSIBILITY_SERVICE = 4;
@@ -32,16 +34,11 @@
public static final int ACCOUNTS_ACCOUNT_SYNC = 9;
public static final int ACCOUNTS_CHOOSE_ACCOUNT_ACTIVITY = 10;
public static final int ACCOUNTS_MANAGE_ACCOUNTS = 11;
- public static final int ACTION_WIFI_ADD_NETWORK = 134;
- public static final int ACTION_WIFI_CONNECT = 135;
- public static final int ACTION_WIFI_FORCE_SCAN = 136;
- public static final int ACTION_WIFI_FORGET = 137;
- public static final int ACTION_WIFI_OFF = 138;
- public static final int ACTION_WIFI_ON = 139;
public static final int APN = 12;
public static final int APN_EDITOR = 13;
+ public static final int APP_OPS_DETAILS = 14;
+ public static final int APP_OPS_SUMMARY = 15;
public static final int APPLICATION = 16;
- public static final int APPLICATIONS_ADVANCED = 130;
public static final int APPLICATIONS_APP_LAUNCH = 17;
public static final int APPLICATIONS_APP_PERMISSION = 18;
public static final int APPLICATIONS_APP_STORAGE = 19;
@@ -49,8 +46,6 @@
public static final int APPLICATIONS_PROCESS_STATS_DETAIL = 21;
public static final int APPLICATIONS_PROCESS_STATS_MEM_DETAIL = 22;
public static final int APPLICATIONS_PROCESS_STATS_UI = 23;
- public static final int APP_OPS_DETAILS = 14;
- public static final int APP_OPS_SUMMARY = 15;
public static final int BLUETOOTH = 24;
public static final int BLUETOOTH_DEVICE_PICKER = 25;
public static final int BLUETOOTH_DEVICE_PROFILES = 26;
@@ -69,9 +64,7 @@
public static final int DEVELOPMENT = 39;
public static final int DEVICEINFO = 40;
public static final int DEVICEINFO_IMEI_INFORMATION = 41;
- @Deprecated
public static final int DEVICEINFO_MEMORY = 42;
- public static final int DEVICEINFO_STORAGE = 42;
public static final int DEVICEINFO_SIM_STATUS = 43;
public static final int DEVICEINFO_STATUS = 44;
public static final int DEVICEINFO_USB = 45;
@@ -86,21 +79,15 @@
public static final int FUELGAUGE_POWER_USAGE_SUMMARY = 54;
public static final int HOME = 55;
public static final int ICC_LOCK = 56;
- public static final int INPUTMETHOD_KEYBOARD = 58;
public static final int INPUTMETHOD_LANGUAGE = 57;
+ public static final int INPUTMETHOD_KEYBOARD = 58;
public static final int INPUTMETHOD_SPELL_CHECKERS = 59;
public static final int INPUTMETHOD_SUBTYPE_ENABLER = 60;
public static final int INPUTMETHOD_USER_DICTIONARY = 61;
public static final int INPUTMETHOD_USER_DICTIONARY_ADD_WORD = 62;
public static final int LOCATION = 63;
public static final int LOCATION_MODE = 64;
- public static final int LOCATION_SCANNING = 131;
- public static final int MAIN_SETTINGS = 1;
public static final int MANAGE_APPLICATIONS = 65;
- public static final int MANAGE_APPLICATIONS_ALL = 132;
- public static final int MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
- public static final int MANAGE_DOMAIN_URLS = 143;
- public static final int MANAGE_PERMISSIONS = 140;
public static final int MASTER_CLEAR = 66;
public static final int MASTER_CLEAR_CONFIRM = 67;
public static final int NET_DATA_USAGE_METERED = 68;
@@ -108,21 +95,45 @@
public static final int NFC_PAYMENT = 70;
public static final int NOTIFICATION = 71;
public static final int NOTIFICATION_APP_NOTIFICATION = 72;
- public static final int NOTIFICATION_ITEM = 128;
- public static final int NOTIFICATION_ITEM_ACTION = 129;
public static final int NOTIFICATION_OTHER_SOUND = 73;
- public static final int NOTIFICATION_PANEL = 127;
public static final int NOTIFICATION_REDACTION = 74;
public static final int NOTIFICATION_STATION = 75;
public static final int NOTIFICATION_ZEN_MODE = 76;
- public static final int NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
- public static final int NOTIFICATION_ZEN_MODE_PRIORITY = 141;
public static final int OWNER_INFO = 77;
public static final int PRINT_JOB_SETTINGS = 78;
public static final int PRINT_SERVICE_SETTINGS = 79;
public static final int PRINT_SETTINGS = 80;
public static final int PRIVACY = 81;
public static final int PROXY_SELECTOR = 82;
+ public static final int RESET_NETWORK = 83;
+ public static final int RESET_NETWORK_CONFIRM = 84;
+ public static final int RUNNING_SERVICE_DETAILS = 85;
+ public static final int SCREEN_PINNING = 86;
+ public static final int SECURITY = 87;
+ public static final int SIM = 88;
+ public static final int TESTING = 89;
+ public static final int TETHER = 90;
+ public static final int TRUST_AGENT = 91;
+ public static final int TRUSTED_CREDENTIALS = 92;
+ public static final int TTS_ENGINE_SETTINGS = 93;
+ public static final int TTS_TEXT_TO_SPEECH = 94;
+ public static final int USAGE_ACCESS = 95;
+ public static final int USER = 96;
+ public static final int USERS_APP_RESTRICTIONS = 97;
+ public static final int USER_DETAILS = 98;
+ public static final int VOICE_INPUT = 99;
+ public static final int VPN = 100;
+ public static final int WALLPAPER_TYPE = 101;
+ public static final int WFD_WIFI_DISPLAY = 102;
+ public static final int WIFI = 103;
+ public static final int WIFI_ADVANCED = 104;
+ public static final int WIFI_CALLING = 105;
+ public static final int WIFI_SAVED_ACCESS_POINTS = 106;
+ public static final int WIFI_APITEST = 107;
+ public static final int WIFI_INFO = 108;
+ public static final int WIFI_P2P = 109;
+ public static final int WIRELESS = 110;
+ public static final int QS_PANEL = 111;
public static final int QS_AIRPLANEMODE = 112;
public static final int QS_BLUETOOTH = 113;
public static final int QS_CAST = 114;
@@ -134,38 +145,70 @@
public static final int QS_HOTSPOT = 120;
public static final int QS_INTENT = 121;
public static final int QS_LOCATION = 122;
- public static final int QS_PANEL = 111;
public static final int QS_ROTATIONLOCK = 123;
- public static final int QS_USERDETAIL = 125;
public static final int QS_USERDETAILITE = 124;
+ public static final int QS_USERDETAIL = 125;
public static final int QS_WIFI = 126;
- public static final int RESET_NETWORK = 83;
- public static final int RESET_NETWORK_CONFIRM = 84;
- public static final int RUNNING_SERVICE_DETAILS = 85;
- public static final int SCREEN_PINNING = 86;
- public static final int SECURITY = 87;
- public static final int SIM = 88;
- public static final int TESTING = 89;
- public static final int TETHER = 90;
- public static final int TRUSTED_CREDENTIALS = 92;
- public static final int TRUST_AGENT = 91;
- public static final int TTS_ENGINE_SETTINGS = 93;
- public static final int TTS_TEXT_TO_SPEECH = 94;
- public static final int USAGE_ACCESS = 95;
- public static final int USER = 96;
- public static final int USERS_APP_RESTRICTIONS = 97;
- public static final int USER_DETAILS = 98;
- public static final int VIEW_UNKNOWN = 0;
- public static final int VOICE_INPUT = 99;
- public static final int VPN = 100;
- public static final int WALLPAPER_TYPE = 101;
- public static final int WFD_WIFI_DISPLAY = 102;
- public static final int WIFI = 103;
- public static final int WIFI_ADVANCED = 104;
- public static final int WIFI_APITEST = 107;
- public static final int WIFI_CALLING = 105;
- public static final int WIFI_INFO = 108;
- public static final int WIFI_P2P = 109;
- public static final int WIFI_SAVED_ACCESS_POINTS = 106;
- public static final int WIRELESS = 110;
+ public static final int NOTIFICATION_PANEL = 127;
+ public static final int NOTIFICATION_ITEM = 128;
+ public static final int NOTIFICATION_ITEM_ACTION = 129;
+ public static final int APPLICATIONS_ADVANCED = 130;
+ public static final int LOCATION_SCANNING = 131;
+ public static final int MANAGE_APPLICATIONS_ALL = 132;
+ public static final int MANAGE_APPLICATIONS_NOTIFICATIONS = 133;
+ public static final int ACTION_WIFI_ADD_NETWORK = 134;
+ public static final int ACTION_WIFI_CONNECT = 135;
+ public static final int ACTION_WIFI_FORCE_SCAN = 136;
+ public static final int ACTION_WIFI_FORGET = 137;
+ public static final int ACTION_WIFI_OFF = 138;
+ public static final int ACTION_WIFI_ON = 139;
+ public static final int MANAGE_PERMISSIONS = 140;
+ public static final int NOTIFICATION_ZEN_MODE_PRIORITY = 141;
+ public static final int NOTIFICATION_ZEN_MODE_AUTOMATION = 142;
+ public static final int MANAGE_DOMAIN_URLS = 143;
+ public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
+ public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
+ public static final int NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
+ public static final int ACTION_BAN_APP_NOTES = 147;
+ public static final int ACTION_DISMISS_ALL_NOTES = 148;
+ public static final int QS_DND_DETAILS = 149;
+ public static final int QS_BLUETOOTH_DETAILS = 150;
+ public static final int QS_CAST_DETAILS = 151;
+ public static final int QS_WIFI_DETAILS = 152;
+ public static final int QS_WIFI_TOGGLE = 153;
+ public static final int QS_BLUETOOTH_TOGGLE = 154;
+ public static final int QS_CELLULAR_TOGGLE = 155;
+ public static final int QS_SWITCH_USER = 156;
+ public static final int QS_CAST_SELECT = 157;
+ public static final int QS_CAST_DISCONNECT = 158;
+ public static final int ACTION_BLUETOOTH_TOGGLE = 159;
+ public static final int ACTION_BLUETOOTH_SCAN = 160;
+ public static final int ACTION_BLUETOOTH_RENAME = 161;
+ public static final int ACTION_BLUETOOTH_FILES = 162;
+ public static final int QS_DND_TIME = 163;
+ public static final int QS_DND_CONDITION_SELECT = 164;
+ public static final int QS_DND_ZEN_SELECT = 165;
+ public static final int QS_DND_TOGGLE = 166;
+ public static final int ACTION_ZEN_ALLOW_REMINDERS = 167;
+ public static final int ACTION_ZEN_ALLOW_EVENTS = 168;
+ public static final int ACTION_ZEN_ALLOW_MESSAGES = 169;
+ public static final int ACTION_ZEN_ALLOW_CALLS = 170;
+ public static final int ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
+ public static final int ACTION_ZEN_ADD_RULE = 172;
+ public static final int ACTION_ZEN_ADD_RULE_OK = 173;
+ public static final int ACTION_ZEN_DELETE_RULE = 174;
+ public static final int ACTION_ZEN_DELETE_RULE_OK = 175;
+ public static final int ACTION_ZEN_ENABLE_RULE = 176;
+ public static final int ACTION_AIRPLANE_TOGGLE = 177;
+ public static final int ACTION_CELL_DATA_TOGGLE = 178;
+ public static final int NOTIFICATION_ACCESS = 179;
+ public static final int NOTIFICATION_ZEN_MODE_ACCESS = 180;
+ public static final int APPLICATIONS_DEFAULT_APPS = 181;
+ public static final int APPLICATIONS_STORAGE_APPS = 182;
+ public static final int APPLICATIONS_USAGE_ACCESS_DETAIL = 183;
+ public static final int APPLICATIONS_HIGH_POWER_APPS = 184;
+ public static final int FUELGAUGE_HIGH_POWER_DETAILS = 185;
+
+ //aliases
+ public static final int DEVICEINFO_STORAGE = DEVICEINFO_MEMORY;
}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index cf25cef..230d96d 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -26,45 +26,7 @@
* @hide
*/
public class MetricsLogger implements MetricsConstants {
- // These constants are temporary, they should migrate to MetricsConstants.
-
- public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
- public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
- public static final int ACTION_BAN_APP_NOTES = 146;
- public static final int NOTIFICATION_ZEN_MODE_EVENT_RULE = 147;
- public static final int ACTION_DISMISS_ALL_NOTES = 148;
- public static final int QS_DND_DETAILS = 149;
- public static final int QS_BLUETOOTH_DETAILS = 150;
- public static final int QS_CAST_DETAILS = 151;
- public static final int QS_WIFI_DETAILS = 152;
- public static final int QS_WIFI_TOGGLE = 153;
- public static final int QS_BLUETOOTH_TOGGLE = 154;
- public static final int QS_CELLULAR_TOGGLE = 155;
- public static final int QS_SWITCH_USER = 156;
- public static final int QS_CAST_SELECT = 157;
- public static final int QS_CAST_DISCONNECT = 158;
- public static final int ACTION_BLUETOOTH_TOGGLE = 159;
- public static final int ACTION_BLUETOOTH_SCAN = 160;
- public static final int ACTION_BLUETOOTH_RENAME = 161;
- public static final int ACTION_BLUETOOTH_FILES = 162;
- public static final int QS_DND_TIME = 163;
- public static final int QS_DND_CONDITION_SELECT = 164;
- public static final int QS_DND_ZEN_SELECT = 165;
- public static final int QS_DND_TOGGLE = 166;
- public static final int ACTION_ZEN_ALLOW_REMINDERS = 167;
- public static final int ACTION_ZEN_ALLOW_EVENTS = 168;
- public static final int ACTION_ZEN_ALLOW_MESSAGES = 169;
- public static final int ACTION_ZEN_ALLOW_CALLS = 170;
- public static final int ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
- public static final int ACTION_ZEN_ADD_RULE = 172;
- public static final int ACTION_ZEN_ADD_RULE_OK = 173;
- public static final int ACTION_ZEN_DELETE_RULE = 174;
- public static final int ACTION_ZEN_DELETE_RULE_OK = 175;
- public static final int ACTION_ZEN_ENABLE_RULE = 176;
- public static final int ACTION_AIRPLANE_TOGGLE = 177;
- public static final int ACTION_CELL_DATA_TOGGLE = 178;
- public static final int NOTIFICATION_ACCESS = 179;
- public static final int NOTIFICATION_ZEN_MODE_ACCESS = 180;
+ // Temporary constants go here, to await migration to MetricsConstants.
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/midi/MidiDispatcher.java b/core/java/com/android/internal/midi/MidiDispatcher.java
index 70e699a..1a3c37c 100644
--- a/core/java/com/android/internal/midi/MidiDispatcher.java
+++ b/core/java/com/android/internal/midi/MidiDispatcher.java
@@ -27,7 +27,7 @@
* This class subclasses {@link android.media.midi.MidiReceiver} and dispatches any data it receives
* to its receiver list. Any receivers that throw an exception upon receiving data will
* be automatically removed from the receiver list, but no IOException will be returned
- * from the dispatcher's {@link android.media.midi.MidiReceiver#onReceive} in that case.
+ * from the dispatcher's {@link android.media.midi.MidiReceiver#onSend} in that case.
*/
public final class MidiDispatcher extends MidiReceiver {
@@ -35,21 +35,13 @@
= new CopyOnWriteArrayList<MidiReceiver>();
private final MidiSender mSender = new MidiSender() {
- /**
- * Called to connect a {@link android.media.midi.MidiReceiver} to the sender
- *
- * @param receiver the receiver to connect
- */
- public void connect(MidiReceiver receiver) {
+ @Override
+ public void onConnect(MidiReceiver receiver) {
mReceivers.add(receiver);
}
- /**
- * Called to disconnect a {@link android.media.midi.MidiReceiver} from the sender
- *
- * @param receiver the receiver to disconnect
- */
- public void disconnect(MidiReceiver receiver) {
+ @Override
+ public void onDisconnect(MidiReceiver receiver) {
mReceivers.remove(receiver);
}
};
@@ -73,10 +65,10 @@
}
@Override
- public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException {
+ public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
for (MidiReceiver receiver : mReceivers) {
try {
- receiver.sendWithTimestamp(msg, offset, count, timestamp);
+ receiver.send(msg, offset, count, timestamp);
} catch (IOException e) {
// if the receiver fails we remove the receiver but do not propagate the exception
mReceivers.remove(receiver);
@@ -85,7 +77,7 @@
}
@Override
- public void flush() throws IOException {
+ public void onFlush() throws IOException {
for (MidiReceiver receiver : mReceivers) {
receiver.flush();
}
diff --git a/core/java/com/android/internal/midi/MidiEventScheduler.java b/core/java/com/android/internal/midi/MidiEventScheduler.java
index 4dc5838..7b01904 100644
--- a/core/java/com/android/internal/midi/MidiEventScheduler.java
+++ b/core/java/com/android/internal/midi/MidiEventScheduler.java
@@ -36,7 +36,7 @@
* time.
*/
@Override
- public void onReceive(byte[] msg, int offset, int count, long timestamp)
+ public void onSend(byte[] msg, int offset, int count, long timestamp)
throws IOException {
MidiEvent event = createScheduledEvent(msg, offset, count, timestamp);
if (event != null) {
@@ -45,7 +45,7 @@
}
@Override
- public void flush() {
+ public void onFlush() {
MidiEventScheduler.this.flush();
}
}
diff --git a/core/java/com/android/internal/midi/MidiFramer.java b/core/java/com/android/internal/midi/MidiFramer.java
index 8ed5b5a..058f57c 100644
--- a/core/java/com/android/internal/midi/MidiFramer.java
+++ b/core/java/com/android/internal/midi/MidiFramer.java
@@ -54,10 +54,10 @@
}
/*
- * @see android.midi.MidiReceiver#onReceive(byte[], int, int, long)
+ * @see android.midi.MidiReceiver#onSend(byte[], int, int, long)
*/
@Override
- public void onReceive(byte[] data, int offset, int count, long timestamp)
+ public void onSend(byte[] data, int offset, int count, long timestamp)
throws IOException {
// Log.i(TAG, formatMidiData(data, offset, count));
int sysExStartOffset = (mInSysEx ? offset : -1);
@@ -77,7 +77,7 @@
} else if (b == 0xF7 /* SysEx End */) {
// Log.i(TAG, "SysEx End");
if (mInSysEx) {
- mReceiver.sendWithTimestamp(data, sysExStartOffset,
+ mReceiver.send(data, sysExStartOffset,
offset - sysExStartOffset + 1, timestamp);
mInSysEx = false;
sysExStartOffset = -1;
@@ -91,11 +91,11 @@
} else { // real-time?
// Single byte message interleaved with other data.
if (mInSysEx) {
- mReceiver.sendWithTimestamp(data, sysExStartOffset,
+ mReceiver.send(data, sysExStartOffset,
offset - sysExStartOffset, timestamp);
sysExStartOffset = offset + 1;
}
- mReceiver.sendWithTimestamp(data, offset, 1, timestamp);
+ mReceiver.send(data, offset, 1, timestamp);
}
} else { // data byte
// Save SysEx data for SysEx End marker or end of buffer.
@@ -105,7 +105,7 @@
if (mRunningStatus != 0) {
mBuffer[0] = (byte) mRunningStatus;
}
- mReceiver.sendWithTimestamp(mBuffer, 0, mCount, timestamp);
+ mReceiver.send(mBuffer, 0, mCount, timestamp);
mNeeded = MidiConstants.getBytesPerMessage(mBuffer[0]) - 1;
mCount = 1;
}
@@ -116,7 +116,7 @@
// send any accumulatedSysEx data
if (sysExStartOffset >= 0 && sysExStartOffset < offset) {
- mReceiver.sendWithTimestamp(data, sysExStartOffset,
+ mReceiver.send(data, sysExStartOffset,
offset - sysExStartOffset, timestamp);
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index a53d46c..fbe87c5 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -615,6 +615,7 @@
mStatsType);
if (bs.sumPower() > 0) {
aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
+ mUsageList.add(bs);
}
}
@@ -742,7 +743,6 @@
parcel.setDataPosition(0);
BatteryStatsImpl stats = com.android.internal.os.BatteryStatsImpl.CREATOR
.createFromParcel(parcel);
- stats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
return stats;
} catch (IOException e) {
Log.w(TAG, "Unable to read statistics stream", e);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 405c861..eaca43b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -78,6 +78,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -104,7 +105,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 125 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 126 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -131,6 +132,9 @@
private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
+ private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
+ private final KernelCpuSpeedReader mKernelCpuSpeedReader = new KernelCpuSpeedReader();
+
public interface BatteryCallback {
public void batteryNeedsCpuUpdate();
public void batteryPowerChanged(boolean onBattery);
@@ -302,9 +306,6 @@
String mStartPlatformVersion;
String mEndPlatformVersion;
- long mLastRecordedClockTime;
- long mLastRecordedClockRealtime;
-
long mUptime;
long mUptimeStart;
long mRealtime;
@@ -796,20 +797,6 @@
}
}
- public static class SamplingCounter extends Counter {
- SamplingCounter(TimeBase timeBase, Parcel in) {
- super(timeBase, in);
- }
-
- SamplingCounter(TimeBase timeBase) {
- super(timeBase);
- }
-
- public void addCountAtomic(long count) {
- mCount.addAndGet((int)count);
- }
- }
-
public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
final TimeBase mTimeBase;
long mCount;
@@ -2329,8 +2316,6 @@
if (dataSize == 0) {
// The history is currently empty; we need it to start with a time stamp.
cur.currentTime = System.currentTimeMillis();
- mLastRecordedClockTime = cur.currentTime;
- mLastRecordedClockRealtime = elapsedRealtimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
}
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
@@ -2503,8 +2488,6 @@
mHistoryOverflow = false;
mActiveHistoryStates = 0xffffffff;
mActiveHistoryStates2 = 0xffffffff;
- mLastRecordedClockTime = 0;
- mLastRecordedClockRealtime = 0;
}
public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
@@ -2554,18 +2537,6 @@
final long currentTime = System.currentTimeMillis();
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
- if (isStartClockTimeValid()) {
- // Has the time changed sufficiently that it is really worth recording?
- if (mLastRecordedClockTime != 0) {
- long expectedClockTime = mLastRecordedClockTime
- + (elapsedRealtime - mLastRecordedClockRealtime);
- if (currentTime >= (expectedClockTime-500)
- && currentTime <= (expectedClockTime+500)) {
- // Not sufficiently changed, skip!
- return;
- }
- }
- }
recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
if (isStartClockTimeValid()) {
mStartClockTime = currentTime;
@@ -2936,8 +2907,7 @@
public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
- int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime,
- long[] cpuSpeedTimes) {
+ int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime) {
if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
+ " user=" + statUserTime + " sys=" + statSystemTime
+ " io=" + statIOWaitTime + " irq=" + statIrqTime
@@ -2977,7 +2947,7 @@
remainSTtime -= mySTime;
num--;
Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
- proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes);
+ proc.addCpuTimeLocked(myUTime, mySTime);
}
}
}
@@ -2988,7 +2958,7 @@
Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
if (uid != null) {
Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
- proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes);
+ proc.addCpuTimeLocked(remainUTime, remainSTtime);
}
}
}
@@ -4416,6 +4386,10 @@
long mCurStepUserTime;
long mCurStepSystemTime;
+ LongSamplingCounter mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
+ LongSamplingCounter mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase);
+ LongSamplingCounter[] mSpeedBins;
+
/**
* The statistics we have collected for this uid's wake locks.
*/
@@ -4473,6 +4447,7 @@
mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
mWifiMulticastTimers, mOnBatteryTimeBase);
mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
+ mSpeedBins = new LongSamplingCounter[getCpuSpeedSteps()];
}
@Override
@@ -4943,6 +4918,26 @@
}
@Override
+ public long getUserCpuTimeUs(int which) {
+ return mUserCpuTime.getCountLocked(which);
+ }
+
+ @Override
+ public long getSystemCpuTimeUs(int which) {
+ return mSystemCpuTime.getCountLocked(which);
+ }
+
+ @Override
+ public long getTimeAtCpuSpeed(int step, int which) {
+ if (step >= 0 && step < mSpeedBins.length) {
+ if (mSpeedBins[step] != null) {
+ return mSpeedBins[step].getCountLocked(which);
+ }
+ }
+ return 0;
+ }
+
+ @Override
public long getWifiControllerActivity(int type, int which) {
if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
mWifiControllerTime[type] != null) {
@@ -5044,6 +5039,15 @@
}
}
+ mUserCpuTime.reset(false);
+ mSystemCpuTime.reset(false);
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ c.reset(false);
+ }
+ }
+
final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
for (int iw=wakeStats.size()-1; iw>=0; iw--) {
Wakelock wl = wakeStats.valueAt(iw);
@@ -5177,6 +5181,15 @@
}
}
mPids.clear();
+
+ mUserCpuTime.detach();
+ mSystemCpuTime.detach();
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ c.detach();
+ }
+ }
}
return !active;
@@ -5335,6 +5348,20 @@
out.writeInt(0);
}
}
+
+ mUserCpuTime.writeToParcel(out);
+ mSystemCpuTime.writeToParcel(out);
+
+ out.writeInt(mSpeedBins.length);
+ for (int i = 0; i < mSpeedBins.length; i++) {
+ LongSamplingCounter c = mSpeedBins[i];
+ if (c != null) {
+ out.writeInt(1);
+ c.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
}
void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
@@ -5500,6 +5527,18 @@
mBluetoothControllerTime[i] = null;
}
}
+
+ mUserCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ mSystemCpuTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+
+ int bins = in.readInt();
+ int steps = getCpuSpeedSteps();
+ mSpeedBins = new LongSamplingCounter[bins >= steps ? bins : steps];
+ for (int i = 0; i < bins; i++) {
+ if (in.readInt() != 0) {
+ mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+ }
+ }
}
/**
@@ -5780,14 +5819,11 @@
*/
int mProcessState = PROCESS_STATE_NONE;
- SamplingCounter[] mSpeedBins;
-
ArrayList<ExcessivePower> mExcessivePower;
Proc(String name) {
mName = name;
mOnBatteryTimeBase.add(this);
- mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
}
public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
@@ -5809,25 +5845,12 @@
mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- c.reset(false);
- }
- }
mExcessivePower = null;
}
void detach() {
mActive = false;
mOnBatteryTimeBase.remove(this);
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- mOnBatteryTimeBase.remove(c);
- mSpeedBins[i] = null;
- }
- }
}
public int countExcessivePowers() {
@@ -5921,18 +5944,6 @@
out.writeInt(mUnpluggedStarts);
out.writeInt(mUnpluggedNumCrashes);
out.writeInt(mUnpluggedNumAnrs);
-
- out.writeInt(mSpeedBins.length);
- for (int i = 0; i < mSpeedBins.length; i++) {
- SamplingCounter c = mSpeedBins[i];
- if (c != null) {
- out.writeInt(1);
- c.writeToParcel(out);
- } else {
- out.writeInt(0);
- }
- }
-
writeExcessivePowerToParcelLocked(out);
}
@@ -5955,39 +5966,12 @@
mUnpluggedStarts = in.readInt();
mUnpluggedNumCrashes = in.readInt();
mUnpluggedNumAnrs = in.readInt();
-
- int bins = in.readInt();
- int steps = getCpuSpeedSteps();
- mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
- for (int i = 0; i < bins; i++) {
- if (in.readInt() != 0) {
- mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
- }
- }
-
readExcessivePowerFromParcelLocked(in);
}
- public BatteryStatsImpl getBatteryStats() {
- return BatteryStatsImpl.this;
- }
-
- public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) {
+ public void addCpuTimeLocked(int utime, int stime) {
mUserTime += utime;
- mCurStepUserTime += utime;
mSystemTime += stime;
- mCurStepSystemTime += stime;
-
- for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) {
- long amt = speedStepBins[i];
- if (amt != 0) {
- SamplingCounter c = mSpeedBins[i];
- if (c == null) {
- mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
- }
- c.addCountAtomic(speedStepBins[i]);
- }
- }
}
public void addForegroundTimeLocked(long ttime) {
@@ -6076,16 +6060,6 @@
}
return val;
}
-
- @Override
- public long getTimeAtCpuSpeedStep(int speedStep, int which) {
- if (speedStep < mSpeedBins.length) {
- SamplingCounter c = mSpeedBins[speedStep];
- return c != null ? c.getCountLocked(which) : 0;
- } else {
- return 0;
- }
- }
}
/**
@@ -6833,7 +6807,7 @@
final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(memStream, "utf-8");
+ out.setOutput(memStream, StandardCharsets.UTF_8.name());
writeDailyItemsLocked(out);
BackgroundThread.getHandler().post(new Runnable() {
@Override
@@ -6919,7 +6893,7 @@
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
readDailyItemsLocked(parser);
} catch (XmlPullParserException e) {
} finally {
@@ -7747,7 +7721,7 @@
* @param info The energy information from the bluetooth controller.
*/
public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
- if (info != null && mOnBatteryInternal && false) {
+ if (info != null && mOnBatteryInternal) {
mHasBluetoothEnergyReporting = true;
mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
info.getControllerRxTimeMillis());
@@ -7803,6 +7777,32 @@
}
}
+ /**
+ * Read and distribute CPU usage across apps.
+ */
+ public void updateCpuTimeLocked(boolean firstTime) {
+ final int cpuSpeedSteps = getCpuSpeedSteps();
+ final long[] cpuSpeeds = mKernelCpuSpeedReader.readDelta();
+ KernelUidCpuTimeReader.Callback callback = null;
+ if (mOnBatteryInternal && !firstTime) {
+ callback = new KernelUidCpuTimeReader.Callback() {
+ @Override
+ public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
+ final Uid u = getUidStatsLocked(mapUid(uid));
+ u.mUserCpuTime.addCountLocked(userTimeUs);
+ u.mSystemCpuTime.addCountLocked(systemTimeUs);
+ for (int i = 0; i < cpuSpeedSteps; i++) {
+ if (u.mSpeedBins[i] == null) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ }
+ u.mSpeedBins[i].addCountLocked(cpuSpeeds[i]);
+ }
+ }
+ };
+ }
+ mKernelUidCpuTimeReader.readDelta(callback);
+ }
+
boolean setChargingLocked(boolean charging) {
if (mCharging != charging) {
mCharging = charging;
@@ -7941,8 +7941,6 @@
boolean reset) {
mRecordingHistory = true;
mHistoryCur.currentTime = System.currentTimeMillis();
- mLastRecordedClockTime = mHistoryCur.currentTime;
- mLastRecordedClockRealtime = elapsedRealtimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
mHistoryCur);
@@ -7956,8 +7954,6 @@
final long uptimeMs) {
if (mRecordingHistory) {
mHistoryCur.currentTime = currentTime;
- mLastRecordedClockTime = currentTime;
- mLastRecordedClockRealtime = elapsedRealtimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
mHistoryCur);
mHistoryCur.currentTime = 0;
@@ -7967,8 +7963,6 @@
private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
if (mRecordingHistory) {
mHistoryCur.currentTime = System.currentTimeMillis();
- mLastRecordedClockTime = mHistoryCur.currentTime;
- mLastRecordedClockRealtime = elapsedRealtimeMs;
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
mHistoryCur);
mHistoryCur.currentTime = 0;
@@ -8431,6 +8425,7 @@
* Remove the statistics object for a particular uid.
*/
public void removeUidStatsLocked(int uid) {
+ mKernelUidCpuTimeReader.removeUid(uid);
mUidStats.remove(uid);
}
@@ -8464,58 +8459,6 @@
return u.getServiceStatsLocked(pkg, name);
}
- /**
- * Massage data to distribute any reasonable work down to more specific
- * owners. Must only be called on a dead BatteryStats object!
- */
- public void distributeWorkLocked(int which) {
- // Aggregate all CPU time associated with WIFI.
- Uid wifiUid = mUidStats.get(Process.WIFI_UID);
- if (wifiUid != null) {
- long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
- for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) {
- Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip);
- long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
- for (int i=0; i<mUidStats.size(); i++) {
- Uid uid = mUidStats.valueAt(i);
- if (uid.mUid != Process.WIFI_UID) {
- long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
- if (uidRunningTime > 0) {
- Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
- long time = proc.getUserTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mUserTime += time;
- proc.mUserTime -= time;
- time = proc.getSystemTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mSystemTime += time;
- proc.mSystemTime -= time;
- time = proc.getForegroundTime(which);
- time = (time*uidRunningTime)/totalRunningTime;
- uidProc.mForegroundTime += time;
- proc.mForegroundTime -= time;
- for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
- SamplingCounter sc = proc.mSpeedBins[sb];
- if (sc != null) {
- time = sc.getCountLocked(which);
- time = (time*uidRunningTime)/totalRunningTime;
- SamplingCounter uidSc = uidProc.mSpeedBins[sb];
- if (uidSc == null) {
- uidSc = new SamplingCounter(mOnBatteryTimeBase);
- uidProc.mSpeedBins[sb] = uidSc;
- }
- uidSc.mCount.addAndGet((int)time);
- sc.mCount.addAndGet((int)-time);
- }
- }
- totalRunningTime -= uidRunningTime;
- }
- }
- }
- }
- }
- }
-
public void shutdownLocked() {
recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
writeSyncLocked();
@@ -8974,6 +8917,23 @@
u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
}
+ u.mUserCpuTime.readSummaryFromParcelLocked(in);
+ u.mSystemCpuTime.readSummaryFromParcelLocked(in);
+
+ int NSB = in.readInt();
+ if (NSB > 100) {
+ Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
+ return;
+ }
+
+ u.mSpeedBins = new LongSamplingCounter[NSB];
+ for (int i=0; i<NSB; i++) {
+ if (in.readInt() != 0) {
+ u.mSpeedBins[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+ u.mSpeedBins[i].readSummaryFromParcelLocked(in);
+ }
+ }
+
int NW = in.readInt();
if (NW > 100) {
Slog.w(TAG, "File corrupt: too many wake locks " + NW);
@@ -9031,18 +8991,6 @@
p.mStarts = p.mLoadedStarts = in.readInt();
p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
- int NSB = in.readInt();
- if (NSB > 100) {
- Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
- return;
- }
- p.mSpeedBins = new SamplingCounter[NSB];
- for (int i=0; i<NSB; i++) {
- if (in.readInt() != 0) {
- p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
- p.mSpeedBins[i].readSummaryFromParcelLocked(in);
- }
- }
if (!p.readExcessivePowerFromParcelLocked(in)) {
return;
}
@@ -9302,6 +9250,20 @@
u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
}
+ u.mUserCpuTime.writeSummaryFromParcelLocked(out);
+ u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
+
+ out.writeInt(u.mSpeedBins.length);
+ for (int i = 0; i < u.mSpeedBins.length; i++) {
+ LongSamplingCounter speedBin = u.mSpeedBins[i];
+ if (speedBin != null) {
+ out.writeInt(1);
+ speedBin.writeSummaryFromParcelLocked(out);
+ } else {
+ out.writeInt(0);
+ }
+ }
+
final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
int NW = wakeStats.size();
out.writeInt(NW);
@@ -9368,16 +9330,6 @@
out.writeInt(ps.mStarts);
out.writeInt(ps.mNumCrashes);
out.writeInt(ps.mNumAnrs);
- final int N = ps.mSpeedBins.length;
- out.writeInt(N);
- for (int i=0; i<N; i++) {
- if (ps.mSpeedBins[i] != null) {
- out.writeInt(1);
- ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
- } else {
- out.writeInt(0);
- }
- }
ps.writeExcessivePowerToParcelLocked(out);
}
diff --git a/core/java/com/android/internal/os/CpuPowerCalculator.java b/core/java/com/android/internal/os/CpuPowerCalculator.java
index 6c3f958..a3ef612 100644
--- a/core/java/com/android/internal/os/CpuPowerCalculator.java
+++ b/core/java/com/android/internal/os/CpuPowerCalculator.java
@@ -44,55 +44,57 @@
long rawUptimeUs, int statsType) {
final int speedSteps = mSpeedStepTimes.length;
+ long totalTimeAtSpeeds = 0;
+ for (int step = 0; step < speedSteps; step++) {
+ mSpeedStepTimes[step] = u.getTimeAtCpuSpeed(step, statsType);
+ totalTimeAtSpeeds += mSpeedStepTimes[step];
+ }
+ totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
+
+ app.cpuTimeMs = (u.getUserCpuTimeUs(statsType) + u.getSystemCpuTimeUs(statsType)) / 1000;
+ if (DEBUG && app.cpuTimeMs != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU time " + app.cpuTimeMs + " ms");
+ }
+
+ double cpuPowerMaMs = 0;
+ for (int step = 0; step < speedSteps; step++) {
+ final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
+ final double cpuSpeedStepPower = ratio * app.cpuTimeMs * mPowerCpuNormal[step];
+ if (DEBUG && ratio != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
+ + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
+ + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
+ }
+ cpuPowerMaMs += cpuSpeedStepPower;
+ }
+
+ if (DEBUG && cpuPowerMaMs != 0) {
+ Log.d(TAG, "UID " + u.getUid() + ": cpu total power="
+ + BatteryStatsHelper.makemAh(cpuPowerMaMs / (60 * 60 * 1000)));
+ }
+
// Keep track of the package with highest drain.
double highestDrain = 0;
+ app.cpuFgTimeMs = 0;
final ArrayMap<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
final int processStatsCount = processStats.size();
for (int i = 0; i < processStatsCount; i++) {
final BatteryStats.Uid.Proc ps = processStats.valueAt(i);
final String processName = processStats.keyAt(i);
-
app.cpuFgTimeMs += ps.getForegroundTime(statsType);
- final long totalCpuTime = ps.getUserTime(statsType) + ps.getSystemTime(statsType);
- app.cpuTimeMs += totalCpuTime;
- // Calculate the total CPU time spent at the various speed steps.
- long totalTimeAtSpeeds = 0;
- for (int step = 0; step < speedSteps; step++) {
- mSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, statsType);
- totalTimeAtSpeeds += mSpeedStepTimes[step];
- }
- totalTimeAtSpeeds = Math.max(totalTimeAtSpeeds, 1);
-
- // Then compute the ratio of time spent at each speed and figure out
- // the total power consumption.
- double cpuPower = 0;
- for (int step = 0; step < speedSteps; step++) {
- final double ratio = (double) mSpeedStepTimes[step] / totalTimeAtSpeeds;
- final double cpuSpeedStepPower = ratio * totalCpuTime * mPowerCpuNormal[step];
- if (DEBUG && ratio != 0) {
- Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
- + step + " ratio=" + BatteryStatsHelper.makemAh(ratio) + " power="
- + BatteryStatsHelper.makemAh(cpuSpeedStepPower / (60 * 60 * 1000)));
- }
- cpuPower += cpuSpeedStepPower;
- }
-
- if (DEBUG && cpuPower != 0) {
- Log.d(TAG, String.format("process %s, cpu power=%s",
- processName, BatteryStatsHelper.makemAh(cpuPower / (60 * 60 * 1000))));
- }
- app.cpuPowerMah += cpuPower;
+ final long costValue = ps.getUserTime(statsType) + ps.getSystemTime(statsType)
+ + ps.getForegroundTime(statsType);
// Each App can have multiple packages and with multiple running processes.
// Keep track of the package who's process has the highest drain.
if (app.packageWithHighestDrain == null ||
app.packageWithHighestDrain.startsWith("*")) {
- highestDrain = cpuPower;
+ highestDrain = costValue;
app.packageWithHighestDrain = processName;
- } else if (highestDrain < cpuPower && !processName.startsWith("*")) {
- highestDrain = cpuPower;
+ } else if (highestDrain < costValue && !processName.startsWith("*")) {
+ highestDrain = costValue;
app.packageWithHighestDrain = processName;
}
}
@@ -108,6 +110,6 @@
}
// Convert the CPU power to mAh
- app.cpuPowerMah /= (60 * 60 * 1000);
+ app.cpuPowerMah = cpuPowerMaMs / (60 * 60 * 1000);
}
}
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
new file mode 100644
index 0000000..c30df28
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -0,0 +1,69 @@
+/*
+ * 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.internal.os;
+
+import android.text.TextUtils;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Reads CPU time spent at various frequencies and provides a delta from the last call to
+ * {@link #readDelta}. Each line in the proc file has the format:
+ *
+ * freq time
+ *
+ * where time is measured in 1/100 seconds.
+ */
+public class KernelCpuSpeedReader {
+ private static final String TAG = "KernelCpuSpeedReader";
+ private static final String sProcFile =
+ "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state";
+ private static final int MAX_SPEEDS = 60;
+
+ private long[] mLastSpeedTimes = new long[MAX_SPEEDS];
+ private long[] mDeltaSpeedTimes = new long[MAX_SPEEDS];
+
+ /**
+ * The returned array is modified in subsequent calls to {@link #readDelta}.
+ * @return The time (in milliseconds) spent at different cpu speeds since the last call to
+ * {@link #readDelta}.
+ */
+ public long[] readDelta() {
+ try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
+ String line;
+ int speedIndex = 0;
+ while ((line = reader.readLine()) != null) {
+ splitter.setString(line);
+ Long.parseLong(splitter.next());
+
+ // The proc file reports time in 1/100 sec, so convert to milliseconds.
+ long time = Long.parseLong(splitter.next()) * 10;
+ mDeltaSpeedTimes[speedIndex] = time - mLastSpeedTimes[speedIndex];
+ mLastSpeedTimes[speedIndex] = time;
+ speedIndex++;
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read cpu-freq", e);
+ Arrays.fill(mDeltaSpeedTimes, 0);
+ }
+ return mDeltaSpeedTimes;
+ }
+}
diff --git a/core/java/com/android/internal/os/KernelUidCpuTimeReader.java b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
new file mode 100644
index 0000000..b236378
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelUidCpuTimeReader.java
@@ -0,0 +1,115 @@
+/*
+ * 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.internal.os;
+
+import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.util.SparseLongArray;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+
+/**
+ * Reads /proc/uid_cputime/show_uid_stat which has the line format:
+ *
+ * uid: user_time_micro_seconds system_time_micro_seconds
+ *
+ * This provides the time a UID's processes spent executing in user-space and kernel-space.
+ * The file contains a monotonically increasing count of time for a single boot. This class
+ * maintains the previous results of a call to {@link #readDelta} in order to provide a proper
+ * delta.
+ */
+public class KernelUidCpuTimeReader {
+ private static final String TAG = "KernelUidCpuTimeReader";
+ private static final String sProcFile = "/proc/uid_cputime/show_uid_stat";
+ private static final String sRemoveUidProcFile = "/proc/uid_cputime/remove_uid_range";
+
+ /**
+ * Callback interface for processing each line of the proc file.
+ */
+ public interface Callback {
+ void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs);
+ }
+
+ private SparseLongArray mLastUserTimeUs = new SparseLongArray();
+ private SparseLongArray mLastSystemTimeUs = new SparseLongArray();
+
+ /**
+ * Reads the proc file, calling into the callback with a delta of time for each UID.
+ * @param callback The callback to invoke for each line of the proc file. If null,
+ * the data is consumed and subsequent calls to readDelta will provide
+ * a fresh delta.
+ */
+ public void readDelta(@Nullable Callback callback) {
+ try (BufferedReader reader = new BufferedReader(new FileReader(sProcFile))) {
+ TextUtils.SimpleStringSplitter splitter = new TextUtils.SimpleStringSplitter(' ');
+ String line;
+ while ((line = reader.readLine()) != null) {
+ splitter.setString(line);
+ final String uidStr = splitter.next();
+ final int uid = Integer.parseInt(uidStr.substring(0, uidStr.length() - 1), 10);
+ final long userTimeUs = Long.parseLong(splitter.next(), 10);
+ final long systemTimeUs = Long.parseLong(splitter.next(), 10);
+
+ if (callback != null) {
+ long userTimeDeltaUs = userTimeUs;
+ long systemTimeDeltaUs = systemTimeUs;
+ int index = mLastUserTimeUs.indexOfKey(uid);
+ if (index >= 0) {
+ userTimeDeltaUs -= mLastUserTimeUs.valueAt(index);
+ systemTimeDeltaUs -= mLastSystemTimeUs.valueAt(index);
+
+ if (userTimeDeltaUs < 0 || systemTimeDeltaUs < 0) {
+ // The UID must have been removed from accounting, then added back.
+ userTimeDeltaUs = userTimeUs;
+ systemTimeDeltaUs = systemTimeUs;
+ }
+ }
+
+ if (userTimeDeltaUs != 0 || systemTimeDeltaUs != 0) {
+ callback.onUidCpuTime(uid, userTimeDeltaUs, systemTimeDeltaUs);
+ }
+ }
+ mLastUserTimeUs.put(uid, userTimeUs);
+ mLastSystemTimeUs.put(uid, systemTimeUs);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to read uid_cputime", e);
+ }
+ }
+
+ /**
+ * Removes the UID from the kernel module and from internal accounting data.
+ * @param uid The UID to remove.
+ */
+ public void removeUid(int uid) {
+ int index = mLastUserTimeUs.indexOfKey(uid);
+ if (index >= 0) {
+ mLastUserTimeUs.removeAt(index);
+ mLastSystemTimeUs.removeAt(index);
+ }
+
+ try (FileWriter writer = new FileWriter(sRemoveUidProcFile)) {
+ writer.write(Integer.toString(uid) + "-" + Integer.toString(uid));
+ writer.flush();
+ } catch (IOException e) {
+ Slog.e(TAG, "failed to remove uid from uid_cputime module", e);
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 2983047..8393e2a 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -170,21 +170,6 @@
private byte[] mBuffer = new byte[4096];
- /**
- * The time in microseconds that the CPU has been running at each speed.
- */
- private long[] mCpuSpeedTimes;
-
- /**
- * The relative time in microseconds that the CPU has been running at each speed.
- */
- private long[] mRelCpuSpeedTimes;
-
- /**
- * The different speeds that the CPU can be running at.
- */
- private long[] mCpuSpeeds;
-
public static class Stats {
public final int pid;
public final int uid;
@@ -590,70 +575,6 @@
}
}
- /**
- * Returns the delta time (in clock ticks, or 1/100 sec) spent at each CPU
- * speed, since the last call to this method. If this is the first call, it
- * will return 1 for each value.
- */
- public long[] getLastCpuSpeedTimes() {
- if (mCpuSpeedTimes == null) {
- mCpuSpeedTimes = getCpuSpeedTimes(null);
- mRelCpuSpeedTimes = new long[mCpuSpeedTimes.length];
- for (int i = 0; i < mCpuSpeedTimes.length; i++) {
- mRelCpuSpeedTimes[i] = 1; // Initialize
- }
- } else {
- getCpuSpeedTimes(mRelCpuSpeedTimes);
- for (int i = 0; i < mCpuSpeedTimes.length; i++) {
- long temp = mRelCpuSpeedTimes[i];
- mRelCpuSpeedTimes[i] -= mCpuSpeedTimes[i];
- mCpuSpeedTimes[i] = temp;
- }
- }
- return mRelCpuSpeedTimes;
- }
-
- private long[] getCpuSpeedTimes(long[] out) {
- long[] tempTimes = out;
- long[] tempSpeeds = mCpuSpeeds;
- final int MAX_SPEEDS = 60;
- if (out == null) {
- tempTimes = new long[MAX_SPEEDS]; // Hopefully no more than that
- tempSpeeds = new long[MAX_SPEEDS];
- }
- int speed = 0;
- String file = readFile("/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state", '\0');
- // Note: file may be null on kernels without cpufreq (i.e. the emulator's)
- if (file != null) {
- StringTokenizer st = new StringTokenizer(file, "\n ");
- while (st.hasMoreElements()) {
- String token = st.nextToken();
- try {
- long val = Long.parseLong(token);
- tempSpeeds[speed] = val;
- token = st.nextToken();
- val = Long.parseLong(token);
- tempTimes[speed] = val;
- speed++;
- if (speed == MAX_SPEEDS) break; // No more
- if (localLOGV && out == null) {
- Slog.v(TAG, "First time : Speed/Time = " + tempSpeeds[speed - 1]
- + "\t" + tempTimes[speed - 1]);
- }
- } catch (NumberFormatException nfe) {
- Slog.i(TAG, "Unable to parse time_in_state");
- }
- }
- }
- if (out == null) {
- out = new long[speed];
- mCpuSpeeds = new long[speed];
- System.arraycopy(tempSpeeds, 0, mCpuSpeeds, 0, speed);
- System.arraycopy(tempTimes, 0, out, 0, speed);
- }
- return out;
- }
-
final public int getLastUserTime() {
return mRelUserTime;
}
diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
deleted file mode 100644
index 280e4d5..0000000
--- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.policy;
-
-import android.os.IBinder;
-
-/** {@hide} */
-oneway interface IFaceLockCallback {
- void unlock();
- void cancel();
- void reportFailedAttempt();
- void pokeWakelock(int millis);
-}
diff --git a/core/java/com/android/internal/policy/IFaceLockInterface.aidl b/core/java/com/android/internal/policy/IFaceLockInterface.aidl
deleted file mode 100644
index bc1f002..0000000
--- a/core/java/com/android/internal/policy/IFaceLockInterface.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.policy;
-
-import android.os.IBinder;
-import com.android.internal.policy.IFaceLockCallback;
-
-/** {@hide} */
-interface IFaceLockInterface {
- void startUi(IBinder containingWindowToken, int x, int y, int width, int height,
- boolean useLiveliness);
- void stopUi();
- void startWithoutUi();
- void registerCallback(IFaceLockCallback cb);
- void unregisterCallback(IFaceLockCallback cb);
-}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index a578a6e..bc64373 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3376,9 +3376,8 @@
mFloatingActionMode.finish();
}
cleanupFloatingActionModeViews();
- mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this);
- final FloatingActionMode mode = new FloatingActionMode(
- mContext, callback, originatingView, mFloatingToolbar);
+ final FloatingActionMode mode =
+ new FloatingActionMode(mContext, callback, originatingView);
mFloatingActionModeOriginatingView = originatingView;
mFloatingToolbarPreDrawListener =
new OnPreDrawListener() {
@@ -3393,6 +3392,8 @@
private void setHandledFloatingActionMode(ActionMode mode) {
mFloatingActionMode = mode;
+ mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this);
+ ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar);
mFloatingActionMode.invalidate();
mFloatingToolbar.show();
mFloatingActionModeOriginatingView.getViewTreeObserver()
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index e0792cb..4693d4b 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -16,40 +16,46 @@
package com.android.internal.statusbar;
+import android.graphics.drawable.Icon;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
public class StatusBarIcon implements Parcelable {
- public String iconPackage;
public UserHandle user;
- public int iconId;
+ public Icon icon;
public int iconLevel;
public boolean visible = true;
public int number;
public CharSequence contentDescription;
- public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number,
+ public StatusBarIcon(UserHandle user, Icon icon, int iconLevel, int number,
CharSequence contentDescription) {
- this.iconPackage = iconPackage;
this.user = user;
- this.iconId = iconId;
+ this.icon = icon;
this.iconLevel = iconLevel;
this.number = number;
this.contentDescription = contentDescription;
}
+ public StatusBarIcon(String iconPackage, UserHandle user,
+ int iconId, int iconLevel, int number,
+ CharSequence contentDescription) {
+ this(user, Icon.createWithResource(iconPackage, iconId),
+ iconLevel, number, contentDescription);
+ }
+
@Override
public String toString() {
- return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier()
- + " id=0x" + Integer.toHexString(this.iconId)
+ return "StatusBarIcon(icon=" + this.icon
+ + " user=" + user.getIdentifier()
+ " level=" + this.iconLevel + " visible=" + visible
+ " num=" + this.number + " )";
}
@Override
public StatusBarIcon clone() {
- StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId,
+ StatusBarIcon that = new StatusBarIcon(this.user, this.icon,
this.iconLevel, this.number, this.contentDescription);
that.visible = this.visible;
return that;
@@ -63,9 +69,8 @@
}
public void readFromParcel(Parcel in) {
- this.iconPackage = in.readString();
+ this.icon = (Icon) in.readParcelable(null);
this.user = (UserHandle) in.readParcelable(null);
- this.iconId = in.readInt();
this.iconLevel = in.readInt();
this.visible = in.readInt() != 0;
this.number = in.readInt();
@@ -73,9 +78,8 @@
}
public void writeToParcel(Parcel out, int flags) {
- out.writeString(this.iconPackage);
+ out.writeParcelable(this.icon, 0);
out.writeParcelable(this.user, 0);
- out.writeInt(this.iconId);
out.writeInt(this.iconLevel);
out.writeInt(this.visible ? 1 : 0);
out.writeInt(this.number);
diff --git a/core/java/com/android/internal/util/ImageUtils.java b/core/java/com/android/internal/util/ImageUtils.java
index a0d0b20..7d56e9e 100644
--- a/core/java/com/android/internal/util/ImageUtils.java
+++ b/core/java/com/android/internal/util/ImageUtils.java
@@ -66,7 +66,7 @@
COMPACT_BITMAP_SIZE, COMPACT_BITMAP_SIZE, Bitmap.Config.ARGB_8888
);
mTempCompactBitmapCanvas = new Canvas(mTempCompactBitmap);
- mTempCompactBitmapPaint = new Paint();
+ mTempCompactBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTempCompactBitmapPaint.setFilterBitmap(true);
}
mTempMatrix.reset();
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 3249ea3..60769734 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -24,6 +24,7 @@
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.graphics.drawable.VectorDrawable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -129,6 +130,20 @@
}
}
+ public boolean isGrayscaleIcon(Context context, Icon icon) {
+ if (icon == null) {
+ return false;
+ }
+ switch (icon.getType()) {
+ case Icon.TYPE_BITMAP:
+ return isGrayscaleIcon(icon.getBitmap());
+ case Icon.TYPE_RESOURCE:
+ return isGrayscaleIcon(context, icon.getResId());
+ default:
+ return false;
+ }
+ }
+
/**
* Checks whether a drawable with a resoure id is a small grayscale icon.
* Grayscale here means "very close to a perfect gray"; icon means "no larger than 64dp".
diff --git a/core/java/com/android/internal/util/XmlUtils.java b/core/java/com/android/internal/util/XmlUtils.java
index 0350d61..32746c2 100644
--- a/core/java/com/android/internal/util/XmlUtils.java
+++ b/core/java/com/android/internal/util/XmlUtils.java
@@ -33,6 +33,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ProtocolException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -182,7 +183,7 @@
public static final void writeMapXml(Map val, OutputStream out)
throws XmlPullParserException, java.io.IOException {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
writeMapXml(val, null, serializer);
@@ -205,7 +206,7 @@
throws XmlPullParserException, java.io.IOException
{
XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
writeListXml(val, null, serializer);
@@ -732,7 +733,7 @@
throws XmlPullParserException, java.io.IOException
{
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(in, null);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
return (HashMap<String, ?>) readValueXml(parser, new String[1]);
}
@@ -753,7 +754,7 @@
throws XmlPullParserException, java.io.IOException
{
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(in, null);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
return (ArrayList)readValueXml(parser, new String[1]);
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 993ab58..e27ba13 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -100,7 +100,11 @@
}
@Override
- public void doneAnimating() {
+ public void onAnimationStarted(int remainingFrameCount) {
+ }
+
+ @Override
+ public void onAnimationStopped() {
}
@Override
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index aacdb34..c3f4da7 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -24,6 +24,7 @@
import android.view.MenuItem;
import android.view.View;
+import com.android.internal.util.Preconditions;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.FloatingToolbar;
@@ -32,20 +33,28 @@
private final Context mContext;
private final ActionMode.Callback2 mCallback;
private final MenuBuilder mMenu;
- private final FloatingToolbar mFloatingToolbar;
private final Rect mContentRect;
private final Rect mContentRectOnWindow;
private final Rect mPreviousContentRectOnWindow;
private final int[] mViewPosition;
private final View mOriginatingView;
+ private FloatingToolbar mFloatingToolbar;
public FloatingActionMode(
- Context context, ActionMode.Callback2 callback, View originatingView,
- FloatingToolbar floatingToolbar) {
+ Context context, ActionMode.Callback2 callback, View originatingView) {
mContext = context;
mCallback = callback;
mMenu = new MenuBuilder(context).setDefaultShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ setType(ActionMode.TYPE_FLOATING);
+ mContentRect = new Rect();
+ mContentRectOnWindow = new Rect();
+ mPreviousContentRectOnWindow = new Rect();
+ mViewPosition = new int[2];
+ mOriginatingView = originatingView;
+ }
+
+ public void setFloatingToolbar(FloatingToolbar floatingToolbar) {
mFloatingToolbar = floatingToolbar
.setMenu(mMenu)
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@@ -54,12 +63,6 @@
return mCallback.onActionItemClicked(FloatingActionMode.this, item);
}
});
- setType(ActionMode.TYPE_FLOATING);
- mContentRect = new Rect();
- mContentRectOnWindow = new Rect();
- mPreviousContentRectOnWindow = new Rect();
- mViewPosition = new int[2];
- mOriginatingView = originatingView;
}
@Override
@@ -79,6 +82,7 @@
@Override
public void invalidate() {
+ Preconditions.checkNotNull(mFloatingToolbar);
mCallback.onPrepareActionMode(this, mMenu);
mFloatingToolbar.updateLayout();
invalidateContentRect();
@@ -86,11 +90,13 @@
@Override
public void invalidateContentRect() {
+ Preconditions.checkNotNull(mFloatingToolbar);
mCallback.onGetContentRect(this, mOriginatingView, mContentRect);
repositionToolbar();
}
public void updateViewLocationInWindow() {
+ Preconditions.checkNotNull(mFloatingToolbar);
mOriginatingView.getLocationInWindow(mViewPosition);
repositionToolbar();
}
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
new file mode 100644
index 0000000..ac0f5fe
--- /dev/null
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -0,0 +1,146 @@
+package com.android.internal.widget;
+
+import android.os.AsyncTask;
+
+import java.util.List;
+
+/**
+ * Helper class to check/verify PIN/Password/Pattern asynchronously.
+ */
+public final class LockPatternChecker {
+ /**
+ * Interface for a callback to be invoked after security check.
+ */
+ public interface OnCheckCallback {
+ /**
+ * Invoked when a security check is finished.
+ *
+ * @param matched Whether the PIN/Password/Pattern matches the stored one.
+ */
+ void onChecked(boolean matched);
+ }
+
+ /**
+ * Interface for a callback to be invoked after security verification.
+ */
+ public interface OnVerifyCallback {
+ /**
+ * Invoked when a security verification is finished.
+ *
+ * @param attestation The attestation that the challenge was verified, or null.
+ */
+ void onVerified(byte[] attestation);
+ }
+
+ /**
+ * Verify a pattern asynchronously.
+ *
+ * @param utils The LockPatternUtils instance to use.
+ * @param pattern The pattern to check.
+ * @param challenge The challenge to verify against the pattern.
+ * @param userId The user to check against the pattern.
+ * @param callback The callback to be invoked with the verification result.
+ */
+ public static AsyncTask<?, ?, ?> verifyPattern(final LockPatternUtils utils,
+ final List<LockPatternView.Cell> pattern,
+ final long challenge,
+ final int userId,
+ final OnVerifyCallback callback) {
+ AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
+ @Override
+ protected byte[] doInBackground(Void... args) {
+ return utils.verifyPattern(pattern, challenge, userId);
+ }
+
+ @Override
+ protected void onPostExecute(byte[] result) {
+ callback.onVerified(result);
+ }
+ };
+ task.execute();
+ return task;
+ }
+
+ /**
+ * Checks a pattern asynchronously.
+ *
+ * @param utils The LockPatternUtils instance to use.
+ * @param pattern The pattern to check.
+ * @param userId The user to check against the pattern.
+ * @param callback The callback to be invoked with the check result.
+ */
+ public static AsyncTask<?, ?, ?> checkPattern(final LockPatternUtils utils,
+ final List<LockPatternView.Cell> pattern,
+ final int userId,
+ final OnCheckCallback callback) {
+ AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... args) {
+ return utils.checkPattern(pattern, userId);
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ callback.onChecked(result);
+ }
+ };
+ task.execute();
+ return task;
+ }
+
+ /**
+ * Verify a password asynchronously.
+ *
+ * @param utils The LockPatternUtils instance to use.
+ * @param password The password to check.
+ * @param challenge The challenge to verify against the pattern.
+ * @param userId The user to check against the pattern.
+ * @param callback The callback to be invoked with the verification result.
+ */
+ public static AsyncTask<?, ?, ?> verifyPassword(final LockPatternUtils utils,
+ final String password,
+ final long challenge,
+ final int userId,
+ final OnVerifyCallback callback) {
+ AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() {
+ @Override
+ protected byte[] doInBackground(Void... args) {
+ return utils.verifyPassword(password, challenge, userId);
+ }
+
+ @Override
+ protected void onPostExecute(byte[] result) {
+ callback.onVerified(result);
+ }
+ };
+ task.execute();
+ return task;
+ }
+
+ /**
+ * Checks a password asynchronously.
+ *
+ * @param utils The LockPatternUtils instance to use.
+ * @param password The password to check.
+ * @param userId The user to check against the pattern.
+ * @param callback The callback to be invoked with the check result.
+ */
+ public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils,
+ final String password,
+ final int userId,
+ final OnCheckCallback callback) {
+ AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
+ @Override
+ protected Boolean doInBackground(Void... args) {
+ return utils.checkPassword(password, userId);
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ callback.onChecked(result);
+ }
+ };
+ task.execute();
+ return task;
+ }
+}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3d23986..e5ef60c 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1097,8 +1097,11 @@
Log.w(TAG, "Only device owner may call setCredentialRequiredForDecrypt()");
return;
}
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0);
+
+ if (isDeviceEncryptionEnabled()){
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT, required ? 1 : 0);
+ }
}
private boolean isDoNotAskCredentialsOnBootSet() {
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 01e835b..be727f1 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -661,13 +661,20 @@
}
}
+ final int oldCollapsibleHeight = mCollapsibleHeight;
mCollapsibleHeight = Math.max(0,
heightUsed - alwaysShowHeight - getMaxCollapsedHeight());
mUncollapsibleHeight = heightUsed - mCollapsibleHeight;
if (isLaidOut()) {
final boolean isCollapsedOld = mCollapseOffset != 0;
- mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
+ if (oldCollapsibleHeight < mCollapsibleHeight
+ && mCollapseOffset == oldCollapsibleHeight) {
+ // Stay closed even at the new height.
+ mCollapseOffset = mCollapsibleHeight;
+ } else {
+ mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
+ }
final boolean isCollapsedNew = mCollapseOffset != 0;
if (isCollapsedOld != isCollapsedNew) {
notifyViewAccessibilityStateChangedIfNeeded(
diff --git a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java
index 4d53d40..250932b 100644
--- a/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java
+++ b/core/java/org/apache/http/conn/ssl/SSLSocketFactory.java
@@ -329,6 +329,14 @@
sslsock.setSoTimeout(soTimeout);
try {
+ // BEGIN android-added
+ /*
+ * Make sure we have started the handshake before verifying.
+ * Otherwise when we go to the hostname verifier, it directly calls
+ * SSLSocket#getSession() which swallows SSL handshake errors.
+ */
+ sslsock.startHandshake();
+ // END android-added
hostnameVerifier.verify(host, sslsock);
// verifyHostName() didn't blowup - good!
} catch (IOException iox) {
@@ -389,6 +397,14 @@
port,
autoClose
);
+ // BEGIN android-added
+ /*
+ * Make sure we have started the handshake before verifying.
+ * Otherwise when we go to the hostname verifier, it directly calls
+ * SSLSocket#getSession() which swallows SSL handshake errors.
+ */
+ sslSocket.startHandshake();
+ // END android-added
hostnameVerifier.verify(host, sslSocket);
// verifyHostName() didn't blowup - good!
return sslSocket;
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 348b0ec..e69f64e 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -102,8 +102,8 @@
canvas->translate(bounds.fLeft, bounds.fTop);
canvas->scale(scale, scale);
- bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
- bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
+ bounds.fRight = (bounds.fRight-bounds.fLeft) / scale;
+ bounds.fBottom = (bounds.fBottom-bounds.fTop) / scale;
bounds.fLeft = bounds.fTop = 0;
ALOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d",
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 26ce967..323f832 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -94,8 +94,7 @@
SkScalar spaceRemaining = boundsLimit - startingPoint;
SkScalar stretchySpaceRemaining =
spaceRemaining - SkIntToScalar(numFixedPixelsRemaining);
- return SkScalarMulDiv(srcSpace, stretchySpaceRemaining,
- numStrechyPixelsRemaining);
+ return srcSpace * stretchySpaceRemaining / numStrechyPixelsRemaining;
}
void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds,
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 35d69fe..08d61d5 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -341,6 +341,12 @@
surfaceTexture->abandon();
}
+static jboolean SurfaceTexture_isReleased(JNIEnv* env, jobject thiz)
+{
+ sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ return surfaceTexture->isAbandoned();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceTextureMethods[] = {
@@ -355,6 +361,7 @@
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
{"nativeRelease", "()V", (void*)SurfaceTexture_release },
+ {"nativeIsReleased", "()Z", (void*)SurfaceTexture_isReleased },
};
int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index bce2b33..40029bb 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -150,7 +150,105 @@
return result;
}
-template<class JArray, class T>
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jint mode) {
+ _env->ReleaseByteArrayElements(array, data, mode);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jint mode) {
+ _env->ReleaseBooleanArrayElements(array, data, mode);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jint mode) {
+ _env->ReleaseCharArrayElements(array, data, mode);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jint mode) {
+ _env->ReleaseShortArrayElements(array, data, mode);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jint mode) {
+ _env->ReleaseIntArrayElements(array, data, mode);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jint mode) {
+ _env->ReleaseLongArrayElements(array, data, mode);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jint mode) {
+ _env->ReleaseFloatArrayElements(array, data, mode);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jint mode) {
+ _env->ReleaseDoubleArrayElements(array, data, mode);
+ }
+};
+
+template<class JArray, class T, class ArrayGetter, class ArrayReleaser>
class ArrayHelper {
public:
ArrayHelper(JNIEnv* env, JArray ref, jint offset, jint minSize) {
@@ -164,7 +262,7 @@
~ArrayHelper() {
if (mBase) {
- mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
+ ArrayReleaser::Release(mEnv, mRef, mBase, mReleaseParam);
}
}
@@ -195,7 +293,7 @@
// Bind the array.
void bind() {
- mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
+ mBase = (T*) ArrayGetter::Get(mEnv, mRef, (jboolean *) 0);
mData = mBase + mOffset;
}
@@ -215,10 +313,10 @@
int mReleaseParam;
};
-typedef ArrayHelper<jfloatArray, float> FloatArrayHelper;
-typedef ArrayHelper<jcharArray, unsigned short> UnsignedShortArrayHelper;
-typedef ArrayHelper<jintArray, int> IntArrayHelper;
-typedef ArrayHelper<jbyteArray, unsigned char> ByteArrayHelper;
+typedef ArrayHelper<jfloatArray, float, FloatArrayGetter, FloatArrayReleaser> FloatArrayHelper;
+typedef ArrayHelper<jcharArray, unsigned short, CharArrayGetter, CharArrayReleaser> UnsignedShortArrayHelper;
+typedef ArrayHelper<jintArray, int, IntArrayGetter, IntArrayReleaser> IntArrayHelper;
+typedef ArrayHelper<jbyteArray, unsigned char, ByteArrayGetter, ByteArrayReleaser> ByteArrayHelper;
inline float distance2(float x, float y, float z) {
return x * x + y * y + z * z;
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 5548476..2229071 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1358,7 +1358,7 @@
uint32_t dimensionLimit = 128; // Smallest image dimension crop margin from.
if (imageWidth >= dimensionLimit && imageHeight >= dimensionLimit) {
uint32_t defaultCropOrigin[] = {margin, margin};
- uint32_t defaultCropSize[] = {imageWidth - margin, imageHeight - margin};
+ uint32_t defaultCropSize[] = {imageWidth - 2 * margin, imageHeight - 2 * margin};
BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPORIGIN, 2, defaultCropOrigin,
TIFF_IFD_0), env, TAG_DEFAULTCROPORIGIN, writer);
BAIL_IF_INVALID(writer->addEntry(TAG_DEFAULTCROPSIZE, 2, defaultCropSize,
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index aeb058bc9..daafd5e 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -702,18 +702,40 @@
return;
}
- PlaybackParams pbs;
- pbs.fillFromJobject(env, gPlaybackParamsFields, params);
+ PlaybackParams pbp;
+ pbp.fillFromJobject(env, gPlaybackParamsFields, params);
ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u",
- pbs.speedSet, pbs.audioRate.mSpeed,
- pbs.pitchSet, pbs.audioRate.mPitch,
- pbs.audioFallbackModeSet, pbs.audioRate.mFallbackMode,
- pbs.audioStretchModeSet, pbs.audioRate.mStretchMode);
+ pbp.speedSet, pbp.audioRate.mSpeed,
+ pbp.pitchSet, pbp.audioRate.mPitch,
+ pbp.audioFallbackModeSet, pbp.audioRate.mFallbackMode,
+ pbp.audioStretchModeSet, pbp.audioRate.mStretchMode);
- if (lpTrack->setPlaybackRate(pbs.audioRate) != OK) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "arguments out of range");
+ // to simulate partially set params, we do a read-modify-write.
+ // TODO: pass in the valid set mask into AudioTrack.
+ AudioPlaybackRate rate = lpTrack->getPlaybackRate();
+ bool updatedRate = false;
+ if (pbp.speedSet) {
+ rate.mSpeed = pbp.audioRate.mSpeed;
+ updatedRate = true;
+ }
+ if (pbp.pitchSet) {
+ rate.mPitch = pbp.audioRate.mPitch;
+ updatedRate = true;
+ }
+ if (pbp.audioFallbackModeSet) {
+ rate.mFallbackMode = pbp.audioRate.mFallbackMode;
+ updatedRate = true;
+ }
+ if (pbp.audioStretchModeSet) {
+ rate.mStretchMode = pbp.audioRate.mStretchMode;
+ updatedRate = true;
+ }
+ if (updatedRate) {
+ if (lpTrack->setPlaybackRate(rate) != OK) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "arguments out of range");
+ }
}
}
diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp
index 36f7963..9f5b3bc 100644
--- a/core/jni/android_opengl_EGL14.cpp
+++ b/core/jni/android_opengl_EGL14.cpp
@@ -204,7 +204,7 @@
goto exit;
}
major_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(major_ref, (jboolean *)0);
+ _env->GetIntArrayElements(major_ref, (jboolean *)0);
major = major_base + majorOffset;
if (!minor_ref) {
@@ -227,7 +227,7 @@
goto exit;
}
minor_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(minor_ref, (jboolean *)0);
+ _env->GetIntArrayElements(minor_ref, (jboolean *)0);
minor = minor_base + minorOffset;
_returnValue = eglInitialize(
@@ -238,11 +238,11 @@
exit:
if (minor_base) {
- _env->ReleasePrimitiveArrayCritical(minor_ref, minor_base,
+ _env->ReleaseIntArrayElements(minor_ref, (jint*)minor_base,
_exception ? JNI_ABORT: 0);
}
if (major_base) {
- _env->ReleasePrimitiveArrayCritical(major_ref, major_base,
+ _env->ReleaseIntArrayElements(major_ref, (jint*)major_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -324,7 +324,7 @@
}
_num_configRemaining = _env->GetArrayLength(num_config_ref) - num_configOffset;
num_config_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+ _env->GetIntArrayElements(num_config_ref, (jboolean *)0);
num_config = num_config_base + num_configOffset;
_returnValue = eglGetConfigs(
@@ -336,7 +336,7 @@
exit:
if (num_config_base) {
- _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+ _env->ReleaseIntArrayElements(num_config_ref, (jint*)num_config_base,
_exception ? JNI_ABORT: 0);
}
if (configs) {
@@ -385,7 +385,7 @@
}
_attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - attrib_listOffset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + attrib_listOffset;
attrib_list_sentinel = false;
for (int i = _attrib_listRemaining - 1; i >= 0; i--) {
@@ -442,7 +442,7 @@
goto exit;
}
num_config_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(num_config_ref, (jboolean *)0);
+ _env->GetIntArrayElements(num_config_ref, (jboolean *)0);
num_config = num_config_base + num_configOffset;
_returnValue = eglChooseConfig(
@@ -455,11 +455,11 @@
exit:
if (num_config_base) {
- _env->ReleasePrimitiveArrayCritical(num_config_ref, num_config_base,
+ _env->ReleaseIntArrayElements(num_config_ref, (jint*)num_config_base,
_exception ? JNI_ABORT: 0);
}
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
JNI_ABORT);
}
if (configs) {
@@ -509,7 +509,7 @@
goto exit;
}
value_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
_returnValue = eglGetConfigAttrib(
@@ -521,7 +521,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -573,7 +573,7 @@
_remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
attrib_list_sentinel = 0;
for (int i = _remaining - 1; i >= 0; i--) {
@@ -598,7 +598,7 @@
exit:
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
JNI_ABORT);
}
if (_exception) {
@@ -655,7 +655,7 @@
_remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
attrib_list_sentinel = 0;
for (int i = _remaining - 1; i >= 0; i--) {
@@ -680,7 +680,7 @@
exit:
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
JNI_ABORT);
}
if (_exception) {
@@ -717,7 +717,7 @@
}
_remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
attrib_list_sentinel = false;
for (int i = _remaining - 1; i >= 0; i--) {
@@ -741,7 +741,7 @@
exit:
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
JNI_ABORT);
}
if (_exception) {
@@ -808,7 +808,7 @@
goto exit;
}
value_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
_returnValue = eglQuerySurface(
@@ -820,7 +820,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -896,7 +896,7 @@
}
_remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
attrib_list_sentinel = false;
for (int i = _remaining - 1; i >= 0; i--) {
@@ -922,7 +922,7 @@
exit:
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
JNI_ABORT);
}
if (_exception) {
@@ -940,7 +940,6 @@
}
return android_eglCreatePbufferFromClientBuffer(_env, _this, dpy, buftype, buffer, config, attrib_list_ref, offset);
}
-
/* EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value ) */
static jboolean
android_eglSurfaceAttrib
@@ -1034,7 +1033,7 @@
}
_remaining = _env->GetArrayLength(attrib_list_ref) - offset;
attrib_list_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
attrib_list = attrib_list_base + offset;
attrib_list_sentinel = false;
for (int i = _remaining - 1; i >= 0; i--) {
@@ -1059,7 +1058,7 @@
exit:
if (attrib_list_base) {
- _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ _env->ReleaseIntArrayElements(attrib_list_ref, (jint*)attrib_list_base,
JNI_ABORT);
}
if (_exception) {
@@ -1165,7 +1164,7 @@
goto exit;
}
value_base = (EGLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
_returnValue = eglQueryContext(
@@ -1177,7 +1176,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
diff --git a/core/jni/android_opengl_GLES10.cpp b/core/jni/android_opengl_GLES10.cpp
index c9b68bf..dac98de 100644
--- a/core/jni/android_opengl_GLES10.cpp
+++ b/core/jni/android_opengl_GLES10.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -515,7 +629,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -544,7 +658,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -637,7 +751,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glDeleteTextures(
@@ -647,7 +761,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
JNI_ABORT);
}
if (_exception) {
@@ -662,12 +776,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -675,7 +789,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glDeleteTextures(
@@ -685,7 +799,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -771,7 +885,7 @@
jint _remaining;
GLvoid *indices = (GLvoid *) 0;
- indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+ indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count) {
_exception = 1;
_exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -882,7 +996,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glFogfv(
@@ -892,7 +1006,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -907,12 +1021,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_FOG_COLOR)
@@ -931,7 +1045,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glFogfv(
@@ -941,7 +1055,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1000,7 +1114,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glFogxv(
@@ -1010,7 +1124,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1025,12 +1139,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_FOG_COLOR)
@@ -1049,7 +1163,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glFogxv(
@@ -1059,7 +1173,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1134,7 +1248,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glGenTextures(
@@ -1144,7 +1258,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1159,12 +1273,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1172,7 +1286,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glGenTextures(
@@ -1182,7 +1296,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1202,16 +1316,17 @@
static void
android_glGetIntegerv__I_3II
(JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
- get<jintArray, GLint, glGetIntegerv>(_env, _this, pname, params_ref, offset);
+ get<jintArray, IntArrayGetter, jint*, IntArrayReleaser, GLint, glGetIntegerv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetIntegerv ( GLenum pname, GLint *params ) */
static void
android_glGetIntegerv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLint, glGetIntegerv>(_env, _this, pname, params_buf);
+ getarray<GLint, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetIntegerv>(
+ _env, _this, pname, params_buf);
}
-
/* const GLubyte * glGetString ( GLenum name ) */
static jstring android_glGetString(JNIEnv* _env, jobject, jint name) {
const char* chars = (const char*) glGetString((GLenum) name);
@@ -1279,7 +1394,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightModelfv(
@@ -1289,7 +1404,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1304,12 +1419,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_LIGHT_MODEL_AMBIENT)
@@ -1328,7 +1443,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glLightModelfv(
@@ -1338,7 +1453,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1397,7 +1512,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightModelxv(
@@ -1407,7 +1522,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1422,12 +1537,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_LIGHT_MODEL_AMBIENT)
@@ -1446,7 +1561,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightModelxv(
@@ -1456,7 +1571,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1530,7 +1645,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightfv(
@@ -1541,7 +1656,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1556,12 +1671,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_DIRECTION)
@@ -1594,7 +1709,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glLightfv(
@@ -1605,7 +1720,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1679,7 +1794,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightxv(
@@ -1690,7 +1805,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1705,12 +1820,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_DIRECTION)
@@ -1743,7 +1858,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightxv(
@@ -1754,7 +1869,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1811,7 +1926,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glLoadMatrixf(
@@ -1820,7 +1935,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -1832,21 +1947,21 @@
static void
android_glLoadMatrixf__Ljava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *m = (GLfloat *) 0;
- m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
m = (GLfloat *) (_mBase + _bufferOffset);
}
glLoadMatrixf(
(GLfloat *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
}
}
@@ -1875,7 +1990,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glLoadMatrixx(
@@ -1884,7 +1999,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -1896,21 +2011,21 @@
static void
android_glLoadMatrixx__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glLoadMatrixx(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -1988,7 +2103,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glMaterialfv(
@@ -1999,7 +2114,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2014,12 +2129,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_AMBIENT)
@@ -2050,7 +2165,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glMaterialfv(
@@ -2061,7 +2176,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2133,7 +2248,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glMaterialxv(
@@ -2144,7 +2259,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2159,12 +2274,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_AMBIENT)
@@ -2195,7 +2310,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glMaterialxv(
@@ -2206,7 +2321,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2247,7 +2362,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glMultMatrixf(
@@ -2256,7 +2371,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -2268,21 +2383,21 @@
static void
android_glMultMatrixf__Ljava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *m = (GLfloat *) 0;
- m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
m = (GLfloat *) (_mBase + _bufferOffset);
}
glMultMatrixf(
(GLfloat *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
}
}
@@ -2311,7 +2426,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glMultMatrixx(
@@ -2320,7 +2435,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -2332,21 +2447,21 @@
static void
android_glMultMatrixx__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glMultMatrixx(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -2520,7 +2635,7 @@
jint _remaining;
GLvoid *pixels = (GLvoid *) 0;
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -2734,7 +2849,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnvfv(
@@ -2745,7 +2860,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2760,12 +2875,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -2784,7 +2899,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexEnvfv(
@@ -2795,7 +2910,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2855,7 +2970,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnvxv(
@@ -2866,7 +2981,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2881,12 +2996,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -2905,7 +3020,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexEnvxv(
@@ -2916,7 +3031,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2933,7 +3048,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -2987,7 +3102,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
diff --git a/core/jni/android_opengl_GLES10Ext.cpp b/core/jni/android_opengl_GLES10Ext.cpp
index 4f1eaa5..95be11b 100644
--- a/core/jni/android_opengl_GLES10Ext.cpp
+++ b/core/jni/android_opengl_GLES10Ext.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -363,7 +477,7 @@
goto exit;
}
mantissa_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
+ _env->GetIntArrayElements(mantissa_ref, (jboolean *)0);
mantissa = mantissa_base + mantissaOffset;
if (!exponent_ref) {
@@ -386,7 +500,7 @@
goto exit;
}
exponent_base = (GLint *)
- _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
+ _env->GetIntArrayElements(exponent_ref, (jboolean *)0);
exponent = exponent_base + exponentOffset;
_returnValue = glQueryMatrixxOES(
@@ -396,11 +510,11 @@
exit:
if (exponent_base) {
- _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
+ _env->ReleaseIntArrayElements(exponent_ref, (jint*)exponent_base,
_exception ? JNI_ABORT: 0);
}
if (mantissa_base) {
- _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
+ _env->ReleaseIntArrayElements(mantissa_ref, (jint*)mantissa_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -416,9 +530,9 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _mantissaArray = (jarray) 0;
+ jintArray _mantissaArray = (jintArray) 0;
jint _mantissaBufferOffset = (jint) 0;
- jarray _exponentArray = (jarray) 0;
+ jintArray _exponentArray = (jintArray) 0;
jint _exponentBufferOffset = (jint) 0;
GLbitfield _returnValue = -1;
jint _mantissaRemaining;
@@ -426,14 +540,14 @@
jint _exponentRemaining;
GLint *exponent = (GLint *) 0;
- mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
+ mantissa = (GLfixed *)getPointer(_env, mantissa_buf, (jarray*)&_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
if (_mantissaRemaining < 16) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
_exceptionMessage = "remaining() < 16 < needed";
goto exit;
}
- exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
+ exponent = (GLint *)getPointer(_env, exponent_buf, (jarray*)&_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
if (_exponentRemaining < 16) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -441,11 +555,11 @@
goto exit;
}
if (mantissa == NULL) {
- char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
+ char * _mantissaBase = (char *)_env->GetIntArrayElements(_mantissaArray, (jboolean *) 0);
mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
}
if (exponent == NULL) {
- char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
+ char * _exponentBase = (char *)_env->GetIntArrayElements(_exponentArray, (jboolean *) 0);
exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
}
_returnValue = glQueryMatrixxOES(
@@ -455,10 +569,10 @@
exit:
if (_exponentArray) {
- releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_exponentArray, (jint*)exponent, _exception ? JNI_ABORT : 0);
}
if (_mantissaArray) {
- releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_mantissaArray, (jint*)mantissa, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES11.cpp b/core/jni/android_opengl_GLES11.cpp
index 08c4740..6970a3c 100644
--- a/core/jni/android_opengl_GLES11.cpp
+++ b/core/jni/android_opengl_GLES11.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -351,7 +465,7 @@
GLvoid *data = (GLvoid *) 0;
if (data_buf) {
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -391,7 +505,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -443,7 +557,7 @@
}
_remaining = _env->GetArrayLength(equation_ref) - offset;
equation_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanef(
@@ -453,7 +567,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -468,14 +582,14 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *equation = (GLfloat *) 0;
- equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
equation = (GLfloat *) (_equationBase + _bufferOffset);
}
glClipPlanef(
@@ -483,7 +597,7 @@
(GLfloat *)equation
);
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -515,7 +629,7 @@
}
_remaining = _env->GetArrayLength(equation_ref) - offset;
equation_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetIntArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanex(
@@ -525,7 +639,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -540,14 +654,14 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *equation = (GLfixed *) 0;
- equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
equation = (GLfixed *) (_equationBase + _bufferOffset);
}
glClipPlanex(
@@ -555,7 +669,7 @@
(GLfixed *)equation
);
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -617,7 +731,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glDeleteBuffers(
@@ -627,7 +741,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -642,12 +756,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -655,7 +769,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glDeleteBuffers(
@@ -665,7 +779,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -721,7 +835,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glGenBuffers(
@@ -731,7 +845,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -746,12 +860,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -759,7 +873,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glGenBuffers(
@@ -769,7 +883,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -780,14 +894,16 @@
static void
android_glGetBooleanv__I_3ZI
(JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
- get<jbooleanArray, GLboolean, glGetBooleanv>(_env, _this, pname, params_ref, offset);
+ get<jbooleanArray, BooleanArrayGetter, jboolean*, BooleanArrayReleaser, GLboolean, glGetBooleanv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
static void
android_glGetBooleanv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLboolean, glGetBooleanv>(_env, _this, pname, params_buf);
+ getarray<GLboolean, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetBooleanv>(
+ _env, _this, pname, params_buf);
}
/* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
static void
@@ -820,7 +936,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetBufferParameteriv(
@@ -831,7 +947,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -846,12 +962,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -859,7 +975,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetBufferParameteriv(
@@ -870,7 +986,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -908,7 +1024,7 @@
goto exit;
}
eqn_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanef(
@@ -918,7 +1034,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -933,12 +1049,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *eqn = (GLfloat *) 0;
- eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -946,7 +1062,7 @@
goto exit;
}
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
eqn = (GLfloat *) (_eqnBase + _bufferOffset);
}
glGetClipPlanef(
@@ -956,7 +1072,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -994,7 +1110,7 @@
goto exit;
}
eqn_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanex(
@@ -1004,7 +1120,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1019,12 +1135,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *eqn = (GLfixed *) 0;
- eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1032,7 +1148,7 @@
goto exit;
}
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
eqn = (GLfixed *) (_eqnBase + _bufferOffset);
}
glGetClipPlanex(
@@ -1042,7 +1158,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)eqn, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1074,7 +1190,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFixedv(
@@ -1084,7 +1200,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1096,14 +1212,14 @@
static void
android_glGetFixedv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetFixedv(
@@ -1111,7 +1227,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1119,14 +1235,16 @@
static void
android_glGetFloatv__I_3FI
(JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
- get<jfloatArray, GLfloat, glGetFloatv>(_env, _this, pname, params_ref, offset);
+ get<jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, GLfloat, glGetFloatv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetFloatv ( GLenum pname, GLfloat *params ) */
static void
android_glGetFloatv__ILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLfloat, glGetFloatv>(_env, _this, pname, params_buf);
+ getarray<GLfloat, jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, glGetFloatv>(
+ _env, _this, pname, params_buf);
}
/* void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params ) */
static void
@@ -1184,7 +1302,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetLightfv(
@@ -1195,7 +1313,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1210,12 +1328,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_DIRECTION)
@@ -1248,7 +1366,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetLightfv(
@@ -1259,7 +1377,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1322,7 +1440,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetLightxv(
@@ -1333,7 +1451,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1348,12 +1466,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_DIRECTION)
@@ -1386,7 +1504,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetLightxv(
@@ -1397,7 +1515,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1458,7 +1576,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetMaterialfv(
@@ -1469,7 +1587,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1484,12 +1602,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_AMBIENT)
@@ -1520,7 +1638,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetMaterialfv(
@@ -1531,7 +1649,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1592,7 +1710,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetMaterialxv(
@@ -1603,7 +1721,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1618,12 +1736,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_AMBIENT)
@@ -1654,7 +1772,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetMaterialxv(
@@ -1665,7 +1783,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1714,7 +1832,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnvfv(
@@ -1725,7 +1843,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1740,12 +1858,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -1764,7 +1882,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexEnvfv(
@@ -1775,7 +1893,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1824,7 +1942,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnviv(
@@ -1835,7 +1953,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1850,12 +1968,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -1874,7 +1992,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexEnviv(
@@ -1885,7 +2003,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1934,7 +2052,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnvxv(
@@ -1945,7 +2063,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1960,12 +2078,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -1984,7 +2102,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexEnvxv(
@@ -1995,7 +2113,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2033,7 +2151,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterfv(
@@ -2044,7 +2162,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2059,12 +2177,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2072,7 +2190,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexParameterfv(
@@ -2083,7 +2201,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2121,7 +2239,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameteriv(
@@ -2132,7 +2250,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2147,12 +2265,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2160,7 +2278,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexParameteriv(
@@ -2171,7 +2289,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2209,7 +2327,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterxv(
@@ -2220,7 +2338,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2235,12 +2353,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2248,7 +2366,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexParameterxv(
@@ -2259,7 +2377,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2351,7 +2469,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glPointParameterfv(
@@ -2361,7 +2479,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2376,12 +2494,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2389,7 +2507,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glPointParameterfv(
@@ -2399,7 +2517,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2447,7 +2565,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glPointParameterxv(
@@ -2457,7 +2575,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2472,12 +2590,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2485,7 +2603,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glPointParameterxv(
@@ -2495,7 +2613,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2590,7 +2708,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnviv(
@@ -2601,7 +2719,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2616,12 +2734,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_COLOR)
@@ -2640,7 +2758,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexEnviv(
@@ -2651,7 +2769,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2689,7 +2807,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterfv(
@@ -2700,7 +2818,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2715,12 +2833,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2728,7 +2846,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexParameterfv(
@@ -2739,7 +2857,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2788,7 +2906,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameteriv(
@@ -2799,7 +2917,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2814,12 +2932,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2827,7 +2945,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexParameteriv(
@@ -2838,7 +2956,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2876,7 +2994,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterxv(
@@ -2887,7 +3005,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2902,12 +3020,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2915,7 +3033,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexParameterxv(
@@ -2926,7 +3044,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES11Ext.cpp b/core/jni/android_opengl_GLES11Ext.cpp
index 21e5670f..6422ff2 100644
--- a/core/jni/android_opengl_GLES11Ext.cpp
+++ b/core/jni/android_opengl_GLES11Ext.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -429,7 +543,7 @@
goto exit;
}
coords_base = (GLshort *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetShortArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexsvOES(
@@ -438,7 +552,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseShortArrayElements(coords_ref, (jshort*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -453,12 +567,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jshortArray _array = (jshortArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLshort *coords = (GLshort *) 0;
- coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLshort *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -466,7 +580,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetShortArrayElements(_array, (jboolean *) 0);
coords = (GLshort *) (_coordsBase + _bufferOffset);
}
glDrawTexsvOES(
@@ -475,7 +589,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseShortArrayElements(_array, (jshort*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -513,7 +627,7 @@
goto exit;
}
coords_base = (GLint *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetIntArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexivOES(
@@ -522,7 +636,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -537,12 +651,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *coords = (GLint *) 0;
- coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLint *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -550,7 +664,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
coords = (GLint *) (_coordsBase + _bufferOffset);
}
glDrawTexivOES(
@@ -559,7 +673,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -597,7 +711,7 @@
goto exit;
}
coords_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetIntArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexxvOES(
@@ -606,7 +720,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -621,12 +735,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *coords = (GLfixed *) 0;
- coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLfixed *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -634,7 +748,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
coords = (GLfixed *) (_coordsBase + _bufferOffset);
}
glDrawTexxvOES(
@@ -643,7 +757,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -694,7 +808,7 @@
goto exit;
}
coords_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexfvOES(
@@ -703,7 +817,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseFloatArrayElements(coords_ref, (jfloat*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -718,12 +832,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *coords = (GLfloat *) 0;
- coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLfloat *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -731,7 +845,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
coords = (GLfloat *) (_coordsBase + _bufferOffset);
}
glDrawTexfvOES(
@@ -740,7 +854,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -756,7 +870,7 @@
jint _remaining;
GLeglImageOES image = (GLeglImageOES) 0;
- image = (GLeglImageOES)getPointer(_env, image_buf, &_array, &_remaining, &_bufferOffset);
+ image = (GLeglImageOES)getPointer(_env, image_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (image == NULL) {
char * _imageBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
image = (GLeglImageOES) (_imageBase + _bufferOffset);
@@ -779,7 +893,7 @@
jint _remaining;
GLeglImageOES image = (GLeglImageOES) 0;
- image = (GLeglImageOES)getPointer(_env, image_buf, &_array, &_remaining, &_bufferOffset);
+ image = (GLeglImageOES)getPointer(_env, image_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (image == NULL) {
char * _imageBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
image = (GLeglImageOES) (_imageBase + _bufferOffset);
@@ -849,7 +963,7 @@
}
_remaining = _env->GetArrayLength(equation_ref) - offset;
equation_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetIntArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanexOES(
@@ -859,7 +973,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -871,14 +985,14 @@
static void
android_glClipPlanexOES__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *equation = (GLfixed *) 0;
- equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
equation = (GLfixed *) (_equationBase + _bufferOffset);
}
glClipPlanexOES(
@@ -886,7 +1000,7 @@
(GLfixed *)equation
);
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
}
}
@@ -947,7 +1061,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glFogxvOES(
@@ -957,7 +1071,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -969,14 +1083,14 @@
static void
android_glFogxvOES__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glFogxvOES(
@@ -984,7 +1098,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -1033,7 +1147,7 @@
goto exit;
}
eqn_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanexOES(
@@ -1043,7 +1157,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1058,12 +1172,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *eqn = (GLfixed *) 0;
- eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1071,7 +1185,7 @@
goto exit;
}
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
eqn = (GLfixed *) (_eqnBase + _bufferOffset);
}
glGetClipPlanexOES(
@@ -1081,7 +1195,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)eqn, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1113,7 +1227,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFixedvOES(
@@ -1123,7 +1237,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1135,14 +1249,14 @@
static void
android_glGetFixedvOES__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetFixedvOES(
@@ -1150,7 +1264,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1179,7 +1293,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetLightxvOES(
@@ -1190,7 +1304,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1202,14 +1316,14 @@
static void
android_glGetLightxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetLightxvOES(
@@ -1218,7 +1332,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1247,7 +1361,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetMaterialxvOES(
@@ -1258,7 +1372,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1270,14 +1384,14 @@
static void
android_glGetMaterialxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetMaterialxvOES(
@@ -1286,7 +1400,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1315,7 +1429,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnvxvOES(
@@ -1326,7 +1440,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1338,14 +1452,14 @@
static void
android_glGetTexEnvxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint env, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexEnvxvOES(
@@ -1354,7 +1468,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1383,7 +1497,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterxvOES(
@@ -1394,7 +1508,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1406,14 +1520,14 @@
static void
android_glGetTexParameterxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexParameterxvOES(
@@ -1422,7 +1536,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1461,7 +1575,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightModelxvOES(
@@ -1471,7 +1585,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1483,14 +1597,14 @@
static void
android_glLightModelxvOES__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightModelxvOES(
@@ -1498,7 +1612,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -1538,7 +1652,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightxvOES(
@@ -1549,7 +1663,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1561,14 +1675,14 @@
static void
android_glLightxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint light, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightxvOES(
@@ -1577,7 +1691,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -1615,7 +1729,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glLoadMatrixxOES(
@@ -1624,7 +1738,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -1636,21 +1750,21 @@
static void
android_glLoadMatrixxOES__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glLoadMatrixxOES(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -1690,7 +1804,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glMaterialxvOES(
@@ -1701,7 +1815,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1713,14 +1827,14 @@
static void
android_glMaterialxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint face, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glMaterialxvOES(
@@ -1729,7 +1843,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -1758,7 +1872,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glMultMatrixxOES(
@@ -1767,7 +1881,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -1779,21 +1893,21 @@
static void
android_glMultMatrixxOES__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glMultMatrixxOES(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -1870,7 +1984,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glPointParameterxvOES(
@@ -1880,7 +1994,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1892,14 +2006,14 @@
static void
android_glPointParameterxvOES__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glPointParameterxvOES(
@@ -1907,7 +2021,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -1999,7 +2113,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnvxvOES(
@@ -2010,7 +2124,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2022,14 +2136,14 @@
static void
android_glTexEnvxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexEnvxvOES(
@@ -2038,7 +2152,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -2078,7 +2192,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterxvOES(
@@ -2089,7 +2203,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2101,14 +2215,14 @@
static void
android_glTexParameterxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexParameterxvOES(
@@ -2117,7 +2231,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -2184,7 +2298,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glDeleteRenderbuffersOES(
@@ -2194,7 +2308,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -2209,12 +2323,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2222,7 +2336,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glDeleteRenderbuffersOES(
@@ -2232,7 +2346,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2270,7 +2384,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glGenRenderbuffersOES(
@@ -2280,7 +2394,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2295,12 +2409,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2308,7 +2422,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glGenRenderbuffersOES(
@@ -2318,7 +2432,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2368,7 +2482,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetRenderbufferParameterivOES(
@@ -2379,7 +2493,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2394,12 +2508,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2407,7 +2521,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetRenderbufferParameterivOES(
@@ -2418,7 +2532,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2477,7 +2591,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glDeleteFramebuffersOES(
@@ -2487,7 +2601,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -2502,12 +2616,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2515,7 +2629,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glDeleteFramebuffersOES(
@@ -2525,7 +2639,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2563,7 +2677,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glGenFramebuffersOES(
@@ -2573,7 +2687,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2588,12 +2702,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2601,7 +2715,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glGenFramebuffersOES(
@@ -2611,7 +2725,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2685,7 +2799,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFramebufferAttachmentParameterivOES(
@@ -2697,7 +2811,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2712,12 +2826,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2725,7 +2839,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetFramebufferAttachmentParameterivOES(
@@ -2737,7 +2851,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2880,7 +2994,7 @@
}
_remaining = _env->GetArrayLength(equation_ref) - offset;
equation_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanefOES(
@@ -2890,7 +3004,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -2902,14 +3016,14 @@
static void
android_glClipPlanefOES__ILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint plane, jobject equation_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *equation = (GLfloat *) 0;
- equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
equation = (GLfloat *) (_equationBase + _bufferOffset);
}
glClipPlanefOES(
@@ -2917,7 +3031,7 @@
(GLfloat *)equation
);
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
}
}
@@ -2952,7 +3066,7 @@
goto exit;
}
eqn_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanefOES(
@@ -2962,7 +3076,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2977,12 +3091,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *eqn = (GLfloat *) 0;
- eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2990,7 +3104,7 @@
goto exit;
}
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
eqn = (GLfloat *) (_eqnBase + _bufferOffset);
}
glGetClipPlanefOES(
@@ -3000,7 +3114,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, eqn, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3052,7 +3166,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGenfvOES(
@@ -3063,7 +3177,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -3075,14 +3189,14 @@
static void
android_glTexGenfvOES__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexGenfvOES(
@@ -3091,7 +3205,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
}
@@ -3131,7 +3245,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGenivOES(
@@ -3142,7 +3256,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -3154,14 +3268,14 @@
static void
android_glTexGenivOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexGenivOES(
@@ -3170,7 +3284,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -3210,7 +3324,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGenxvOES(
@@ -3221,7 +3335,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -3233,14 +3347,14 @@
static void
android_glTexGenxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexGenxvOES(
@@ -3249,7 +3363,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -3278,7 +3392,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGenfvOES(
@@ -3289,7 +3403,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3301,14 +3415,14 @@
static void
android_glGetTexGenfvOES__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexGenfvOES(
@@ -3317,7 +3431,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
@@ -3346,7 +3460,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGenivOES(
@@ -3357,7 +3471,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3369,14 +3483,14 @@
static void
android_glGetTexGenivOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexGenivOES(
@@ -3385,7 +3499,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -3414,7 +3528,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGenxvOES(
@@ -3425,7 +3539,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3437,14 +3551,14 @@
static void
android_glGetTexGenxvOES__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint coord, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexGenxvOES(
@@ -3453,7 +3567,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
diff --git a/core/jni/android_opengl_GLES20.cpp b/core/jni/android_opengl_GLES20.cpp
index cd0c1354..f9a0dfe 100644
--- a/core/jni/android_opengl_GLES20.cpp
+++ b/core/jni/android_opengl_GLES20.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -486,7 +600,7 @@
GLvoid *data = (GLvoid *) 0;
if (data_buf) {
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -526,7 +640,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -633,7 +747,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -662,7 +776,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -775,7 +889,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glDeleteBuffers(
@@ -785,7 +899,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -800,12 +914,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -813,7 +927,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glDeleteBuffers(
@@ -823,7 +937,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -861,7 +975,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glDeleteFramebuffers(
@@ -871,7 +985,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -886,12 +1000,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -899,7 +1013,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glDeleteFramebuffers(
@@ -909,7 +1023,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -956,7 +1070,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glDeleteRenderbuffers(
@@ -966,7 +1080,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -981,12 +1095,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -994,7 +1108,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glDeleteRenderbuffers(
@@ -1004,7 +1118,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1051,7 +1165,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glDeleteTextures(
@@ -1061,7 +1175,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
JNI_ABORT);
}
if (_exception) {
@@ -1076,12 +1190,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1089,7 +1203,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glDeleteTextures(
@@ -1099,7 +1213,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1203,7 +1317,7 @@
jint _remaining;
GLvoid *indices = (GLvoid *) 0;
- indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+ indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count) {
_exception = 1;
_exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -1327,7 +1441,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glGenBuffers(
@@ -1337,7 +1451,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1352,12 +1466,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1365,7 +1479,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glGenBuffers(
@@ -1375,7 +1489,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1422,7 +1536,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glGenFramebuffers(
@@ -1432,7 +1546,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1447,12 +1561,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1460,7 +1574,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glGenFramebuffers(
@@ -1470,7 +1584,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1508,7 +1622,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glGenRenderbuffers(
@@ -1518,7 +1632,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1533,12 +1647,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1546,7 +1660,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glGenRenderbuffers(
@@ -1556,7 +1670,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1594,7 +1708,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glGenTextures(
@@ -1604,7 +1718,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1619,12 +1733,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1632,7 +1746,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glGenTextures(
@@ -1642,7 +1756,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1683,7 +1797,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!size_ref) {
@@ -1700,7 +1814,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -1717,7 +1831,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
if (!name_ref) {
@@ -1734,7 +1848,7 @@
}
_nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
name_base = (char *)
- _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+ _env->GetByteArrayElements(name_ref, (jboolean *)0);
name = name_base + nameOffset;
glGetActiveAttrib(
@@ -1749,19 +1863,19 @@
exit:
if (name_base) {
- _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+ _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
_exception ? JNI_ABORT: 0);
}
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1773,11 +1887,11 @@
static void
android_glGetActiveAttrib__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
(JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -1786,19 +1900,19 @@
jint _typeRemaining;
GLenum *type = (GLenum *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetActiveAttrib(
@@ -1811,13 +1925,13 @@
reinterpret_cast<char *>(name)
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
}
}
@@ -1862,7 +1976,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -1879,7 +1993,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
glGetActiveAttrib(
@@ -1893,11 +2007,11 @@
);
exit:
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (_exception != 1) {
@@ -1920,9 +2034,9 @@
static jstring
android_glGetActiveAttrib2
(JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -1945,14 +2059,14 @@
return NULL;
}
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetActiveAttrib(
@@ -1966,10 +2080,10 @@
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
result = _env->NewStringUTF(buf);
if (buf) {
@@ -2011,7 +2125,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!size_ref) {
@@ -2028,7 +2142,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -2045,7 +2159,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
if (!name_ref) {
@@ -2062,7 +2176,7 @@
}
_nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
name_base = (char *)
- _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+ _env->GetByteArrayElements(name_ref, (jboolean *)0);
name = name_base + nameOffset;
glGetActiveUniform(
@@ -2077,19 +2191,19 @@
exit:
if (name_base) {
- _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+ _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
_exception ? JNI_ABORT: 0);
}
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2101,11 +2215,11 @@
static void
android_glGetActiveUniform__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
(JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -2114,19 +2228,19 @@
jint _typeRemaining;
GLenum *type = (GLenum *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetActiveUniform(
@@ -2139,13 +2253,13 @@
reinterpret_cast<char *>(name)
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
}
}
@@ -2193,7 +2307,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -2210,7 +2324,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
glGetActiveUniform(
@@ -2225,11 +2339,11 @@
exit:
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (_exception != 1) {
@@ -2251,9 +2365,9 @@
static jstring
android_glGetActiveUniform2
(JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _sizeRemaining;
GLint *size = (GLint *) 0;
@@ -2273,15 +2387,15 @@
return NULL;
}
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetActiveUniform(
@@ -2295,10 +2409,10 @@
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
result = _env->NewStringUTF(buf);
if (buf) {
@@ -2340,7 +2454,7 @@
goto exit;
}
count_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(count_ref, (jboolean *)0);
+ _env->GetIntArrayElements(count_ref, (jboolean *)0);
count = count_base + countOffset;
if (!shaders_ref) {
@@ -2363,7 +2477,7 @@
goto exit;
}
shaders_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(shaders_ref, (jboolean *)0);
+ _env->GetIntArrayElements(shaders_ref, (jboolean *)0);
shaders = shaders_base + shadersOffset;
glGetAttachedShaders(
@@ -2375,11 +2489,11 @@
exit:
if (shaders_base) {
- _env->ReleasePrimitiveArrayCritical(shaders_ref, shaders_base,
+ _env->ReleaseIntArrayElements(shaders_ref, (jint*)shaders_base,
_exception ? JNI_ABORT: 0);
}
if (count_base) {
- _env->ReleasePrimitiveArrayCritical(count_ref, count_base,
+ _env->ReleaseIntArrayElements(count_ref, (jint*)count_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2394,9 +2508,9 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _countArray = (jarray) 0;
+ jintArray _countArray = (jintArray) 0;
jint _countBufferOffset = (jint) 0;
- jarray _shadersArray = (jarray) 0;
+ jintArray _shadersArray = (jintArray) 0;
jint _shadersBufferOffset = (jint) 0;
jint _countRemaining;
GLsizei *count = (GLsizei *) 0;
@@ -2404,7 +2518,7 @@
GLuint *shaders = (GLuint *) 0;
if (count_buf) {
- count = (GLsizei *)getPointer(_env, count_buf, &_countArray, &_countRemaining, &_countBufferOffset);
+ count = (GLsizei *)getPointer(_env, count_buf, (jarray*)&_countArray, &_countRemaining, &_countBufferOffset);
if (_countRemaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2413,7 +2527,7 @@
}
}
if (shaders_buf) {
- shaders = (GLuint *)getPointer(_env, shaders_buf, &_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
+ shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
if (_shadersRemaining < maxcount) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2422,11 +2536,11 @@
}
}
if (count_buf && count == NULL) {
- char * _countBase = (char *)_env->GetPrimitiveArrayCritical(_countArray, (jboolean *) 0);
+ char * _countBase = (char *)_env->GetIntArrayElements(_countArray, (jboolean *) 0);
count = (GLsizei *) (_countBase + _countBufferOffset);
}
if (shaders_buf && shaders == NULL) {
- char * _shadersBase = (char *)_env->GetPrimitiveArrayCritical(_shadersArray, (jboolean *) 0);
+ char * _shadersBase = (char *)_env->GetIntArrayElements(_shadersArray, (jboolean *) 0);
shaders = (GLuint *) (_shadersBase + _shadersBufferOffset);
}
glGetAttachedShaders(
@@ -2438,10 +2552,10 @@
exit:
if (_shadersArray) {
- releasePointer(_env, _shadersArray, shaders, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_shadersArray, (jint*)shaders, _exception ? JNI_ABORT : 0);
}
if (_countArray) {
- releasePointer(_env, _countArray, count, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_countArray, (jint*)count, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2486,14 +2600,16 @@
static void
android_glGetBooleanv__I_3ZI
(JNIEnv *_env, jobject _this, jint pname, jbooleanArray params_ref, jint offset) {
- get<jbooleanArray, GLboolean, glGetBooleanv>(_env, _this, pname, params_ref, offset);
+ get<jbooleanArray, BooleanArrayGetter, jboolean*, BooleanArrayReleaser, GLboolean, glGetBooleanv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetBooleanv ( GLenum pname, GLboolean *params ) */
static void
android_glGetBooleanv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLboolean, glGetBooleanv>(_env, _this, pname, params_buf);
+ getarray<GLboolean, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetBooleanv>(
+ _env, _this, pname, params_buf);
}
/* void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params ) */
static void
@@ -2526,7 +2642,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetBufferParameteriv(
@@ -2537,7 +2653,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2552,12 +2668,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2565,7 +2681,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetBufferParameteriv(
@@ -2576,7 +2692,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2596,14 +2712,16 @@
static void
android_glGetFloatv__I_3FI
(JNIEnv *_env, jobject _this, jint pname, jfloatArray params_ref, jint offset) {
- get<jfloatArray, GLfloat, glGetFloatv>(_env, _this, pname, params_ref, offset);
+ get<jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, GLfloat, glGetFloatv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetFloatv ( GLenum pname, GLfloat *params ) */
static void
android_glGetFloatv__ILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLfloat, glGetFloatv>(_env, _this, pname, params_buf);
+ getarray<GLfloat, jfloatArray, FloatArrayGetter, jfloat*, FloatArrayReleaser, glGetFloatv>(
+ _env, _this, pname, params_buf);
}
/* void glGetFramebufferAttachmentParameteriv ( GLenum target, GLenum attachment, GLenum pname, GLint *params ) */
static void
@@ -2630,7 +2748,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFramebufferAttachmentParameteriv(
@@ -2642,7 +2760,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2654,14 +2772,14 @@
static void
android_glGetFramebufferAttachmentParameteriv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint attachment, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetFramebufferAttachmentParameteriv(
@@ -2671,7 +2789,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -2679,16 +2797,17 @@
static void
android_glGetIntegerv__I_3II
(JNIEnv *_env, jobject _this, jint pname, jintArray params_ref, jint offset) {
- get<jintArray, GLint, glGetIntegerv>(_env, _this, pname, params_ref, offset);
+ get<jintArray, IntArrayGetter, jint*, IntArrayReleaser, GLint, glGetIntegerv>(
+ _env, _this, pname, params_ref, offset);
}
/* void glGetIntegerv ( GLenum pname, GLint *params ) */
static void
android_glGetIntegerv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- getarray<GLint, glGetIntegerv>(_env, _this, pname, params_buf);
+ getarray<GLint, jintArray, IntArrayGetter, jint*, IntArrayReleaser, glGetIntegerv>(
+ _env, _this, pname, params_buf);
}
-
/* void glGetProgramiv ( GLuint program, GLenum pname, GLint *params ) */
static void
android_glGetProgramiv__II_3II
@@ -2720,7 +2839,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetProgramiv(
@@ -2731,7 +2850,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2746,12 +2865,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2759,7 +2878,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetProgramiv(
@@ -2770,7 +2889,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2827,7 +2946,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetRenderbufferParameteriv(
@@ -2838,7 +2957,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2853,12 +2972,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2866,7 +2985,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetRenderbufferParameteriv(
@@ -2877,7 +2996,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2915,7 +3034,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetShaderiv(
@@ -2926,7 +3045,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2941,12 +3060,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -2954,7 +3073,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetShaderiv(
@@ -2965,7 +3084,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3025,7 +3144,7 @@
goto exit;
}
range_base = (GLint *)
- _env->GetPrimitiveArrayCritical(range_ref, (jboolean *)0);
+ _env->GetIntArrayElements(range_ref, (jboolean *)0);
range = range_base + rangeOffset;
if (!precision_ref) {
@@ -3048,7 +3167,7 @@
goto exit;
}
precision_base = (GLint *)
- _env->GetPrimitiveArrayCritical(precision_ref, (jboolean *)0);
+ _env->GetIntArrayElements(precision_ref, (jboolean *)0);
precision = precision_base + precisionOffset;
glGetShaderPrecisionFormat(
@@ -3060,11 +3179,11 @@
exit:
if (precision_base) {
- _env->ReleasePrimitiveArrayCritical(precision_ref, precision_base,
+ _env->ReleaseIntArrayElements(precision_ref, (jint*)precision_base,
_exception ? JNI_ABORT: 0);
}
if (range_base) {
- _env->ReleasePrimitiveArrayCritical(range_ref, range_base,
+ _env->ReleaseIntArrayElements(range_ref, (jint*)range_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3079,23 +3198,23 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _rangeArray = (jarray) 0;
+ jintArray _rangeArray = (jintArray) 0;
jint _rangeBufferOffset = (jint) 0;
- jarray _precisionArray = (jarray) 0;
+ jintArray _precisionArray = (jintArray) 0;
jint _precisionBufferOffset = (jint) 0;
jint _rangeRemaining;
GLint *range = (GLint *) 0;
jint _precisionRemaining;
GLint *precision = (GLint *) 0;
- range = (GLint *)getPointer(_env, range_buf, &_rangeArray, &_rangeRemaining, &_rangeBufferOffset);
+ range = (GLint *)getPointer(_env, range_buf, (jarray*)&_rangeArray, &_rangeRemaining, &_rangeBufferOffset);
if (_rangeRemaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
_exceptionMessage = "remaining() < 1 < needed";
goto exit;
}
- precision = (GLint *)getPointer(_env, precision_buf, &_precisionArray, &_precisionRemaining, &_precisionBufferOffset);
+ precision = (GLint *)getPointer(_env, precision_buf, (jarray*)&_precisionArray, &_precisionRemaining, &_precisionBufferOffset);
if (_precisionRemaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -3103,11 +3222,11 @@
goto exit;
}
if (range == NULL) {
- char * _rangeBase = (char *)_env->GetPrimitiveArrayCritical(_rangeArray, (jboolean *) 0);
+ char * _rangeBase = (char *)_env->GetIntArrayElements(_rangeArray, (jboolean *) 0);
range = (GLint *) (_rangeBase + _rangeBufferOffset);
}
if (precision == NULL) {
- char * _precisionBase = (char *)_env->GetPrimitiveArrayCritical(_precisionArray, (jboolean *) 0);
+ char * _precisionBase = (char *)_env->GetIntArrayElements(_precisionArray, (jboolean *) 0);
precision = (GLint *) (_precisionBase + _precisionBufferOffset);
}
glGetShaderPrecisionFormat(
@@ -3119,10 +3238,10 @@
exit:
if (_precisionArray) {
- releasePointer(_env, _precisionArray, precision, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_precisionArray, (jint*)precision, _exception ? JNI_ABORT : 0);
}
if (_rangeArray) {
- releasePointer(_env, _rangeArray, range, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_rangeArray, (jint*)range, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3157,7 +3276,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!source_ref) {
@@ -3174,7 +3293,7 @@
}
_sourceRemaining = _env->GetArrayLength(source_ref) - sourceOffset;
source_base = (char *)
- _env->GetPrimitiveArrayCritical(source_ref, (jboolean *)0);
+ _env->GetByteArrayElements(source_ref, (jboolean *)0);
source = source_base + sourceOffset;
glGetShaderSource(
@@ -3186,11 +3305,11 @@
exit:
if (source_base) {
- _env->ReleasePrimitiveArrayCritical(source_ref, source_base,
+ _env->ReleaseByteArrayElements(source_ref, (jbyte*)source_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3202,14 +3321,14 @@
static void
android_glGetShaderSource__IILjava_nio_IntBuffer_2B
(JNIEnv *_env, jobject _this, jint shader, jint bufsize, jobject length_buf, jbyte source) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLsizei *length = (GLsizei *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_array, &_remaining, &_bufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _bufferOffset);
}
glGetShaderSource(
@@ -3219,7 +3338,7 @@
reinterpret_cast<char *>(source)
);
if (_array) {
- releasePointer(_env, _array, length, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _array, (jint*)length, JNI_TRUE);
}
}
@@ -3276,7 +3395,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterfv(
@@ -3287,7 +3406,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3302,12 +3421,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -3315,7 +3434,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexParameterfv(
@@ -3326,7 +3445,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3364,7 +3483,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameteriv(
@@ -3375,7 +3494,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3390,12 +3509,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -3403,7 +3522,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexParameteriv(
@@ -3414,7 +3533,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3452,7 +3571,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetUniformfv(
@@ -3463,7 +3582,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3478,12 +3597,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -3491,7 +3610,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetUniformfv(
@@ -3502,7 +3621,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3540,7 +3659,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetUniformiv(
@@ -3551,7 +3670,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3566,12 +3685,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -3579,7 +3698,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetUniformiv(
@@ -3590,7 +3709,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3673,7 +3792,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetVertexAttribfv(
@@ -3684,7 +3803,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3699,12 +3818,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_CURRENT_VERTEX_ATTRIB)
@@ -3723,7 +3842,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetVertexAttribfv(
@@ -3734,7 +3853,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3783,7 +3902,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetVertexAttribiv(
@@ -3794,7 +3913,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3809,12 +3928,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_CURRENT_VERTEX_ATTRIB)
@@ -3833,7 +3952,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetVertexAttribiv(
@@ -3844,7 +3963,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3985,7 +4104,7 @@
jint _remaining;
GLvoid *pixels = (GLvoid *) 0;
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -4074,10 +4193,10 @@
}
_shadersRemaining = _env->GetArrayLength(shaders_ref) - offset;
shaders_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(shaders_ref, (jboolean *)0);
+ _env->GetIntArrayElements(shaders_ref, (jboolean *)0);
shaders = shaders_base + offset;
- binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_binaryRemaining, &_bufferOffset);
+ binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_binaryRemaining, &_bufferOffset);
if (_binaryRemaining < length) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4101,7 +4220,7 @@
releasePointer(_env, _array, binary, JNI_FALSE);
}
if (shaders_base) {
- _env->ReleasePrimitiveArrayCritical(shaders_ref, shaders_base,
+ _env->ReleaseIntArrayElements(shaders_ref, (jint*)shaders_base,
JNI_ABORT);
}
if (_exception) {
@@ -4116,17 +4235,17 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _shadersArray = (jarray) 0;
+ jintArray _shadersArray = (jintArray) 0;
jint _shadersBufferOffset = (jint) 0;
- jarray _binaryArray = (jarray) 0;
+ jintArray _binaryArray = (jintArray) 0;
jint _binaryBufferOffset = (jint) 0;
jint _shadersRemaining;
GLuint *shaders = (GLuint *) 0;
jint _binaryRemaining;
GLvoid *binary = (GLvoid *) 0;
- shaders = (GLuint *)getPointer(_env, shaders_buf, &_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
- binary = (GLvoid *)getPointer(_env, binary_buf, &_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
+ shaders = (GLuint *)getPointer(_env, shaders_buf, (jarray*)&_shadersArray, &_shadersRemaining, &_shadersBufferOffset);
+ binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
if (_binaryRemaining < length) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4134,7 +4253,7 @@
goto exit;
}
if (shaders == NULL) {
- char * _shadersBase = (char *)_env->GetPrimitiveArrayCritical(_shadersArray, (jboolean *) 0);
+ char * _shadersBase = (char *)_env->GetIntArrayElements(_shadersArray, (jboolean *) 0);
shaders = (GLuint *) (_shadersBase + _shadersBufferOffset);
}
if (binary == NULL) {
@@ -4154,7 +4273,7 @@
releasePointer(_env, _binaryArray, binary, JNI_FALSE);
}
if (_shadersArray) {
- releasePointer(_env, _shadersArray, shaders, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_shadersArray, (jint*)shaders, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4253,7 +4372,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -4317,7 +4436,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterfv(
@@ -4328,7 +4447,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -4343,12 +4462,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4356,7 +4475,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexParameterfv(
@@ -4367,7 +4486,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4416,7 +4535,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameteriv(
@@ -4427,7 +4546,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -4442,12 +4561,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4455,7 +4574,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexParameteriv(
@@ -4466,7 +4585,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4483,7 +4602,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -4546,7 +4665,7 @@
goto exit;
}
v_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform1fv(
@@ -4557,7 +4676,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -4572,12 +4691,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *v = (GLfloat *) 0;
- v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4585,7 +4704,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
v = (GLfloat *) (_vBase + _bufferOffset);
}
glUniform1fv(
@@ -4596,7 +4715,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4644,7 +4763,7 @@
goto exit;
}
v_base = (GLint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform1iv(
@@ -4655,7 +4774,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -4670,12 +4789,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *v = (GLint *) 0;
- v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4683,7 +4802,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLint *) (_vBase + _bufferOffset);
}
glUniform1iv(
@@ -4694,7 +4813,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4743,7 +4862,7 @@
goto exit;
}
v_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform2fv(
@@ -4754,7 +4873,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -4769,12 +4888,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *v = (GLfloat *) 0;
- v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*2) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4782,7 +4901,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
v = (GLfloat *) (_vBase + _bufferOffset);
}
glUniform2fv(
@@ -4793,7 +4912,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4842,7 +4961,7 @@
goto exit;
}
v_base = (GLint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform2iv(
@@ -4853,7 +4972,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -4868,12 +4987,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *v = (GLint *) 0;
- v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*2) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4881,7 +5000,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLint *) (_vBase + _bufferOffset);
}
glUniform2iv(
@@ -4892,7 +5011,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4942,7 +5061,7 @@
goto exit;
}
v_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform3fv(
@@ -4953,7 +5072,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -4968,12 +5087,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *v = (GLfloat *) 0;
- v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*3) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4981,7 +5100,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
v = (GLfloat *) (_vBase + _bufferOffset);
}
glUniform3fv(
@@ -4992,7 +5111,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5042,7 +5161,7 @@
goto exit;
}
v_base = (GLint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform3iv(
@@ -5053,7 +5172,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -5068,12 +5187,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *v = (GLint *) 0;
- v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*3) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5081,7 +5200,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLint *) (_vBase + _bufferOffset);
}
glUniform3iv(
@@ -5092,7 +5211,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5143,7 +5262,7 @@
goto exit;
}
v_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform4fv(
@@ -5154,7 +5273,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseFloatArrayElements(v_ref, (jfloat*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -5169,12 +5288,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *v = (GLfloat *) 0;
- v = (GLfloat *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLfloat *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5182,7 +5301,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
v = (GLfloat *) (_vBase + _bufferOffset);
}
glUniform4fv(
@@ -5193,7 +5312,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5244,7 +5363,7 @@
goto exit;
}
v_base = (GLint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glUniform4iv(
@@ -5255,7 +5374,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -5270,12 +5389,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *v = (GLint *) 0;
- v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5283,7 +5402,7 @@
goto exit;
}
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLint *) (_vBase + _bufferOffset);
}
glUniform4iv(
@@ -5294,7 +5413,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5332,7 +5451,7 @@
goto exit;
}
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix2fv(
@@ -5344,7 +5463,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -5359,12 +5478,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5372,7 +5491,7 @@
goto exit;
}
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix2fv(
@@ -5384,7 +5503,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5422,7 +5541,7 @@
goto exit;
}
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix3fv(
@@ -5434,7 +5553,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -5449,12 +5568,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*9) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5462,7 +5581,7 @@
goto exit;
}
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix3fv(
@@ -5474,7 +5593,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5512,7 +5631,7 @@
goto exit;
}
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix4fv(
@@ -5524,7 +5643,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -5539,12 +5658,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count*16) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5552,7 +5671,7 @@
goto exit;
}
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix4fv(
@@ -5564,7 +5683,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5630,7 +5749,7 @@
goto exit;
}
values_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(values_ref, (jboolean *)0);
values = values_base + offset;
glVertexAttrib1fv(
@@ -5640,7 +5759,7 @@
exit:
if (values_base) {
- _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+ _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
JNI_ABORT);
}
if (_exception) {
@@ -5655,12 +5774,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *values = (GLfloat *) 0;
- values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+ values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5668,7 +5787,7 @@
goto exit;
}
if (values == NULL) {
- char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
values = (GLfloat *) (_valuesBase + _bufferOffset);
}
glVertexAttrib1fv(
@@ -5678,7 +5797,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, values, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5727,7 +5846,7 @@
goto exit;
}
values_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(values_ref, (jboolean *)0);
values = values_base + offset;
glVertexAttrib2fv(
@@ -5737,7 +5856,7 @@
exit:
if (values_base) {
- _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+ _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
JNI_ABORT);
}
if (_exception) {
@@ -5752,12 +5871,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *values = (GLfloat *) 0;
- values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+ values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 2) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5765,7 +5884,7 @@
goto exit;
}
if (values == NULL) {
- char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
values = (GLfloat *) (_valuesBase + _bufferOffset);
}
glVertexAttrib2fv(
@@ -5775,7 +5894,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, values, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5825,7 +5944,7 @@
goto exit;
}
values_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(values_ref, (jboolean *)0);
values = values_base + offset;
glVertexAttrib3fv(
@@ -5835,7 +5954,7 @@
exit:
if (values_base) {
- _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+ _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
JNI_ABORT);
}
if (_exception) {
@@ -5850,12 +5969,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *values = (GLfloat *) 0;
- values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+ values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 3) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5863,7 +5982,7 @@
goto exit;
}
if (values == NULL) {
- char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
values = (GLfloat *) (_valuesBase + _bufferOffset);
}
glVertexAttrib3fv(
@@ -5873,7 +5992,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, values, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5924,7 +6043,7 @@
goto exit;
}
values_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(values_ref, (jboolean *)0);
values = values_base + offset;
glVertexAttrib4fv(
@@ -5934,7 +6053,7 @@
exit:
if (values_base) {
- _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+ _env->ReleaseFloatArrayElements(values_ref, (jfloat*)values_base,
JNI_ABORT);
}
if (_exception) {
@@ -5949,12 +6068,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *values = (GLfloat *) 0;
- values = (GLfloat *)getPointer(_env, values_buf, &_array, &_remaining, &_bufferOffset);
+ values = (GLfloat *)getPointer(_env, values_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5962,7 +6081,7 @@
goto exit;
}
if (values == NULL) {
- char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valuesBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
values = (GLfloat *) (_valuesBase + _bufferOffset);
}
glVertexAttrib4fv(
@@ -5972,7 +6091,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, values, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)values, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp
index 226162d..1d92cd4 100644
--- a/core/jni/android_opengl_GLES30.cpp
+++ b/core/jni/android_opengl_GLES30.cpp
@@ -126,6 +126,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -229,7 +339,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -264,8 +375,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -275,8 +386,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -284,20 +395,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -310,7 +422,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -320,7 +433,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -346,7 +460,7 @@
jint _remaining;
GLvoid *indices = (GLvoid *) 0;
- indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+ indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (indices == NULL) {
char * _indicesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
indices = (GLvoid *) (_indicesBase + _bufferOffset);
@@ -387,7 +501,7 @@
jint _remaining;
GLvoid *pixels = (GLvoid *) 0;
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -436,7 +550,7 @@
jint _remaining;
GLvoid *pixels = (GLvoid *) 0;
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -504,7 +618,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -551,7 +665,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -618,7 +732,7 @@
}
_remaining = _env->GetArrayLength(ids_ref) - offset;
ids_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+ _env->GetIntArrayElements(ids_ref, (jboolean *)0);
ids = ids_base + offset;
glGenQueries(
@@ -628,7 +742,7 @@
exit:
if (ids_base) {
- _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+ _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -640,14 +754,14 @@
static void
android_glGenQueries__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *ids = (GLuint *) 0;
- ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+ ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (ids == NULL) {
- char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
ids = (GLuint *) (_idsBase + _bufferOffset);
}
glGenQueries(
@@ -655,7 +769,7 @@
(GLuint *)ids
);
if (_array) {
- releasePointer(_env, _array, ids, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)ids, 0);
}
}
@@ -684,7 +798,7 @@
}
_remaining = _env->GetArrayLength(ids_ref) - offset;
ids_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+ _env->GetIntArrayElements(ids_ref, (jboolean *)0);
ids = ids_base + offset;
glDeleteQueries(
@@ -694,7 +808,7 @@
exit:
if (ids_base) {
- _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+ _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
JNI_ABORT);
}
if (_exception) {
@@ -706,14 +820,14 @@
static void
android_glDeleteQueries__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *ids = (GLuint *) 0;
- ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+ ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (ids == NULL) {
- char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
ids = (GLuint *) (_idsBase + _bufferOffset);
}
glDeleteQueries(
@@ -721,7 +835,7 @@
(GLuint *)ids
);
if (_array) {
- releasePointer(_env, _array, ids, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
}
}
@@ -780,7 +894,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetQueryiv(
@@ -791,7 +905,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -803,14 +917,14 @@
static void
android_glGetQueryiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetQueryiv(
@@ -819,7 +933,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -848,7 +962,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetQueryObjectuiv(
@@ -859,7 +973,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -871,14 +985,14 @@
static void
android_glGetQueryObjectuiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint id, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glGetQueryObjectuiv(
@@ -887,7 +1001,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -938,7 +1052,7 @@
}
_remaining = _env->GetArrayLength(bufs_ref) - offset;
bufs_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(bufs_ref, (jboolean *)0);
+ _env->GetIntArrayElements(bufs_ref, (jboolean *)0);
bufs = bufs_base + offset;
glDrawBuffers(
@@ -948,7 +1062,7 @@
exit:
if (bufs_base) {
- _env->ReleasePrimitiveArrayCritical(bufs_ref, bufs_base,
+ _env->ReleaseIntArrayElements(bufs_ref, (jint*)bufs_base,
JNI_ABORT);
}
if (_exception) {
@@ -960,14 +1074,14 @@
static void
android_glDrawBuffers__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject bufs_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLenum *bufs = (GLenum *) 0;
- bufs = (GLenum *)getPointer(_env, bufs_buf, &_array, &_remaining, &_bufferOffset);
+ bufs = (GLenum *)getPointer(_env, bufs_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (bufs == NULL) {
- char * _bufsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _bufsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
bufs = (GLenum *) (_bufsBase + _bufferOffset);
}
glDrawBuffers(
@@ -975,7 +1089,7 @@
(GLenum *)bufs
);
if (_array) {
- releasePointer(_env, _array, bufs, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)bufs, JNI_ABORT);
}
}
@@ -1004,7 +1118,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix2x3fv(
@@ -1016,7 +1130,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1028,14 +1142,14 @@
static void
android_glUniformMatrix2x3fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix2x3fv(
@@ -1045,7 +1159,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1074,7 +1188,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix3x2fv(
@@ -1086,7 +1200,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1098,14 +1212,14 @@
static void
android_glUniformMatrix3x2fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix3x2fv(
@@ -1115,7 +1229,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1144,7 +1258,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix2x4fv(
@@ -1156,7 +1270,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1168,14 +1282,14 @@
static void
android_glUniformMatrix2x4fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix2x4fv(
@@ -1185,7 +1299,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1214,7 +1328,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix4x2fv(
@@ -1226,7 +1340,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1238,14 +1352,14 @@
static void
android_glUniformMatrix4x2fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix4x2fv(
@@ -1255,7 +1369,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1284,7 +1398,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix3x4fv(
@@ -1296,7 +1410,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1308,14 +1422,14 @@
static void
android_glUniformMatrix3x4fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix3x4fv(
@@ -1325,7 +1439,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1354,7 +1468,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniformMatrix4x3fv(
@@ -1366,7 +1480,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1378,14 +1492,14 @@
static void
android_glUniformMatrix4x3fv__IIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glUniformMatrix4x3fv(
@@ -1395,7 +1509,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1501,7 +1615,7 @@
}
_remaining = _env->GetArrayLength(arrays_ref) - offset;
arrays_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(arrays_ref, (jboolean *)0);
+ _env->GetIntArrayElements(arrays_ref, (jboolean *)0);
arrays = arrays_base + offset;
glDeleteVertexArrays(
@@ -1511,7 +1625,7 @@
exit:
if (arrays_base) {
- _env->ReleasePrimitiveArrayCritical(arrays_ref, arrays_base,
+ _env->ReleaseIntArrayElements(arrays_ref, (jint*)arrays_base,
JNI_ABORT);
}
if (_exception) {
@@ -1523,14 +1637,14 @@
static void
android_glDeleteVertexArrays__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject arrays_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *arrays = (GLuint *) 0;
- arrays = (GLuint *)getPointer(_env, arrays_buf, &_array, &_remaining, &_bufferOffset);
+ arrays = (GLuint *)getPointer(_env, arrays_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (arrays == NULL) {
- char * _arraysBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _arraysBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
arrays = (GLuint *) (_arraysBase + _bufferOffset);
}
glDeleteVertexArrays(
@@ -1538,7 +1652,7 @@
(GLuint *)arrays
);
if (_array) {
- releasePointer(_env, _array, arrays, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)arrays, JNI_ABORT);
}
}
@@ -1567,7 +1681,7 @@
}
_remaining = _env->GetArrayLength(arrays_ref) - offset;
arrays_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(arrays_ref, (jboolean *)0);
+ _env->GetIntArrayElements(arrays_ref, (jboolean *)0);
arrays = arrays_base + offset;
glGenVertexArrays(
@@ -1577,7 +1691,7 @@
exit:
if (arrays_base) {
- _env->ReleasePrimitiveArrayCritical(arrays_ref, arrays_base,
+ _env->ReleaseIntArrayElements(arrays_ref, (jint*)arrays_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1589,14 +1703,14 @@
static void
android_glGenVertexArrays__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject arrays_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *arrays = (GLuint *) 0;
- arrays = (GLuint *)getPointer(_env, arrays_buf, &_array, &_remaining, &_bufferOffset);
+ arrays = (GLuint *)getPointer(_env, arrays_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (arrays == NULL) {
- char * _arraysBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _arraysBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
arrays = (GLuint *) (_arraysBase + _bufferOffset);
}
glGenVertexArrays(
@@ -1604,7 +1718,7 @@
(GLuint *)arrays
);
if (_array) {
- releasePointer(_env, _array, arrays, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)arrays, 0);
}
}
@@ -1644,7 +1758,7 @@
}
_remaining = _env->GetArrayLength(data_ref) - offset;
data_base = (GLint *)
- _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+ _env->GetIntArrayElements(data_ref, (jboolean *)0);
data = data_base + offset;
glGetIntegeri_v(
@@ -1655,7 +1769,7 @@
exit:
if (data_base) {
- _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+ _env->ReleaseIntArrayElements(data_ref, (jint*)data_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1667,14 +1781,14 @@
static void
android_glGetIntegeri_v__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *data = (GLint *) 0;
- data = (GLint *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLint *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
- char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _dataBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
data = (GLint *) (_dataBase + _bufferOffset);
}
glGetIntegeri_v(
@@ -1683,7 +1797,7 @@
(GLint *)data
);
if (_array) {
- releasePointer(_env, _array, data, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)data, 0);
}
}
@@ -1810,7 +1924,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!size_ref) {
@@ -1827,7 +1941,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -1844,7 +1958,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
if (!name_ref) {
@@ -1861,7 +1975,7 @@
}
_nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
name_base = (char *)
- _env->GetPrimitiveArrayCritical(name_ref, (jboolean *)0);
+ _env->GetByteArrayElements(name_ref, (jboolean *)0);
name = name_base + nameOffset;
glGetTransformFeedbackVarying(
@@ -1876,19 +1990,19 @@
exit:
if (name_base) {
- _env->ReleasePrimitiveArrayCritical(name_ref, name_base,
+ _env->ReleaseByteArrayElements(name_ref, (jbyte*)name_base,
_exception ? JNI_ABORT: 0);
}
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1900,11 +2014,11 @@
static void
android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_IntBuffer_2B
(JNIEnv *_env, jobject _this, jint program, jint index, jint bufsize, jobject length_buf, jobject size_buf, jobject type_buf, jbyte name) {
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -1913,19 +2027,19 @@
jint _typeRemaining;
GLenum *type = (GLenum *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetTransformFeedbackVarying(
@@ -1942,13 +2056,13 @@
(char *)static_cast<uintptr_t>(name)
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _lengthArray, (jint*)length, JNI_TRUE);
}
}
@@ -1993,7 +2107,7 @@
}
_sizeRemaining = _env->GetArrayLength(size_ref) - sizeOffset;
size_base = (GLint *)
- _env->GetPrimitiveArrayCritical(size_ref, (jboolean *)0);
+ _env->GetIntArrayElements(size_ref, (jboolean *)0);
size = size_base + sizeOffset;
if (!type_ref) {
@@ -2010,7 +2124,7 @@
}
_typeRemaining = _env->GetArrayLength(type_ref) - typeOffset;
type_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(type_ref, (jboolean *)0);
+ _env->GetIntArrayElements(type_ref, (jboolean *)0);
type = type_base + typeOffset;
glGetTransformFeedbackVarying(
@@ -2024,11 +2138,11 @@
);
exit:
if (type_base) {
- _env->ReleasePrimitiveArrayCritical(type_ref, type_base,
+ _env->ReleaseIntArrayElements(type_ref, (jint*)type_base,
_exception ? JNI_ABORT: 0);
}
if (size_base) {
- _env->ReleasePrimitiveArrayCritical(size_ref, size_base,
+ _env->ReleaseIntArrayElements(size_ref, (jint*)size_base,
_exception ? JNI_ABORT: 0);
}
if (_exception != 1) {
@@ -2051,9 +2165,9 @@
static jstring
android_glGetTransformFeedbackVarying2
(JNIEnv *_env, jobject _this, jint program, jint index, jobject size_buf, jobject type_buf) {
- jarray _sizeArray = (jarray) 0;
+ jintArray _sizeArray = (jintArray) 0;
jint _sizeBufferOffset = (jint) 0;
- jarray _typeArray = (jarray) 0;
+ jintArray _typeArray = (jintArray) 0;
jint _typeBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -2076,14 +2190,14 @@
return NULL;
}
- size = (GLint *)getPointer(_env, size_buf, &_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
- type = (GLenum *)getPointer(_env, type_buf, &_typeArray, &_typeRemaining, &_typeBufferOffset);
+ size = (GLint *)getPointer(_env, size_buf, (jarray*)&_sizeArray, &_sizeRemaining, &_sizeBufferOffset);
+ type = (GLenum *)getPointer(_env, type_buf, (jarray*)&_typeArray, &_typeRemaining, &_typeBufferOffset);
if (size == NULL) {
- char * _sizeBase = (char *)_env->GetPrimitiveArrayCritical(_sizeArray, (jboolean *) 0);
+ char * _sizeBase = (char *)_env->GetIntArrayElements(_sizeArray, (jboolean *) 0);
size = (GLint *) (_sizeBase + _sizeBufferOffset);
}
if (type == NULL) {
- char * _typeBase = (char *)_env->GetPrimitiveArrayCritical(_typeArray, (jboolean *) 0);
+ char * _typeBase = (char *)_env->GetIntArrayElements(_typeArray, (jboolean *) 0);
type = (GLenum *) (_typeBase + _typeBufferOffset);
}
glGetTransformFeedbackVarying(
@@ -2097,10 +2211,10 @@
);
if (_typeArray) {
- releasePointer(_env, _typeArray, type, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _typeArray, (jint*)type, JNI_TRUE);
}
if (_sizeArray) {
- releasePointer(_env, _sizeArray, size, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(_env, _sizeArray, (jint*)size, JNI_TRUE);
}
result = _env->NewStringUTF(buf);
if (buf) {
@@ -2171,7 +2285,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetVertexAttribIiv(
@@ -2182,7 +2296,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2194,14 +2308,14 @@
static void
android_glGetVertexAttribIiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetVertexAttribIiv(
@@ -2210,7 +2324,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -2239,7 +2353,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetVertexAttribIuiv(
@@ -2250,7 +2364,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2262,14 +2376,14 @@
static void
android_glGetVertexAttribIuiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint index, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glGetVertexAttribIuiv(
@@ -2278,7 +2392,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -2333,7 +2447,7 @@
}
_remaining = _env->GetArrayLength(v_ref) - offset;
v_base = (GLint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glVertexAttribI4iv(
@@ -2343,7 +2457,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -2355,14 +2469,14 @@
static void
android_glVertexAttribI4iv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint index, jobject v_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *v = (GLint *) 0;
- v = (GLint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLint *) (_vBase + _bufferOffset);
}
glVertexAttribI4iv(
@@ -2370,7 +2484,7 @@
(GLint *)v
);
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
}
@@ -2399,7 +2513,7 @@
}
_remaining = _env->GetArrayLength(v_ref) - offset;
v_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(v_ref, (jboolean *)0);
+ _env->GetIntArrayElements(v_ref, (jboolean *)0);
v = v_base + offset;
glVertexAttribI4uiv(
@@ -2409,7 +2523,7 @@
exit:
if (v_base) {
- _env->ReleasePrimitiveArrayCritical(v_ref, v_base,
+ _env->ReleaseIntArrayElements(v_ref, (jint*)v_base,
JNI_ABORT);
}
if (_exception) {
@@ -2421,14 +2535,14 @@
static void
android_glVertexAttribI4uiv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint index, jobject v_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *v = (GLuint *) 0;
- v = (GLuint *)getPointer(_env, v_buf, &_array, &_remaining, &_bufferOffset);
+ v = (GLuint *)getPointer(_env, v_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (v == NULL) {
- char * _vBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _vBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
v = (GLuint *) (_vBase + _bufferOffset);
}
glVertexAttribI4uiv(
@@ -2436,7 +2550,7 @@
(GLuint *)v
);
if (_array) {
- releasePointer(_env, _array, v, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)v, JNI_ABORT);
}
}
@@ -2465,7 +2579,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetUniformuiv(
@@ -2476,7 +2590,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2488,14 +2602,14 @@
static void
android_glGetUniformuiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glGetUniformuiv(
@@ -2504,7 +2618,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -2613,7 +2727,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniform1uiv(
@@ -2624,7 +2738,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2636,14 +2750,14 @@
static void
android_glUniform1uiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glUniform1uiv(
@@ -2652,7 +2766,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -2681,7 +2795,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniform2uiv(
@@ -2692,7 +2806,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2704,14 +2818,14 @@
static void
android_glUniform2uiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glUniform2uiv(
@@ -2720,7 +2834,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -2749,7 +2863,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniform3uiv(
@@ -2760,7 +2874,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2772,14 +2886,14 @@
static void
android_glUniform3uiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glUniform3uiv(
@@ -2788,7 +2902,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -2817,7 +2931,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glUniform4uiv(
@@ -2828,7 +2942,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2840,14 +2954,14 @@
static void
android_glUniform4uiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glUniform4uiv(
@@ -2856,7 +2970,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -2885,7 +2999,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glClearBufferiv(
@@ -2896,7 +3010,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2908,14 +3022,14 @@
static void
android_glClearBufferiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *value = (GLint *) 0;
- value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLint *) (_valueBase + _bufferOffset);
}
glClearBufferiv(
@@ -2924,7 +3038,7 @@
(GLint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -2953,7 +3067,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glClearBufferuiv(
@@ -2964,7 +3078,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2976,14 +3090,14 @@
static void
android_glClearBufferuiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glClearBufferuiv(
@@ -2992,7 +3106,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -3021,7 +3135,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glClearBufferfv(
@@ -3032,7 +3146,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -3044,14 +3158,14 @@
static void
android_glClearBufferfv__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint buffer, jint drawbuffer, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glClearBufferfv(
@@ -3060,7 +3174,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -3148,7 +3262,7 @@
_exceptionMessage = "not enough space in uniformIndices";
goto exit;
}
- _indices_base = (GLuint*)_env->GetPrimitiveArrayCritical(
+ _indices_base = (GLuint*)_env->GetIntArrayElements(
uniformIndices_ref, 0);
_indices = _indices_base + uniformIndicesOffset;
@@ -3156,8 +3270,8 @@
exit:
if (_indices_base) {
- _env->ReleasePrimitiveArrayCritical(uniformIndices_ref, _indices_base,
- _exception ? JNI_ABORT : 0);
+ _env->ReleaseIntArrayElements(uniformIndices_ref, (jint*)_indices_base,
+ _exception ? JNI_ABORT : 0);
}
for (_i = _count - 1; _i >= 0; _i--) {
if (_names[_i]) {
@@ -3184,7 +3298,7 @@
jint _count = 0;
jint _i;
const char** _names = NULL;
- jarray _uniformIndicesArray = (jarray)0;
+ jintArray _uniformIndicesArray = (jintArray)0;
jint _uniformIndicesRemaining;
jint _uniformIndicesOffset = 0;
GLuint* _indices = NULL;
@@ -3217,11 +3331,11 @@
}
_indices = (GLuint*)getPointer(_env, uniformIndices_buf,
- &_uniformIndicesArray, &_uniformIndicesRemaining,
+ (jarray*)&_uniformIndicesArray, &_uniformIndicesRemaining,
&_uniformIndicesOffset);
if (!_indices) {
- _indicesBase = (char*)_env->GetPrimitiveArrayCritical(
- _uniformIndicesArray, 0);
+ _indicesBase = (char*)_env->GetIntArrayElements(
+ _uniformIndicesArray, 0);
_indices = (GLuint*)(_indicesBase + _uniformIndicesOffset);
}
if (_uniformIndicesRemaining < _count) {
@@ -3235,7 +3349,8 @@
exit:
if (_uniformIndicesArray) {
- releasePointer(_env, _uniformIndicesArray, _indicesBase, JNI_TRUE);
+ releaseArrayPointer<jintArray, jint*, IntArrayReleaser>(
+ _env, _uniformIndicesArray, (jint*)_indicesBase, JNI_TRUE);
}
for (_i = _count - 1; _i >= 0; _i--) {
if (_names[_i]) {
@@ -3250,7 +3365,6 @@
jniThrowException(_env, _exceptionType, _exceptionMessage);
}
}
-
/* void glGetActiveUniformsiv ( GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params ) */
static void
android_glGetActiveUniformsiv__II_3III_3II
@@ -3279,7 +3393,7 @@
}
_uniformIndicesRemaining = _env->GetArrayLength(uniformIndices_ref) - uniformIndicesOffset;
uniformIndices_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(uniformIndices_ref, (jboolean *)0);
+ _env->GetIntArrayElements(uniformIndices_ref, (jboolean *)0);
uniformIndices = uniformIndices_base + uniformIndicesOffset;
if (!params_ref) {
@@ -3296,7 +3410,7 @@
}
_paramsRemaining = _env->GetArrayLength(params_ref) - paramsOffset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + paramsOffset;
glGetActiveUniformsiv(
@@ -3309,11 +3423,11 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (uniformIndices_base) {
- _env->ReleasePrimitiveArrayCritical(uniformIndices_ref, uniformIndices_base,
+ _env->ReleaseIntArrayElements(uniformIndices_ref, (jint*)uniformIndices_base,
JNI_ABORT);
}
if (_exception) {
@@ -3325,23 +3439,23 @@
static void
android_glGetActiveUniformsiv__IILjava_nio_IntBuffer_2ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint uniformCount, jobject uniformIndices_buf, jint pname, jobject params_buf) {
- jarray _uniformIndicesArray = (jarray) 0;
+ jintArray _uniformIndicesArray = (jintArray) 0;
jint _uniformIndicesBufferOffset = (jint) 0;
- jarray _paramsArray = (jarray) 0;
+ jintArray _paramsArray = (jintArray) 0;
jint _paramsBufferOffset = (jint) 0;
jint _uniformIndicesRemaining;
GLuint *uniformIndices = (GLuint *) 0;
jint _paramsRemaining;
GLint *params = (GLint *) 0;
- uniformIndices = (GLuint *)getPointer(_env, uniformIndices_buf, &_uniformIndicesArray, &_uniformIndicesRemaining, &_uniformIndicesBufferOffset);
- params = (GLint *)getPointer(_env, params_buf, &_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
+ uniformIndices = (GLuint *)getPointer(_env, uniformIndices_buf, (jarray*)&_uniformIndicesArray, &_uniformIndicesRemaining, &_uniformIndicesBufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
if (uniformIndices == NULL) {
- char * _uniformIndicesBase = (char *)_env->GetPrimitiveArrayCritical(_uniformIndicesArray, (jboolean *) 0);
+ char * _uniformIndicesBase = (char *)_env->GetIntArrayElements(_uniformIndicesArray, (jboolean *) 0);
uniformIndices = (GLuint *) (_uniformIndicesBase + _uniformIndicesBufferOffset);
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_paramsArray, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_paramsArray, (jboolean *) 0);
params = (GLint *) (_paramsBase + _paramsBufferOffset);
}
glGetActiveUniformsiv(
@@ -3352,10 +3466,10 @@
(GLint *)params
);
if (_paramsArray) {
- releasePointer(_env, _paramsArray, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_paramsArray, (jint*)params, 0);
}
if (_uniformIndicesArray) {
- releasePointer(_env, _uniformIndicesArray, uniformIndices, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_uniformIndicesArray, (jint*)uniformIndices, JNI_ABORT);
}
}
@@ -3418,7 +3532,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetActiveUniformBlockiv(
@@ -3430,7 +3544,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3442,14 +3556,14 @@
static void
android_glGetActiveUniformBlockiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint uniformBlockIndex, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetActiveUniformBlockiv(
@@ -3459,7 +3573,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -3490,7 +3604,7 @@
goto exit;
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
- _length_base = (GLsizei*)_env->GetPrimitiveArrayCritical(
+ _length_base = (GLsizei*)_env->GetIntArrayElements(
length_ref, (jboolean*)0);
_length = _length_base + lengthOffset;
@@ -3507,7 +3621,7 @@
goto exit;
}
_nameRemaining = _env->GetArrayLength(name_ref) - nameOffset;
- _name_base = (GLchar*)_env->GetPrimitiveArrayCritical(
+ _name_base = (GLchar*)_env->GetByteArrayElements(
name_ref, (jboolean*)0);
_name = _name_base + nameOffset;
@@ -3521,11 +3635,11 @@
exit:
if (_name_base) {
- _env->ReleasePrimitiveArrayCritical(name_ref, _name_base,
+ _env->ReleaseByteArrayElements(name_ref, (jbyte*)_name_base,
_exception ? JNI_ABORT: 0);
}
if (_length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, _length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)_length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3589,7 +3703,6 @@
free(name);
return result;
}
-
/* void glUniformBlockBinding ( GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding ) */
static void
android_glUniformBlockBinding__III
@@ -3651,7 +3764,6 @@
(GLsizei)instanceCount
);
}
-
/* GLsync glFenceSync ( GLenum condition, GLbitfield flags ) */
static jlong
android_glFenceSync__II
@@ -3733,7 +3845,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint64 *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetLongArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetInteger64v(
@@ -3743,7 +3855,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseLongArrayElements(params_ref, (jlong*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3755,14 +3867,14 @@
static void
android_glGetInteger64v__ILjava_nio_LongBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jlongArray _array = (jlongArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint64 *params = (GLint64 *) 0;
- params = (GLint64 *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint64 *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
params = (GLint64 *) (_paramsBase + _bufferOffset);
}
glGetInteger64v(
@@ -3770,7 +3882,7 @@
(GLint64 *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseLongArrayElements(_array, (jlong*)params, 0);
}
}
@@ -3802,7 +3914,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!values_ref) {
@@ -3819,7 +3931,7 @@
}
_valuesRemaining = _env->GetArrayLength(values_ref) - valuesOffset;
values_base = (GLint *)
- _env->GetPrimitiveArrayCritical(values_ref, (jboolean *)0);
+ _env->GetIntArrayElements(values_ref, (jboolean *)0);
values = values_base + valuesOffset;
glGetSynciv(
@@ -3832,11 +3944,11 @@
exit:
if (values_base) {
- _env->ReleasePrimitiveArrayCritical(values_ref, values_base,
+ _env->ReleaseIntArrayElements(values_ref, (jint*)values_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3848,23 +3960,23 @@
static void
android_glGetSynciv__JIILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jlong sync, jint pname, jint bufSize, jobject length_buf, jobject values_buf) {
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _valuesArray = (jarray) 0;
+ jintArray _valuesArray = (jintArray) 0;
jint _valuesBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
jint _valuesRemaining;
GLint *values = (GLint *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- values = (GLint *)getPointer(_env, values_buf, &_valuesArray, &_valuesRemaining, &_valuesBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ values = (GLint *)getPointer(_env, values_buf, (jarray*)&_valuesArray, &_valuesRemaining, &_valuesBufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (values == NULL) {
- char * _valuesBase = (char *)_env->GetPrimitiveArrayCritical(_valuesArray, (jboolean *) 0);
+ char * _valuesBase = (char *)_env->GetIntArrayElements(_valuesArray, (jboolean *) 0);
values = (GLint *) (_valuesBase + _valuesBufferOffset);
}
glGetSynciv(
@@ -3875,10 +3987,10 @@
(GLint *)values
);
if (_valuesArray) {
- releasePointer(_env, _valuesArray, values, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_valuesArray, (jint*)values, 0);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
}
}
@@ -3907,7 +4019,7 @@
}
_remaining = _env->GetArrayLength(data_ref) - offset;
data_base = (GLint64 *)
- _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+ _env->GetLongArrayElements(data_ref, (jboolean *)0);
data = data_base + offset;
glGetInteger64i_v(
@@ -3918,7 +4030,7 @@
exit:
if (data_base) {
- _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+ _env->ReleaseLongArrayElements(data_ref, (jlong*)data_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3930,14 +4042,14 @@
static void
android_glGetInteger64i_v__IILjava_nio_LongBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
- jarray _array = (jarray) 0;
+ jlongArray _array = (jlongArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint64 *data = (GLint64 *) 0;
- data = (GLint64 *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLint64 *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
- char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _dataBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
data = (GLint64 *) (_dataBase + _bufferOffset);
}
glGetInteger64i_v(
@@ -3946,7 +4058,7 @@
(GLint64 *)data
);
if (_array) {
- releasePointer(_env, _array, data, JNI_TRUE);
+ _env->ReleaseLongArrayElements(_array, (jlong*)data, 0);
}
}
@@ -3975,7 +4087,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint64 *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetLongArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetBufferParameteri64v(
@@ -3986,7 +4098,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseLongArrayElements(params_ref, (jlong*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -3998,14 +4110,14 @@
static void
android_glGetBufferParameteri64v__IILjava_nio_LongBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jlongArray _array = (jlongArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint64 *params = (GLint64 *) 0;
- params = (GLint64 *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint64 *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetLongArrayElements(_array, (jboolean *) 0);
params = (GLint64 *) (_paramsBase + _bufferOffset);
}
glGetBufferParameteri64v(
@@ -4014,7 +4126,7 @@
(GLint64 *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseLongArrayElements(_array, (jlong*)params, 0);
}
}
@@ -4043,7 +4155,7 @@
}
_remaining = _env->GetArrayLength(samplers_ref) - offset;
samplers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(samplers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(samplers_ref, (jboolean *)0);
samplers = samplers_base + offset;
glGenSamplers(
@@ -4053,7 +4165,7 @@
exit:
if (samplers_base) {
- _env->ReleasePrimitiveArrayCritical(samplers_ref, samplers_base,
+ _env->ReleaseIntArrayElements(samplers_ref, (jint*)samplers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4065,14 +4177,14 @@
static void
android_glGenSamplers__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint count, jobject samplers_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *samplers = (GLuint *) 0;
- samplers = (GLuint *)getPointer(_env, samplers_buf, &_array, &_remaining, &_bufferOffset);
+ samplers = (GLuint *)getPointer(_env, samplers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (samplers == NULL) {
- char * _samplersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _samplersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
samplers = (GLuint *) (_samplersBase + _bufferOffset);
}
glGenSamplers(
@@ -4080,7 +4192,7 @@
(GLuint *)samplers
);
if (_array) {
- releasePointer(_env, _array, samplers, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)samplers, 0);
}
}
@@ -4109,7 +4221,7 @@
}
_remaining = _env->GetArrayLength(samplers_ref) - offset;
samplers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(samplers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(samplers_ref, (jboolean *)0);
samplers = samplers_base + offset;
glDeleteSamplers(
@@ -4119,7 +4231,7 @@
exit:
if (samplers_base) {
- _env->ReleasePrimitiveArrayCritical(samplers_ref, samplers_base,
+ _env->ReleaseIntArrayElements(samplers_ref, (jint*)samplers_base,
JNI_ABORT);
}
if (_exception) {
@@ -4131,14 +4243,14 @@
static void
android_glDeleteSamplers__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint count, jobject samplers_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *samplers = (GLuint *) 0;
- samplers = (GLuint *)getPointer(_env, samplers_buf, &_array, &_remaining, &_bufferOffset);
+ samplers = (GLuint *)getPointer(_env, samplers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (samplers == NULL) {
- char * _samplersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _samplersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
samplers = (GLuint *) (_samplersBase + _bufferOffset);
}
glDeleteSamplers(
@@ -4146,7 +4258,7 @@
(GLuint *)samplers
);
if (_array) {
- releasePointer(_env, _array, samplers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)samplers, JNI_ABORT);
}
}
@@ -4207,7 +4319,7 @@
}
_remaining = _env->GetArrayLength(param_ref) - offset;
param_base = (GLint *)
- _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+ _env->GetIntArrayElements(param_ref, (jboolean *)0);
param = param_base + offset;
glSamplerParameteriv(
@@ -4218,7 +4330,7 @@
exit:
if (param_base) {
- _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+ _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
JNI_ABORT);
}
if (_exception) {
@@ -4230,14 +4342,14 @@
static void
android_glSamplerParameteriv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *param = (GLint *) 0;
- param = (GLint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+ param = (GLint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (param == NULL) {
- char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
param = (GLint *) (_paramBase + _bufferOffset);
}
glSamplerParameteriv(
@@ -4246,7 +4358,7 @@
(GLint *)param
);
if (_array) {
- releasePointer(_env, _array, param, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
}
}
@@ -4286,7 +4398,7 @@
}
_remaining = _env->GetArrayLength(param_ref) - offset;
param_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(param_ref, (jboolean *)0);
param = param_base + offset;
glSamplerParameterfv(
@@ -4297,7 +4409,7 @@
exit:
if (param_base) {
- _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+ _env->ReleaseFloatArrayElements(param_ref, (jfloat*)param_base,
JNI_ABORT);
}
if (_exception) {
@@ -4309,14 +4421,14 @@
static void
android_glSamplerParameterfv__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *param = (GLfloat *) 0;
- param = (GLfloat *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+ param = (GLfloat *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (param == NULL) {
- char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
param = (GLfloat *) (_paramBase + _bufferOffset);
}
glSamplerParameterfv(
@@ -4325,7 +4437,7 @@
(GLfloat *)param
);
if (_array) {
- releasePointer(_env, _array, param, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)param, JNI_ABORT);
}
}
@@ -4354,7 +4466,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetSamplerParameteriv(
@@ -4365,7 +4477,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4377,14 +4489,14 @@
static void
android_glGetSamplerParameteriv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetSamplerParameteriv(
@@ -4393,7 +4505,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -4422,7 +4534,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetSamplerParameterfv(
@@ -4433,7 +4545,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4445,14 +4557,14 @@
static void
android_glGetSamplerParameterfv__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetSamplerParameterfv(
@@ -4461,7 +4573,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
@@ -4510,7 +4622,7 @@
}
_remaining = _env->GetArrayLength(ids_ref) - offset;
ids_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+ _env->GetIntArrayElements(ids_ref, (jboolean *)0);
ids = ids_base + offset;
glDeleteTransformFeedbacks(
@@ -4520,7 +4632,7 @@
exit:
if (ids_base) {
- _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+ _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
JNI_ABORT);
}
if (_exception) {
@@ -4532,14 +4644,14 @@
static void
android_glDeleteTransformFeedbacks__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *ids = (GLuint *) 0;
- ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+ ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (ids == NULL) {
- char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
ids = (GLuint *) (_idsBase + _bufferOffset);
}
glDeleteTransformFeedbacks(
@@ -4547,7 +4659,7 @@
(GLuint *)ids
);
if (_array) {
- releasePointer(_env, _array, ids, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
}
}
@@ -4576,7 +4688,7 @@
}
_remaining = _env->GetArrayLength(ids_ref) - offset;
ids_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+ _env->GetIntArrayElements(ids_ref, (jboolean *)0);
ids = ids_base + offset;
glGenTransformFeedbacks(
@@ -4586,7 +4698,7 @@
exit:
if (ids_base) {
- _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+ _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4598,14 +4710,14 @@
static void
android_glGenTransformFeedbacks__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject ids_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *ids = (GLuint *) 0;
- ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+ ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (ids == NULL) {
- char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
ids = (GLuint *) (_idsBase + _bufferOffset);
}
glGenTransformFeedbacks(
@@ -4613,7 +4725,7 @@
(GLuint *)ids
);
if (_array) {
- releasePointer(_env, _array, ids, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)ids, 0);
}
}
@@ -4674,7 +4786,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!binaryFormat_ref) {
@@ -4691,10 +4803,10 @@
}
_binaryFormatRemaining = _env->GetArrayLength(binaryFormat_ref) - binaryFormatOffset;
binaryFormat_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(binaryFormat_ref, (jboolean *)0);
+ _env->GetIntArrayElements(binaryFormat_ref, (jboolean *)0);
binaryFormat = binaryFormat_base + binaryFormatOffset;
- binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_binaryRemaining, &_bufferOffset);
+ binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_binaryRemaining, &_bufferOffset);
if (binary == NULL) {
char * _binaryBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
binary = (GLvoid *) (_binaryBase + _bufferOffset);
@@ -4712,11 +4824,11 @@
releasePointer(_env, _array, binary, _exception ? JNI_FALSE : JNI_TRUE);
}
if (binaryFormat_base) {
- _env->ReleasePrimitiveArrayCritical(binaryFormat_ref, binaryFormat_base,
+ _env->ReleaseIntArrayElements(binaryFormat_ref, (jint*)binaryFormat_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4728,11 +4840,11 @@
static void
android_glGetProgramBinary__IILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2Ljava_nio_Buffer_2
(JNIEnv *_env, jobject _this, jint program, jint bufSize, jobject length_buf, jobject binaryFormat_buf, jobject binary_buf) {
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _binaryFormatArray = (jarray) 0;
+ jintArray _binaryFormatArray = (jintArray) 0;
jint _binaryFormatBufferOffset = (jint) 0;
- jarray _binaryArray = (jarray) 0;
+ jintArray _binaryArray = (jintArray) 0;
jint _binaryBufferOffset = (jint) 0;
jint _lengthRemaining;
GLsizei *length = (GLsizei *) 0;
@@ -4741,15 +4853,15 @@
jint _binaryRemaining;
GLvoid *binary = (GLvoid *) 0;
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- binaryFormat = (GLenum *)getPointer(_env, binaryFormat_buf, &_binaryFormatArray, &_binaryFormatRemaining, &_binaryFormatBufferOffset);
- binary = (GLvoid *)getPointer(_env, binary_buf, &_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ binaryFormat = (GLenum *)getPointer(_env, binaryFormat_buf, (jarray*)&_binaryFormatArray, &_binaryFormatRemaining, &_binaryFormatBufferOffset);
+ binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_binaryArray, &_binaryRemaining, &_binaryBufferOffset);
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (binaryFormat == NULL) {
- char * _binaryFormatBase = (char *)_env->GetPrimitiveArrayCritical(_binaryFormatArray, (jboolean *) 0);
+ char * _binaryFormatBase = (char *)_env->GetIntArrayElements(_binaryFormatArray, (jboolean *) 0);
binaryFormat = (GLenum *) (_binaryFormatBase + _binaryFormatBufferOffset);
}
if (binary == NULL) {
@@ -4767,10 +4879,10 @@
releasePointer(_env, _binaryArray, binary, JNI_TRUE);
}
if (_binaryFormatArray) {
- releasePointer(_env, _binaryFormatArray, binaryFormat, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_binaryFormatArray, (jint*)binaryFormat, 0);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
}
}
@@ -4783,7 +4895,7 @@
jint _remaining;
GLvoid *binary = (GLvoid *) 0;
- binary = (GLvoid *)getPointer(_env, binary_buf, &_array, &_remaining, &_bufferOffset);
+ binary = (GLvoid *)getPointer(_env, binary_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (binary == NULL) {
char * _binaryBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
binary = (GLvoid *) (_binaryBase + _bufferOffset);
@@ -4835,7 +4947,7 @@
}
_remaining = _env->GetArrayLength(attachments_ref) - offset;
attachments_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(attachments_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attachments_ref, (jboolean *)0);
attachments = attachments_base + offset;
glInvalidateFramebuffer(
@@ -4846,7 +4958,7 @@
exit:
if (attachments_base) {
- _env->ReleasePrimitiveArrayCritical(attachments_ref, attachments_base,
+ _env->ReleaseIntArrayElements(attachments_ref, (jint*)attachments_base,
JNI_ABORT);
}
if (_exception) {
@@ -4858,14 +4970,14 @@
static void
android_glInvalidateFramebuffer__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint numAttachments, jobject attachments_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLenum *attachments = (GLenum *) 0;
- attachments = (GLenum *)getPointer(_env, attachments_buf, &_array, &_remaining, &_bufferOffset);
+ attachments = (GLenum *)getPointer(_env, attachments_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (attachments == NULL) {
- char * _attachmentsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _attachmentsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
attachments = (GLenum *) (_attachmentsBase + _bufferOffset);
}
glInvalidateFramebuffer(
@@ -4874,7 +4986,7 @@
(GLenum *)attachments
);
if (_array) {
- releasePointer(_env, _array, attachments, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)attachments, JNI_ABORT);
}
}
@@ -4903,7 +5015,7 @@
}
_remaining = _env->GetArrayLength(attachments_ref) - offset;
attachments_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(attachments_ref, (jboolean *)0);
+ _env->GetIntArrayElements(attachments_ref, (jboolean *)0);
attachments = attachments_base + offset;
glInvalidateSubFramebuffer(
@@ -4918,7 +5030,7 @@
exit:
if (attachments_base) {
- _env->ReleasePrimitiveArrayCritical(attachments_ref, attachments_base,
+ _env->ReleaseIntArrayElements(attachments_ref, (jint*)attachments_base,
JNI_ABORT);
}
if (_exception) {
@@ -4930,14 +5042,14 @@
static void
android_glInvalidateSubFramebuffer__IILjava_nio_IntBuffer_2IIII
(JNIEnv *_env, jobject _this, jint target, jint numAttachments, jobject attachments_buf, jint x, jint y, jint width, jint height) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLenum *attachments = (GLenum *) 0;
- attachments = (GLenum *)getPointer(_env, attachments_buf, &_array, &_remaining, &_bufferOffset);
+ attachments = (GLenum *)getPointer(_env, attachments_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (attachments == NULL) {
- char * _attachmentsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _attachmentsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
attachments = (GLenum *) (_attachmentsBase + _bufferOffset);
}
glInvalidateSubFramebuffer(
@@ -4950,7 +5062,7 @@
(GLsizei)height
);
if (_array) {
- releasePointer(_env, _array, attachments, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)attachments, JNI_ABORT);
}
}
@@ -5006,7 +5118,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetInternalformativ(
@@ -5019,7 +5131,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5031,14 +5143,14 @@
static void
android_glGetInternalformativ__IIIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint internalformat, jint pname, jint bufSize, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetInternalformativ(
@@ -5049,7 +5161,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
diff --git a/core/jni/android_opengl_GLES31.cpp b/core/jni/android_opengl_GLES31.cpp
index e5ea950..92ecbe0 100644
--- a/core/jni/android_opengl_GLES31.cpp
+++ b/core/jni/android_opengl_GLES31.cpp
@@ -124,6 +124,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -227,7 +337,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -262,8 +373,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -273,8 +384,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -282,20 +393,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -308,7 +420,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -318,7 +431,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -410,7 +524,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFramebufferParameteriv(
@@ -421,7 +535,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -433,14 +547,14 @@
static void
android_glGetFramebufferParameteriv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetFramebufferParameteriv(
@@ -449,7 +563,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -478,7 +592,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetProgramInterfaceiv(
@@ -490,7 +604,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -502,14 +616,14 @@
static void
android_glGetProgramInterfaceiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint programInterface, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetProgramInterfaceiv(
@@ -519,7 +633,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -597,7 +711,7 @@
}
_propsRemaining = _env->GetArrayLength(props_ref) - propsOffset;
props_base = (GLenum *)
- _env->GetPrimitiveArrayCritical(props_ref, (jboolean *)0);
+ _env->GetIntArrayElements(props_ref, (jboolean *)0);
props = props_base + propsOffset;
if (!length_ref) {
@@ -614,7 +728,7 @@
}
_lengthRemaining = _env->GetArrayLength(length_ref) - lengthOffset;
length_base = (GLsizei *)
- _env->GetPrimitiveArrayCritical(length_ref, (jboolean *)0);
+ _env->GetIntArrayElements(length_ref, (jboolean *)0);
length = length_base + lengthOffset;
if (!params_ref) {
@@ -631,7 +745,7 @@
}
_paramsRemaining = _env->GetArrayLength(params_ref) - paramsOffset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + paramsOffset;
glGetProgramResourceiv(
@@ -647,15 +761,15 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (length_base) {
- _env->ReleasePrimitiveArrayCritical(length_ref, length_base,
+ _env->ReleaseIntArrayElements(length_ref, (jint*)length_base,
_exception ? JNI_ABORT: 0);
}
if (props_base) {
- _env->ReleasePrimitiveArrayCritical(props_ref, props_base,
+ _env->ReleaseIntArrayElements(props_ref, (jint*)props_base,
JNI_ABORT);
}
if (_exception) {
@@ -667,11 +781,11 @@
static void
android_glGetProgramResourceiv__IIIILjava_nio_IntBuffer_2ILjava_nio_IntBuffer_2Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint programInterface, jint index, jint propCount, jobject props_buf, jint bufSize, jobject length_buf, jobject params_buf) {
- jarray _propsArray = (jarray) 0;
+ jintArray _propsArray = (jintArray) 0;
jint _propsBufferOffset = (jint) 0;
- jarray _lengthArray = (jarray) 0;
+ jintArray _lengthArray = (jintArray) 0;
jint _lengthBufferOffset = (jint) 0;
- jarray _paramsArray = (jarray) 0;
+ jintArray _paramsArray = (jintArray) 0;
jint _paramsBufferOffset = (jint) 0;
jint _propsRemaining;
GLenum *props = (GLenum *) 0;
@@ -680,19 +794,19 @@
jint _paramsRemaining;
GLint *params = (GLint *) 0;
- props = (GLenum *)getPointer(_env, props_buf, &_propsArray, &_propsRemaining, &_propsBufferOffset);
- length = (GLsizei *)getPointer(_env, length_buf, &_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
- params = (GLint *)getPointer(_env, params_buf, &_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
+ props = (GLenum *)getPointer(_env, props_buf, (jarray*)&_propsArray, &_propsRemaining, &_propsBufferOffset);
+ length = (GLsizei *)getPointer(_env, length_buf, (jarray*)&_lengthArray, &_lengthRemaining, &_lengthBufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_paramsArray, &_paramsRemaining, &_paramsBufferOffset);
if (props == NULL) {
- char * _propsBase = (char *)_env->GetPrimitiveArrayCritical(_propsArray, (jboolean *) 0);
+ char * _propsBase = (char *)_env->GetIntArrayElements(_propsArray, (jboolean *) 0);
props = (GLenum *) (_propsBase + _propsBufferOffset);
}
if (length == NULL) {
- char * _lengthBase = (char *)_env->GetPrimitiveArrayCritical(_lengthArray, (jboolean *) 0);
+ char * _lengthBase = (char *)_env->GetIntArrayElements(_lengthArray, (jboolean *) 0);
length = (GLsizei *) (_lengthBase + _lengthBufferOffset);
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_paramsArray, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_paramsArray, (jboolean *) 0);
params = (GLint *) (_paramsBase + _paramsBufferOffset);
}
glGetProgramResourceiv(
@@ -706,13 +820,13 @@
(GLint *)params
);
if (_paramsArray) {
- releasePointer(_env, _paramsArray, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_paramsArray, (jint*)params, 0);
}
if (_lengthArray) {
- releasePointer(_env, _lengthArray, length, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_lengthArray, (jint*)length, 0);
}
if (_propsArray) {
- releasePointer(_env, _propsArray, props, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_propsArray, (jint*)props, JNI_ABORT);
}
}
@@ -814,7 +928,7 @@
}
_remaining = _env->GetArrayLength(pipelines_ref) - offset;
pipelines_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(pipelines_ref, (jboolean *)0);
+ _env->GetIntArrayElements(pipelines_ref, (jboolean *)0);
pipelines = pipelines_base + offset;
glDeleteProgramPipelines(
@@ -824,7 +938,7 @@
exit:
if (pipelines_base) {
- _env->ReleasePrimitiveArrayCritical(pipelines_ref, pipelines_base,
+ _env->ReleaseIntArrayElements(pipelines_ref, (jint*)pipelines_base,
JNI_ABORT);
}
if (_exception) {
@@ -836,14 +950,14 @@
static void
android_glDeleteProgramPipelines__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject pipelines_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *pipelines = (GLuint *) 0;
- pipelines = (GLuint *)getPointer(_env, pipelines_buf, &_array, &_remaining, &_bufferOffset);
+ pipelines = (GLuint *)getPointer(_env, pipelines_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pipelines == NULL) {
- char * _pipelinesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _pipelinesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
pipelines = (GLuint *) (_pipelinesBase + _bufferOffset);
}
glDeleteProgramPipelines(
@@ -851,7 +965,7 @@
(GLuint *)pipelines
);
if (_array) {
- releasePointer(_env, _array, pipelines, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)pipelines, JNI_ABORT);
}
}
@@ -880,7 +994,7 @@
}
_remaining = _env->GetArrayLength(pipelines_ref) - offset;
pipelines_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(pipelines_ref, (jboolean *)0);
+ _env->GetIntArrayElements(pipelines_ref, (jboolean *)0);
pipelines = pipelines_base + offset;
glGenProgramPipelines(
@@ -890,7 +1004,7 @@
exit:
if (pipelines_base) {
- _env->ReleasePrimitiveArrayCritical(pipelines_ref, pipelines_base,
+ _env->ReleaseIntArrayElements(pipelines_ref, (jint*)pipelines_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -902,14 +1016,14 @@
static void
android_glGenProgramPipelines__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint n, jobject pipelines_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *pipelines = (GLuint *) 0;
- pipelines = (GLuint *)getPointer(_env, pipelines_buf, &_array, &_remaining, &_bufferOffset);
+ pipelines = (GLuint *)getPointer(_env, pipelines_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pipelines == NULL) {
- char * _pipelinesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _pipelinesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
pipelines = (GLuint *) (_pipelinesBase + _bufferOffset);
}
glGenProgramPipelines(
@@ -917,7 +1031,7 @@
(GLuint *)pipelines
);
if (_array) {
- releasePointer(_env, _array, pipelines, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)pipelines, 0);
}
}
@@ -957,7 +1071,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetProgramPipelineiv(
@@ -968,7 +1082,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -980,14 +1094,14 @@
static void
android_glGetProgramPipelineiv__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pipeline, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetProgramPipelineiv(
@@ -996,7 +1110,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1175,7 +1289,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform1iv(
@@ -1187,7 +1301,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1199,14 +1313,14 @@
static void
android_glProgramUniform1iv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *value = (GLint *) 0;
- value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLint *) (_valueBase + _bufferOffset);
}
glProgramUniform1iv(
@@ -1216,7 +1330,7 @@
(GLint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1245,7 +1359,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform2iv(
@@ -1257,7 +1371,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1269,14 +1383,14 @@
static void
android_glProgramUniform2iv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *value = (GLint *) 0;
- value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLint *) (_valueBase + _bufferOffset);
}
glProgramUniform2iv(
@@ -1286,7 +1400,7 @@
(GLint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1315,7 +1429,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform3iv(
@@ -1327,7 +1441,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1339,14 +1453,14 @@
static void
android_glProgramUniform3iv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *value = (GLint *) 0;
- value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLint *) (_valueBase + _bufferOffset);
}
glProgramUniform3iv(
@@ -1356,7 +1470,7 @@
(GLint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1385,7 +1499,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform4iv(
@@ -1397,7 +1511,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1409,14 +1523,14 @@
static void
android_glProgramUniform4iv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *value = (GLint *) 0;
- value = (GLint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLint *) (_valueBase + _bufferOffset);
}
glProgramUniform4iv(
@@ -1426,7 +1540,7 @@
(GLint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1455,7 +1569,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform1uiv(
@@ -1467,7 +1581,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1479,14 +1593,14 @@
static void
android_glProgramUniform1uiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glProgramUniform1uiv(
@@ -1496,7 +1610,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1525,7 +1639,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform2uiv(
@@ -1537,7 +1651,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1549,14 +1663,14 @@
static void
android_glProgramUniform2uiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glProgramUniform2uiv(
@@ -1566,7 +1680,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1595,7 +1709,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform3uiv(
@@ -1607,7 +1721,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1619,14 +1733,14 @@
static void
android_glProgramUniform3uiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glProgramUniform3uiv(
@@ -1636,7 +1750,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1665,7 +1779,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetIntArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform4uiv(
@@ -1677,7 +1791,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseIntArrayElements(value_ref, (jint*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1689,14 +1803,14 @@
static void
android_glProgramUniform4uiv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *value = (GLuint *) 0;
- value = (GLuint *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLuint *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
value = (GLuint *) (_valueBase + _bufferOffset);
}
glProgramUniform4uiv(
@@ -1706,7 +1820,7 @@
(GLuint *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)value, JNI_ABORT);
}
}
@@ -1735,7 +1849,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform1fv(
@@ -1747,7 +1861,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1759,14 +1873,14 @@
static void
android_glProgramUniform1fv__IIILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniform1fv(
@@ -1776,7 +1890,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1805,7 +1919,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform2fv(
@@ -1817,7 +1931,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1829,14 +1943,14 @@
static void
android_glProgramUniform2fv__IIILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniform2fv(
@@ -1846,7 +1960,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1875,7 +1989,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform3fv(
@@ -1887,7 +2001,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1899,14 +2013,14 @@
static void
android_glProgramUniform3fv__IIILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniform3fv(
@@ -1916,7 +2030,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -1945,7 +2059,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniform4fv(
@@ -1957,7 +2071,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -1969,14 +2083,14 @@
static void
android_glProgramUniform4fv__IIILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniform4fv(
@@ -1986,7 +2100,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2015,7 +2129,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix2fv(
@@ -2028,7 +2142,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2040,14 +2154,14 @@
static void
android_glProgramUniformMatrix2fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix2fv(
@@ -2058,7 +2172,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2087,7 +2201,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix3fv(
@@ -2100,7 +2214,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2112,14 +2226,14 @@
static void
android_glProgramUniformMatrix3fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix3fv(
@@ -2130,7 +2244,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2159,7 +2273,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix4fv(
@@ -2172,7 +2286,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2184,14 +2298,14 @@
static void
android_glProgramUniformMatrix4fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix4fv(
@@ -2202,7 +2316,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2231,7 +2345,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix2x3fv(
@@ -2244,7 +2358,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2256,14 +2370,14 @@
static void
android_glProgramUniformMatrix2x3fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix2x3fv(
@@ -2274,7 +2388,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2303,7 +2417,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix3x2fv(
@@ -2316,7 +2430,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2328,14 +2442,14 @@
static void
android_glProgramUniformMatrix3x2fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix3x2fv(
@@ -2346,7 +2460,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2375,7 +2489,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix2x4fv(
@@ -2388,7 +2502,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2400,14 +2514,14 @@
static void
android_glProgramUniformMatrix2x4fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix2x4fv(
@@ -2418,7 +2532,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2447,7 +2561,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix4x2fv(
@@ -2460,7 +2574,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2472,14 +2586,14 @@
static void
android_glProgramUniformMatrix4x2fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix4x2fv(
@@ -2490,7 +2604,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2519,7 +2633,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix3x4fv(
@@ -2532,7 +2646,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2544,14 +2658,14 @@
static void
android_glProgramUniformMatrix3x4fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix3x4fv(
@@ -2562,7 +2676,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2591,7 +2705,7 @@
}
_remaining = _env->GetArrayLength(value_ref) - offset;
value_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(value_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(value_ref, (jboolean *)0);
value = value_base + offset;
glProgramUniformMatrix4x3fv(
@@ -2604,7 +2718,7 @@
exit:
if (value_base) {
- _env->ReleasePrimitiveArrayCritical(value_ref, value_base,
+ _env->ReleaseFloatArrayElements(value_ref, (jfloat*)value_base,
JNI_ABORT);
}
if (_exception) {
@@ -2616,14 +2730,14 @@
static void
android_glProgramUniformMatrix4x3fv__IIIZLjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint program, jint location, jint count, jboolean transpose, jobject value_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *value = (GLfloat *) 0;
- value = (GLfloat *)getPointer(_env, value_buf, &_array, &_remaining, &_bufferOffset);
+ value = (GLfloat *)getPointer(_env, value_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (value == NULL) {
- char * _valueBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valueBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
value = (GLfloat *) (_valueBase + _bufferOffset);
}
glProgramUniformMatrix4x3fv(
@@ -2634,7 +2748,7 @@
(GLfloat *)value
);
if (_array) {
- releasePointer(_env, _array, value, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)value, JNI_ABORT);
}
}
@@ -2706,7 +2820,7 @@
}
_remaining = _env->GetArrayLength(data_ref) - offset;
data_base = (GLboolean *)
- _env->GetPrimitiveArrayCritical(data_ref, (jboolean *)0);
+ _env->GetBooleanArrayElements(data_ref, (jboolean *)0);
data = data_base + offset;
glGetBooleani_v(
@@ -2717,7 +2831,7 @@
exit:
if (data_base) {
- _env->ReleasePrimitiveArrayCritical(data_ref, data_base,
+ _env->ReleaseBooleanArrayElements(data_ref, (jboolean*)data_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2729,14 +2843,14 @@
static void
android_glGetBooleani_v__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint index, jobject data_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLboolean *data = (GLboolean *) 0;
- data = (GLboolean *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLboolean *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
- char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _dataBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
data = (GLboolean *) (_dataBase + _bufferOffset);
}
glGetBooleani_v(
@@ -2745,7 +2859,7 @@
(GLboolean *)data
);
if (_array) {
- releasePointer(_env, _array, data, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)data, 0);
}
}
@@ -2806,7 +2920,7 @@
}
_remaining = _env->GetArrayLength(val_ref) - offset;
val_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(val_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(val_ref, (jboolean *)0);
val = val_base + offset;
glGetMultisamplefv(
@@ -2817,7 +2931,7 @@
exit:
if (val_base) {
- _env->ReleasePrimitiveArrayCritical(val_ref, val_base,
+ _env->ReleaseFloatArrayElements(val_ref, (jfloat*)val_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2829,14 +2943,14 @@
static void
android_glGetMultisamplefv__IILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jint index, jobject val_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *val = (GLfloat *) 0;
- val = (GLfloat *)getPointer(_env, val_buf, &_array, &_remaining, &_bufferOffset);
+ val = (GLfloat *)getPointer(_env, val_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (val == NULL) {
- char * _valBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _valBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
val = (GLfloat *) (_valBase + _bufferOffset);
}
glGetMultisamplefv(
@@ -2845,7 +2959,7 @@
(GLfloat *)val
);
if (_array) {
- releasePointer(_env, _array, val, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)val, 0);
}
}
@@ -2884,7 +2998,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexLevelParameteriv(
@@ -2896,7 +3010,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2908,14 +3022,14 @@
static void
android_glGetTexLevelParameteriv__IIILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint level, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexLevelParameteriv(
@@ -2925,7 +3039,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -2954,7 +3068,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexLevelParameterfv(
@@ -2966,7 +3080,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -2978,14 +3092,14 @@
static void
android_glGetTexLevelParameterfv__IIILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint level, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexLevelParameterfv(
@@ -2995,7 +3109,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
diff --git a/core/jni/android_opengl_GLES31Ext.cpp b/core/jni/android_opengl_GLES31Ext.cpp
index 7317e9f..2856308 100644
--- a/core/jni/android_opengl_GLES31Ext.cpp
+++ b/core/jni/android_opengl_GLES31Ext.cpp
@@ -125,6 +125,116 @@
return NULL;
}
+class ByteArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
+ return _env->GetByteArrayElements(array, is_copy);
+ }
+};
+class BooleanArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
+ return _env->GetBooleanArrayElements(array, is_copy);
+ }
+};
+class CharArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
+ return _env->GetCharArrayElements(array, is_copy);
+ }
+};
+class ShortArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
+ return _env->GetShortArrayElements(array, is_copy);
+ }
+};
+class IntArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
+ return _env->GetIntArrayElements(array, is_copy);
+ }
+};
+class LongArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
+ return _env->GetLongArrayElements(array, is_copy);
+ }
+};
+class FloatArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
+ return _env->GetFloatArrayElements(array, is_copy);
+ }
+};
+class DoubleArrayGetter {
+public:
+ static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
+ return _env->GetDoubleArrayElements(array, is_copy);
+ }
+};
+
+template<typename JTYPEARRAY, typename ARRAYGETTER>
+static void*
+getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
+ return ARRAYGETTER::Get(_env, array, is_copy);
+}
+
+class ByteArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
+ _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class BooleanArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
+ _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class CharArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
+ _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class ShortArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
+ _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class IntArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
+ _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class LongArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
+ _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class FloatArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
+ _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+class DoubleArrayReleaser {
+public:
+ static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
+ _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
+ }
+};
+
+template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
+static void
+releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
+ ARRAYRELEASER::Release(_env, array, data, commit);
+}
+
static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -228,7 +338,8 @@
return needed;
}
-template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
(JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -263,8 +374,8 @@
_exceptionMessage = "length - offset < needed";
goto exit;
}
- params_base = (CTYPE *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, params_ref, (jboolean *)0);
params = params_base + offset;
GET(
@@ -274,8 +385,8 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
- _exception ? JNI_ABORT: 0);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, params_ref, params_base, !_exception);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -283,20 +394,21 @@
}
-template <typename CTYPE, void GET(GLenum, CTYPE*)>
+template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
+ typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
jint _exception = 0;
const char * _exceptionType;
const char * _exceptionMessage;
- jarray _array = (jarray) 0;
+ JTYPEARRAY _array = (JTYPEARRAY) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
CTYPE *params = (CTYPE *) 0;
int _needed = 0;
- params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
_remaining /= sizeof(CTYPE); // convert from bytes to item count
_needed = getNeededCount(pname);
// if we didn't find this pname, we just assume the user passed
@@ -309,7 +421,8 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
+ _env, _array, (jboolean *) 0);
params = (CTYPE *) (_paramsBase + _bufferOffset);
}
GET(
@@ -319,7 +432,8 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
+ _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -359,7 +473,7 @@
}
_remaining = _env->GetArrayLength(ids_ref) - offset;
ids_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(ids_ref, (jboolean *)0);
+ _env->GetIntArrayElements(ids_ref, (jboolean *)0);
ids = ids_base + offset;
glDebugMessageControlKHR(
@@ -373,7 +487,7 @@
exit:
if (ids_base) {
- _env->ReleasePrimitiveArrayCritical(ids_ref, ids_base,
+ _env->ReleaseIntArrayElements(ids_ref, (jint*)ids_base,
JNI_ABORT);
}
if (_exception) {
@@ -385,14 +499,14 @@
static void
android_glDebugMessageControlKHR__IIIILjava_nio_IntBuffer_2Z
(JNIEnv *_env, jobject _this, jint source, jint type, jint severity, jint count, jobject ids_buf, jboolean enabled) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *ids = (GLuint *) 0;
- ids = (GLuint *)getPointer(_env, ids_buf, &_array, &_remaining, &_bufferOffset);
+ ids = (GLuint *)getPointer(_env, ids_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (ids == NULL) {
- char * _idsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _idsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
ids = (GLuint *) (_idsBase + _bufferOffset);
}
glDebugMessageControlKHR(
@@ -404,7 +518,7 @@
(GLboolean)enabled
);
if (_array) {
- releasePointer(_env, _array, ids, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)ids, JNI_ABORT);
}
}
@@ -784,7 +898,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterIivEXT(
@@ -795,7 +909,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -807,14 +921,14 @@
static void
android_glTexParameterIivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexParameterIivEXT(
@@ -823,7 +937,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -852,7 +966,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterIuivEXT(
@@ -863,7 +977,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -875,14 +989,14 @@
static void
android_glTexParameterIuivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glTexParameterIuivEXT(
@@ -891,7 +1005,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
}
@@ -920,7 +1034,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterIivEXT(
@@ -931,7 +1045,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -943,14 +1057,14 @@
static void
android_glGetTexParameterIivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexParameterIivEXT(
@@ -959,7 +1073,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -988,7 +1102,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterIuivEXT(
@@ -999,7 +1113,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1011,14 +1125,14 @@
static void
android_glGetTexParameterIuivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint target, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glGetTexParameterIuivEXT(
@@ -1027,7 +1141,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1056,7 +1170,7 @@
}
_remaining = _env->GetArrayLength(param_ref) - offset;
param_base = (GLint *)
- _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+ _env->GetIntArrayElements(param_ref, (jboolean *)0);
param = param_base + offset;
glSamplerParameterIivEXT(
@@ -1067,7 +1181,7 @@
exit:
if (param_base) {
- _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+ _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
JNI_ABORT);
}
if (_exception) {
@@ -1079,14 +1193,14 @@
static void
android_glSamplerParameterIivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *param = (GLint *) 0;
- param = (GLint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+ param = (GLint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (param == NULL) {
- char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
param = (GLint *) (_paramBase + _bufferOffset);
}
glSamplerParameterIivEXT(
@@ -1095,7 +1209,7 @@
(GLint *)param
);
if (_array) {
- releasePointer(_env, _array, param, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
}
}
@@ -1124,7 +1238,7 @@
}
_remaining = _env->GetArrayLength(param_ref) - offset;
param_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(param_ref, (jboolean *)0);
+ _env->GetIntArrayElements(param_ref, (jboolean *)0);
param = param_base + offset;
glSamplerParameterIuivEXT(
@@ -1135,7 +1249,7 @@
exit:
if (param_base) {
- _env->ReleasePrimitiveArrayCritical(param_ref, param_base,
+ _env->ReleaseIntArrayElements(param_ref, (jint*)param_base,
JNI_ABORT);
}
if (_exception) {
@@ -1147,14 +1261,14 @@
static void
android_glSamplerParameterIuivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject param_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *param = (GLuint *) 0;
- param = (GLuint *)getPointer(_env, param_buf, &_array, &_remaining, &_bufferOffset);
+ param = (GLuint *)getPointer(_env, param_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (param == NULL) {
- char * _paramBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
param = (GLuint *) (_paramBase + _bufferOffset);
}
glSamplerParameterIuivEXT(
@@ -1163,7 +1277,7 @@
(GLuint *)param
);
if (_array) {
- releasePointer(_env, _array, param, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)param, JNI_ABORT);
}
}
@@ -1192,7 +1306,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetSamplerParameterIivEXT(
@@ -1203,7 +1317,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1215,14 +1329,14 @@
static void
android_glGetSamplerParameterIivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetSamplerParameterIivEXT(
@@ -1231,7 +1345,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -1260,7 +1374,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetSamplerParameterIuivEXT(
@@ -1271,7 +1385,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1283,14 +1397,14 @@
static void
android_glGetSamplerParameterIuivEXT__IILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint sampler, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *params = (GLuint *) 0;
- params = (GLuint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLuint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLuint *) (_paramsBase + _bufferOffset);
}
glGetSamplerParameterIuivEXT(
@@ -1299,7 +1413,7 @@
(GLuint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp
index 5e73ef2..90e4bb6 100644
--- a/core/jni/android_text_StaticLayout.cpp
+++ b/core/jni/android_text_StaticLayout.cpp
@@ -48,10 +48,11 @@
static jclass gLineBreaks_class;
static JLineBreaksID gLineBreaks_fieldID;
-// set text and set a number of parameters for creating a layout (width, tabstops, strategy)
+// set text and set a number of parameters for creating a layout (width, tabstops, strategy,
+// hyphenFrequency)
static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length,
jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth,
- jintArray variableTabStops, jint defaultTabStop, jint strategy) {
+ jintArray variableTabStops, jint defaultTabStop, jint strategy, jint hyphenFrequency) {
LineBreaker* b = reinterpret_cast<LineBreaker*>(nativePtr);
b->resize(length);
env->GetCharArrayRegion(text, 0, length, b->buffer());
@@ -64,6 +65,7 @@
b->setTabStops(stops.get(), stops.size(), defaultTabStop);
}
b->setStrategy(static_cast<BreakStrategy>(strategy));
+ b->setHyphenationFrequency(static_cast<HyphenationFrequency>(hyphenFrequency));
}
static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks,
@@ -177,7 +179,7 @@
{"nFinishBuilder", "(J)V", (void*) nFinishBuilder},
{"nLoadHyphenator", "(Ljava/lang/String;)J", (void*) nLoadHyphenator},
{"nSetLocale", "(JLjava/lang/String;J)V", (void*) nSetLocale},
- {"nSetupParagraph", "(J[CIFIF[III)V", (void*) nSetupParagraph},
+ {"nSetupParagraph", "(J[CIFIF[IIII)V", (void*) nSetupParagraph},
{"nSetIndents", "(J[I)V", (void*) nSetIndents},
{"nAddStyleRun", "(JJJIIZ)F", (void*) nAddStyleRun},
{"nAddMeasuredRun", "(JII[F)V", (void*) nAddMeasuredRun},
diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp
index 265daeb..d61dee7 100644
--- a/core/jni/android_view_InputEventSender.cpp
+++ b/core/jni/android_view_InputEventSender.cpp
@@ -135,7 +135,8 @@
for (size_t i = 0; i <= event->getHistorySize(); i++) {
publishedSeq = mNextPublishedSeq++;
status_t status = mInputPublisher.publishMotionEvent(publishedSeq,
- event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(),
+ event->getDeviceId(), event->getSource(),
+ event->getAction(), event->getActionButton(), event->getFlags(),
event->getEdgeFlags(), event->getMetaState(), event->getButtonState(),
event->getXOffset(), event->getYOffset(),
event->getXPrecision(), event->getYPrecision(),
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index e622768..1f28643 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -370,7 +370,7 @@
env->DeleteLocalRef(pointerCoordsObj);
}
- event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState,
+ event->initialize(deviceId, source, action, flags, edgeFlags, metaState, buttonState, 0,
xOffset, yOffset, xPrecision, yPrecision,
downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords);
@@ -456,6 +456,12 @@
event->setAction(action);
}
+static int android_view_MotionEvent_nativeGetActionButton(JNIEnv* env, jclass clazz,
+ jlong nativePtr) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ return event->getActionButton();
+}
+
static jboolean android_view_MotionEvent_nativeIsTouchEvent(JNIEnv* env, jclass clazz,
jlong nativePtr) {
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
@@ -498,6 +504,12 @@
return event->getButtonState();
}
+static void android_view_MotionEvent_nativeSetButtonState(JNIEnv* env, jclass clazz,
+ jlong nativePtr, jint buttonState) {
+ MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
+ event->setButtonState(buttonState);
+}
+
static void android_view_MotionEvent_nativeOffsetLocation(JNIEnv* env, jclass clazz,
jlong nativePtr, jfloat deltaX, jfloat deltaY) {
MotionEvent* event = reinterpret_cast<MotionEvent*>(nativePtr);
@@ -764,6 +776,9 @@
{ "nativeSetAction",
"(JI)V",
(void*)android_view_MotionEvent_nativeSetAction },
+ { "nativeGetActionButton",
+ "(J)I",
+ (void*)android_view_MotionEvent_nativeGetActionButton},
{ "nativeIsTouchEvent",
"(J)Z",
(void*)android_view_MotionEvent_nativeIsTouchEvent },
@@ -785,6 +800,9 @@
{ "nativeGetButtonState",
"(J)I",
(void*)android_view_MotionEvent_nativeGetButtonState },
+ { "nativeSetButtonState",
+ "(JI)V",
+ (void*)android_view_MotionEvent_nativeSetButtonState },
{ "nativeOffsetLocation",
"(JFF)V",
(void*)android_view_MotionEvent_nativeOffsetLocation },
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index c4cd7ff..3fa92a8 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -483,7 +483,8 @@
proxy->initialize(surface);
// Shadows can't be used via this interface, so just set the light source
// to all 0s. (and width & height are unused, TODO remove them)
- proxy->setup(0, 0, (Vector3){0, 0, 0}, 0, 0, 0);
+ proxy->setup(0, 0, 0, 0, 0);
+ proxy->setLightCenter((Vector3){0, 0, 0});
return (jlong) proxy;
}
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 5d5465b..47132f4 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -290,12 +290,15 @@
}
static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
- jint width, jint height,
- jfloat lightX, jfloat lightY, jfloat lightZ, jfloat lightRadius,
- jint ambientShadowAlpha, jint spotShadowAlpha, jfloat density) {
+ jint width, jint height, jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->setup(width, height, (Vector3){lightX, lightY, lightZ}, lightRadius,
- ambientShadowAlpha, spotShadowAlpha);
+ proxy->setup(width, height, lightRadius, ambientShadowAlpha, spotShadowAlpha);
+}
+
+static void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) {
+ RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+ proxy->setLightCenter((Vector3){lightX, lightY, lightZ});
}
static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
@@ -461,7 +464,8 @@
{ "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
{ "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
{ "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
- { "nSetup", "(JIIFFFFII)V", (void*) android_view_ThreadedRenderer_setup },
+ { "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
+ { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
{ "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroy", "(J)V", (void*) android_view_ThreadedRenderer_destroy },
diff --git a/core/jni/com_google_android_gles_jni_GLImpl.cpp b/core/jni/com_google_android_gles_jni_GLImpl.cpp
index c5f330e..f15f957 100644
--- a/core/jni/com_google_android_gles_jni_GLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_GLImpl.cpp
@@ -449,7 +449,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -478,7 +478,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (data == NULL) {
char * _dataBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
data = (GLvoid *) (_dataBase + _bufferOffset);
@@ -571,7 +571,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glDeleteTextures(
@@ -581,7 +581,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
JNI_ABORT);
}
if (_exception) {
@@ -596,12 +596,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -609,7 +609,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glDeleteTextures(
@@ -619,7 +619,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -705,7 +705,7 @@
jint _remaining;
GLvoid *indices = (GLvoid *) 0;
- indices = (GLvoid *)getPointer(_env, indices_buf, &_array, &_remaining, &_bufferOffset);
+ indices = (GLvoid *)getPointer(_env, indices_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < count) {
_exception = 1;
_exceptionType = "java/lang/ArrayIndexOutOfBoundsException";
@@ -830,7 +830,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glFogfv(
@@ -840,7 +840,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -855,12 +855,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_FOG_MODE)
@@ -893,7 +893,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glFogfv(
@@ -903,7 +903,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -976,7 +976,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glFogxv(
@@ -986,7 +986,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -1001,12 +1001,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_FOG_MODE)
@@ -1039,7 +1039,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glFogxv(
@@ -1049,7 +1049,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1124,7 +1124,7 @@
goto exit;
}
textures_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(textures_ref, (jboolean *)0);
+ _env->GetIntArrayElements(textures_ref, (jboolean *)0);
textures = textures_base + offset;
glGenTextures(
@@ -1134,7 +1134,7 @@
exit:
if (textures_base) {
- _env->ReleasePrimitiveArrayCritical(textures_ref, textures_base,
+ _env->ReleaseIntArrayElements(textures_ref, (jint*)textures_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1149,12 +1149,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *textures = (GLuint *) 0;
- textures = (GLuint *)getPointer(_env, textures_buf, &_array, &_remaining, &_bufferOffset);
+ textures = (GLuint *)getPointer(_env, textures_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -1162,7 +1162,7 @@
goto exit;
}
if (textures == NULL) {
- char * _texturesBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _texturesBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
textures = (GLuint *) (_texturesBase + _bufferOffset);
}
glGenTextures(
@@ -1172,7 +1172,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, textures, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)textures, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -1550,7 +1550,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetIntegerv(
@@ -1560,7 +1560,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -1575,12 +1575,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_ALPHA_BITS)
@@ -1919,7 +1919,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetIntegerv(
@@ -1929,7 +1929,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2008,7 +2008,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightModelfv(
@@ -2018,7 +2018,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2033,12 +2033,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_LIGHT_MODEL_TWO_SIDE)
@@ -2062,7 +2062,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glLightModelfv(
@@ -2072,7 +2072,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2136,7 +2136,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightModelxv(
@@ -2146,7 +2146,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2161,12 +2161,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_LIGHT_MODEL_TWO_SIDE)
@@ -2190,7 +2190,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightModelxv(
@@ -2200,7 +2200,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2291,7 +2291,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightfv(
@@ -2302,7 +2302,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2317,12 +2317,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_EXPONENT)
@@ -2372,7 +2372,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glLightfv(
@@ -2383,7 +2383,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2474,7 +2474,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glLightxv(
@@ -2485,7 +2485,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2500,12 +2500,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_EXPONENT)
@@ -2555,7 +2555,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glLightxv(
@@ -2566,7 +2566,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2623,7 +2623,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glLoadMatrixf(
@@ -2632,7 +2632,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -2644,21 +2644,21 @@
static void
android_glLoadMatrixf__Ljava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *m = (GLfloat *) 0;
- m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
m = (GLfloat *) (_mBase + _bufferOffset);
}
glLoadMatrixf(
(GLfloat *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
}
}
@@ -2687,7 +2687,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glLoadMatrixx(
@@ -2696,7 +2696,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -2708,21 +2708,21 @@
static void
android_glLoadMatrixx__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glLoadMatrixx(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -2805,7 +2805,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glMaterialfv(
@@ -2816,7 +2816,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2831,12 +2831,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SHININESS)
@@ -2872,7 +2872,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glMaterialfv(
@@ -2883,7 +2883,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -2960,7 +2960,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glMaterialxv(
@@ -2971,7 +2971,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -2986,12 +2986,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SHININESS)
@@ -3027,7 +3027,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glMaterialxv(
@@ -3038,7 +3038,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3079,7 +3079,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glMultMatrixf(
@@ -3088,7 +3088,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseFloatArrayElements(m_ref, (jfloat*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -3100,21 +3100,21 @@
static void
android_glMultMatrixf__Ljava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *m = (GLfloat *) 0;
- m = (GLfloat *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfloat *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
m = (GLfloat *) (_mBase + _bufferOffset);
}
glMultMatrixf(
(GLfloat *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)m, JNI_ABORT);
}
}
@@ -3143,7 +3143,7 @@
}
_remaining = _env->GetArrayLength(m_ref) - offset;
m_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(m_ref, (jboolean *)0);
+ _env->GetIntArrayElements(m_ref, (jboolean *)0);
m = m_base + offset;
glMultMatrixx(
@@ -3152,7 +3152,7 @@
exit:
if (m_base) {
- _env->ReleasePrimitiveArrayCritical(m_ref, m_base,
+ _env->ReleaseIntArrayElements(m_ref, (jint*)m_base,
JNI_ABORT);
}
if (_exception) {
@@ -3164,21 +3164,21 @@
static void
android_glMultMatrixx__Ljava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jobject m_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *m = (GLfixed *) 0;
- m = (GLfixed *)getPointer(_env, m_buf, &_array, &_remaining, &_bufferOffset);
+ m = (GLfixed *)getPointer(_env, m_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (m == NULL) {
- char * _mBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _mBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
m = (GLfixed *) (_mBase + _bufferOffset);
}
glMultMatrixx(
(GLfixed *)m
);
if (_array) {
- releasePointer(_env, _array, m, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)m, JNI_ABORT);
}
}
@@ -3352,7 +3352,7 @@
jint _remaining;
GLvoid *pixels = (GLvoid *) 0;
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
pixels = (GLvoid *) (_pixelsBase + _bufferOffset);
@@ -3577,7 +3577,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnvfv(
@@ -3588,7 +3588,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -3603,12 +3603,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_MODE)
@@ -3638,7 +3638,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexEnvfv(
@@ -3649,7 +3649,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3720,7 +3720,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnvxv(
@@ -3731,7 +3731,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -3746,12 +3746,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_MODE)
@@ -3781,7 +3781,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexEnvxv(
@@ -3792,7 +3792,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -3809,7 +3809,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -3863,7 +3863,7 @@
GLvoid *pixels = (GLvoid *) 0;
if (pixels_buf) {
- pixels = (GLvoid *)getPointer(_env, pixels_buf, &_array, &_remaining, &_bufferOffset);
+ pixels = (GLvoid *)getPointer(_env, pixels_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
}
if (pixels_buf && pixels == NULL) {
char * _pixelsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
@@ -3978,7 +3978,7 @@
goto exit;
}
mantissa_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(mantissa_ref, (jboolean *)0);
+ _env->GetIntArrayElements(mantissa_ref, (jboolean *)0);
mantissa = mantissa_base + mantissaOffset;
if (!exponent_ref) {
@@ -4001,7 +4001,7 @@
goto exit;
}
exponent_base = (GLint *)
- _env->GetPrimitiveArrayCritical(exponent_ref, (jboolean *)0);
+ _env->GetIntArrayElements(exponent_ref, (jboolean *)0);
exponent = exponent_base + exponentOffset;
_returnValue = glQueryMatrixxOES(
@@ -4011,11 +4011,11 @@
exit:
if (exponent_base) {
- _env->ReleasePrimitiveArrayCritical(exponent_ref, exponent_base,
+ _env->ReleaseIntArrayElements(exponent_ref, (jint*)exponent_base,
_exception ? JNI_ABORT: 0);
}
if (mantissa_base) {
- _env->ReleasePrimitiveArrayCritical(mantissa_ref, mantissa_base,
+ _env->ReleaseIntArrayElements(mantissa_ref, (jint*)mantissa_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4031,9 +4031,9 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _mantissaArray = (jarray) 0;
+ jintArray _mantissaArray = (jintArray) 0;
jint _mantissaBufferOffset = (jint) 0;
- jarray _exponentArray = (jarray) 0;
+ jintArray _exponentArray = (jintArray) 0;
jint _exponentBufferOffset = (jint) 0;
GLbitfield _returnValue = -1;
jint _mantissaRemaining;
@@ -4041,14 +4041,14 @@
jint _exponentRemaining;
GLint *exponent = (GLint *) 0;
- mantissa = (GLfixed *)getPointer(_env, mantissa_buf, &_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
+ mantissa = (GLfixed *)getPointer(_env, mantissa_buf, (jarray*)&_mantissaArray, &_mantissaRemaining, &_mantissaBufferOffset);
if (_mantissaRemaining < 16) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
_exceptionMessage = "remaining() < 16 < needed";
goto exit;
}
- exponent = (GLint *)getPointer(_env, exponent_buf, &_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
+ exponent = (GLint *)getPointer(_env, exponent_buf, (jarray*)&_exponentArray, &_exponentRemaining, &_exponentBufferOffset);
if (_exponentRemaining < 16) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4056,11 +4056,11 @@
goto exit;
}
if (mantissa == NULL) {
- char * _mantissaBase = (char *)_env->GetPrimitiveArrayCritical(_mantissaArray, (jboolean *) 0);
+ char * _mantissaBase = (char *)_env->GetIntArrayElements(_mantissaArray, (jboolean *) 0);
mantissa = (GLfixed *) (_mantissaBase + _mantissaBufferOffset);
}
if (exponent == NULL) {
- char * _exponentBase = (char *)_env->GetPrimitiveArrayCritical(_exponentArray, (jboolean *) 0);
+ char * _exponentBase = (char *)_env->GetIntArrayElements(_exponentArray, (jboolean *) 0);
exponent = (GLint *) (_exponentBase + _exponentBufferOffset);
}
_returnValue = glQueryMatrixxOES(
@@ -4070,10 +4070,10 @@
exit:
if (_exponentArray) {
- releasePointer(_env, _exponentArray, exponent, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_exponentArray, (jint*)exponent, _exception ? JNI_ABORT : 0);
}
if (_mantissaArray) {
- releasePointer(_env, _mantissaArray, mantissa, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_mantissaArray, (jint*)mantissa, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4104,7 +4104,7 @@
GLvoid *data = (GLvoid *) 0;
if (data_buf) {
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4144,7 +4144,7 @@
jint _remaining;
GLvoid *data = (GLvoid *) 0;
- data = (GLvoid *)getPointer(_env, data_buf, &_array, &_remaining, &_bufferOffset);
+ data = (GLvoid *)getPointer(_env, data_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < size) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4202,7 +4202,7 @@
goto exit;
}
equation_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanef(
@@ -4212,7 +4212,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseFloatArrayElements(equation_ref, (jfloat*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -4227,12 +4227,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *equation = (GLfloat *) 0;
- equation = (GLfloat *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfloat *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4240,7 +4240,7 @@
goto exit;
}
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
equation = (GLfloat *) (_equationBase + _bufferOffset);
}
glClipPlanef(
@@ -4250,7 +4250,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)equation, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4288,7 +4288,7 @@
goto exit;
}
equation_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(equation_ref, (jboolean *)0);
+ _env->GetIntArrayElements(equation_ref, (jboolean *)0);
equation = equation_base + offset;
glClipPlanex(
@@ -4298,7 +4298,7 @@
exit:
if (equation_base) {
- _env->ReleasePrimitiveArrayCritical(equation_ref, equation_base,
+ _env->ReleaseIntArrayElements(equation_ref, (jint*)equation_base,
JNI_ABORT);
}
if (_exception) {
@@ -4313,12 +4313,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *equation = (GLfixed *) 0;
- equation = (GLfixed *)getPointer(_env, equation_buf, &_array, &_remaining, &_bufferOffset);
+ equation = (GLfixed *)getPointer(_env, equation_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 4) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4326,7 +4326,7 @@
goto exit;
}
if (equation == NULL) {
- char * _equationBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _equationBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
equation = (GLfixed *) (_equationBase + _bufferOffset);
}
glClipPlanex(
@@ -4336,7 +4336,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, equation, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)equation, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4398,7 +4398,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glDeleteBuffers(
@@ -4408,7 +4408,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
JNI_ABORT);
}
if (_exception) {
@@ -4423,12 +4423,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4436,7 +4436,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glDeleteBuffers(
@@ -4446,7 +4446,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4502,7 +4502,7 @@
goto exit;
}
buffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(buffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(buffers_ref, (jboolean *)0);
buffers = buffers_base + offset;
glGenBuffers(
@@ -4512,7 +4512,7 @@
exit:
if (buffers_base) {
- _env->ReleasePrimitiveArrayCritical(buffers_ref, buffers_base,
+ _env->ReleaseIntArrayElements(buffers_ref, (jint*)buffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4527,12 +4527,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *buffers = (GLuint *) 0;
- buffers = (GLuint *)getPointer(_env, buffers_buf, &_array, &_remaining, &_bufferOffset);
+ buffers = (GLuint *)getPointer(_env, buffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -4540,7 +4540,7 @@
goto exit;
}
if (buffers == NULL) {
- char * _buffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _buffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
buffers = (GLuint *) (_buffersBase + _bufferOffset);
}
glGenBuffers(
@@ -4550,7 +4550,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, buffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)buffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -4582,7 +4582,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLboolean *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetBooleanArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetBooleanv(
@@ -4592,7 +4592,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseBooleanArrayElements(params_ref, (jboolean*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4604,14 +4604,14 @@
static void
android_glGetBooleanv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLboolean *params = (GLboolean *) 0;
- params = (GLboolean *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLboolean *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLboolean *) (_paramsBase + _bufferOffset);
}
glGetBooleanv(
@@ -4619,7 +4619,7 @@
(GLboolean *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -4664,7 +4664,7 @@
}
_remaining = _env->GetArrayLength(eqn_ref) - offset;
eqn_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanef(
@@ -4674,7 +4674,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseFloatArrayElements(eqn_ref, (jfloat*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4686,14 +4686,14 @@
static void
android_glGetClipPlanef__ILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *eqn = (GLfloat *) 0;
- eqn = (GLfloat *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfloat *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
eqn = (GLfloat *) (_eqnBase + _bufferOffset);
}
glGetClipPlanef(
@@ -4701,7 +4701,7 @@
(GLfloat *)eqn
);
if (_array) {
- releasePointer(_env, _array, eqn, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)eqn, 0);
}
}
@@ -4730,7 +4730,7 @@
}
_remaining = _env->GetArrayLength(eqn_ref) - offset;
eqn_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(eqn_ref, (jboolean *)0);
+ _env->GetIntArrayElements(eqn_ref, (jboolean *)0);
eqn = eqn_base + offset;
glGetClipPlanex(
@@ -4740,7 +4740,7 @@
exit:
if (eqn_base) {
- _env->ReleasePrimitiveArrayCritical(eqn_ref, eqn_base,
+ _env->ReleaseIntArrayElements(eqn_ref, (jint*)eqn_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4752,14 +4752,14 @@
static void
android_glGetClipPlanex__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject eqn_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *eqn = (GLfixed *) 0;
- eqn = (GLfixed *)getPointer(_env, eqn_buf, &_array, &_remaining, &_bufferOffset);
+ eqn = (GLfixed *)getPointer(_env, eqn_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (eqn == NULL) {
- char * _eqnBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _eqnBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
eqn = (GLfixed *) (_eqnBase + _bufferOffset);
}
glGetClipPlanex(
@@ -4767,7 +4767,7 @@
(GLfixed *)eqn
);
if (_array) {
- releasePointer(_env, _array, eqn, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)eqn, 0);
}
}
@@ -4796,7 +4796,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFixedv(
@@ -4806,7 +4806,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4818,14 +4818,14 @@
static void
android_glGetFixedv__ILjava_nio_IntBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetFixedv(
@@ -4833,7 +4833,7 @@
(GLfixed *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -4862,7 +4862,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFloatv(
@@ -4872,7 +4872,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -4884,14 +4884,14 @@
static void
android_glGetFloatv__ILjava_nio_FloatBuffer_2
(JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetFloatv(
@@ -4899,7 +4899,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
@@ -4976,7 +4976,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetLightfv(
@@ -4987,7 +4987,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5002,12 +5002,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_EXPONENT)
@@ -5057,7 +5057,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetLightfv(
@@ -5068,7 +5068,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5148,7 +5148,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetLightxv(
@@ -5159,7 +5159,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5174,12 +5174,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SPOT_EXPONENT)
@@ -5229,7 +5229,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetLightxv(
@@ -5240,7 +5240,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5306,7 +5306,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetMaterialfv(
@@ -5317,7 +5317,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5332,12 +5332,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SHININESS)
@@ -5373,7 +5373,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetMaterialfv(
@@ -5384,7 +5384,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5450,7 +5450,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetMaterialxv(
@@ -5461,7 +5461,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5476,12 +5476,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_SHININESS)
@@ -5517,7 +5517,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetMaterialxv(
@@ -5528,7 +5528,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5588,7 +5588,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnviv(
@@ -5599,7 +5599,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5614,12 +5614,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_MODE)
@@ -5649,7 +5649,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexEnviv(
@@ -5660,7 +5660,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5720,7 +5720,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexEnvxv(
@@ -5731,7 +5731,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5746,12 +5746,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_MODE)
@@ -5781,7 +5781,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexEnvxv(
@@ -5792,7 +5792,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5830,7 +5830,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterfv(
@@ -5841,7 +5841,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5856,12 +5856,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5869,7 +5869,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexParameterfv(
@@ -5880,7 +5880,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -5918,7 +5918,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameteriv(
@@ -5929,7 +5929,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -5944,12 +5944,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -5957,7 +5957,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexParameteriv(
@@ -5968,7 +5968,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6006,7 +6006,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexParameterxv(
@@ -6017,7 +6017,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -6032,12 +6032,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6045,7 +6045,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glGetTexParameterxv(
@@ -6056,7 +6056,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6148,7 +6148,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glPointParameterfv(
@@ -6158,7 +6158,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6173,12 +6173,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6186,7 +6186,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glPointParameterfv(
@@ -6196,7 +6196,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6244,7 +6244,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glPointParameterxv(
@@ -6254,7 +6254,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6269,12 +6269,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6282,7 +6282,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glPointParameterxv(
@@ -6292,7 +6292,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6398,7 +6398,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexEnviv(
@@ -6409,7 +6409,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6424,12 +6424,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
int _needed;
switch (pname) {
#if defined(GL_TEXTURE_ENV_MODE)
@@ -6459,7 +6459,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexEnviv(
@@ -6470,7 +6470,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6508,7 +6508,7 @@
goto exit;
}
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterfv(
@@ -6519,7 +6519,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6534,12 +6534,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6547,7 +6547,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexParameterfv(
@@ -6558,7 +6558,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6607,7 +6607,7 @@
goto exit;
}
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameteriv(
@@ -6618,7 +6618,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6633,12 +6633,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6646,7 +6646,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexParameteriv(
@@ -6657,7 +6657,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6695,7 +6695,7 @@
goto exit;
}
params_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexParameterxv(
@@ -6706,7 +6706,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
JNI_ABORT);
}
if (_exception) {
@@ -6721,12 +6721,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *params = (GLfixed *) 0;
- params = (GLfixed *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfixed *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 1) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6734,7 +6734,7 @@
goto exit;
}
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLfixed *) (_paramsBase + _bufferOffset);
}
glTexParameterxv(
@@ -6745,7 +6745,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, params, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6817,7 +6817,7 @@
goto exit;
}
coords_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexfvOES(
@@ -6826,7 +6826,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseFloatArrayElements(coords_ref, (jfloat*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -6841,12 +6841,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *coords = (GLfloat *) 0;
- coords = (GLfloat *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLfloat *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6854,7 +6854,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
coords = (GLfloat *) (_coordsBase + _bufferOffset);
}
glDrawTexfvOES(
@@ -6863,7 +6863,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -6914,7 +6914,7 @@
goto exit;
}
coords_base = (GLint *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetIntArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexivOES(
@@ -6923,7 +6923,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -6938,12 +6938,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *coords = (GLint *) 0;
- coords = (GLint *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLint *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -6951,7 +6951,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
coords = (GLint *) (_coordsBase + _bufferOffset);
}
glDrawTexivOES(
@@ -6960,7 +6960,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7011,7 +7011,7 @@
goto exit;
}
coords_base = (GLshort *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetShortArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexsvOES(
@@ -7020,7 +7020,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseShortArrayElements(coords_ref, (jshort*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -7035,12 +7035,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jshortArray _array = (jshortArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLshort *coords = (GLshort *) 0;
- coords = (GLshort *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLshort *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7048,7 +7048,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetShortArrayElements(_array, (jboolean *) 0);
coords = (GLshort *) (_coordsBase + _bufferOffset);
}
glDrawTexsvOES(
@@ -7057,7 +7057,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseShortArrayElements(_array, (jshort*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7108,7 +7108,7 @@
goto exit;
}
coords_base = (GLfixed *)
- _env->GetPrimitiveArrayCritical(coords_ref, (jboolean *)0);
+ _env->GetIntArrayElements(coords_ref, (jboolean *)0);
coords = coords_base + offset;
glDrawTexxvOES(
@@ -7117,7 +7117,7 @@
exit:
if (coords_base) {
- _env->ReleasePrimitiveArrayCritical(coords_ref, coords_base,
+ _env->ReleaseIntArrayElements(coords_ref, (jint*)coords_base,
JNI_ABORT);
}
if (_exception) {
@@ -7132,12 +7132,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfixed *coords = (GLfixed *) 0;
- coords = (GLfixed *)getPointer(_env, coords_buf, &_array, &_remaining, &_bufferOffset);
+ coords = (GLfixed *)getPointer(_env, coords_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < 5) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7145,7 +7145,7 @@
goto exit;
}
if (coords == NULL) {
- char * _coordsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _coordsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
coords = (GLfixed *) (_coordsBase + _bufferOffset);
}
glDrawTexxvOES(
@@ -7154,7 +7154,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, coords, JNI_FALSE);
+ _env->ReleaseIntArrayElements(_array, (jint*)coords, JNI_ABORT);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7368,7 +7368,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glDeleteFramebuffersOES(
@@ -7378,7 +7378,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7398,12 +7398,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7411,7 +7411,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glDeleteFramebuffersOES(
@@ -7421,7 +7421,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7464,7 +7464,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glDeleteRenderbuffersOES(
@@ -7474,7 +7474,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7494,12 +7494,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7507,7 +7507,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glDeleteRenderbuffersOES(
@@ -7517,7 +7517,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7609,7 +7609,7 @@
goto exit;
}
framebuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(framebuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(framebuffers_ref, (jboolean *)0);
framebuffers = framebuffers_base + offset;
glGenFramebuffersOES(
@@ -7619,7 +7619,7 @@
exit:
if (framebuffers_base) {
- _env->ReleasePrimitiveArrayCritical(framebuffers_ref, framebuffers_base,
+ _env->ReleaseIntArrayElements(framebuffers_ref, (jint*)framebuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7639,12 +7639,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *framebuffers = (GLuint *) 0;
- framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, &_array, &_remaining, &_bufferOffset);
+ framebuffers = (GLuint *)getPointer(_env, framebuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7652,7 +7652,7 @@
goto exit;
}
if (framebuffers == NULL) {
- char * _framebuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _framebuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
framebuffers = (GLuint *) (_framebuffersBase + _bufferOffset);
}
glGenFramebuffersOES(
@@ -7662,7 +7662,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, framebuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)framebuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7705,7 +7705,7 @@
goto exit;
}
renderbuffers_base = (GLuint *)
- _env->GetPrimitiveArrayCritical(renderbuffers_ref, (jboolean *)0);
+ _env->GetIntArrayElements(renderbuffers_ref, (jboolean *)0);
renderbuffers = renderbuffers_base + offset;
glGenRenderbuffersOES(
@@ -7715,7 +7715,7 @@
exit:
if (renderbuffers_base) {
- _env->ReleasePrimitiveArrayCritical(renderbuffers_ref, renderbuffers_base,
+ _env->ReleaseIntArrayElements(renderbuffers_ref, (jint*)renderbuffers_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7735,12 +7735,12 @@
jint _exception = 0;
const char * _exceptionType = NULL;
const char * _exceptionMessage = NULL;
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLuint *renderbuffers = (GLuint *) 0;
- renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, &_array, &_remaining, &_bufferOffset);
+ renderbuffers = (GLuint *)getPointer(_env, renderbuffers_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (_remaining < n) {
_exception = 1;
_exceptionType = "java/lang/IllegalArgumentException";
@@ -7748,7 +7748,7 @@
goto exit;
}
if (renderbuffers == NULL) {
- char * _renderbuffersBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _renderbuffersBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
renderbuffers = (GLuint *) (_renderbuffersBase + _bufferOffset);
}
glGenRenderbuffersOES(
@@ -7758,7 +7758,7 @@
exit:
if (_array) {
- releasePointer(_env, _array, renderbuffers, _exception ? JNI_FALSE : JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)renderbuffers, _exception ? JNI_ABORT : 0);
}
if (_exception) {
jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -7795,7 +7795,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetFramebufferAttachmentParameterivOES(
@@ -7807,7 +7807,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7824,14 +7824,14 @@
"glGetFramebufferAttachmentParameterivOES");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetFramebufferAttachmentParameterivOES(
@@ -7841,7 +7841,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -7875,7 +7875,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetRenderbufferParameterivOES(
@@ -7886,7 +7886,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7903,14 +7903,14 @@
"glGetRenderbufferParameterivOES");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetRenderbufferParameterivOES(
@@ -7919,7 +7919,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -7953,7 +7953,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGenfv(
@@ -7964,7 +7964,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -7981,14 +7981,14 @@
"glGetTexGenfv");
return;
}
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glGetTexGenfv(
@@ -7997,7 +7997,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
@@ -8031,7 +8031,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGeniv(
@@ -8042,7 +8042,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -8059,14 +8059,14 @@
"glGetTexGeniv");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexGeniv(
@@ -8075,7 +8075,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -8109,7 +8109,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glGetTexGenxv(
@@ -8120,7 +8120,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -8137,14 +8137,14 @@
"glGetTexGenxv");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glGetTexGenxv(
@@ -8153,7 +8153,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -8252,7 +8252,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLfloat *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetFloatArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGenfv(
@@ -8263,7 +8263,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseFloatArrayElements(params_ref, (jfloat*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -8280,14 +8280,14 @@
"glTexGenfv");
return;
}
- jarray _array = (jarray) 0;
+ jfloatArray _array = (jfloatArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLfloat *params = (GLfloat *) 0;
- params = (GLfloat *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLfloat *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetFloatArrayElements(_array, (jboolean *) 0);
params = (GLfloat *) (_paramsBase + _bufferOffset);
}
glTexGenfv(
@@ -8296,7 +8296,7 @@
(GLfloat *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseFloatArrayElements(_array, (jfloat*)params, 0);
}
}
@@ -8346,7 +8346,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGeniv(
@@ -8357,7 +8357,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -8374,14 +8374,14 @@
"glTexGeniv");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexGeniv(
@@ -8390,7 +8390,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
@@ -8440,7 +8440,7 @@
}
_remaining = _env->GetArrayLength(params_ref) - offset;
params_base = (GLint *)
- _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
+ _env->GetIntArrayElements(params_ref, (jboolean *)0);
params = params_base + offset;
glTexGenxv(
@@ -8451,7 +8451,7 @@
exit:
if (params_base) {
- _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
+ _env->ReleaseIntArrayElements(params_ref, (jint*)params_base,
_exception ? JNI_ABORT: 0);
}
if (_exception) {
@@ -8468,14 +8468,14 @@
"glTexGenxv");
return;
}
- jarray _array = (jarray) 0;
+ jintArray _array = (jintArray) 0;
jint _bufferOffset = (jint) 0;
jint _remaining;
GLint *params = (GLint *) 0;
- params = (GLint *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
+ params = (GLint *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
if (params == NULL) {
- char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+ char * _paramsBase = (char *)_env->GetIntArrayElements(_array, (jboolean *) 0);
params = (GLint *) (_paramsBase + _bufferOffset);
}
glTexGenxv(
@@ -8484,7 +8484,7 @@
(GLint *)params
);
if (_array) {
- releasePointer(_env, _array, params, JNI_TRUE);
+ _env->ReleaseIntArrayElements(_array, (jint*)params, 0);
}
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e5bba6e..608d718 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -678,6 +678,7 @@
<!-- Allows an app to use fingerprint hardware. -->
<permission android:name="android.permission.USE_FINGERPRINT"
+ android:permissionGroup="android.permission-group.SENSORS"
android:label="@string/permlab_useFingerprint"
android:description="@string/permdesc_useFingerprint"
android:protectionLevel="dangerous" />
@@ -836,9 +837,7 @@
<!-- Allows an application to create mock location providers for testing. -->
<permission android:name="android.permission.ACCESS_MOCK_LOCATION"
- android:label="@string/permlab_accessMockLocation"
- android:description="@string/permdesc_accessMockLocation"
- android:protectionLevel="normal" />
+ android:protectionLevel="signature" />
<!-- ======================================= -->
<!-- Permissions for accessing networks -->
@@ -849,7 +848,7 @@
<permission android:name="android.permission.INTERNET"
android:description="@string/permdesc_createNetworkSockets"
android:label="@string/permlab_createNetworkSockets"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="normal" />
<!-- Allows applications to access information about networks -->
<permission android:name="android.permission.ACCESS_NETWORK_STATE"
@@ -942,7 +941,7 @@
<permission android:name="android.permission.NFC"
android:description="@string/permdesc_nfc"
android:label="@string/permlab_nfc"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="normal" />
<!-- @SystemApi Allows an internal user to use privileged ConnectivityManager APIs.
@hide -->
@@ -1109,6 +1108,11 @@
<permission android:name="android.permission.CAPTURE_TV_INPUT"
android:protectionLevel="signatureOrSystem" />
+ <!-- @hide Allows TvInputService to access DVB device.
+ <p>Not for use by third-party applications. -->
+ <permission android:name="android.permission.DVB_DEVICE"
+ android:protectionLevel="signatureOrSystem" />
+
<!-- @hide Allows enabling/disabling OEM unlock
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.OEM_UNLOCK_STATE"
@@ -1186,10 +1190,20 @@
android:protectionLevel="system|signature" />
<!-- Must be required by a {@link android.telecom.ConnectionService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ @deprecated {@link android.telecom.ConnectionService}s should require
+ android.permission.BIND_TELECOM_CONNECTION_SERVICE instead.
+ @SystemApi
+ @hide -->
<permission android:name="android.permission.BIND_CONNECTION_SERVICE"
android:protectionLevel="system|signature" />
+ <!-- Must be required by a {@link android.telecom.ConnectionService},
+ to ensure that only the system can bind to it. -->
+ <permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
+ android:protectionLevel="system|signature" />
+
+
<!-- @SystemApi Allows an application to control the in-call experience.
@hide -->
<permission android:name="android.permission.CONTROL_INCALL_EXPERIENCE"
@@ -1262,7 +1276,7 @@
<permission android:name="android.permission.DISABLE_KEYGUARD"
android:description="@string/permdesc_disableKeyguard"
android:label="@string/permlab_disableKeyguard"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="normal" />
<!-- ================================== -->
<!-- Permissions to access other installed applications -->
@@ -2391,8 +2405,7 @@
<permission android:name="android.permission.REMOVE_DRM_CERTIFICATES"
android:protectionLevel="signature|system" />
- <!-- Must be required by a {@link android.service.carrier.CarrierMessagingService}.
- Any service that filters for this intent must be a carrier privileged app. -->
+ <!-- @deprecated Use {@link android.Manifest.permission#BIND_CARRIER_SERVICES} instead -->
<permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"
android:protectionLevel="signature|system" />
@@ -2414,13 +2427,12 @@
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature" />
- <!-- The system process that pulls carrier configuration from carrier apps will
- have this permission. Carrier apps that provide
- {@link android.service.carrier.CarrierConfigService} should require this
- permission for clients binding to their service. -->
- <permission android:name="android.permission.BIND_CARRIER_CONFIG_SERVICE"
- android:label="@string/permlab_bindCarrierConfigService"
- android:description="@string/permdesc_bindCarrierConfigService"
+ <!-- The system process that is allowed to bind to services in carrier apps will
+ have this permission. Carrier apps should use this permission to protect
+ their services that only the system is allowed to bind to. -->
+ <permission android:name="android.permission.BIND_CARRIER_SERVICES"
+ android:label="@string/permlab_bindCarrierServices"
+ android:description="@string/permdesc_bindCarrierServices"
android:protectionLevel="signature|system" />
<!-- Allows an application to query whether DO_NOT_ASK_CREDENTIALS_ON_BOOT
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 65cb046..f5d945a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -14,35 +14,30 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="560.0dp"
- android:height="560.0dp"
- android:viewportWidth="560.0"
- android:viewportHeight="560.0">
+ android:width="480dp"
+ android:height="480dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
<path
- android:pathData="M264.079987,240.736l0.0,9.82c7.31,-7.15 17.139999,-11.56 28.07,-11.56c22.639999,0.0 40.799999,18.48 40.799999,41.12c0.0,22.48 -18.16,40.880 -40.799999,40.880c-10.93,0.0 -20.280,-4.09 -27.59,-10.93L264.559998,339.0l-11.32,0.0l0.0,-98.269997L264.079987,240.731zM265.809998,264.869995c-0.47,0.79 -1.26,2.04 -1.26,4.79l0.0,21.07c0.0,1.97 0.47,3.07 1.1,4.17c5.19,8.88 14.78,14.94 25.63,14.94c16.43,0.0 29.950,-13.44 29.950,-29.870c0.0,-16.280 -13.52,-29.799999 -29.950,-29.799999C280.51,250.169998 271.0,256.059998 265.809998,264.869995z"
+ android:pathData="M24.0,2.0C11.8,2.0 2.0,11.8 2.0,24.0c0.0,6.1 2.5,11.6 6.4,15.6L39.6,8.4C35.6,4.5 30.1,2.0 24.0,2.0z"
+ android:fillColor="#F57C00"/>
+ <path
+ android:pathData="M39.6,8.4L8.4,39.6c4.0,4.0 9.5,6.4 15.6,6.4c12.2,0.0 22.0,-9.8 22.0,-22.0C46.0,17.9 43.5,12.4 39.6,8.4z"
+ android:fillColor="#FF9800"/>
+ <path
+ android:pathData="M45.9,25.9L34.0,14.0L14.0,34.0l11.9,11.9C36.5,45.0 45.0,36.5 45.9,25.9z"
+ android:fillAlpha="0.33"
+ android:fillColor="#F57C00"/>
+ <path
+ android:pathData="M24.0,24.0c0.0,0.0 0.0,2.2 0.0,5.0s0.0,5.0 0.0,5.0l10.0,-10.0L34.0,14.0L24.0,24.0z"
android:fillColor="#FFFFFF"/>
<path
- android:pathData="M445.731,240.736l0.0,9.82c7.31,-7.15 17.139999,-11.56 28.07,-11.56c22.639999,0.0 40.799999,18.48 40.799999,41.12c0.0,22.48 -18.16,40.880 -40.799999,40.880c-10.93,0.0 -20.280,-4.09 -27.59,-10.93L446.210052,339.0l-11.32,0.0l0.0,-98.269997L445.731,240.731zM447.459991,264.869995c-0.47,0.79 -1.26,2.04 -1.26,4.79l0.0,21.07c0.0,1.97 0.47,3.07 1.1,4.17c5.19,8.88 14.78,14.94 25.63,14.94c16.43,0.0 29.950,-13.44 29.950,-29.870c0.0,-16.280 -13.52,-29.799999 -29.950,-29.799999C462.160004,250.169998 452.649994,256.059998 447.459991,264.869995z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M24.0,24.0L14.0,14.0l0.0,10.0l10.0,10.0c0.0,0.0 0.0,-2.2 0.0,-5.0S24.0,24.0 24.0,24.0z"
+ android:fillColor="#EEEEEE"/>
<path
- android:pathData="M169.490005,279.880005c0.0,22.639999 -18.32,41.12 -40.810,41.12c-22.639999,0.0 -41.040,-18.48 -41.040,-41.12c0.0,-22.48 18.389999,-40.880 41.040,-40.880C151.169998,239.0 169.490005,257.399994 169.490005,279.880005zM158.089996,280.040009c0.0,-16.43 -13.13,-29.870 -29.41,-29.870c-16.51,0.0 -29.4,13.44 -29.4,29.870c0.0,16.280 12.89,29.799999 29.4,29.799999C144.960007,309.8387 158.089996,296.309998 158.089996,280.040009z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z"
+ android:fillColor="#DDDDDD"/>
<path
- android:pathData="M423.790009,279.880005c0.0,22.639999 -18.32,41.12 -40.810,41.12c-22.639999,0.0 -41.040,-18.48 -41.040,-41.12c0.0,-22.48 18.389999,-40.880 41.040,-40.880C405.470,239.0 423.790009,257.399994 423.790009,279.880005zM412.395,280.040009c0.0,-16.43 -13.13,-29.870 -29.41,-29.870c-16.51,0.0 -29.4,13.44 -29.4,29.870c0.0,16.280 12.89,29.799999 29.4,29.799999C399.26,309.8387 412.395,296.309998 412.395,280.040009z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M229.02,221.0l11.17,0.0l0.0,11.48l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M229.02,240.65l11.17,0.0l0.0,78.62l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M65.4,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M180.58,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M204.8,221.0l11.17,0.0l0.0,98.27l-11.17,0.0z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z"
+ android:fillColor="#DDDDDD"/>
</vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index d89d1f9..8f5109df 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -19,9 +19,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:pathData="M19.000000,10.000000c0.000000,3.866000 -3.134000,7.000000 -7.000000,7.000000s-7.000000,-3.134000 -7.000000,-7.000000c0.000000,-2.318000 1.131000,-4.367000 2.867000,-5.641000L5.778000,2.270000l0.824000,-0.825000l2.290000,2.290000C9.830000,3.269000 10.882000,3.000000 12.000000,3.000000c1.118000,0.000000 2.170000,0.269000 3.107000,0.734000l2.290000,-2.290000l0.824000,0.825000l-2.089000,2.090000C17.868000,5.633000 19.000000,7.682000 19.000000,10.000000zM10.000000,8.000000c0.000000,-0.552000 -0.447000,-1.000000 -1.000000,-1.000000S8.000000,7.448000 8.000000,8.000000s0.447000,1.000000 1.000000,1.000000S10.000000,8.552000 10.000000,8.000000zM16.000000,8.000000c0.000000,-0.552000 -0.447000,-1.000000 -1.000000,-1.000000s-1.000000,0.448000 -1.000000,1.000000s0.447000,1.000000 1.000000,1.000000S16.000000,8.552000 16.000000,8.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M11,18l2,0l0,5l-2,0z"
- android:fillColor="#FFFFFF"/>
+ android:fillColor="#FF000000"
+ android:pathData="M12.0,12.0l-10.0,-10.0 0.0,10.0 0.0,10.0 10.0,0.0 10.0,0.0 0.0,-10.0 0.0,-10.0z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_alarm.xml b/core/res/res/drawable/ic_audio_alarm.xml
index fc4bf10..96206ea 100644
--- a/core/res/res/drawable/ic_audio_alarm.xml
+++ b/core/res/res/drawable/ic_audio_alarm.xml
@@ -17,8 +17,9 @@
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportHeight="48.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M44.0,11.44l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-28.24,-4.66l-2.57,-3.06 -9.19,7.71 2.57,3.06 9.19,-7.71zm9.24,9.22l-3.0,0.0l0.0,12.0l9.49,5.71 1.51,-2.47 -8.0,-4.74l0.0,-10.5zm-1.01,-8.0c-9.95,0.0 -17.99,8.06 -17.99,18.0s8.04,18.0 17.99,18.0 18.01,-8.06 18.01,-18.0 -8.06,-18.0 -18.01,-18.0zm0.01,32.0c-7.73,0.0 -14.0,-6.27 -14.0,-14.0s6.27,-14.0 14.0,-14.0 14.0,6.27 14.0,14.0 -6.26,14.0 -14.0,14.0z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_alarm_mute.xml b/core/res/res/drawable/ic_audio_alarm_mute.xml
index 1d24081..7f248c3 100644
--- a/core/res/res/drawable/ic_audio_alarm_mute.xml
+++ b/core/res/res/drawable/ic_audio_alarm_mute.xml
@@ -17,8 +17,9 @@
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportHeight="48.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M24.0,12.0c7.73,0.0 14.0,6.27 14.0,14.0 0.0,1.69 -0.31,3.3 -0.86,4.8l3.04,3.04c1.16,-2.37 1.82,-5.03 1.82,-7.84 0.0,-9.94 -8.06,-18.0 -18.01,-18.0 -2.81,0.0 -5.46,0.66 -7.84,1.81l3.05,3.05c1.5,-0.55 3.11,-0.86 4.8,-0.86zm20.0,-0.56l-9.19,-7.71 -2.57,3.06 9.19,7.71 2.57,-3.06zm-38.16,-6.85l-2.55,2.54 2.66,2.66 -2.22,1.86 2.84,2.84 2.22,-1.86 1.6,1.6c-2.73,3.16 -4.39,7.27 -4.39,11.77 0.0,9.94 8.04,18.0 17.99,18.0 4.51,0.0 8.62,-1.67 11.77,-4.4l4.4,4.4 2.54,-2.55 -34.91,-34.91 -1.95,-1.95zm27.1,32.19c-2.43,2.01 -5.54,3.22 -8.94,3.22 -7.73,0.0 -14.0,-6.27 -14.0,-14.0 0.0,-3.4 1.21,-6.51 3.22,-8.94l19.72,19.72zm-16.91,-30.23l-2.84,-2.84 -1.7,1.43 2.84,2.84 1.7,-1.43z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_media.xml b/core/res/res/drawable/ic_audio_media.xml
index a453b3db..4ef5340 100644
--- a/core/res/res/drawable/ic_audio_media.xml
+++ b/core/res/res/drawable/ic_audio_media.xml
@@ -17,10 +17,11 @@
android:height="32.0dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
- android:width="32.0dp" >
+ android:width="32.0dp"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M12.0,3.0l0.0,9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12.0 6.0,14.01 6.0,16.5S8.01,21.0 10.5,21.0c2.31,0.0 4.2,-1.75 4.45,-4.0L15.0,17.0L15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0z" />
</vector>
diff --git a/core/res/res/drawable/ic_audio_media_mute.xml b/core/res/res/drawable/ic_audio_media_mute.xml
index 2e7f6dc..2be6dc4 100644
--- a/core/res/res/drawable/ic_audio_media_mute.xml
+++ b/core/res/res/drawable/ic_audio_media_mute.xml
@@ -17,13 +17,14 @@
android:height="32.0dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0"
- android:width="32.0dp" >
+ android:width="32.0dp"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M15.0,6.0l4.0,0.0L19.0,3.0l-7.0,0.0l0.0,5.6l3.0,3.0C15.0,8.8 15.0,6.0 15.0,6.0z" />
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M4.8,3.9L3.5,5.1l6.9,6.9C8.0,12.1 6.0,14.0 6.0,16.5C6.0,19.0 8.0,21.0 10.5,21.0c2.7,0.0 4.5,-2.3 4.5,-4.3c0.0,0.0 0.0,-0.1 0.0,-0.1l4.0,4.0l1.3,-1.3L4.8,3.9z" />
</vector>
diff --git a/core/res/res/drawable/ic_audio_ring_notif.xml b/core/res/res/drawable/ic_audio_ring_notif.xml
index 60a98ab..54c4074 100644
--- a/core/res/res/drawable/ic_audio_ring_notif.xml
+++ b/core/res/res/drawable/ic_audio_ring_notif.xml
@@ -17,9 +17,10 @@
android:width="32dp"
android:height="32dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="#8A000000"
+ android:fillColor="@color/black"
android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_ring_notif_mute.xml b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
index 17dfa7e..b591520 100644
--- a/core/res/res/drawable/ic_audio_ring_notif_mute.xml
+++ b/core/res/res/drawable/ic_audio_ring_notif_mute.xml
@@ -17,9 +17,10 @@
android:width="32dp"
android:height="32dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="#8A000000"
+ android:fillColor="@color/black"
android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7C9.5,4.3 9.0,4.5 8.6,4.7l9.4,9.4L18.0,10.5zM17.7,19.0l2.0,2.0l1.3,-1.3L4.3,3.0L3.0,4.3l2.9,2.9C5.3,8.2 5.0,9.3 5.0,10.5L5.0,16.0l-2.0,2.0l0.0,1.0L17.7,19.0z" />
</vector>
diff --git a/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml
index 2ed33ea..b3a2859 100644
--- a/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml
+++ b/core/res/res/drawable/ic_audio_ring_notif_vibrate.xml
@@ -17,9 +17,10 @@
android:width="32dp"
android:height="32dp"
android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:viewportHeight="24.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="#8A000000"
+ android:fillColor="@color/black"
android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_vol.xml b/core/res/res/drawable/ic_audio_vol.xml
index a55be93..fc216e5 100644
--- a/core/res/res/drawable/ic_audio_vol.xml
+++ b/core/res/res/drawable/ic_audio_vol.xml
@@ -17,8 +17,9 @@
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportHeight="48.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,8.0L14.0,18.0L6.0,18.0zm27.0,6.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,16.11c2.96,-1.48 5.0,-4.53 5.0,-8.06zM28.0,6.46l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41s-4.22,11.69 -10.0,13.41l0.0,4.13c8.01,-1.82 14.0,-8.97 14.0,-17.54S36.01,8.28 28.0,6.46z"/>
</vector>
diff --git a/core/res/res/drawable/ic_audio_vol_mute.xml b/core/res/res/drawable/ic_audio_vol_mute.xml
index ab50a7d..7cf604c 100644
--- a/core/res/res/drawable/ic_audio_vol_mute.xml
+++ b/core/res/res/drawable/ic_audio_vol_mute.xml
@@ -17,8 +17,9 @@
android:width="32.0dp"
android:height="32.0dp"
android:viewportWidth="48.0"
- android:viewportHeight="48.0">
+ android:viewportHeight="48.0"
+ android:tint="?attr/colorControlNormal">
<path
- android:fillColor="?android:attr/colorControlNormal"
+ android:fillColor="@color/black"
android:pathData="M33.0,24.0c0.0,-3.53 -2.04,-6.58 -5.0,-8.05l0.0,4.42l4.91,4.91c0.06,-0.42 0.09,-0.85 0.09,-1.28zm5.0,0.0c0.0,1.88 -0.41,3.65 -1.08,5.28l3.03,3.03C41.25,29.82 42.0,27.0 42.0,24.0c0.0,-8.56 -5.99,-15.72 -14.0,-17.54l0.0,4.13c5.78,1.72 10.0,7.07 10.0,13.41zM8.55,6.0L6.0,8.55 15.45,18.0L6.0,18.0l0.0,12.0l8.0,0.0l10.0,10.0L24.0,26.55l8.51,8.51c-1.34,1.03 -2.85,1.86 -4.51,2.36l0.0,4.13c2.75,-0.63 5.26,-1.89 7.37,-3.62L39.45,42.0 42.0,39.45l-18.0,-18.0L8.55,6.0zM24.0,8.0l-4.18,4.18L24.0,16.36L24.0,8.0z"/>
</vector>
diff --git a/core/res/res/drawable/ic_eject_24dp.xml b/core/res/res/drawable/ic_eject_24dp.xml
new file mode 100644
index 0000000..1bb351a
--- /dev/null
+++ b/core/res/res/drawable/ic_eject_24dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M5 17h14v2H5zm7,-12L5.33 15h13.34z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_folder_24dp.xml b/core/res/res/drawable/ic_folder_24dp.xml
new file mode 100644
index 0000000..9a386ca
--- /dev/null
+++ b/core/res/res/drawable/ic_folder_24dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M20 8H8c-2.21 0,-3.98 1.79,-3.98 4L4 36c0 2.21 1.79 4 4 4h32c2.21 0 4,-1.79 4,-4V16c0,-2.21,-1.79,-4,-4,-4H24l-4,-4z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_perm_device_info.xml b/core/res/res/drawable/ic_perm_device_info.xml
new file mode 100644
index 0000000..ef91c74
--- /dev/null
+++ b/core/res/res/drawable/ic_perm_device_info.xml
@@ -0,0 +1,24 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M26.0,14.0l-4.0,0.0l0.0,4.0l4.0,0.0l0.0,-4.0zm0.0,8.0l-4.0,0.0l0.0,12.0l4.0,0.0L26.0,22.0zm8.0,-19.98L14.0,2.0c-2.21,0.0 -4.0,1.79 -4.0,4.0l0.0,36.0c0.0,2.21 1.79,4.0 4.0,4.0l20.0,0.0c2.21,0.0 4.0,-1.79 4.0,-4.0L38.0,6.0c0.0,-2.21 -1.79,-3.98 -4.0,-3.98zM34.0,38.0L14.0,38.0L14.0,10.0l20.0,0.0l0.0,28.0z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_sd_card_48dp.xml b/core/res/res/drawable/ic_sd_card_48dp.xml
new file mode 100644
index 0000000..90bab47
--- /dev/null
+++ b/core/res/res/drawable/ic_sd_card_48dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M36 4H20L8.04 16 8 40c0 2.2 1.8 4 4 4h24c2.2 0 4,-1.8 4,-4V8c0,-2.2,-1.8,-4,-4,-4zM24 16h-4V8h4v8zm6 0h-4V8h4v8zm6 0h-4V8h4v8z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_settings_24dp.xml b/core/res/res/drawable/ic_settings_24dp.xml
new file mode 100644
index 0000000..fc75f04
--- /dev/null
+++ b/core/res/res/drawable/ic_settings_24dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M38.86 25.95c.08,-.64.14,-1.29.14,-1.95s-.06,-1.31,-.14,-1.95l4.23,-3.31c.38,-.3.49,-.84.24,-1.28l-4,-6.93c-.25,-.43,-.77,-.61,-1.22,-.43l-4.98 2.01c-1.03,-.79,-2.16,-1.46,-3.38,-1.97L29 4.84c-.09,-.47,-.5,-.84,-1,-.84h-8c-.5 0,-.91.37,-.99.84l-.75 5.3c-1.22.51,-2.35 1.17,-3.38 1.97L9.9 10.1c-.45,-.17,-.97 0,-1.22.43l-4 6.93c-.25.43,-.14.97.24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31.14 1.95l-4.22 3.31c-.38.3,-.49.84,-.24 1.28l4 6.93c.25.43.77.61 1.22.43l4.98,-2.01c1.03.79 2.16 1.46 3.38 1.97l.75 5.3c.08.47.49.84.99.84h8c.5 0 .91,-.37.99,-.84l.75,-5.3c1.22,-.51 2.35,-1.17 3.38,-1.97l4.98 2.01c.45.17.97 0 1.22,-.43l4,-6.93c.25,-.43.14,-.97,-.24,-1.28l-4.22,-3.31zM24 31c-3.87 0,-7,-3.13,-7,-7s3.13,-7 7,-7 7 3.13 7 7,-3.13 7,-7 7z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_storage_48dp.xml b/core/res/res/drawable/ic_storage_48dp.xml
new file mode 100644
index 0000000..14233a4
--- /dev/null
+++ b/core/res/res/drawable/ic_storage_48dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M4 40h40v-8H4v8zm4,-6h4v4H8v-4zM4 8v8h40V8H4zm8 6H8v-4h4v4zM4 28h40v-8H4v8zm4,-6h4v4H8v-4z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_usb_48dp.xml b/core/res/res/drawable/ic_usb_48dp.xml
new file mode 100644
index 0000000..b2ec709
--- /dev/null
+++ b/core/res/res/drawable/ic_usb_48dp.xml
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M30 14v8h2v4h-6V10h4l-6,-8,-6 8h4v16h-6v-4.14c1.41,-.73 2.4,-2.16 2.4,-3.86 0,-2.43,-1.97,-4.4,-4.4,-4.4,-2.43 0,-4.4 1.97,-4.4 4.4 0 1.7.99 3.13 2.4 3.86V26c0 2.21 1.79 4 4 4h6v6.1c-1.42.73,-2.4 2.19,-2.4 3.9 0 2.43 1.97 4.4 4.4 4.4 2.43 0 4.4,-1.97 4.4,-4.4 0,-1.71,-.98,-3.17,-2.4,-3.9V30h6c2.21 0 4,-1.79 4,-4v-4h2v-8h-8z"/>
+</vector>
diff --git a/core/res/res/layout/select_dialog_multichoice_material.xml b/core/res/res/layout/select_dialog_multichoice_material.xml
index e21df73..36e8e57 100644
--- a/core/res/res/layout/select_dialog_multichoice_material.xml
+++ b/core/res/res/layout/select_dialog_multichoice_material.xml
@@ -25,6 +25,6 @@
android:gravity="center_vertical"
android:paddingStart="@dimen/select_dialog_padding_start_material"
android:paddingEnd="?attr/dialogPreferredPadding"
- android:checkMark="?attr/listChoiceIndicatorMultiple"
- android:checkMarkGravity="start"
+ android:drawableStart="?attr/listChoiceIndicatorMultiple"
+ android:drawablePadding="20dp"
android:ellipsize="marquee" />
diff --git a/core/res/res/layout/select_dialog_singlechoice_material.xml b/core/res/res/layout/select_dialog_singlechoice_material.xml
index 3828317..995272a 100644
--- a/core/res/res/layout/select_dialog_singlechoice_material.xml
+++ b/core/res/res/layout/select_dialog_singlechoice_material.xml
@@ -25,6 +25,6 @@
android:gravity="center_vertical"
android:paddingStart="@dimen/select_dialog_padding_start_material"
android:paddingEnd="?attr/dialogPreferredPadding"
- android:checkMark="?attr/listChoiceIndicatorSingle"
- android:checkMarkGravity="start"
+ android:drawableStart="?attr/listChoiceIndicatorSingle"
+ android:drawablePadding="20dp"
android:ellipsize="marquee" />
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 204e43e..a49907e 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Persoonlike programme"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"toegang tot jou kontakte verkry en hulle wysig"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"gaan by jou kontakte in"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ligging"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"toegang tot jou ligging verkry"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Jou sosiale inligting"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte toegang tot inligting oor jou kontakte en sosiale verbindings."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"toegang tot jou kalender verkry en dit wysig"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"gaan by jou kalender in"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"toegang tot SMS verkry en dit wysig"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"bekyk en bestuur SMS-boodskappe"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Gebruikerwoordeboek"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lees of skryf woorde in gebruikerswoordeboek."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Boekmerke en geskiedenis"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte toegang tot boekmerke en blaaiergeskiedenis."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"toestelmikrofoon gebruik"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"neem oudio op"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"toestelkamera gebruik"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"neem foto\'s en neem video op"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Foon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"toesteltelefonie gebruik"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"maak en bestuur foonoproepe"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"toegang tot sensors en drabare toestelle verkry"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"gaan in by data vanaf sensors en drabare toestelle"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Haal venster-inhoud op"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ondersoek die inhoud van \'n venster waarmee jy interaksie het."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Skakel Verken deur raak aan"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Laat die program toe om gebeure wat op jou tablet aangepas kan word, by te voeg, te verwyder of te verander, insluitend dié van vriende en medewerkers. Dit kan moontlik die program toelaat om boodskappe wat lyk of dit van kalendereienaars af kom, te stuur, of om gebeure sonder die eienaar se kennis aan te pas."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Laat die program toe om geleenthede wat jy op jou TV kan wysig, by te voeg, te verwyder en te verander, insluitend dié van vriende of kollegas. Dit kan die program toelaat om boodskappe te stuur wat lyk of dit van kalendereienaars af kom, of om geleenthede te wysig sonder dat die eienaar dit weet."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Laat die program toe om gebeure wat op jou foon aangepas kan word, by te voeg, te verwyder of te verander, insluitend dié van vriende en medewerkers. Dit kan moontlik die program toelaat om boodskappe wat lyk of dit van kalendereienaars af kom, te stuur, of om gebeure sonder die eienaar se kennis aan te pas."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"kamma liggingbronne vir toetsing"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Skep skynliggingsbronne vir toetsing of installeer \'n nuwe liggingsverskaffer. Die program kan dan die ligging en/of status wat deurgegee is deur ander liggingsbronne, soos GPS of liggingsverskaffers, oorheers."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Kry toegang tot ekstra liggingverskaffer-bevele"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Gee die program toegang tot ekstra liggingverskaffer-bevele. Dit kan die program dalk toelaat om in te meng met die werking van die GPS of ander liggingbronne."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"presiese ligging (GPS en netwerkgebaseer)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Vingerafdrukhandeling is gekanselleer."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Te veel pogings. Probeer later weer."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probeer weer."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lees sinkroniseer-instellings"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"As jy die USB-geheue aanskakel, sal sekere programme wat jy gebruik, stop en onbeskikbaar wees totdat jy die USB-geheue afskakel."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-handeling was onsuksesvol"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Gekoppel as \'n mediatoestel"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Gekoppel as \'n kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Gekoppel as \'n MIDI-toestel"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Gekoppel as \'n installeerder"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Gekoppel aan \'n USB-toebehoorsel"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Raak vir ander USB-opsies."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formateer USB-geheue?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formateer SD-kaart?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle lêers wat op jou USB-geheue gestoor is, sal uitgevee word. Hierdie handeling kan nie omgekeer word nie!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d minute lank (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Een minuut lank (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d uur lank (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Een uur lank (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d minute lank</item>
<item quantity="one">Een minuut lank</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d uur lank</item>
<item quantity="one">Een uur lank</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Totdat jy dit afskakel"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Vou in"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Moenie steur nie"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Staantyd"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Weeksaand"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Naweek"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Geleentheid"</string>
<string name="muted_by" msgid="6147073845094180001">"Gedemp deur <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Daar is \'n interne probleem met jou toestel en dit sal dalk onstabiel wees totdat jy \'n fabriekterugstelling doen."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Daar is \'n interne probleem met jou toestel. Kontak jou vervaardiger vir besonderhede."</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index f993bba..d1fb436 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"የግል መተግበሪያዎች"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ስራ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ዕውቂያዎች"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"የእርስዎን ዕውቂያዎች ይድረስበት እና ያሻሽል"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"የእርስዎ እውቂያዎች ላይ ይድረሱባቸው"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"መገኛ አካባቢ"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"የእርስዎን መገኛ አካባቢ ይድረስበት"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ማህበራዊ መረጃዎ"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ወደ የእውቂያዎችህና የማህበራዊ ግንኙነቶችህ መረጃ ቀጥተኛ መዳረሻ።"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ቀን መቁጠሪያ"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"የእርስዎን ቀን መቁጠሪያ ይድረስበት እና ያሻሽል"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"የእርስዎን ቀን መቁጠሪያ ይድረሱበት"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"ኤስኤምኤስ"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"ኤስኤምኤስ ላይ ይድረስበት እና ያሻሽል"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ኤስኤምኤስ መልዕክቶችን ይመልከቱ እና ያስተዳድሩ"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"የተጠቃሚ መዝገበ ቃላት"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"በተጠቃሚ መዝገበቃላት ላይ ቃሎችን አንብብ ወይም ጻፍ።"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ዕልባቶች እና ታሪክ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ወደ ዕልባቶችና የአሳሽ ታሪክ ቀጥተኛ መዳረሻ።"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ማይክሮፎን"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"የመሣሪያ ማይክራፎን ተጠቀም"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ኦዲዮ ይቅዱ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ካሜራ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"የመሣሪያ ካሜራ ይጠቀም"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ስዕሎች ያንሱ እና ቪዲዮ ይቅረጹ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ስልክ"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"የመሣሪያ ቴሌፎኒ ተጠቀም"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"የስልክ ጥሪዎች ያድርጉ እና ያስተዳድሩ"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"አነፍናፊዎች"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"አነፍናፊዎችን እና ተለባሾችን ይድረስባቸው"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ከአነፍናፊዎች እና ተለባሽ መሣሪያዎች ውሂብ ላይ ይድረሱባቸው"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"የመስኮት ይዘት ሰርስረው ያውጡ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"መስተጋበር የሚፈጥሩት የመስኮት ይዘት ይመርምሩ።"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"በመንካት ያስሱን ያብሩ"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"መተግበሪያው የጓደኞችህን እና የስራ ባልደረቦችህን ጨምሮ በጡባዊ ተኮህ ላይ ልታስተካክላቸው የምትችላቸውን ክስተቶች እንዲያክል፣ እንዲያስወግድ፣ እንዲለውጥ ይፈቅድለታል። ይህ መተግበሪያው ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልዕክቶችን እንዲልክ ወይም ያለባለቤቱ እውቀት ክስተቶችን እንዲያስተካክል ሊፈቅድለት ይችላል።"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"መተግበሪያው የጓደኛዎችን እና የስራ ባልደረባዎችን ጨምሮ በቴሌቪዥንዎ ላይ እርስዎ ሊቀይሯቸው የሚችሏቸው ክስተቶችን እንዲያክል፣ እንዲያስወግድ ወይም እንዲቀይር ያስችለዋል። ይሄ መተግበሪያው ያለባለቤቱ እውቀት ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልዕክቶችን እንዲልክ፣ ወይም ክስተቶችን እንዲቀይር ሊፈቅድለት ይችላል።"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"መተግበሪያው የጓደኞችዎን እና የስራ ባልደረቦችዎን ጨምሮ በስልክዎ ላይ ሊያስተካክሏቸው የሚችሏቸውን ክስተቶች እንዲያክል፣ እንዲያስወግድ፣ እንዲለውጥ ይፈቅድለታል። ይህ መተግበሪያው ከቀን መቁጠሪያ ባለቤቶች የመጡ የሚመስሉ መልዕክቶችን እንዲልክ ወይም ያለባለቤቱ እውቀት ክስተቶችን እንዲያስተካክል ሊፈቅድለት ይችላል።"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ለሙከራ ጊዜያዊ ሥፍራ ፍጠር።"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ለሙከራ የጊዜያዊ የመነሻ ምንጮችን ይፍጠሩ ወይም አዲስ የአካባቢ አቅራቢ ይጫኑ። ይህ መተግበሪያው አካባቢውን እና/ወይም እንደ GPS ወይም የአካባቢ አቅራቢዎች ባሉ ሌላ የመነሻ ምንጮች የተመለሱ ሁኔታዎችን ችላ እንዲል ይፈቅድለታል።"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ተጨማሪ ሥፍራ አቅራቢ ትዕዛዞችን ድረስ።"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"መተግበሪያው ተጨማሪ የአካባቢ አቅራቢ ትእዛዞችን እንዲደርስ ይፈቅድለታል። ይሄ መተግበሪያው በጂፒኤስ ወይም ሌላ የአካባቢ ምንጮች ስራ ላይ ጣልቃ እንዲገባ ሊፈቅድለት ይችላል።"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ትክክለኛ አካባቢ (በጂ ፒ ኤስ እና አውታረ መረብ ላይ የተመሠረተ)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"የጣት አሻራ ስርዓተ ክወና ተትቷል።"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ከልክ በላይ ብዙ ሙከራዎች። በኋላ ላይ እንደገና ይሞክሩ።"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"እንደገና ይሞክሩ።"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"የሥምሪያ ቅንብሮች አንብብ"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB ማህደረ ትውስታ ካበራህ፤የምትጠቀማቸው አንዳንድ መተግበሪያዎች ይቆማሉ እና የUSB ማህደረ ትውስታ እስክታጠፋ ድረስ ላይገኙ ይችላሉ።"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ክወና ስኬታማ አልነበረም"</string>
<string name="dlg_ok" msgid="7376953167039865701">"እሺ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"እንደ ማህደረ መረጃ መሣሪያ ተያይዟል"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"እንደካሜራ ተያይዟል"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"እንደ MIDI መሣሪያ ተገናኝቷል"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"እንደ ጫኝ ተያይዟል"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ለUSB ተቀጥላ ተያይዟል"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ለሌላ የUSB አማራጮች ንካ።"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"የUSB ማከማቻ ቅረፅ"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD ካርድ ቅረፅ"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"በUSB ማህደረ ትውስታህ ውስጥ የተከማቹ ሁሉም ፋይሎች ይጠፋሉ፡፡ ይህ እርምጃ አይቀለበስም!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">ለ%1$d ደቂቃዎች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
<item quantity="other">ለ%1$d ደቂቃዎች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">ለ%1$d ሰዓቶች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
<item quantity="other">ለ%1$d ሰዓቶች (እስከ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ድረስ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">ለ%d ደቂቃዎች</item>
<item quantity="other">ለ%d ደቂቃዎች</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">ለ%d ሰዓቶች</item>
<item quantity="other">ለ%d ሰዓቶች</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ድረስ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ይህን እስኪያጠፉት ድረስ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ሰብስብ"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"አትረብሽ"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"የማይገኝበት ጊዜ"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"የሳምንት ለሊት"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"የሳምንት እረፍት ቀናት"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ክስተት"</string>
<string name="muted_by" msgid="6147073845094180001">"ድምጽ በ<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ተዘግቷል"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ፣ የፋብሪካ ውሂብ ዳግም እስኪያስጀምሩት ድረስ ላይረጋጋ ይችላል።"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"መሣሪያዎ ላይ የውስጣዊ ችግር አለ። ዝርዝሮችን ለማግኘት አምራችዎን ያነጋግሩ።"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1218957..f30b730 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -224,27 +224,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"التطبيقات الشخصية"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"عمل"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"جهات الاتصال"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"الدخول إلى جهات الاتصال وتعديلها"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"الوصول إلى جهات اتصالك"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"الموقع"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"الدخول إلى موقعك"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"المعلومات الاجتماعية"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"الدخول المباشر إلى معلومات عن جهات الاتصال والاتصالات الاجتماعية."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"التقويم"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"الدخول إلى التقويم وتعديله"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"الوصول تقويمك"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"الدخول إلى SMS وتعديلها"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"عرض الرسائل القصيرة SMS وإدارتها"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"قاموس المستخدم"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"قراءة الكلمات وكتابتها في قاموس المستخدم."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"الإشارات المرجعية والسجل"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"الدخول المباشر إلى الإشارات المرجعية وسجل المتصفح."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"الميكروفون"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"استخدام ميكروفون الجهاز"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"تسجيل الصوت"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"الكاميرا"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"استخدام كاميرا الجهاز"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"التقاط صور وتسجيل فيديو"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"الهاتف"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"استخدام الاتصالات الهاتفية للجهاز"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"إجراء مكالمات هاتفية وإدارتها"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"أجهزة الاستشعار"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"الدخول إلى أجهزة الاستشعار والأجهزة القابلة للارتداء"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"الوصول إلى البيانات من مستشعرات وأجهزة قابلة للارتداء"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"استرداد محتوى النافذة"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"فحص محتوى نافذة يتم التفاعل معها."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"تشغيل الاستكشاف باللمس"</string>
@@ -339,8 +339,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"للسماح للتطبيق بإضافة أو إزالة أو تغيير الأحداث التي يمكنك تعديلها على جهازك اللوحي، بما في ذلك أحداث الأصدقاء أو زملاء العمل. وقد يتيح هذا للتطبيق إرسال رسائل يبدو أنها واردة من أصحاب التقويم أو تعديل الأحداث بدون معرفة المالكين."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"يتيح للتطبيق إضافة أحداث يمكنك تعديلها على التلفزيون كما يتيح إزالتها أو تغييرها، بما في ذلك أحداث الأصدقاء وزملاء العمل. وقد يتيح هذا للتطبيق إرسال رسائل تبدو أنها من أصحاب التقاويم أو تعديل الأحداث بدون علم أصحاب هذه التقاويم."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"للسماح للتطبيق بإضافة أو إزالة أو تغيير الأحداث التي يمكنك تعديلها على هاتفك، بما في ذلك أحداث الأصدقاء أو زملاء العمل. وقد يتيح هذا للتطبيق إرسال رسائل يبدو أنها واردة من أصحاب التقويم أو تعديل الأحداث بدون معرفة المالكين."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"مصادر مواقع وهمية للاختبار"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"لإنشاء مصادر مواقع زائفة للاختبار أو تثبيت موفر مواقع جديد. يتيح هذا للتطبيق إلغاء الموقع و/أو الحالة التي تعرضها مصادر المواقع الأخرى مثل GPS أو موفري المواقع."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"الدخول إلى المزيد من أوامر موفر الموقع"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"للسماح للتطبيق بالدخول إلى أوامر إضافية لموفر الموقع. قد يتيح هذا للتطبيق التداخل مع تشغيل تقنية نظام تحديد المواقع العالمي (GPS) أو مصادر الموقع الأخرى."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"الموقع الدقيق (مستند إلى نظام تحديد المواقع العالمي والشبكة)"</string>
@@ -442,6 +440,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"تم إلغاء تشغيل بصمة الإصبع."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"تم إجراء عدد كبير من المحاولات. أعد المحاولة لاحقًا."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"أعد المحاولة."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"قراءة إعدادات المزامنة"</string>
@@ -1070,12 +1070,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"إذا تم تشغيل وحدة تخزين USB، فستتوقف بعض التطبيقات التي تستخدمها وربما تصبح غير متاحة إلى أن يتم إيقاف وحدة تخزين USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"لم تتم عملية USB بنجاح"</string>
<string name="dlg_ok" msgid="7376953167039865701">"موافق"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"التوصيل كجهاز وسائط"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"التوصيل ككاميرا"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"تم التوصيل كجهاز MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"التوصيل كأداة تثبيت"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"الاتصال بجهاز USB ملحق"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"المس للاطلاع على خيارات USB الأخرى."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"تهيئة وحدة تخزين USB؟"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"هل تريد تنسيق بطاقة SD؟"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"سيتم مسح جميع الملفات المخزنة على وحدة تخزين USB. لا يمكن عكس هذا الإجراء!"</string>
@@ -1506,6 +1512,7 @@
<item quantity="other">لمدة %1$d من الدقائق (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">لمدة دقيقة واحدة (حتى <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="zero">لمدة أقل من ساعة (%1$d) (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="two">لمدة ساعتين (%1$d) (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
@@ -1514,6 +1521,7 @@
<item quantity="other">لمدة %1$d من الساعات (حتى <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">لمدة ساعة واحدة (حتى <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="zero">لمدة أقل من دقيقة (%d)</item>
<item quantity="two">لمدة دقيقتين (%d)</item>
@@ -1522,6 +1530,7 @@
<item quantity="other">لمدة %d من الدقائق</item>
<item quantity="one">لمدة دقيقة واحدة</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="zero">لمدة أقل من ساعة (%d)</item>
<item quantity="two">لمدة ساعتين (%d)</item>
@@ -1530,18 +1539,16 @@
<item quantity="other">لمدة %d من الساعات</item>
<item quantity="one">لمدة ساعة واحدة</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"لحين تعطيل هذا الإعداد"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"تصغير"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"الرجاء عدم الإزعاج"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"التعطل"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ليلة يوم من أيام الأسبوع"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"نهاية الأسبوع"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"حدث"</string>
<string name="muted_by" msgid="6147073845094180001">"تم كتم الصوت بواسطة <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"حدثت مشكلة داخلية في جهازك، وقد لا يستقر وضعه حتى إجراء إعادة الضبط بحسب بيانات المصنع."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"حدثت مشكلة داخلية في جهازك. يمكنك الاتصال بالمصنِّع للحصول على تفاصيل."</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 402f67f..c94330d 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Лични приложения"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Служебен"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"достъп до и промяна на контактите ви"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"достъп до контактите ви"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"достъп до местоположението ви"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Социалната ви информация"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Осъществяване на директен достъп до информация за контактите и социалните ви връзки."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"достъп до и промяна на календара ви"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"достъп до календара ви"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"достъп до и промяна на SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"преглед и управление на SMS съобщенията"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Потребителски речник"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Четене или запис на думи в потребителския речник."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Отметки и история"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Осъществяване на директен достъп до отметките и историята на браузъра."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"използване на микрофона на устройството"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"запис на звук"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"използване на камерата на устройството"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"правене на снимки и запис на видеоклипове"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"използване на телефонните функции на устройството"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"извършване и управление на телефонни обаждания"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"достъп до сензорите и носимите аксесоари"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"достъп до данните от сензорите и носимите устройства"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Извличане на съдържанието от прозореца"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Инспектиране на съдържанието на прозорец, с който взаимодействате."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включване на изследването чрез докосване"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Разрешава на приложението да добавя, премахва и променя събития, които можете да променяте на таблета си, включително тези на приятели или колеги. Това може да му позволи да изпраща съобщения, които изглежда, че идват от собствениците на календарите, или да променя събития без знанието на собствениците."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Разрешава на приложението да добавя, премахва и променя събития, които можете да променяте на телевизора си, включително тези на приятели или колеги. Така приложението може да изпраща съобщения от името на собствениците на календарите или да променя събития без тяхно знание."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Разрешава на приложението да добавя, премахва и променя събития, които можете да променяте на телефона си, включително тези на приятели или колеги. Това може да му позволи да изпраща съобщения, които изглежда, че идват от собствениците на календарите, или да променя събития без знанието на собствениците."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"имитиране на източници на местоположение за тестване"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Създаване на мними източници на местоположение за тестване или инсталиране на нов доставчик на местоположение. Това разрешава на приложението да заменя местоположението и/или състоянието, връщано от други източници, като GPS или доставчиците."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"достъп до допълнителни команди на доставчика на местоположение"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Разрешава на приложението достъп до допълнителни команди на доставчика на местоположение. Това може да позволи на приложението да смущава работата на GPS или на другите източници на местоположение."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"точно местоположение (основано на GPS и мрежата)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операцията за отпечатък е анулирана."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Твърде много опити. Пробвайте отново по-късно."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Опитайте отново."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"четене на настройките за синхронизиране"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ако включите USB хранилището, някои използвани от вас приложения ще спрат и може да не са налице, докато не го изключите."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Операцията през USB не бе успешна"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Свързан като медийно устройство"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Свързан като камера"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Свързано като MIDI устройство"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Свързан като инсталационна програма"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Установена е връзка с аксесоар за USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Докоснете за други опции за USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Да се форматира ли USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Да се форматира ли SD картата?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Всички файлове, съхранявани в USB хранилището ви, ще бъдат изтрити. Това действие не може да бъде отменено!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">За %1$d минути (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">За една минута (до <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">За %1$d часа (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">За един час (до <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">За %d минути</item>
<item quantity="one">За една минута</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">За %d часа</item>
<item quantity="one">За един час</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Докато не изключите това"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Свиване"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Не безпокойте"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Почивка"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Делнична нощ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Събота и неделя"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Събитие"</string>
<string name="muted_by" msgid="6147073845094180001">"Заглушено от <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Възникна вътрешен проблем с устройството ви. То може да е нестабилно, докато не възстановите фабричните настройки."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Възникна вътрешен проблем с устройството ви. За подробности се свържете с производителя."</string>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index ab988ed..ba71f0e 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ব্যক্তিগত অ্যাপ্লিকেশানগুলি"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"কর্মক্ষেত্র্র"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"পরিচিতি"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"আপনার পরিচিতি অ্যাক্সেস এবং সংশোধন করুন"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"আপনার পরিচিতিগুলিতে অ্যাক্সেস করুন"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"অবস্থান"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"আপনার অবস্থান অ্যাক্সেস করুন"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"আপনার সামাজিক তথ্য"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"আপনার পরিচিতিগুলি এবং সামাজিক পরিচিতিগুলি সম্পর্কিত তথ্যে সরাসরি অ্যাক্সেস৷"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ক্যালেন্ডার"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"আপনার ক্যালেন্ডার অ্যাক্সেস এবং সংশোধন করুন"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"আপনার ক্যালেন্ডারে অ্যাক্সেস করুন"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS অ্যাক্সেস এবং সংশোধন করুন"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS বার্তাগুলি দেখুন এবং পরিচালনা করুন"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"ব্যবহারকারীর অভিধান"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ব্যবহারকারীর অভিধানে শব্দগুলিকে পড়ুন এবং লিখুন৷"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"বুকমার্কগুলি এবং ইতিহাস"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"বুকমার্কগুলি এবং ব্রাউজারের ইতিহাসে সরাসরি অ্যাক্সেস৷"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"মাইক্রোফোন"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ডিভাইসের মাইক্রোফোন ব্যবহার করুন"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"অডিও রেকর্ড করুন"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ক্যামেরা"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ডিভাইসের ক্যামেরা ব্যবহার করুন"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ছবি তুলুন এবং ভিডিও রেকর্ড করুন"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ফোন"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ডিভাইসের টেলিফোনি ব্যবহার করুন"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ফোন কলগুলি করুন এবং পরিচালনা করুন"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"সেন্সরগুলি"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"সেন্সর এবং হালকা ও ছোট ডিভাইসগুলি অ্যাক্সেস করুন"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"সেন্সর এবং পরে থাকা যায় এমন ডিভাইসগুলি থেকে ডেটা অ্যাক্সেস করুন"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"উইন্ডোর সামগ্রী পুনরুদ্ধার করে"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"আপনি ইন্টারঅ্যাক্ট করছেন এমন একটি উইন্ডোর সামগ্রীকে সযত্নে নিরীক্ষণ করে৷"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"স্পর্শের মাধ্যমে অন্বেষণ করা চালু করুন"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"সেইসকল বন্ধু বা সহকর্মী সহ আপনি আপনার ট্যাবলেটে যে ইভেন্টগুলি সংশোধন করতে পারেন তা যুক্ত করাতে, সরাতে, পরিবর্তন করতে এই অ্যাপ্লিকেশানটিকে অনুমতি দেয়৷ এটি যেগুলি ক্যালেন্ডার মালিকদের থেকে এসে প্রদর্শিত হবে সেগুলিতে বার্তা পাঠাতে অথবা মালিককে না জানিয়ে ইভেন্টগুলি পরিবর্তন করতে দিতে পারে৷"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"অ্যাপ্লিকেশানকে ইভেন্টগুলি যোগ করার, সরানোর, পরিবর্তন করার অনুমতি দেয় যা আপনি আপনার টিভিতে বন্ধু বা সহকর্মীদের থেকে আসা ইভেন্টগুলি সমেত সেগুলি সংশোধন করতে পারবেন৷ এটি অ্যাপ্লিকেশানকে ক্যালেন্ডারের মালিকের থেকে এসেছে বলে মনে হয় এমন বার্তাগুলিকে পাঠানোর বা আপনার অজান্তে ইভেন্টগুলি সংশোধন করার অনুমতি দিতে পারে৷"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"সেইসকল বন্ধু বা সহকর্মী সহ আপনি আপনার ফোনে যে ইভেন্টগুলি সংশোধন করতে পারেন তা যুক্ত করাতে, সরাতে, পরিবর্তন করতে এই অ্যাপ্লিকেশানটিকে অনুমতি দেয়৷ এটি অ্যাপ্লিকেশানটিকে বার্তা পাঠাতে দেয় যা দেখে মনে হবে যে এটি ক্যালেন্ডার মালিকদের থেকে এসেছে অথবা মালিককে না জানিয়ে ইভেন্টগুলি পরিবর্তন করতে দিতে পারে৷"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"পরীক্ষার জন্য অবস্থান উৎসগুলি নকল করে"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"অবস্থান নির্ণয়ের সাথে সম্পর্কিত একটি নতুন পরিষেবা প্রদানকারী ইনস্টল বা পরীক্ষা করার জন্য অনুরূপ অবস্থান তৈরি করে৷ এটি অ্যাপ্লিকেশানটিকে অবস্থান এবং/অথবা অন্যান্য অবস্থান নির্ণয়ের সাথে সম্পর্কিত উৎসগুলি যেমন GPS বা অবস্থান সম্পর্কিত পরিষেবা প্রদানকারীদের থেকে পাওয়া স্থিতি ওভাররাইড করতে মঞ্জুর করে৷"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"অতিরিক্ত অবস্থান প্রদানকারী কমান্ডগুলি অ্যাক্সেস করে"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"অবস্থানের সাথে সম্পর্কিত তথ্য প্রদানকারীর অতিরিক্ত কম্যান্ডগুলিকে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এটি অ্যাপ্লিকেশানটিকে GPS অথবা অন্যান্য অবস্থান নির্ণয়ের সাথে সম্পর্কিত উৎসগুলির ক্রিয়াপ্রণালীর নিয়ন্ত্রণকে মঞ্জুর করতে পারে৷"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"সুনির্দিষ্ট অবস্থান (GPS এবং নেটওয়ার্ক ভিত্তিক)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"আঙ্গুলের ছাপ অপারেশন বাতিল করা হয়েছে৷"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"অনেকবার প্রচেষ্টা করা হয়েছে৷ পরে আবার চেষ্টা করুন৷"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"আবার চেষ্টা করুন৷"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"সিঙ্ক সেটিংস পড়ে"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"আপনি যদি USB সঞ্চয়স্থান চালু করেন তাহলে আপনার USB সঞ্চয়স্থান বন্ধ না করা পর্যন্ত আপনার ব্যবহৃত অ্যাপ্লিকেশানগুলির মধ্যে কয়েকটি বন্ধ হয়ে যাবে এবং অনুপলব্ধ হতে পারে৷"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB প্রক্রিয়াটি অসফল হয়েছে"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ঠিক আছে"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"একটি মিডিয়া ডিভাইস হিসাবে সংযুক্ত হয়েছে"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"একটি ক্যামেরা হিসাবে সংযুক্ত"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"একটি MIDI ডিভাইস হিসাবে সংযুক্ত করা হয়েছে"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"একটি ইনস্টলার হিসাবে সংযুক্ত হয়েছে"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"একটি USB যন্ত্রাংশতে সংযুক্ত হয়েছে"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"অন্যন্য USB বিকল্পের জন্য স্পর্শ করুন৷"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB সঞ্চয়স্থান ফরম্যাট করবেন?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD ফরম্যাট করবেন?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"আপনার USB সঞ্চয়স্থানে সংরক্ষিত সমস্ত ফাইল মুছে ফেলা হবে৷ এই ক্রিয়াটিকে পূর্বাবস্থায় ফেরানো যাবে না!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
<item quantity="other">%1$d মিনিটের জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d ঘন্টার জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
<item quantity="other">%1$d ঘন্টার জন্য (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> পর্যন্ত)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d মিনিটের জন্য</item>
<item quantity="other">%d মিনিটের জন্য</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d ঘন্টার জন্য</item>
<item quantity="other">%d ঘন্টার জন্য</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"আপনার দ্বারা এটি বন্ধ করা পর্যন্ত"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"বিরক্ত করবেন না"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ডাউনটাইম"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"সপ্তাহান্তের রাত্রি"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"সপ্তাহান্ত"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ইভেন্ট"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> দ্বারা নিঃশব্দ করা হয়েছে"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে, এবং আপনি যতক্ষণ না পর্যন্ত এটিকে ফ্যাক্টরি ডেটা রিসেট করছেন ততক্ষণ এটি ঠিকভাবে কাজ নাও করতে পারে৷"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"আপনার ডিভাইসে একটি অভ্যন্তরীন সমস্যা হয়েছে৷ বিস্তারিত জানার জন্য প্রস্তুতকারকের সাথে যোগাযোগ করুন৷"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index ae21dec..69b72ef 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicacions personals"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Feina"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactes"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"accedir als contactes i modificar-los"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedir als contactes"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicació"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"accedir a la ubicació"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informació social"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accés directe a informació sobre els teus contactes i sobre les teves connexions socials."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendari"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"accedir al calendari i modificar-lo"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accedir al calendari"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"accedir als SMS i modificar-los"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"consultar i gestionar els missatges SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionari de l\'usuari"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Llegir o escriure paraules al diccionari de l\'usuari."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadors i historial"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accés directe a l\'historial de marcadors i de navegació."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micròfon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"fer servir el micròfon del dispositiu"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrar àudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Càmera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utilitzar la càmera del dispositiu"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fer fotos i vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telèfon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"fer servir la telefonia del dispositiu"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar les trucades telefòniques"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"accedir als sensors i als complements connectats"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accedir a les dades dels sensors i dels dispositius connectats"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de les finestres"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb la qual estàs interaccionant."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar Exploració tàctil"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar a la tauleta, inclosos els d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permet que l\'aplicació afegeixi, suprimeixi o canviï esdeveniments que pots modificar al televisor, com ara els d\'amics o de companys de feina. És possible que l\'aplicació enviï missatges que sembli que provenen dels propietaris del calendari o bé que modifiqui esdeveniments sense que el propietari ho sàpiga."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet que l\'aplicació afegeixi, elimini o canviï esdeveniments que pots modificar al telèfon, inclosos els d\'amics o de companys de feina. Aquesta acció pot permetre que l\'aplicació enviï missatges que sembli que provinguin dels propietaris del calendari o que modifiqui esdeveniments sense el coneixement dels propietaris."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"crear orígens d\'ubicacions fictícies per fer proves"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Crea fonts d\'ubicació fictícies per provar o per instal·lar un proveïdor d\'ubicació nou. Aquesta acció permet que l\'aplicació substitueixi la ubicació o l\'estat que retornen altres fonts d\'ubicació, com ara el GPS o altres proveïdors d\'ubicació."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accedir a ordres del proveïdor d\'ubicació addicionals"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet que l\'aplicació accedeixi a ordres addicionals del proveïdor d\'ubicacions; per tant, és possible que l\'aplicació pugui interferir en el funcionament del GPS o d\'altres fonts d\'ubicacions."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ubicació precisa (basada en GPS i xarxa)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"S\'ha cancel·lat l\'operació d\'empremta digital."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"S\'han produït massa intents. Torna-ho a provar més tard."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Torna-ho a provar."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"llegir la configuració de sincronització"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si actives l\'emmagatzematge USB, algunes de les aplicacions que utilitzes s\'aturaran i pot ser que no estiguin disponibles fins que no desactivis l\'emmagatzematge USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"S\'ha produït un error amb l\'operació de l\'USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"D\'acord"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connectat com a disp. multimèdia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connectat com a càmera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connectat com a dispositiu MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connectat com a instal·lador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connectat a un accessori USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toca per accedir a altres opcions d\'USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formata l\'emmagatzematge USB"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vols formatar la targeta SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"S\'esborraran tots els fitxers emmagatzemats al dispositiu d\'emmagatzematge USB. Aquesta acció no es pot desfer."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Durant %1$d minuts (fins a les <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durant 1 minut (fins a les <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Durant %1$d hores (fins a les <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durant 1 hora (fins a les <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Durant %d minuts</item>
<item quantity="one">Durant un minut</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Durant %d hores</item>
<item quantity="one">Durant 1 hora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Fins que no ho desactivis"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Replega"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"No molesteu"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Temps d\'inactivitat"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Nit entre setmana"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Cap de setmana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Esdeveniment"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciat per <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"S\'ha produït un error intern al dispositiu i és possible que funcioni de manera inestable fins que restableixis les dades de fàbrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"S\'ha produït un error intern al dispositiu. Contacta amb el fabricant del dispositiu per obtenir més informació."</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 3578830..bb21517 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Osobní aplikace"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Práce"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"přístup k vašim kontaktům a jejich úpravy"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"přístup ke kontaktům"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"přístup k poloze"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informace o vašich kontaktech a sociálních sítích"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Přímý přístup k informacím o vašich kontaktech a sociálních propojeních"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendář"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"přístup k vašemu kalendáři a jeho úpravy"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"přístup ke kalendáři"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"přístup ke zprávám SMS a jejich úpravy"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"zobrazení a správa zpráv SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Uživatelský slovník"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čtení a zápis slov v uživatelském slovníku"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Záložky a historie"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Přímý přístup k záložkám a historii prohlížení"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"používání mikrofonu zařízení"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"nahrávání zvuku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"používání fotoaparátu zařízení"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"pořizování fotografií a nahrávání videa"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"používání funkcí telefonování"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"uskutečňování a správa telefonních hovorů"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"přístup k senzorům a nositelným zařízením"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"přístup k datům ze senzorů a nositelných zařízení"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načíst obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Můžete prozkoumat obsah okna, se kterým pracujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnout funkci Prozkoumání dotykem"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Umožňuje aplikaci přidat, odebrat nebo změnit události, které můžete v tabletu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníka kalendáře, nebo upravovat události bez vědomí vlastníka."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Umožňuje aplikaci přidávat, odstraňovat a měnit události, které můžete v televizi upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníka kalendáře, nebo upravovat události bez vědomí vlastníka."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Umožňuje aplikaci přidat, odebrat nebo změnit události, které můžete v telefonu upravovat, a to včetně událostí přátel a spolupracovníků. Toto oprávnění umožňuje aplikaci odesílat zprávy, které budou zdánlivě přicházet od vlastníků kalendářů, nebo upravovat události bez vědomí vlastníků."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"simulace zdrojů polohy pro účely testování"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Vytváření simulace zdrojů polohy pro účely testování nebo instalace nového poskytovatele polohy. Toto oprávnění umožňuje aplikaci přepsat polohu nebo stav, který vracejí jiné zdroje polohy, například systém GPS nebo poskytovatelé polohy."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"přístup k dalším příkazům poskytovatele polohy"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Umožňuje aplikaci přístup k dalším příkazům poskytovatele polohy. To aplikaci umožní zasahovat do fungování systému GPS a dalších zdrojů polohy."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"přesná poloha (pomocí GPS a sítě)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operace otisku prstu byla zrušena."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Příliš mnoho pokusů. Zkuste to později."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Zkuste to znovu."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čtení nastavení synchronizace"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Pokud zapnete úložiště USB, dojde k zastavení některých používaných aplikací. Tyto aplikace pravděpodobně nebudou k dispozici až do vypnutí úložiště USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operace rozhraní USB se nezdařila."</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Připojeno jako mediální zařízení"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Připojeno jako fotoaparát"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Připojeno jako zařízení MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Připojeno jako instalátor"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Připojeno k perifernímu zařízení USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dotykem zobrazíte další možnosti rozhraní USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formátovat úložiště USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formátovat kartu SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Všechny soubory uložené v úložišti USB budou vymazány. Tuto akci nelze vrátit zpět."</string>
@@ -1486,36 +1492,37 @@
<item quantity="other">%1$d minut (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Jednu minutu (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="few">%1$d hodiny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d hodiny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d hodin (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Jednu hodinu (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="few">%d minuty</item>
<item quantity="many">%d minuty</item>
<item quantity="other">%d minut</item>
<item quantity="one">Jednu minutu</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="few">%d hodiny</item>
<item quantity="many">%d hodiny</item>
<item quantity="other">%d hodin</item>
<item quantity="one">Jednu hodinu</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokud tuto funkci nevypnete"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sbalit"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Nerušit"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Období klidu"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Večer v pracovním týdnu"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Víkend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Událost"</string>
<string name="muted_by" msgid="6147073845094180001">"Ignorováno stranou <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"V zařízení došlo k internímu problému. Dokud neprovedete obnovení továrních dat, může být nestabilní."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"V zařízení došlo k internímu problému. Další informace vám sdělí výrobce."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index a546772..a9231c3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personlige apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Arbejde"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersoner"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"få adgang til og redigere dine kontaktpersoner"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"få adgang til din placering"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Dine sociale oplysninger"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte adgang til oplysninger om dine kontaktpersoner og sociale forbindelser."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"få adgang til og redigere din kalender"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"have adgang til din kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"få adgang til og redigere sms\'er"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"se og administrere sms-beskeder"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Brugerordbog"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Læse eller skrive ord i brugerordbogen."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bogmærker og historik"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte adgang til bogmærker og browserhistorik."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"bruge enhedens mikrofon"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"optage lyd"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"bruge enhedens kamera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"tage billeder og optage video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"bruge enhedens telefoni"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"foretage og administrere telefonopkald"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"få adgang til sensorer og wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"have adgang til data fra sensorer og wearables"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente indholdet i vinduet"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tillader, at appen kan tilføje, fjerne, ændre begivenheder, som du kan redigere på din tablet, f.eks. venners eller kollegers. Med denne tilladelelse kan appen sende meddelelser, der synes at komme fra ejere af kalendere, eller ændre begivenheder uden ejernes viden."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Giver appen lov til at tilføje, fjerne eller ændre begivenheder, som du kan redigere på dit tv, herunder venners og kollegers begivenheder. Dette kan give appen mulighed for at sende meddelelser, der ser ud, som om de kommer fra ejere af kalendere, eller for at ændre begivenheder uden ejernes viden."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Tillader, at appen kan tilføje, fjerne og ændre begivenheder, som du kan redigere på din telefon, f.eks. venners eller kollegers. Med denne tilladelse kan appen sende meddelelser, der synes at komme fra ejere af kalendere, eller ændre begivenheder uden ejernes viden."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imiterede placeringskilder til test"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Opret imiterede placeringskilder til test, eller installer en ny placeringsudbyder. Med denne tilladelse kan appen tilsidesætte den placering og/eller status, der returneres af andre placeringskilder, f.eks. GPS eller placeringsudbydere."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"få adgang til yderligere kommandoer for placeringsudbyder"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tillader, at appen kan få adgang til yderligere kommandoer for placeringsudbydere. Dette kan gøre det muligt for appen at forstyrre GPS-funktionen eller andre placeringskilder."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"præcis placering (GPS- og netværksbaseret)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeraftrykshandlingen blev annulleret."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Du har prøvet for mange gange. Prøv igen senere."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Prøv igen."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"læse indstillinger for synkronisering"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du slår USB-lager til, stoppes nogle af de apps, som du bruger, og de kan være utilgængelige, indtil du slår USB-lager fra igen."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-handlingen mislykkedes"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilsluttet som en medieenhed"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tilsluttet som et kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Forbundet til en MIDI-enhed"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tilsluttet som et installationsprogram"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tilsluttet et USB-ekstraudstyr"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Tryk for at se andre valgmuligheder for USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater USB-lager?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vil du formatere SD-kortet?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle filer, der er gemt på dit USB-lager, slettes. Denne handling kan ikke fortrydes!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">I %1$d minutter (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">I %1$d timer (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">I %1$d timer (indtil <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">I %d minutter</item>
<item quantity="other">I %d minutter</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">I %d timer</item>
<item quantity="other">I %d timer</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Indtil du slår denne indstilling fra"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Vil ikke forstyrres"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Nedetid"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Hverdagsaften"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Begivenhed"</string>
<string name="muted_by" msgid="6147073845094180001">"Lyden blev afbrudt af <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Der er et internt problem med enheden, og den vil muligvis være ustabil, indtil du gendanner fabriksdataene."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Der er et internt problem med enheden. Kontakt producenten for at få yderligere oplysninger."</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index a4dd9a4..8c2a79f 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Private Apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Geschäftlich"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"Auf Kontakte zugreifen und diese ändern"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"Auf Kontakte zuzugreifen"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"Auf Standort zugreifen"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ihre sozialen Informationen"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkter Zugriff auf Informationen über Ihre Kontakte und sozialen Verbindungen"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"Auf Kalender zugreifen und diesen ändern"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Auf Kalender zuzugreifen"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"Auf SMS zugreifen und diese ändern"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS abzurufen und zu verwalten"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Mein Wörterbuch"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Wörter in Mein Wörterbuch lesen oder schreiben"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Lesezeichen und Verlauf"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkter Zugriff auf Lesezeichen und Browserverlauf"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"Gerätemikrofon verwenden"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"Audio aufzunehmen"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"Gerätekamera verwenden"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"Bilder und Videos aufzunehmen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"Gerätetelefonie verwenden"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"Telefonanrufe zu tätigen und zu verwalten"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"Auf Sensoren und Wearables zugreifen"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"Auf Daten von Sensoren und Wearables zuzugreifen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Fensterinhalte abrufen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Die Inhalte eines Fensters mit dem Sie interagieren werden abgerufen."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"\"Tippen & Entdecken\" aktivieren"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Ermöglicht der App, Termine, die Sie auf Ihrem Tablet ändern können, hinzuzufügen, zu entfernen und zu ändern, einschließlich der von Freunden und Kollegen. Damit kann die App Nachrichten senden, die so erscheinen, als stammten sie vom jeweiligen Kalenderinhaber, oder Termine ohne Wissen des Inhabers ändern."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Ermöglicht der App, Termine, die Sie auf Ihrem Fernseher bearbeiten können ‒ einschließlich der von Freunden und Kollegen ‒ hinzuzufügen, zu entfernen und zu ändern. Dadurch kann die App möglicherweise Nachrichten senden, die scheinbar von Kalendereigentümern stammen, oder Termine ohne Wissen der Eigentümer ändern."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ermöglicht der App, Termine, die Sie auf Ihrem Telefon ändern können, hinzuzufügen, zu entfernen und zu ändern, einschließlich der von Freunden und Kollegen. Damit kann die App Nachrichten senden, die so erscheinen, als stammten sie vom jeweiligen Kalenderinhaber, oder Termine ohne Wissen des Inhabers ändern."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Simulierte Standortquellen für Testzwecke"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Erstellen von simulierten Standortquellen für Testzwecke oder Installation eines neuen Standortanbieters. Damit kann die App den von anderen Standortquellen wie GPS oder Standortanbietern zurückgegebenen Standort und/oder Status überschreiben."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Auf zusätzliche Dienstanbieterbefehle für Standort zugreifen"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ermöglicht der App, auf zusätzliche Standortanbieterbefehle zuzugreifen. Damit könnte die App die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"Genauer Standort (GPS- und netzwerkbasiert)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerabdruckvorgang abgebrochen"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zu viele Versuche. Versuchen Sie es später erneut."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bitte versuchen Sie es erneut."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Synchronisierungseinstellungen lesen"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Wenn Sie den USB-Speicher aktivieren, werden einige von Ihnen verwendeten Apps beendet und sind möglicherweise erst wieder verfügbar, wenn Sie den USB-Speicher wieder deaktivieren."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-Vorgang fehlgeschlagen"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Als Mediengerät angeschlossen"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Als Kamera angeschlossen"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Als MIDI-Gerät verbunden"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Als Installationsprogramm angeschlossen"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Mit USB-Zubehör verbunden"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Für mehr USB-Optionen berühren"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB-Speicher formatieren?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD-Karte formatieren?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle in Ihrem USB-Speicher abgelegten Dateien werden gelöscht. Diese Aktion kann nicht rückgängig gemacht werden!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d Minuten (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">1 Minute (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d Stunden (bis <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">1 Stunde (bis <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Für %d Minuten</item>
<item quantity="one">Für 1 Minute</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Für %d Stunden</item>
<item quantity="one">Für eine Stunde</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Bis zur Deaktivierung"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Nicht stören"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Ruhezeit"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Abends unter der Woche"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Wochenende"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Termin"</string>
<string name="muted_by" msgid="6147073845094180001">"Stummgeschaltet durch <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Es liegt ein internes Problem mit Ihrem Gerät vor. Möglicherweise verhält es sich instabil, bis Sie es auf die Werkseinstellungen zurücksetzen."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Es liegt ein internes Problem mit Ihrem Gerät vor. Bitte wenden Sie sich diesbezüglich an den Hersteller."</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index c15f379..5150f45 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Προσωπικές εφαρμογές"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Εργασία"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Επαφές"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"πρόσβαση και τροποποίηση των επαφών σας"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"πρόσβαση στις επαφές σας"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Τοποθεσία"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"πρόσβαση στην τοποθεσία σας"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Οι κοινωνικές πληροφορίες σας"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Άμεση πρόσβαση σε πληροφορίες σχετικά με τις επαφές και τις κοινωνικές συνδέσεις σας."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Ημερολόγιο"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"πρόσβαση και τροποποίηση του ημερολογίου σας"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"πρόσβαση στο ημερολόγιό σας"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"πρόσβαση και τροποποίηση SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"προβολή και διαχείριση μηνυμάτων SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Λεξικό χρήστη"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ανάγνωση ή εγγραφή λέξεων στο λεξικό χρήστη."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Σελιδοδείκτες και ιστορικό"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Άμεση πρόσβαση σε σελιδοδείκτες και ιστορικού προγράμματος περιήγησης."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Μικρόφωνο"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"χρήση μικροφώνου συσκευής"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"εγγραφή ήχου"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Κάμερα"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"χρήση της κάμερας της συσκευής"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"λήψη φωτογραφιών και εγγραφή βίντεο"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Τηλέφωνο"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"χρήση τηλεφωνίας συσκευής"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"πραγματοποίηση και διαχείριση τηλεφωνικών κλήσεων"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Αισθητήρες"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"αισθητήρες πρόσβασης και φορετές συσκευές"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"πρόσβαση σε δεδομένα από αισθητήρες και φορετές συσκευές"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ανάκτηση του περιεχομένου του παραθύρου"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Έλεγχος του περιεχομένου ενός παραθύρου με το οποίο αλληλεπιδράτε."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ενεργοποίηση της \"Εξερεύνησης με άγγιγμα\""</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Επιτρέπει στην εφαρμογή την προσθήκη, την κατάργηση και την αλλαγή συμβάντων που μπορείτε να τροποποιήσετε στο tablet σας, συμπεριλαμβανομένων εκείνων των φίλων ή των συναδέλφων σας. Αυτό μπορεί να επιτρέπει στην εφαρμογή να αποστέλλει μηνύματα που φαίνεται ότι προέρχονται από κατόχους ημερολογίων ή να τροποποιεί συμβάντα χωρίς να το γνωρίζουν οι κάτοχοι."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Επιτρέπει στην εφαρμογή να προσθέτει, να καταργεί και να αλλάζει συμβάντα που μπορείτε να τροποποιείτε στην τηλεόρασή σας, συμπεριλαμβανομένων όσων ανήκουν σε φίλους ή συναδέλφους. Αυτό ενδέχεται να επιτρέπει στην εφαρμογή να αποστέλλει μηνύματα τα οποία φαίνεται ότι προέρχονται από κατόχους ημερολογίου ή να τροποποιεί συμβάντα χωρίς να το γνωρίζουν οι κάτοχοί τους."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Επιτρέπει στην εφαρμογή την προσθήκη, την κατάργηση και την αλλαγή συμβάντων που μπορείτε να τροποποιήσετε στο τηλέφωνό σας, συμπεριλαμβανομένων εκείνων των φίλων ή των συναδέλφων σας. Αυτό μπορεί να επιτρέπει στην εφαρμογή να αποστέλλει μηνύματα που φαίνεται ότι προέρχονται από κατόχους ημερολογίων ή να τροποποιεί συμβάντα χωρίς να το γνωρίζουν οι κάτοχοι."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"δημιουργία ψευδών πηγών τοποθεσίας για δοκιμή"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Δημιουργεί ψευδείς πηγές τοποθεσίας για τη δοκιμή ή την εγκατάσταση νέου παρόχου τοποθεσίας. Αυτό δίνει τη δυνατότητα στην εφαρμογή να παρακάμψει την τοποθεσία και/ή την κατάσταση που επιστρέφεται από άλλες πηγές τοποθεσίας, όπως το GPS ή οι πάροχοι τοποθεσίας."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"πρόσβαση σε επιπλέον εντολές παρόχου τοποθεσίας"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Επιτρέπει στην εφαρμογή την πρόσβαση σε επιπλέον εντολές παρόχου τοποθεσίας. Αυτό μπορεί να δώσει τη δυνατότητα στην εφαρμογή να παρέμβει στη λειτουργία του GPS ή άλλων πηγών τοποθεσίας."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ακριβής θέση (GPS και βάσει δικτύου)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Η λειτουργία μοναδικού χαρακτηριστικού ακυρώθηκε."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Πάρα πολλές προσπάθειες. Δοκιμάστε ξανά αργότερα."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Δοκιμάστε ξανά."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ανάγνωση ρυθμίσεων συγχρονισμού"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Εάν ενεργοποιήσετε τον χώρο αποθήκευσης USB, ορισμένες από τις εφαρμογές που χρησιμοποιείτε θα σταματήσουν και ενδέχεται να μην είναι διαθέσιμες μέχρι να απενεργοποιήσετε τον χώρο αποθήκευσης USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Λειτουργία USB ανεπιτυχής"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ΟΚ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Συνδεδεμένο ως συσκευή πολυμέσων"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Συνδεδεμένο ως φωτογραφική μηχανή"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Συνδεθήκατε ως συσκευή MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Συνδεδεμένο ως πρόγραμμα εγκατάστασης"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Σύνδεση σε αξεσουάρ USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Αγγίξτε για άλλες επιλογές USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Μορφοπ.χώρ.αποθ.USB;"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Να γίνει διαμόρφωση της κάρτας SD;"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Όλα τα αρχεία που είναι αποθηκευμένα στον αποθηκευτικό σας χώρο USB θα διαγραφούν. Αυτή η ενέργεια δεν είναι αναστρέψιμη!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Για %1$d λεπτά (έως τις <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Για ένα λεπτό (έως τις <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Για %1$d ώρες (έως τις <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Για μία ώρα (έως τις <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Για %d λεπτά</item>
<item quantity="one">Για ένα λεπτό</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Για %d ώρες</item>
<item quantity="one">Για μία ώρα</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Μέχρι να το απενεργοποιήσετε"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Μην ενοχλείτε"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Διακοπή λειτουργίας"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Νύχτα καθημερινής"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Σαββατοκύριακο"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Συμβάν"</string>
<string name="muted_by" msgid="6147073845094180001">"Σίγαση από <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας και ενδέχεται να είναι ασταθής μέχρι την επαναφορά των εργοστασιακών ρυθμίσεων."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Υπάρχει ένα εσωτερικό πρόβλημα με τη συσκευή σας. Επικοινωνήστε με τον κατασκευαστή σας για λεπτομέρειες."</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 3b50363..5cb034a 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"access and modify your contacts"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"access your location"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"access and modify your calendar"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"access and modify SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"view and manage SMS messages"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"use device microphone"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"use device camera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"use device telephony"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"access sensors and wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"access data from sensors and wearable devices"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Allows the app to add, remove and change events that you can modify on your tablet, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Allows the app to add, remove, change events that you can modify on your TV, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Allows the app to add, remove and change events that you can modify on your phone, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"mock location sources for testing"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precise location (GPS and network-based)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"If you turn on USB storage, some apps that you\'re using will stop and may be unavailable until you turn off USB storage."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB operation unsuccessful"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connected as a MIDI device"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Touch for other USB options."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format USB storage?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format SD card?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"All files stored in your USB storage will be erased. This action can\'t be reversed!"</string>
@@ -1466,18 +1472,22 @@
<item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one hour (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">For %d minutes</item>
<item quantity="one">For one minute</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">For %d hours</item>
<item quantity="one">For one hour</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 3b50363..5cb034a 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"access and modify your contacts"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"access your location"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"access and modify your calendar"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"access and modify SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"view and manage SMS messages"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"use device microphone"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"use device camera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"use device telephony"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"access sensors and wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"access data from sensors and wearable devices"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Allows the app to add, remove and change events that you can modify on your tablet, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Allows the app to add, remove, change events that you can modify on your TV, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Allows the app to add, remove and change events that you can modify on your phone, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"mock location sources for testing"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precise location (GPS and network-based)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"If you turn on USB storage, some apps that you\'re using will stop and may be unavailable until you turn off USB storage."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB operation unsuccessful"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connected as a MIDI device"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Touch for other USB options."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format USB storage?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format SD card?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"All files stored in your USB storage will be erased. This action can\'t be reversed!"</string>
@@ -1466,18 +1472,22 @@
<item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one hour (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">For %d minutes</item>
<item quantity="one">For one minute</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">For %d hours</item>
<item quantity="one">For one hour</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 3b50363..5cb034a 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personal apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"access and modify your contacts"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"access your location"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Your social information"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direct access to information about your contacts and social connections."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"access and modify your calendar"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"access your calendar"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"access and modify SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"view and manage SMS messages"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"User Dictionary"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Read or write words in user dictionary."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmarks and History"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direct access to bookmarks and browser history."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"use device microphone"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"record audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"use device camera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"take pictures and record video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telephone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"use device telephony"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"make and manage phone calls"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"access sensors and wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"access data from sensors and wearable devices"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Retrieve window content"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspect the content of a window that you\'re interacting with."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Turn on Explore by Touch"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Allows the app to add, remove and change events that you can modify on your tablet, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Allows the app to add, remove, change events that you can modify on your TV, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Allows the app to add, remove and change events that you can modify on your phone, including those of friends or co-workers. This may allow the app to send messages that appear to come from calendar owners, or modify events without the owners\' knowledge."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"mock location sources for testing"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Create mock location sources for testing or install a new location provider. This allows the app to override the location and/or status returned by other location sources such as GPS or location providers."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"access extra location provider commands"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precise location (GPS and network-based)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingerprint operation cancelled."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Too many attempts. Try again later."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Try again."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"read sync settings"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"If you turn on USB storage, some apps that you\'re using will stop and may be unavailable until you turn off USB storage."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB operation unsuccessful"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connected as a media device"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connected as a camera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connected as a MIDI device"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connected as an installer"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connected to a USB accessory"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Touch for other USB options."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format USB storage?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format SD card?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"All files stored in your USB storage will be erased. This action can\'t be reversed!"</string>
@@ -1466,18 +1472,22 @@
<item quantity="other">For %1$d minutes (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one minute (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">For %1$d hours (until <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">For one hour (until <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">For %d minutes</item>
<item quantity="one">For one minute</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">For %d hours</item>
<item quantity="one">For one hour</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index c1ea0df..a36e5d7 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"acceder a los contactos y modificarlos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a los contactos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"acceder a tu ubicación"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Tu información social"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceso directo a información sobre tus contactos y conexiones sociales"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"acceder al calendario y modificarlo"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder al calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"acceder a los SMS y modificarlos"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ver y administrar los mensajes SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionario del usuario"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"leer o escribir palabras en el diccionario del usuario"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e historial"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceso directo a marcadores e historial del navegador"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"usar el micrófono del dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"usar la cámara del dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"tomar fotografías y grabar videos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"usar el teléfono del dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"realizar y administrar llamadas telefónicas"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"acceder a los sensores y wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"acceder a los datos de los sensores y dispositivos wearable"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de las ventanas"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de la ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar la Exploración táctil"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite que la aplicación agregue, elimine y cambie eventos que se pueden modificar en la tablet, incluidos los de amigos o compañeros de trabajo. La aplicación puede utilizar este permiso para enviar mensajes que parezcan proceder de propietarios de un calendario o para modificar eventos sin el consentimiento de los propietarios."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite que la aplicación agregue, elimine y cambie eventos que puedes modificar en la TV, incluidos aquellos de amigos o colegas. Esta opción puede permitir que la aplicación envíe mensajes que parecen ser de propietarios del calendario o modifique eventos sin que lo sepan los propietarios."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite que la aplicación agregue, elimine y cambie eventos que se pueden modificar en el dispositivo, incluidos los de amigos o compañeros de trabajo. La aplicación puede utilizar este permiso para enviar mensajes que parezcan proceder de propietarios de un calendario o para modificar los eventos sin el consentimiento de los propietarios."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"crear fuentes de ubicación de prueba"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permite crear fuentes de ubicación simuladas para hacer pruebas o instalar un nuevo proveedor de ubicación. Esto autoriza a la aplicación a sobrescribir la ubicación o el estado proporcionados por otras fuentes de ubicación, como los proveedores de ubicación o GPS."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acceder a comandos adicionales del proveedor del lugar"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ubicación precisa (según el GPS y la red)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Se canceló la operación de huella digital."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Vuelve a intentarlo."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si activas el almacenamiento USB, se detendrán algunas aplicaciones que estás usando y es posible que no estén disponibles hasta que lo desactives."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Error en el funcionamiento del USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como un dispositivo de medios"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Conectado como dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como un instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toca para acceder a otras opciones de USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"¿Deseas formatear el almacenamiento USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"¿Deseas formatear la tarjeta SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Se borrarán todos los archivos guardados en el almacenamiento USB. Esta acción no se puede deshacer."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Durante %1$d minutos hasta la(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g></item>
<item quantity="one">Durante 1 minuto; hasta la(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g></item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Durante %1$d horas, hasta la(s) <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g></item>
<item quantity="one">Durante 1 hora; hasta la(s) <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g></item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Durante %d minutos</item>
<item quantity="one">Durante un minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Durante %d horas</item>
<item quantity="one">Durante 1 hora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Hasta la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hasta que lo desactives"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"No molestar"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tiempo de inactividad"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noche de entre semana"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fin de semana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciados por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Existe un problema interno con el dispositivo, de modo que el dispositivo puede estar inestable hasta que restablezcas la configuración de fábrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Existe un problema interno con el dispositivo. Comunícate con el fabricante para obtener más información."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 4127655..7a2fc10 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicaciones personales"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabajo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"acceder a tus contactos y modificarlos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a tus contactos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"acceder a tu ubicación"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Tu información social"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceder directamente a la información de tus contactos y tus conexiones sociales"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"acceder el calendario y modificarlo"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder a tu calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"acceder a los SMS y modificarlos"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ver y administrar mensajes SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diccionario del usuario"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Leer o escribir palabras en el diccionario del usuario."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e historial"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceder directamente a los marcadores y al historial del navegador"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"utilizar el micrófono del dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"grabar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utilizar la cámara del dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"hacer fotos y grabar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"utilizar el teléfono del dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"hacer y administrar llamadas de teléfono"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"acceder a los sensores y a los wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"acceder a datos de sensores y dispositivos wearable"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contenido de la ventana"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contenido de una ventana con la que estés interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar exploración táctil"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite que la aplicación añada, elimine y cambie eventos que se pueden modificar en el tablet, incluidos los de amigos o compañeros de trabajo. La aplicación puede utilizar este permiso para enviar mensajes que parezcan proceder de propietarios de un calendario o para modificar eventos sin conocimiento de los propietarios."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite que la aplicación añada, elimine y modifique eventos que puedes modificar en la TV, incluidos los de amigos y compañeros de trabajo. La aplicación puede utilizar este permiso para enviar mensajes que parezcan proceder de propietarios de un calendario o para modificar eventos sin conocimiento de los propietarios."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite que la aplicación añada, elimine y cambie eventos que se pueden modificar en el teléfono, incluidos los de amigos o compañeros de trabajo. La aplicación puede utilizar este permiso para enviar mensajes que parezcan proceder de propietarios de un calendario o para modificar eventos sin conocimiento de los propietarios."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"simular fuentes de ubicación para prueba"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permite crear fuentes de ubicación simuladas para hacer pruebas o instalar un nuevo proveedor de ubicación. Este permiso autoriza a la aplicación a sobrescribir la ubicación o el estado proporcionados por otras fuentes de ubicación, como los proveedores de ubicación o GPS."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acceder a comandos de proveedor de ubicación adicional"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que la aplicación acceda a otros comandos del proveedor de ubicación. De esta forma, la aplicación podrá interferir en el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ubicación precisa (basada en redes y GPS)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Se ha cancelado la operación de huella digital."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Vuelve a intentarlo más tarde."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Vuelve a intentarlo."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"leer la configuración de sincronización"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si activas el almacenamiento USB, se detendrán algunas aplicaciones que estás usando y es posible que no estén disponibles hasta que lo desactives."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Error de funcionamiento de USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como dispositivo multimedia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como una cámara"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Conectado como dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toca para acceder a otras opciones de USB"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"¿Formatear USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"¿Formatear la tarjeta SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Se borrarán todos los archivos almacenados en el almacenamiento USB. Esta acción no se puede deshacer."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Durante %1$d minutos (hasta las <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante un minuto (hasta las <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Durante %1$d horas (hasta las <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante una hora (hasta las <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Durante %d minutos</item>
<item quantity="one">Durante un minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Durante %d horas</item>
<item quantity="one">Durante una hora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hasta apagar el dispositivo"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"No molestar"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tiempo de inactividad"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noche de entre semana"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fin de semana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Se ha producido un problema interno en el dispositivo y es posible que este no sea estable hasta que restablezcas los datos de fábrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Se ha producido un problema interno en el dispositivo. Ponte en contacto con el fabricante para obtener más información."</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 6b82b57..595b634 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Isiklikud rakendused"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Töö"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktid"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"kontaktidele juurdepääsemine ja nende muutmine"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"juurdepääs kontaktidele"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Asukoht"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"asukohale juurdepääsemine"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Teie sotsiaalne teave"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Otsene juurdepääs teie kontaktide teabele ja sotsiaalsetele sidemetele."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"kalendrile juurdepääsemine ja selle muutmine"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"juurdepääs kalendrile"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS-idele juurdepääsemine ja nende muutmine"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS-sõnumite vaatamine ja haldamine"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kasutaja sõnaraamat"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kasutaja sõnaraamatus sõnade lugemine ja nende sinna kirjutamine."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Järjehoidjad ja ajalugu"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Otsene juurdepääs järjehoidjatele ja brauseri ajaloole."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"seadme mikrofoni kasutamine"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"heli salvestamine"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kaamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"seadme kaamera kasutamine"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"pildistamine ja video salvestamine"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"seadme telefoni kasutamine"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"helistamine ja telefonikõnede haldamine"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Andurid"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"anduritele ja kaasaskantavatele seadmetele juurdepääsemine"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"juurdepääs andmetele andurite ja aksessuaaride kaudu"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Akna sisu toomine"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tutvuge kasutatava akna sisuga."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Puudutusega sirvimise sisselülitamine"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Võimaldab rakendusel lisada, eemaldada ja muuta sündmusi, mida saate muuta oma tahvelarvutis, sh sõprade ja töökaaslaste omi. See võib võimaldada rakendusel saata sõnumeid, mis näivad tulevat kalendri omanikelt, või muuta sündmusi omaniku teadmata."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Lubab rakendusel lisada, kustutada ja muuta sündmusi, mida saate teleris muuta, sealhulgas sõprade ja töökaaslaste omi. See lubab rakendusel saata sõnumeid, mis pärinevad näiliselt kalendrite omanikelt, või muuta sündmusi omanike teadmata."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Võimaldab rakendusel lisada, eemaldada ja muuta sündmusi, mida saate muuta oma telefonis, sh sõprade ja töökaaslaste omi. See võib võimaldada rakendusel saata sõnumeid, mis näivad tulevat kalendri omanikelt, või muuta sündmusi omaniku teadmata."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"võltsasukohad testimiseks"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Looge võltsasukoha allikaid, et katsetada või installida uut asukohapakkujat. See lubab rakendusel tühistada teiste asukohaallikate, näiteks GPS-i või asukohapakkujate tagastatud asukoha ja/või oleku."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"juurdepääs asukohapakkuja lisakäskudele"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Võimaldab rakendusel juurde pääseda asukohapakkuja erikäskudele. See võib lubada rakendusel mõjutada GPS-i või muude asukohaallikate tööd."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"täpne asukoht (GPS- ja võrgupõhine)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Sõrmejälje toiming tühistati."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Liiga palju katseid. Proovige hiljem uuesti."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Proovige uuesti."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"loe sünkroonimisseadeid"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Kui lülitate USB-salvestusruumi sisse, võivad mõned kasutatavad rakendused peatuda ega pruugi olla saadaval enne USB-salvestusruumi väljalülitamist."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB toiming ebaõnnestus"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ühendatud meediumiseadmena"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ühendatud kaamerana"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Ühendatud MIDI-seadmena"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ühendatud installijana"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ühendatud USB-lisaseadmega"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Puudutage teisi USB valikuid."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Vormind. USB-seade?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Kas vormindada SD-kaart?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Kõik USB-mäluseadmele salvestatud failid kustutatakse. Seda toimingut ei saa tagasi võtta."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d minutiks (kuni <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Üheks minutiks (kuni <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d tunniks (kuni <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Üheks tunniks (kuni <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d minutiks</item>
<item quantity="one">Üheks minutiks</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d tunniks</item>
<item quantity="one">Üheks tunniks</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kuni lülitate selle välja"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Ahendamine"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Mitte segada"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Puhkeaeg"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Argiõhtu"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Nädalavahetus"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Sündmus"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> vaigistas"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Seadmes ilmnes sisemine probleem ja seade võib olla ebastabiilne seni, kuni lähtestate seadme tehase andmetele."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Seadmes ilmnes sisemine probleem. Üksikasjaliku teabe saamiseks võtke ühendust tootjaga."</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 7bbe988..77453d2 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplikazio pertsonalak"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Lana"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"Ikusi eta egin aldaketak kontaktuei"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"Atzitu kontaktuak"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"Atzitu kokapena"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sare sozialetako zure informazioa"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Zure kontaktuei eta konexio sozialei buruzko informaziorako sarbide zuzena."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Egutegia"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"Ikusi eta egin aldaketak egutegian"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Atzitu egutegia"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS mezuak"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"Irakurri eta egin aldaketak SMS mezuetan"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"Ikusi eta kudeatu SMS mezuak"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Erabiltzailearen hiztegia"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Irakurri edo idatzi hitzak erabiltzaileek hiztegian."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Laster-markak eta historia"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Laster-marketarako eta arakatzailearen historiarako sarbide zuzena."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonoa"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"Erabili gailuaren mikrofonoa"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"Grabatu audioa"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"Erabili gailuaren kamera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"Atera argazkiak eta grabatu bideoak"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonoa"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"Erabili gailuaren telefono-eginbidea"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"Egin eta kudeatu telefono-deiak"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sentsoreak"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"Atzitu sentsoreak eta osagarriak"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"Atzitu sentsoreen eta gailu eramangarrien datuak"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Eskuratu leihoko edukia"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Arakatu irekita daukazun leihoko edukia."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktibatu ukipen bidez arakatzeko eginbidea"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tabletan alda ditzakezun gertaerak gehitzeko, kentzeko eta aldatzeko baimena ematen die aplikazioei, lagunenak eta lankideenak barne. Horrela, aplikazioak egutegi-jabeenak diruditen mezuak bidal ditzake, edo gertaerak alda ditzake jabeak jakin gabe."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Telebistan alda ditzakezun gertaerak gehitzea, kentzea edo aldatzea baimentzen die aplikazioei, lagunenak eta lankideenak barne. Horrela, egutegi-jabeenak diruditen mezuak bidal ditzakete aplikazioek, edo gertaerak alda ditzakete jabeek jakin gabe."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Telefonoan alda ditzakezun gertaerak gehitzeko, kentzeko eta aldatzeko baimena ematen die aplikazioei, lagunenak eta lankideenak barne. Horrela, aplikazioak egutegi-jabeenak diruditen mezuak bidal ditzake, edo gertaerak alda ditzake jabeak jakin gabe."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imitatu kokapen-iturburuak probak egiteko"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Probak egiteko kokapenaren iturburu faltsuak sortzeko edo kokapen-hornitzaile berria instalatzeko baimena ematen die aplikazioei. Horrela, GPSak edo kokapen-hornitzaileak bezalako kokapenaren iturburuek emandako kokapena edota egoera ordezka ditzake."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"atzitu kokapen-hornitzaileen komando gehigarriak"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Kokapen-hornitzailearen agindu gehigarriak atzitzea baimentzen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"kokapena zehatza (GPSan eta sarean oinarrituta)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Hatz-markaren eragiketa bertan behera utzi da."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Saiakera gehiegi egin dituzu. Saiatu berriro geroago."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Saiatu berriro."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Irakurri sinkronizazio-ezarpenak"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB memoria aktibatzen baduzu, erabiltzen ari zaren aplikazio batzuk gelditu egingo dira eta agian ez dira erabilgarri egongo USB memoria desaktibatu arte."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB eragiketak huts egin du"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Ados"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Multimedia-gailu gisa konektatua"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera gisa konektatua"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI gailu gisa konektatu da"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Instalatzaile gisa konektatua"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB osagarri batera konektatuta"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Ukitu beste USB aukera batzuk ikusteko."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB memoria formateatu?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD txartela formateatu?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB memorian dauden fitxategi guztiak ezabatuko dira. Ezin izango duzu ekintza hori desegin!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d minutuz (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> arte)</item>
<item quantity="one">Minutu batez (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> arte)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d orduz (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> arte)</item>
<item quantity="one">Ordubetez (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> arte)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d minutuz</item>
<item quantity="one">Minutu batez</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d orduz</item>
<item quantity="one">Ordubetez</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Zuk desaktibatu arte"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Tolestu"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ez molestatu"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Jarduerarik gabeko denbora"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Lanegunetako gaua"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Asteburua"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Gertaera"</string>
<string name="muted_by" msgid="6147073845094180001">"Audioa desaktibatu da (<xliff:g id="THIRD_PARTY">%1$s</xliff:g>)"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Barneko arazo bat dago zure gailuan eta agian ezegonkor egongo da jatorrizko datuak berrezartzen dituzun arte."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Barneko arazo bat dago zure gailuan. Xehetasunak jakiteko, jarri fabrikatzailearekin harremanetan."</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 0204692..f92b82d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"برنامههای شخصی"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"محل کار"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"مخاطبین"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"دسترسی به مخاطبین شما و تغییر آنها"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"دسترسی به مخاطبین شما"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"مکان"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"دسترسی به مکان شما"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"اطلاعات اجتماعی شما"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"مستقیم به اطلاعات مخاطبین و روابط اجتماعی دسترسی داشته باشید."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"تقویم"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"دسترسی به تقویم شما و تغییر آن"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"دسترسی به تقویم شما"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"پیامک"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"دسترسی به پیامک و تغییر آن"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"مشاهده و مدیریت پیامکها"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"فرهنگ لغت کاربر"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"خواندن یا نوشتن کلمات در فرهنگ لغت کاربر."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"نشانکها و سابقه"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"مستقیم به نشانکها و سابقه مرور دسترسی داشته باشید."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"میکروفن"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"استفاده از میکروفن دستگاه"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ضبط صدا"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"دوربین"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"استفاده از دوربین دستگاه"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"عکس گرفتن و فیلمبرداری"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"تلفن"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"استفاده از تلفن دستگاه"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"برقراری و مدیریت تماسهای تلفنی"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"حسگرها"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"دسترسی به حسگرها و فناوریهای پوشیدنی"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"دسترسی به اطلاعات به دست آمده از حسگرها و دستگاههای پوشیدنی"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"بازیابی محتوای پنجره"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"محتوای پنجرهای را که در حال تعامل با آن هستید بررسی کنید."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"فعالسازی کاوش لمسی"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"به برنامه اجازه میدهد رویدادهایی را که میتوانید در رایانهٔ لوحی خود اصلاح نمایید، از جمله رویدادهای دوستان یا همکاران خود را، اضافه یا حذف کرده یا تغییر دهد. این ویژگی ممکن است به برنامه اجازه دهد پیامهایی را که به نظر میرسد از مالکین تقویم رسیده است ارسال نموده یا رویدادها را بدون اطلاع مالک اصلاح کنند."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"به برنامه اجازه میدهد به افزودن، حذف یا تغییر رویدادهایی بپردازد که میتوانید در تلویزیونتان تغییر دهید، از جمله رویدادهای دوستان یا همکاران خود. این ویژگی شاید به برنامه اجازه دهد پیامهایی را ارسال کند که به نظر میرسد از جانب مالکین تقویم است یا رویدادها را بدون اطلاع مالک تغییر دهد."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"به برنامه اجازه میدهد رویدادهایی را که میتوانید در تلفن خود اصلاح نمایید، از جمله رویدادهای دوستان یا همکاران خود را، اضافه یا حذف کرده یا تغییر دهد. این ویژگی ممکن است به برنامه اجازه دهد پیامهایی را که به نظر میرسد از مالکین تقویم رسیده است ارسال نموده یا رویدادها را بدون اطلاع مالک اصلاح کنند."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"منابع مکان کاذب برای تست"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"منابع موقعیت مکانی کاذب را برای تست کردن یا نصب یک ارائهدهنده موقعیت مکانی جدید ایجاد نمایید. این کار به برنامه امکان میدهد موقعیت مکانی و/یا وضعیت گزارش داده شده توسط سایر منابع موقعیت مکانی مانند GPS یا ارائهدهندگان موقعیت مکانی را نادیده بگیرد."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"دسترسی به فرمانهای بیشتر ارائه دهنده مکان"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"به برنامه اجازه میدهد به دستورات ارائهدهنده مکان تکمیلی دسترسی داشته باشد. این کار ممکن است به برنامه امکان دهد با کارکرد GPS یا منابع دیگر مکان تداخل داشته باشد."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"موقعیت مکانی دقیق (مبتنی بر GPS و شبکه)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"عملکرد اثر انگشت لغو شد."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"تلاشهای زیادی انجام شده است. بعداً دوباره امتحان کنید."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوباره امتحان کنید."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"خواندن تنظیمات همگامسازی"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"در صورت فعال کردن حافظهٔ USB، برخی از برنامههایی که از آنها استفاده میکنید متوقف میشوند و تا زمانی که حافظهٔ USB را غیرفعال نکنید امکان استفاده از آنها وجود نخواهد داشت."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"راهاندازی USB ناموفق بود."</string>
<string name="dlg_ok" msgid="7376953167039865701">"تأیید"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"متصل شده بهعنوان دستگاه رسانهای"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"متصل شده بهعنوان دوربین"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"به عنوان یک دستگاه MIDI متصل شد"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"متصل شده بهعنوان نصب کننده"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"به یک وسیله جانبی USB وصل شده است"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"برای سایر گزینههای USB لمس کنید."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"حافظهٔ USB فرمت شود؟"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"کارت SD فرمت شود؟"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"همه فایلهای ذخیره شده در حافظهٔ USB پاک خواهد شد. این عمل را نمیتوان برگرداند!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">به مدت %1$d دقیقه (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">به مدت %1$d ساعت (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">به مدت %1$d ساعت (تا <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">به مدت %d دقیقه</item>
<item quantity="other">به مدت %d دقیقه</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">به مدت %d ساعت</item>
<item quantity="other">به مدت %d ساعت</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"تا وقتی آن را خاموش کنید"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"کوچک کردن"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"مزاحم نشوید"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"فرویش"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"شب آخر هفته"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"آخر هفته"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"رویداد"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> آن را بیصدا کرد"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"دستگاهتان یک مشکل داخلی دارد، و ممکن است تا زمانی که بازنشانی به داده کارخانه انجام نگیرد، بیثبات بماند."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"دستگاهتان یک مشکل داخلی دارد. برای جزئیات آن با سازندهتان تماس بگیرید."</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index a7c4f3f..d4f3335 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Omat sovellukset"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Työ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktit"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"käytä ja muokkaa kontakteja"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"käyttää yhteystietoja"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Sijainti"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"käytä sijaintiasi"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosiaaliset tietosi"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktiesi ja internet-kontaktiesi tietojen käyttöoikeus."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenteri"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"käytä ja muokkaa kalenteria"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"käyttää kalenteria"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Tekstiviestit"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"käytä ja muokkaa tekstiviestejä"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"tarkastella ja hallinnoida tekstiviestejä"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Käyttäjän sanakirja"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lue tai kirjoita sanoja käyttäjän sanakirjaan."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Kirjanmerkit ja historia"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Kirjanmerkkien ja selaimen historian käyttöoikeus."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoni"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"käytä laitteen mikrofonia"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"tallentaa ääntä"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"käytä laitteen kameraa"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ottaa kuvia ja videoita"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Puhelin"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"käytä laitteen puhelinta"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"soittaa ja hallinnoida puheluita"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Anturit"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"käytä antureita ja puettavia laitteita"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"käyttää antureiden ja puettavien laitteiden tietoja"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Nouda ikkunan sisältöä"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkista käyttämäsi ikkunan sisältö."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ota kosketuksella tutkiminen käyttöön"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Antaa sovelluksen lisätä, poistaa ja muuttaa tapahtumia, joita voit muokata tablet-laitteellasi. Näihin kuuluvat myös kavereidesi tai työkavereidesi tapahtumat. Sovellus voi lähettää viestejä, jotka vaikuttavat kalenterin omistajien lähettämiltä, tai muokata tapahtumia ilman niiden omistajien lupaa."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Antaa sovelluksen lisätä, poistaa ja muuttaa tapahtumia, joita on mahdollista muokata televisiolla. Tällaiset tapahtumat voivat olla kavereiden tai työkavereiden kutsuja. Sovellus voi lähettää viestejä, jotka näyttävät tulevan kalenterin omistajalta, tai muokata tapahtumia omistajan tietämättä."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Antaa sovelluksen lisätä, poistaa ja muuttaa tapahtumia, joita voit muokata puhelimellasi. Näihin kuuluvat myös kavereidesi tai työkavereidesi tapahtumat. Sovellus voi lähettää viestejä, jotka vaikuttavat kalenterin omistajien lähettämiltä, tai muokata tapahtumia ilman niiden omistajien lupaa."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imitoi sijaintilähteitä testaustarkoituksissa"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Luo imitoituja sijaintilähteitä testaustarkoituksessa tai asenna uusi sijaintipalvelu. Sovellus voi ohittaa muiden sijaintilähteiden kuten GPS:n ja sijaintipalveluiden palauttaman sijainnin ja/tai tilan."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"käytä lisää sijainnintarjoajakomentoja"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Antaa sovelluksen käyttää ylimääräisiä sijaintipalvelukomentoja. Sovellus saattaa tällöin häiritä GPS:n tai muiden sijaintilähteiden toimintaa."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"tarkka sijainti (GPS- ja verkkopohjainen)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Sormenjälkitoiminto peruutettiin."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Liian monta yritystä. Yritä myöhemmin uudelleen."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Yritä uudelleen."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lue synkronointiasetuksia"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jos otat USB-tallennustilan käyttöön, osa käyttämistäsi sovelluksista pysähtyy eikä ehkä ole käytettävissä, ennen kuin poistat USB-tallennustilan käytöstä."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-toiminto epäonnistui."</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Kytketty medialaitteena"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kytketty kamerana"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Yhdistetty MIDI-laitteeseen"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Kytketty asennusohjelmana"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Liitetty USB-laitteeseen"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Käytä muita USB-vaihtoehtoja koskettamalla."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Alusta USB-tila?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Alustetaanko SD-kortti?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Kaikki USB-tallennustilaan tallennetut tiedostot poistetaan. Tätä toimintoa ei voi kumota!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d minuutiksi (kunnes kello on <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Yhdeksi minuutiksi (kunnes kello on <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d tunniksi (kunnes kello on <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Yhdeksi tunniksi (kunnes kello on <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d minuutiksi</item>
<item quantity="one">Minuutiksi</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d tunniksi</item>
<item quantity="one">Tunniksi</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kunnes poistat tämän käytöstä"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Kutista"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Älä häiritse"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Vapaalla"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Arki-iltaisin"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Viikonloppuna"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Tapahtuma"</string>
<string name="muted_by" msgid="6147073845094180001">"Mykistänyt <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Laitteellasi on sisäinen ongelma, joka aiheuttaa epävakautta. Voit korjata tilanteen palauttamalla tehdasasetukset."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Laitteesi yhdistäminen ei onnistu sisäisen virheen takia. Saat lisätietoja valmistajalta."</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index c89d989..10fb74f 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Travail"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"accéder à vos contacts et les modifier"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localisation"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"accéder à votre position"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vos données sur les réseaux sociaux"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accès direct aux informations sur vos contacts et vos amis sur les réseaux sociaux"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"accéder à votre calendrier et le modifier"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Messagerie texte"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"accéder aux messages texte et les modifier"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"afficher et gérer les textos"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dctionnaire personnel"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lire ou écrire des mots dans le dictionnaire personnel."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoris et historique"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accès direct aux favoris et à l\'historique du navigateur"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"utiliser le microphone de l\'appareil"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utiliser l\'appareil photo de l\'appareil"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et filmer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"utiliser les fonctions d\'appel téléphonique de l\'appareil"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"faire et gérer des appels téléphoniques"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"accéder aux capteurs et aux accessoires connectés"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accéder aux données des capteurs et des appareils portables"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permet à l\'application d\'ajouter, de supprimer et de modifier les événements modifiables sur votre téléviseur, y compris ceux de vos amis et de vos collègues. Cette autorisation peut permettre à une application d\'envoyer des messages semblant provenir du propriétaire de l\'agenda ou modifier les événements à l\'insu de celui-ci."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre téléphone, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"créer des sources de localisation fictives à des fins de test"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permet de créer des sources de localisation fictives à des fins de tests ou pour installer un nouveau fournisseur de position. L\'application peut ainsi modifier la position ou l\'état renvoyé par d\'autres sources de localisation telles que le GPS ou les fournisseurs de position."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accéder aux commandes de fournisseur de position géographique supplémentaires"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"position précise (GPS et réseau)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Réessayer."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si vous activez la mémoire de stockage USB, certaines applications en cours d\'utilisation vont être fermées et risquent de rester indisponibles jusqu\'à ce que la mémoire de stockage USB soit désactivée."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Échec du fonctionnement de la mémoire de stockage USB."</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connecté en tant qu\'app. multimédia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connecté en tant qu\'appareil photo"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connecté en tant qu\'appareil MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connecté en tant que programme d\'installation"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Appuyez pour accéder aux autres options USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater mémoire?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formater la carte SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tous les fichiers stockés sur la mémoire de stockage USB vont être effacés. Cette action est irréversible."</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Pendant %d minute</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Pendant %d heure</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne pas déranger"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Temps d\'arrêt"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Soirs de semaine"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fin de semaine"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Événement"</string>
<string name="muted_by" msgid="6147073845094180001">"Mis en sourdine par <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Un problème interne est survenu avec votre appareil. Il se peut qu\'il soit instable jusqu\'à ce que vous le réinitialisiez à sa configuration d\'usine."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Un problème interne est survenu avec votre appareil. Communiquez avec le fabricant pour obtenir plus de détails."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9cc881b..ac0305e 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Applications personnelles"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Professionnel"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"accéder à vos contacts et les modifier"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Position"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"accéder à votre position"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vos informations sur les réseaux sociaux"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accès direct aux informations sur vos contacts et vos amis sur les réseaux sociaux"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"accéder à votre agenda et le modifier"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accéder à votre agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"accéder aux SMS et les modifier"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"afficher et gérer des SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dictionnaire personnel"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Consulter et ajouter des mots dans le dictionnaire personnel"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoris et historique"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accès direct aux favoris et à l\'historique du navigateur"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"utiliser le micro de l\'appareil"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"enregistrer des fichiers audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Appareil photo"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utiliser l\'appareil photo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"prendre des photos et enregistrer des vidéos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Téléphone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"utiliser les fonctionnalités de téléphonie de l\'appareil"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"effectuer et gérer des appels téléphoniques"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Capteurs"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"accéder aux capteurs et aux accessoires connectés"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accéder aux données issues de capteurs et d\'appareils connectés"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Récupérer le contenu d\'une fenêtre"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecter le contenu d\'une fenêtre avec laquelle vous interagissez."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activer la fonctionnalité Explorer au toucher"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre tablette, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permet à l\'application d\'ajouter, de supprimer et de modifier les événements modifiables sur le téléviseur, y compris ceux de vos amis et de vos collègues. Cette autorisation peut permettre à une application d\'envoyer des messages qui semblent provenir du propriétaire de l\'agenda ou de modifier les événements à l\'insu de celui-ci."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permet à l\'application d\'ajouter, de supprimer et d\'apporter des modifications aux événements modifiables sur votre téléphone, y compris ceux de vos amis ou de vos collègues. Cette autorisation peut lui permettre d\'envoyer des messages qui semblent provenir de propriétaires de l\'agenda ou de modifier les événements à l\'insu des propriétaires."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Création de sources de localisation fictives à des fins de test"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permet de créer des sources de localisation fictives à des fins de tests ou pour installer un nouveau fournisseur de position. L\'application peut ainsi modifier la position et/ou l\'état renvoyé par d\'autres sources de localisation telles que le GPS ou les fournisseurs de position."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Accès aux commandes de fournisseur de position géographique supplémentaires"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"connaître votre position précise (GPS et réseau)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Opération d\'empreinte numérique annulée."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Trop de tentatives. Veuillez réessayer plus tard."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Veuillez réessayer."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lire les paramètres de synchronisation"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Si vous activez la mémoire de stockage USB, certaines applications en cours d\'utilisation vont être fermées et risquent de rester indisponibles jusqu\'à ce que la mémoire de stockage USB soit désactivée."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Échec du fonctionnement de la mémoire de stockage USB."</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Connecté en tant qu\'appareil multimédia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Connecté en tant qu\'appareil photo"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connecté en tant qu\'appareil MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Connecté en tant que programme d\'installation"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Connecté à un accessoire USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Appuyez ici pour accéder aux autres options USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formater mémoire ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formater la carte SD ?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tous les fichiers stockés sur la mémoire de stockage USB vont être effacés. Cette action est irréversible."</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Pendant %1$d minute (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d minutes (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Pendant %1$d heure (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Pendant %1$d heures (jusqu\'à <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Pendant %d minute</item>
<item quantity="other">Pendant %d minutes</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Pendant %d heure</item>
<item quantity="other">Pendant %d heures</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne pas déranger"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Temps d\'arrêt"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Soirée de semaine"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Week-end"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Événement"</string>
<string name="muted_by" msgid="6147073845094180001">"Son coupé par : <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Un problème interne lié à votre appareil est survenu. Ce dernier risque d\'être instable jusqu\'à ce que vous rétablissiez la configuration d\'usine."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Un problème interne lié à votre appareil est survenu. Veuillez contacter le fabricant pour en savoir plus."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 9fa0aae..17eef31 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicacións persoais"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Traballo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"acceder e modificar os teus contactos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder aos teus contactos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localización"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"acceder á túa localización"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"A túa información social"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acceso directo a información acerca dos teus contactos e as conexións sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"acceder e modificar o teu calendario"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acceder ao teu calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"acceder e modificar SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"consultar e xestionar mensaxes de SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionario de usuario"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escribir palabras no dicionario de usuario."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoritos e historial"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acceso directo aos favoritos e ao historial do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrófono"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"usar o micrófono do dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Cámara"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"usar a cámara do dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Teléfono"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"usar a telefonía do dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"facer e xestionar chamadas telefónicas"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"acceder aos sensores e dispositivos que se poden levar postos"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"acceder a datos desde sensores e dispositivos que se poden levar postos"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar contido da ventá"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona o contido dunha ventá coa que estás interactuando."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar a exploración táctil"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite á aplicación engadir, eliminar e cambiar eventos que podes modificar no teu tablet, incluídos os de amigos ou compañeiros de traballo. É posible que esta acción permita á aplicación enviar mensaxes que parecen proceder de propietarios de calendarios ou modificar eventos sen o coñecemento dos propietarios."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite que a aplicación engada, elimine e cambie eventos que se poden modificar na televisión, incluídos os de amigos e compañeiros de traballo. A aplicación pode utilizar este permiso para enviar mensaxes que poidan proceder de propietarios dun calendario ou para modificar eventos sen coñecemento dos propietarios."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite á aplicación engadir, eliminar e cambiar eventos que podes modificar no teu teléfono, incluídos os de amigos ou compañeiros de traballo. É posible que esta acción permita á aplicación enviar mensaxes que parecen proceder de propietarios de calendarios ou modificar eventos sen o coñecemento dos propietarios."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fontes da localización falsas para probas"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Permite crear fontes de localización falsas para probar ou instalar un novo provedor de localizacións. Isto permite á aplicación anular a localización e/ou o estado obtido por outras fontes de localización como o GPS ou provedores de localización."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acceder a comandos adicionais do provedor de situación"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite á aplicación acceder a comandos adicionais de fornecedor de localizacións. É posible que isto provoque que a aplicación interfira co funcionamento do GPS ou doutras fontes da localización."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"localización precisa (baseada en GPS e na rede)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Cancelouse a operación da impresión dixital."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiados intentos. Téntao de novo máis tarde."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Téntao de novo."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler a configuración de sincronización"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se activas o almacenamento USB, algunhas aplicacións que estás usando deteranse e é posible que non estean dispoñibles ata que desactives o almacenamento USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Produciuse un erro na operación do USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Aceptar"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como dispositivo multimedia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como unha cámara"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Conectado como dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectado como instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a un accesorio USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toca para acceder a outras opcións de USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Queres formatar o almacenamento USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Queres formatar a tarxeta SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Borraranse todos os ficheiros gardados no teu almacenamento USB. Esta acción non se pode desfacer."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Durante %1$d minutos (ata as <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante un minuto (ata as <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Durante %1$d horas (ata as <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante unha hora (ata as <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Durante %d minutos</item>
<item quantity="one">Durante un minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Durante %d horas</item>
<item quantity="one">Durante unha hora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Ata que desactives isto"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Non molestar"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tempo de inactividade"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noite da semana"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fin de semana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Silenciado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Produciuse un erro interno no teu dispositivo e quizais funcione de maneira inestable ata o restablecemento dos datos de fábrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Produciuse un erro interno co teu dispositivo. Contacta co teu fabricante para obter máis información."</string>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 5e9e6be..aa91eb9 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -129,6 +129,7 @@
<string-array name="wfcOperatorErrorNotificationMessages">
</string-array>
<string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string>
+ <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"બંધ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi પસંદ કર્યું"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"સેલ્યુલર પસંદ કર્યું"</string>
@@ -219,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"વ્યક્તિગત એપ્લિકેશન્સ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"કાર્યાલય"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"સંપર્કો"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"તમારા સંપર્કોને ઍક્સેસ કરો અને સંશોધિત કરો"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"તમારા સંપર્કોને ઍક્સેસ કરો"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"તમારા સ્થાનને ઍક્સેસ કરો"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"તમારી સામાજિક માહિતી"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"તમારા સંપર્કો અને સામાજિક કનેક્શન્સ વિશેની માહિતીની સીધી ઍક્સેસ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"કૅલેન્ડર"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"તમારા કેલેન્ડરને ઍક્સેસ કરો અને સંશોધિત કરો"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"તમારા કેલેન્ડરને ઍક્સેસ કરો"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS ને ઍક્સેસ કરો અને સંશોધિત કરો"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS સંદેશા જુઓ અને સંચાલિત કરો"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"વપરાશકર્તા શબ્દકોશ"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"વપરાશકર્તા શબ્દકોશમાં શબ્દો વાંચો અથવા લખો."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"બુકમાર્ક્સ અને ઇતિહાસ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"બુકમાર્ક્સ અને બ્રાઉઝર ઇતિહાસની સીધી ઍક્સેસ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"માઇક્રોફોન"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ઉપકરણ માઇક્રોફોનનો ઉપયોગ કરો"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ઑડિઓ રેકોર્ડ કરો"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"કૅમેરો"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ઉપકરણ કેમેરાનો ઉપયોગ કરો"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લો અને વિડિઓ રેકોર્ડ કરો"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ફોન"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ઉપકરણ ટેલિફોનીનો ઉપયોગ કરો"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો તથા સંચાલિત કરો"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"સેન્સર્સ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"સેન્સર્સ અને પહેરવાલાયકને ઍક્સેસ કરો"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"સેન્સર્સ અને પહેરવાલાયક ઉપકરણોથી ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો સામગ્રી પુનર્પ્રાપ્ત કરો"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"તમે જેની સાથે ક્રિયાપ્રતિક્રિયા કરી રહ્યાં છો તે વિંડોની સામગ્રીની તપાસ કરો."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ટચ કરીને અન્વેષણ કરો સક્ષમ કરો"</string>
@@ -334,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટેબ્લેટ પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ટીવી પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"એપ્લિકેશનને મિત્રોના અથવા સહકાર્યકરો સહિત તમારા ફોન પર તમે સંશોધિત કરી શકો તે ઇવેન્ટ્સ ઉમેરવા, દૂર કરવા, બદલવાની મંજૂરી આપે છે. આ એપ્લિકેશનને કૅલેન્ડર માલિક તરફથી આવતાં હોય તેવા સંદેશા મોકલવાની અથવા માલિકની જાણ વિના ઇવેન્ટ્સ સંશોધિત કરવાની મંજૂરી આપી શકે છે."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"પરીક્ષણ માટે નકલી સ્થાન સ્રોતો"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"પરીક્ષણ માટે નકલી સ્થાન સ્રોતો બનાવો અથવા એક નવો સ્થાન પ્રદાતા ઇન્સ્ટોલ કરો. આ એપ્લિકેશનને GPS અથવા સ્થાન પ્રદાતાઓ જેવા અન્ય સ્થાન સ્રોતો દ્વારા પરત કરાયેલ સ્થાન અને/અથવા સ્થિતિને ઓવરરાઇડ કરવાની મંજૂરી આપે છે."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરો"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"એપ્લિકેશનને વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને GPS અથવા અન્ય સ્થાન સ્રોતોના ઓપરેશનમાં દખલ કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"નિશ્ચિત સ્થાન (GPS અને નેટવર્ક-આધારિત)"</string>
@@ -437,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ફિંગરપ્રિન્ટ ઓપરેશન રદ કર્યું."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ઘણા બધા પ્રયત્નો. પછીથી ફરી પ્રયાસ કરો."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ફરી પ્રયાસ કરો."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"સમન્વયન સેટિંગ્સ વાંચો"</string>
@@ -1041,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"જો તમે USB સંગ્રહને ચાલુ કરો છો, તો તમે ઉપયોગમાં લઈ રહ્યાં છો તે કેટલીક એપ્લિકેશન્સ બંધ થઈ જશે અને જ્યાં સુધી તમે USB સંગ્રહ બંધ ન કરી લો ત્યાં સુધી અનુપલબ્ધ હોઈ શકે છે."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ઓપરેશન અસફળ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ઑકે"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"એક મીડિયા ઉપકરણ તરીકે કનેક્ટ થયું"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"કૅમેરા તરીકે કનેક્ટ કર્યું"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI ઉપકરણ તરીકે કનેક્ટ થયું"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ઇન્સ્ટોલર તરીકે કનેક્ટ કર્યું"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ઍક્સેસરીથી કનેક્ટ થયાં"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"અન્ય USB વિકલ્પો માટે ટચ કરો."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB સંગ્રહને ફોર્મેટ કરીએ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD કાર્ડ ફોર્મેટ કરીએ?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"તમારા USB સંગ્રહમાં સંગ્રહિત તમામ ફાઇલો કાઢી નાખવામાં આવશે. આ ક્રિયા પલટાવી શકાતી નથી!"</string>
@@ -1078,22 +1085,14 @@
<string name="ext_media_init_action" msgid="8317198948634872507">"સેટઅપ"</string>
<string name="ext_media_unmount_action" msgid="1121883233103278199">"બહાર કાઢો"</string>
<string name="ext_media_browse_action" msgid="8322172381028546087">"અન્વેષણ કરો"</string>
- <!-- no translation found for ext_media_missing_title (620980315821543904) -->
- <skip />
- <!-- no translation found for ext_media_missing_message (5761133583368750174) -->
- <skip />
- <!-- no translation found for ext_media_move_specific_title (1471100343872375842) -->
- <skip />
- <!-- no translation found for ext_media_move_title (1022809140035962662) -->
- <skip />
- <!-- no translation found for ext_media_move_success_title (8575300932957954671) -->
- <skip />
- <!-- no translation found for ext_media_move_success_message (4199002148206265426) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_title (7613189040358789908) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_message (1978096440816403360) -->
- <skip />
+ <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ખૂટે છે"</string>
+ <string name="ext_media_missing_message" msgid="5761133583368750174">"આ ઉપકરણ ફરીથી દાખલ કરો"</string>
+ <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ખસેડી રહ્યાં છીએ"</string>
+ <string name="ext_media_move_title" msgid="1022809140035962662">"ડેટાને ખસેડી રહ્યાં છીએ"</string>
+ <string name="ext_media_move_success_title" msgid="8575300932957954671">"ખસેડવાનું પૂર્ણ થયું"</string>
+ <string name="ext_media_move_success_message" msgid="4199002148206265426">"ડેટાને <xliff:g id="NAME">%s</xliff:g> પર ખસેડી રહ્યાં છીએ"</string>
+ <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ડેટા ખસેડી શક્યાં નથી"</string>
+ <string name="ext_media_move_failure_message" msgid="1978096440816403360">"મૂળ સ્થાન પર બાકી ડેટા"</string>
<string name="activity_list_empty" msgid="1675388330786841066">"કોઈ મેળ ખાતી પ્રવૃત્તિઓ મળી નથી."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"મીડિયા આઉટપુટ રૂટ કરો"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"એપ્લિકેશનને અન્ય બાહ્ય ઉપકરણો પર મીડિયા આઉટપુટને રૂટ કરવની મંજૂરી આપે છે."</string>
@@ -1466,32 +1465,38 @@
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"અનપિન કરતા પહેલાં અનલૉક પેટર્ન માટે પૂછો"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"તમારા વ્યવસ્થાપક દ્વારા ઇન્સ્ટોલ કરેલ"</string>
+ <string name="package_updated_device_owner" msgid="8856631322440187071">"તમારા વ્યવસ્થાપક દ્વારા અપડેટ થયેલ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખેલ"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"બૅટરી આવરદા વધુ સારી કરવામાં સહાય માટે, બૅટરી સેવર તમારા ઉપકરણના પ્રદર્શનને ઘટાડે છે અને વાઇબ્રેશન, સ્થાન સેવાઓ અને મોટાભાગના પૃષ્ઠભૂમિ ડેટાને સીમિત કરે છે. ઇમેઇલ, મેસેજિંગ અને અન્ય એપ્લિકેશન્સ જે સમન્વયન પર આધાર રાખે છે તે તમે તેમને ખોલશો નહીં ત્યાં સુધી અપડેટ થઈ શકતી નથી.\n\nજ્યારે તમારું ઉપકરણ ચાર્જ થઈ રહ્યું હોય ત્યારે બૅટરી સેવર આપમેળે બંધ થઈ જાય છે."</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
<item quantity="one">%1$d મિનિટ માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
<item quantity="other">%1$d મિનિટ માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d કલાક માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
<item quantity="other">%1$d કલાક માટે (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> સુધી)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d મિનિટ માટે</item>
<item quantity="other">%d મિનિટ માટે</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d કલાક માટે</item>
<item quantity="other">%d કલાક માટે</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> સુધી"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"તમે આ બંધ ન કરો ત્યાં સુધી"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"સંકુચિત કરો"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ખલેલ પાડશો નહીં"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ડાઉનટાઇમ"</string>
- <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"સપ્તાહાંત સિવાયની રાત્રે"</string>
- <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"સપ્તાહાંત"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"સપ્તાહાંત રાત્રિ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"સપ્તાહાંત"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ઇવેન્ટ"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> દ્વારા મ્યૂટ કરાયું"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે અને જ્યાં સુધી તમે ફેક્ટરી ડેટા ફરીથી સેટ કરશો નહીં ત્યાં સુધી તે અસ્થિર રહી શકે છે."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"તમારા ઉપકરણમાં આંતરિક સમસ્યા છે. વિગતો માટે તમારા નિર્માતાનો સંપર્ક કરો."</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 8fe28a7..5eff6be 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"व्यक्तिगत ऐप्स"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"कार्यालय"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"अपने संपर्कों को ऐक्सेस करें और उनमें बदलाव करें"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"अपने संपर्कों को ऐक्सेस करें"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"अपना स्थान ऐक्सेस करें"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"आपकी सामाजिक जानकारी"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"अपने संपर्कों और सामाजिक कनेक्शन के बारे में जानकारी पर सीधी पहुंच."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"कैलेंडर"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"अपना कैलेंडर ऐक्सेस करें और उसमें बदलाव करें"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"अपने कैलेंडर को ऐक्सेस करें"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS ऐक्सेस करें और उसमें बदलाव करें"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS संदेश देखें और प्रबंधित करें"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"उपयोगकर्ता शब्दकोश"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"उपयोगकर्ता डिक्शनरी में शब्द पढ़ें या लिखें."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्क और इतिहास"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्क और ब्राउज़र इतिहास पर सीधी पहुंच."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफ़ोन"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"डिवाइस के माइक्रोफ़ोन का उपयोग करें"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"कैमरा"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"डिवाइस के कैमरे का उपयोग करें"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्र लें और वीडियो रिकॉर्ड करें"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फ़ोन"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"डिवाइस टेलीफ़ोनी का उपयोग करें"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"फ़ोन कॉल करें और प्रबंधित करें"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"संवेदक"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"संवेदक तथा पहने जाने योग्य डिवाइस ऐक्सेस करें"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"सेंसर और पहने जाने योग्य डिवाइस से डेटा ऐक्सेस करें"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री प्राप्त करें"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"उस विंडो की सामग्री का निरीक्षण करें जिससे आप सहभागिता कर रहे हैं."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श द्वारा एक्सप्लोर करें को चालू करें"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ऐप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने टेबलेट पर संशोधित कर सकते हैं. इससे ऐप्स ,अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ऐप को ऐसे ईवेंट जोड़ने, निकालने, बदलने देती है जिन्हें आप अपने डिवाइस पर बदल सकते हैं, जिनमें मित्रों या सहकर्मियों के ईवेंट शामिल हैं. इससे ऐप ऐसे संदेश भेज सकता है जो कैलेंडर स्वामी से आते हुए प्रतीत होते हैं या ऐप स्वामी की जानकारी के बिना ईवेंट बदल सकता है."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ऐप्स को मित्रों या सहकर्मियों के ईवेंट के साथ ही वे ईवेंट जोड़ने, निकालने, बदलने देता है जिन्हें आप अपने फ़ोन पर संशोधित कर सकते हैं. इससे ऐप्स , अपनी जानकारी के बिना उन संदेशों को भेज सकता है जो कैलेंडर स्वामियों की ओर से आते दिखाई देते हैं, या ईवेंट संशोधित कर सकता है."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षण के लिए नकली स्थान स्रोत"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षण के लिए कृत्रिम स्थान स्रोत बनाएं या एक नया स्थान प्रदाता इंस्टॉल करें. यह ऐप्स को स्थान और/या अन्य स्थान स्रोतों जैसे GPS या स्थान प्रदाताओं द्वारा लौटाई गई स्थिति को ओवरराइड करने देता है."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेशों में पहुंचे"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप्स को अतिरिक्त स्थान प्रदाता आदेशों पर पहुंचने देती है. इससे ऐप्स GPS या अन्य स्थान स्रोतों के संचालन में अवरोध पहुंचा सकता है."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"सटीक स्थान (GPS और नेटवर्क-आधारित)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"फ़िंगरप्रिंट क्रियान्वयन रोक दिया गया."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"बहुत अधिक प्रयास कर लिए गए हैं. बाद में पुन: प्रयास करें."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन: प्रयास करें."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"समन्वयन सेटिंग पढ़ें"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि आप USB मेमोरी चालू करते हैं, तो आपके द्वारा उपयोग किए जा रहे कुछ ऐप्स रुक जाएंगे और हो सकता है कि वे तब तक अनुपलब्ध रहें जब तक कि आप USB मेमोरी बंद नहीं कर देते."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB कार्यवाही विफल"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ठीक है"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"किसी मीडिया डिवाइस के रूप में कनेक्ट किया गया"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"कैमरे के रूप में कनेक्ट करें"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI डिवाइस के रूप में कनेक्ट है"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"किसी इंस्टॉलर के रूप में कनेक्ट किया गया"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायक सामग्री से कनेक्ट किया गया"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"अन्य USB विकल्पों के लिए स्पर्श करें."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB मेमोरी फ़ॉर्मेट करें?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्ड प्रारूपित करें?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"आपके USB मेमोरी में संग्रहीत सभी फ़ाइलें मिट जाएंगी. यह क्रिया पूर्ववत नहीं की जा सकती!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
<item quantity="other">%1$d मिनट के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d घंटे के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
<item quantity="other">%1$d घंटे के लिए (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> तक)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d मिनट के लिए</item>
<item quantity="other">%d मिनट के लिए</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d घंटे के लिए</item>
<item quantity="other">%d घंटे के लिए</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"जब तक आप इसे बंद नहीं कर देते"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"परेशान ना करें"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"बंद रहने का समय"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"सप्ताह की रात"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ईवेंट"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा म्यूट किया गया"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई और यह तब तक अस्थिर रह सकता है, जब तक आप फ़ैक्टरी डेटा रीसेट नहीं करते हैं."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index a9d5e2b..89da946 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -221,27 +221,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Osobne aplikacije"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Posao"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"pristup kontaktima i njihova izmjena"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupati vašim kontaktima"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"pristup vašoj lokaciji"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informacije o vašoj društvenoj aktivnosti"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Izravan pristup informacijama o kontaktima i društvenim vezama."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"pristup kalendaru i njegova izmjena"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pristupati kalendaru"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"pristup SMS-ovima i njihova izmjena"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"pregledavati SMS poruke i upravljati njima"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Korisnički rječnik"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čitanje ili pisanje riječi u korisničkom rječniku."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Oznake i povijest"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Izravan pristup oznakama i povijest preglednika."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"upotreba mikrofona uređaja"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snimati zvuk"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparat"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"upotreba fotoaparata uređaja"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"snimati fotografije i videozapise"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"upotreba telefonske veze na uređaju"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"uspostavljati telefonske pozive i upravljati njima"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"pristup senzorima i nosivim uređajima"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"pristupati podacima senzora i nosivih uređaja"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dohvaćanje sadržaja prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Istražite sadržaj prozora koji upotrebljavate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključivanje značajke Istraži dodirom"</string>
@@ -336,8 +336,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Aplikaciji omogućuje dodavanje, uklanjanje i promjenu događaja koje možete izmijeniti na tabletnom računalu, uključujući one od vaših prijatelja ili suradnika. To aplikaciji može omogućiti slanje poruka koje izgledaju kao da dolaze od vlasnika kalendara ili izmjenu događaja bez znanja vlasnika."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Aplikaciji omogućuje dodavanje, uklanjanje i promjenu događaja koje možete izmijeniti na televizoru, uključujući one vaših prijatelja ili suradnika. To aplikaciji može omogućiti slanje poruka koje izgledaju kao da ih je poslao vlasnik kalendara ili izmjenu događaja bez znanja vlasnika."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Aplikaciji omogućuje dodavanje, uklanjanje i promjenu događaja koje možete izmijeniti na telefonu, uključujući one od vaših prijatelja ili suradnika. To aplikaciji može omogućiti slanje poruka koje izgledaju kao da dolaze od vlasnika kalendara ili izmjenu događaja bez znanja vlasnika."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"omogućeno testiranje izvora lokacije"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Stvaranje lažnih izvora lokacije radi testiranja ili za instaliranje novog pružatelja usluga lokacije. To aplikaciji omogućuje zaobilaženje lokacije i/ili statusa koji vraćaju drugi izvori lokacije, primjerice GPS ili pružatelji usluga lokacije."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"pristup dodatnim naredbama davatelja lokacije"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Omogućuje aplikaciji pristup dodatnim naredbama davatelja usluga lokacije. To može omogućiti aplikaciji ometanje rada GPS-a ili drugih izvora lokacije."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precizna lokacija (GPS i mreža)"</string>
@@ -439,6 +437,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Radnja otiska prsta otkazana je."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Previše pokušaja. Pokušajte ponovo kasnije."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Pokušajte ponovo."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čitanje postavki sinkronizacije"</string>
@@ -1049,12 +1049,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ako uključite USB pohranu, neke aplikacije koje upotrebljavate zaustavit će se i možda neće biti dostupne dok ne isključite USB pohranu."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Rad USB-a nije uspio"</string>
<string name="dlg_ok" msgid="7376953167039865701">"U redu"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Spojen kao medijski uređaj"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Spojen kao fotoaparat"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Povezan kao MIDI uređaj"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Spojen kao instalacijski program"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Spojen na USB pribor"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dodirnite za ostale opcije USB uređaja"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format. USB pohranu?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatirati SD karticu?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Sve datoteke pohranjene na vašoj USB pohrani bit će izbrisane. Ta se radnja ne može poništiti!"</string>
@@ -1476,33 +1482,34 @@
<item quantity="few">%1$d minute (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d minuta (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d sat (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d sata (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d sati (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d minutu</item>
<item quantity="few">%d minute</item>
<item quantity="other">%d minuta</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d sat</item>
<item quantity="few">%d sata</item>
<item quantity="other">%d sati</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dok ne isključite"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Prekid rada"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noć radnog dana"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Vikend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Događaj"</string>
<string name="muted_by" msgid="6147073845094180001">"Zvuk je isklj. treća strana <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Na vašem uređaju postoji interni problem i možda neće biti stabilan dok ga ne vratite na tvorničko stanje."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Na vašem uređaju postoji interni problem. Obratite se proizvođaču za više pojedinosti."</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index f8d384b..93a747a 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Személyes alkalmazások"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Munkahelyi"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Névjegyek"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"névjegyek elérése és módosítása"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"hozzáférés a névjegyekhez"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Helyadatok"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"hozzáférés a helyadatokhoz"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Az Ön közösségi adatai"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Közvetlen hozzáférés a névjegyekre és közösségi kapcsolatokra vonatkozó információkhoz"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Naptár"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"naptár elérése és módosítása"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"hozzáférés a naptárhoz"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS-ek elérése és módosítása"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS-üzenetek megtekintése és kezelése"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Felhasználói szótár"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Szavak olvasása vagy írása a felhasználói szótárban."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Könyvjelzők és előzmények"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Közvetlen hozzáférés a könyvjelzőkhöz és a böngészési előzményekhez"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"az eszköz mikrofonjának használata"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"hanganyag rögzítése"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fényképezőgép"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"eszközkamera használata"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotók és videók készítése"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"eszköztelefon használata"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonhívások kezdeményezése és kezelése"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Érzékelők"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"hozzáférés az érzékelőkhöz és hordható eszközökhöz"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"hozzáférés az érzékelők és hordható eszközök adataihoz"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Ablaktartalom lekérdezése"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"A használt ablak tartalmának vizsgálata."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Felfedezés érintéssel bekapcsolása"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Lehetővé teszi az alkalmazás számára a táblagépen módosítható események hozzáadását, törlését vagy módosítását, beleértve az ismerősök vagy munkatársak eseményeit is. Az engedéllyel rendelkező alkalmazás üzeneteket küldhet, amelyek úgy tűnhetnek, hogy a naptár tulajdonosától származnak, illetve módosíthatják az eseményeket a tulajdonosok tudta nélkül."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Lehetővé teszi az alkalmazás számára a tévén módosítható események hozzáadását, törlését vagy módosítását, beleértve az ismerősök vagy munkatársak eseményeit is. Ez lehetővé teheti az alkalmazás számára, hogy olyan üzeneteket küldjön, amelyekről úgy tűnik, hogy a naptár tulajdonosától származnak, illetve hogy a tulajdonosok tudta nélkül módosítsa az eseményeket."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Lehetővé teszi az alkalmazás számára a telefonon módosítható események hozzáadását, törlését vagy módosítását, beleértve az ismerősök vagy munkatársak eseményeit is. Az engedéllyel rendelkező alkalmazás üzeneteket küldhet, amelyek úgy tűnhetnek, hogy a naptár tulajdonosától származnak, illetve módosíthatják az eseményeket a tulajdonosok tudta nélkül."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"helyforrások utánzása tesztelés céljából"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Helyforrásutánzatok létrehozása tesztelés céljából, vagy új helyszolgáltató telepítése. Ez lehetővé teszi az alkalmazás számára, hogy felülírja az olyan helyforrások által biztosított hely- és/vagy állapotadatokat, mint a GPS vagy helyszolgáltatók."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"további helyszolgáltatói parancsok elérése"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Lehetővé teszi az alkalmazás számára további helyszolgáltatói parancsok elérését. Ezáltal az alkalmazás beavatkozhat a GPS vagy más helyforrások működésébe."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"pontos (GPS- és hálózatalapú) tartózkodási hely"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Ujjlenyomattal kapcsolatos művelet megszakítva"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Túl sok próbálkozás. Próbálja újra később."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Próbálkozzon újra."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"szinkronizálási beállítások olvasása"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ha bekapcsolja az USB-háttértárat, egyes jelenleg használt alkalmazások leállnak, és lehet, hogy nem lesznek elérhetők az USB-háttértár újbóli kikapcsolásáig."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Az USB-művelet sikertelen"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Csatlakoztatva médiaeszközként"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Csatlakoztatva kameraként"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Csatlakoztatva MIDI-eszközként"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Csatlakoztatva telepítőként"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Csatlakoztatva egy USB-kiegészítőhöz"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Érintse meg a további USB-opciókért."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB-tár formázása?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD-kártya formázása?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Az USB-háttértáron tárolt összes fájl törlésre kerül. Ez a művelet nem visszavonható!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d percen át (eddig: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Egy percen át (eddig: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d órán át (eddig: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Egy órán át (eddig: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d percen át</item>
<item quantity="one">Egy percen át</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d órán át</item>
<item quantity="one">Egy órán át</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Amíg ki nem kapcsolja ezt"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Összecsukás"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne zavarjanak"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Inaktivitás"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Hétköznap éjszaka"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Hétvége"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Esemény"</string>
<string name="muted_by" msgid="6147073845094180001">"A(z) <xliff:g id="THIRD_PARTY">%1$s</xliff:g> elnémította"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Belső probléma van az eszközzel, és instabil lehet, amíg vissza nem állítja a gyári adatokat."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Belső probléma van az eszközzel. A részletekért vegye fel a kapcsolatot a gyártóval."</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 0830950..d981de0 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Անձնական ծրագրեր"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Աշխատանքային"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Կոնտակտներ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"օգտագործել և փոփոխել ձեր կոնտակտները"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"կոնտակտների հասանելիություն"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Տեղադրություն"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"օգտագործել ձեր տեղադրությունը"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ձեր սոցիալական տեղեկությունները"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ուղղակի մուտք ձեր կոնտակտների մասին տեղեկություններ և սոցիալական կապեր:"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Օրացույց"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"օգտագործել և փոփոխել ձեր օրացույցը"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"օրացույցի հասանելիություն"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Կարճ հաղորդագրություն"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"տեսնել և փոփոխել կարճ հաղորդագրությունները"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS հաղորդագրությունների ընթերցում և կառավարում"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Օգտվողի բառարան"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Կարդալ կամ ավելացնել բառեր օգտվողի բառարանում:"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Էջանիշեր և պատմություն"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ուղղակի մուտք դեպի էջանիշեր և դիտարկիչի պատմություն:"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Բարձրախոս"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"օգտագործել սարքի խոսափողը"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ձայնագրում"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Ֆոտոխցիկ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"օգտագործել սարքի խցիկը"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"լուսանկարում և տեսագրում"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Հեռախոս"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"օգտագործել սարքի հեռախոսակապը"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"հեռախոսազանգերի կատարում և կառավարում"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Սենսորներ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"օգտագործել սենսորներն ու կրելի սարքերը"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"սենսորային և կրելի սարքերի տվյալների օգտագործում"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Առբերել պատուհանի բովանդակությունը"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Ստուգեք պատուհանի բովանդակությունը, որի հետ փոխգործակցում եք:"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Միացնել Հպման միջոցով հետազոտումը"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել իրադարձություններ, որոնք դուք կարող եք փոփոխել ձեր գրասալիկում, այդ թվում ընկերների կամ աշխատակիցների իրադարձությունները: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք երևում են որպես օրացույցի սեփականատերերից ուղարկված, կամ փոփոխել իրադարձություններն առանց սեփականատերերի իմացության:"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոփոխել իրադարձությունները, որոնք կարող եք փոփոխել ձեր հեռուստացույցի մեջ, այդ թվում` ընկերների կամ աշխատակիցների հետ կապված իրադարձությունները: Սա կարող է թույլատրել հավելվածին ուղարկել հաղորդագրություններ, որոնք հայտնվում են օրացույցի սեփականատերերից կամ փոփոխել իրադարձություններն` առանց սեփականատերերի իմացության:"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Թույլ է տալիս հավելվածին ավելացնել, հեռացնել, փոխել այն իրադարձությունները, որոնք կարող եք փոփոխել ձեր հեռախոսից, այդ թվում` ընկերների կամ գործընկերների: Սա կարող է թույլ տալ հավելվածին ուղարկել հաղորդագրություններ, որոնք իբրև գալիս են օրացույցի սեփականատիրոջից, կամ փոփոխել իրադարձությունները` առանց սեփականատիրոջ իմացության:"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"կեղծ տեղանքի աղբյուրներ փորձարկման համար"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Ստեղծել կեղծ տեղանքի աղբյուրներ` փորձարկման կամ տեղադրության նոր ծառայություն մատուցողի տեղադրման համար: Սա հնարավորություն է տալիս, որ ծրագիրը անտեսի տեղադրությունը և/կամ կարգավիճակը` տրամադրված տեղանքի այլ աղբյուրների կողմից, ինչպիսիք են GPS-ը կամ տեղադրության ծառայություն մատուցողները:"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"օգտագործել տեղադրություն տրամադրող հավելվյալ հրամաններ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ծրագրին թույլ է տալիս օգտագործել տեղադրության մասին տվյալների աղբյուրների կառավարման լրացուցիչ հրահանգներ: Սա կարող է ծրագրին թույլ տալ միջամտել GPS-ի կամ տեղադրության մասին տվյալների այլ աղբյուրների գործառույթներին:"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ճշգրիտ վայրը (ըստ GPS-ի և ցանցի)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Իսկորոշումը մատնահետքի միջոցով չեղարկվեց:"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Չափից շատ փորձ եք կատարել: Փորձեք նորից քիչ հետո:"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Փորձեք նորից:"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"կարդալ համաժամեցման կարգավորումները"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Եթե դուք միացնեք USB կրիչը, որոշ ծրագրեր,որոնցից օգտվում եք, կդադարեն աշխատել և կարող են անհասանելի լինել, քանի դեռ չեք անջատել USB կրիչը:"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB գործողությունը անհաջող էր"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Լավ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Կապակցված է որպես մեդիա սարք"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Միացված է որպես ֆոտոխցիկ"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Կապակցված է որպես MIDI սարք"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Միացված է որպես տեղադրիչ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Կապակցված է USB լրասարքի"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Հպեք` այլ USB ընտրանքների համար:"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Ֆորմատավորե՞լ USB կրիչը:"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Ֆորմատավորե՞լ SD քարտը:"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Ձեր USB կրիչում պահվող բոլոր ֆայլերը կջնջվեն: Այս գործողությունը անշրջելի է:"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">%1$d րոպե (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d րոպե (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d ժամ (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d ժամ (մինչև <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d րոպե</item>
<item quantity="other">%d րոպե</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d ժամ</item>
<item quantity="other">%d ժամ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Մինչև <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Քանի դեռ չեք անջատել"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Թաքցնել"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Չանհանգստացնել"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Անգործունության ժամանակը"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Աշխատանքային օր"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Շաբաթ-կիրակի"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Իրադարձություն"</string>
<string name="muted_by" msgid="6147073845094180001">"Համրեցվել է <xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ի կողմից"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Սարքում ներքին խնդիր է առաջացել և այն կարող է կրկնվել, մինչև չվերականգնեք գործարանային կարգավորումները:"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Սարքում ներքին խնդիր է առաջացել: Մանրամասների համար կապվեք արտադրողի հետ:"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 69ce711..7689baf 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplikasi pribadi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Kantor"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontak"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"mengakses dan mengubah kontak"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"mengakses kontak"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"mengakses lokasi Anda"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informasi sosial Anda"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke informasi tentang kontak dan hubungan sosial Anda."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"mengakses dan memodifikasi kalender"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"mengakses kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"mengakses dan memodifikasi SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"melihat dan mengelola pesan SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamus Pengguna"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Membaca atau menulis kata dalam kamus pengguna."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bookmark dan Riwayat"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke bookmark dan riwayat browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"menggunakan mikrofon perangkat"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekam audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"menggunakan kamera perangkat"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"mengambil gambar dan merekam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"menggunakan sistem telefoni perangkat"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"melakukan dan mengelola panggilan telepon"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"mengakses sensor dan perangkat yang dapat dikenakan"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"mengakses data dari sensor dan yang dapat dikenakan"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Mengambil konten jendela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Memeriksa konten jendela tempat Anda berinteraksi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Mengaktifkan Jelajahi dengan Sentuhan"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Memungkinkan aplikasi menambahkan, menghapus, mengubah acara yang dapat Anda ubah pada tablet, termasuk acara teman atau rekan kerja. Izin ini memungkinkan aplikasi mengirim pesan yang kelihatannya berasal dari pemilik kalender, atau mengubah acara tanpa sepengetahuan pemilik."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Mengizinkan aplikasi untuk menambah, menghapus, mengubah acara yang dapat Anda modifikasi di TV, termasuk milik teman atau rekan kerja. Izin ini memungkinkan aplikasi untuk mengirim pesan yang terlihat berasal dari pemilik kalender, atau memodifikasi acara tanpa sepengetahuan pemilik."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Memungkinkan aplikasi menambahkan, menghapus, mengubah acara yang dapat Anda ubah pada ponsel, termasuk acara teman atau rekan kerja. Izin ini memungkinkan aplikasi mengirim pesan yang kelihatannya berasal dari pemilik kalender, atau mengubah acara tanpa sepengetahuan pemilik."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"sumber lokasi palsu untuk menguji"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Membuat sumber lokasi palsu untuk uji coba atau memasang penyedia lokasi baru. Izin ini memungkinkan aplikasi mengganti lokasi dan/atau status yang dimunculkan sumber lokasi lain, misalnya GPS atau penyedia lokasi."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"akses perintah penyedia lokasi ekstra"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Memungkinkan aplikasi mengakses perintah penyedia lokasi ekstra. Tindakan ini memungkinkan aplikasi mengganggu pengoperasian GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"lokasi akurat (berbasis jaringan dan GPS)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operasi sidik jari dibatalkan."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Terlalu banyak upaya. Coba lagi nanti."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Coba lagi."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"baca setelan sinkron"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jika Anda menyalakan penyimpanan USB, beberapa apl yang Anda gunakan akan berhenti dan mungkin tidak dapat dibuka hingga penyimpanan USB dimatikan."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB gagal"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Oke"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tersambung sebagai perangkat media"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tersambung sebagai kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Terhubung sebagai perangkat MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tersambung sebagai pemasang"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tersambung ke aksesori USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Sentuh untuk opsi USB lainnya."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format penyimpanan USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format kartu SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Semua file yang tersimpan dalam penyimpanan USB Anda akan dihapus. Tindakan ini tidak dapat diurungkan!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Selama %1$d menit (hingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Selama satu menit (hingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Selama %1$d jam (hingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Selama satu jam (hingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Selama %d menit</item>
<item quantity="one">Selama satu menit</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Selama %d jam</item>
<item quantity="one">Selama satu jam</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hingga Anda menonaktifkan ini"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Jangan ganggu"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Waktu non-operasional"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Malam hari kerja"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Akhir pekan"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Acara"</string>
<string name="muted_by" msgid="6147073845094180001">"Dinonaktifkan oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Ada masalah dengan perangkat. Hal ini mungkin membuat perangkat jadi tidak stabil dan perlu dikembalikan ke setelan pabrik."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Ada masalah dengan perangkat. Hubungi produsen perangkat untuk informasi selengkapnya."</string>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 18fd5da..3bdad48 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Persónuleg forrit"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Vinna"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Tengiliðir"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"opna og breyta tengiliðum"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"fá aðgang að tengiliðunum þínum"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Staðsetning"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"fá aðgang að staðsetningu þinni"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Samfélagsupplýsingarnar þínar"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Beinn aðgangur að upplýsingum um tengiliði og samfélagstengingar."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Dagatal"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"opna og breyta dagatalinu þínu"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"fá aðgang að dagatalinu þínu"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"opna og breyta SMS-skilaboðum"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"skoða og stjórna SMS-skilaboðum"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Orðabók notanda"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lesa eða skrifa orð í orðabók notanda."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bókamerki og ferill"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Beinn aðgangur að bókamerkjum og vafraferli."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Hljóðnemi"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"nota hljóðnema tækisins"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"taka upp hljóð"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Myndavél"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"nota myndavél tækisins"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"taka myndir og taka upp myndskeið"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Sími"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"nota símtæki tækisins"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"hringja og stjórna símtölum"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Skynjarar"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"fá aðgang að skynjurum og búnaði til að bera á sér"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"fá aðgang að gögnum frá skynjurum og tækjum sem notandi ber á sér"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Sækja innihald glugga"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kanna innihald glugga sem þú ert að nota."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Kveikja á snertikönnun"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Leyfir forriti að bæta við, fjarlægja og breyta viðburðum sem hægt er að vinna með í spjaldtölvunni, þ. á m. viðburðum sem vinir eða samstarfsmenn eiga. Þetta getur gert forritinu kleift að senda skilaboð sem virðast koma frá eigendum viðburðarins eða breyta viðburðum án vitundar eigenda þeirra."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Leyfir forriti að bæta við, fjarlægja og breyta viðburðum sem hægt er að breyta í sjónvarpinu, þ. á m. viðburðum sem vinir eða samstarfsmenn eiga. Þetta getur gert forritinu kleift að senda skilaboð sem virðast koma frá eigendum viðburðarins eða breyta viðburðum án vitundar eigenda þeirra."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Leyfir forriti að bæta við, fjarlægja og breyta viðburðum sem hægt er að breyta í símanum, þ. á m. viðburðum sem vinir eða samstarfsmenn eiga. Þetta getur gert forritinu kleift að senda skilaboð sem virðast koma frá eigendum viðburðarins eða breyta viðburðum án vitundar eigenda þeirra."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"gervistaðsetningarbúnaður fyrir prófun"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Búa til gervistaðsetningarbúnað til prófunar eða uppsetningar á nýrri staðsetningarveitu. Þetta gerir forritinu kleift að hnekkja staðsetningu og/eða stöðu frá öðrum staðsetningarbúnaði á borð við GPS eða staðsetningarveitur."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"aðgangur að viðbótarskipunum staðsetningarveitu"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Leyfir forriti að fá aðgang að fleiri skipunum staðsetningarveitu. Þetta getur gert forritinu kleift að hafa áhrif á virkni GPS og annars staðsetningarbúnaðar."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"nákvæm staðsetning (frá GPS og símakerfi)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Hætt við fingrafarsaðgerð."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Of margar tilraunir. Reyndu aftur síðar."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Reyndu aftur."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lesa samstillingar"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ef þú kveikir á USB-geymslu stöðvast sum forrit sem eru í notkun og þau kunna að vera óaðgengileg þar til slökkt er á USB-geymslunni."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-aðgerð mistókst"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Í lagi"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tengt sem geymslumiðill"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tengt sem myndavél"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Tengt sem MIDI-tæki"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tengt sem uppsetningarforrit"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Tengt við USB-aukabúnað"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Snertu til að sjá aðra USB-valkosti."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Sníða USB-geymslu?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Sníða SD-kort?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Öllum skrám í USB-geymslunni verður eytt. Ekki er hægt að afturkalla þessa aðgerð!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Í %1$d mínútu (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Í %1$d mínútur (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Í %1$d klukkustund (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Í %1$d klukkustundir (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Í %d mínútu</item>
<item quantity="other">Í %d mínútur</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Í %d klukkustund</item>
<item quantity="other">Í %d klukkustundir</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Þar til þú slekkur á þessu"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Minnka"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ónáðið ekki"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Hvíldartími"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Virkt kvöld"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Helgi"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Viðburður"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> tók hljóðið af"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Innra vandamál kom upp í tækinu og það kann að vera óstöðugt þangað til þú núllstillir það."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Innra vandamál kom upp í tækinu. Hafðu samband við framleiðanda til að fá nánari upplýsingar."</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 3def7ae..6d65d00 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"App personali"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Lavoro"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatti"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"accesso e modifica ai contatti"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accesso ai contatti"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Posizione"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"accesso alla posizione"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Le tue informazioni social"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Accesso diretto alle informazioni sui tuoi contatti e sulle tue connessioni social."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendario"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"accesso e modifica al calendario"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesso al calendario"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"accesso e modifica agli SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"lettura e gestione di messaggi SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dizionario utente"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lettura o scrittura delle parole contenute nel dizionario utente."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Segnalibri e cronologia"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Accesso diretto ai segnalibri e alla cronologia del browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfono"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"utilizzo del microfono del dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"registrazione audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotocamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utilizzo della fotocamera del dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"acquisizione di foto e registrazione di video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefono"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"utilizzo del servizio di telefonia del dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"esecuzione e gestione delle telefonate"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"accesso ai sensori e ai dispositivi indossabili"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accesso ai dati da sensori e dispositivi indossabili"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperare contenuti finestra"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Esaminare i contenuti di una finestra con cui interagisci."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Attivare Esplora al tocco"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul tablet, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Consente all\'app di aggiungere, rimuovere o modificare eventi che è possibile modificare sulla TV, inclusi quelli di amici o colleghi. L\'app potrebbe inviare messaggi apparentemente provenienti dai proprietari del calendario o modificare eventi all\'insaputa dei proprietari."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Consente all\'applicazione di aggiungere, rimuovere, modificare gli eventi che puoi modificare sul telefono, inclusi quelli di amici o colleghi. Ciò potrebbe consentire all\'applicazione di inviare messaggi apparentemente provenienti dai proprietari del calendario o di modificare eventi all\'insaputa dei proprietari."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fonti di geolocalizzazione fittizie per test"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Crea fonti di geolocalizzazione fittizie per i test o installa un nuovo fornitore di posizione. Ciò consente all\'applicazione di ignorare la posizione e/o lo stato restituito da altre fonti di geolocalizzazione, come il GPS o fornitori di posizione."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesso a comandi aggiuntivi del provider di localizz."</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di localizzazione."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"posizione precisa (GPS e basata sulla rete)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operazione associata all\'impronta digitale annullata."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Troppi tentativi. Riprova più tardi."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Riprova."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lettura impostazioni di sincronizz."</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se attivi l\'archivio USB, alcune applicazioni che stai usando si interromperanno e potrebbero non essere disponibili fino a quando non disattiverai l\'archivio USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operazione USB non riuscita"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Collegato come dispositivo multimediale"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Collegato come fotocamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Connesso come un dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Collegato come installer"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Collegato a un accessorio USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Tocca per altre opzioni USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formattare archivio USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formattare la scheda SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tutti i file memorizzati nell\'archivio USB verranno cancellati. Questa azione non può essere annullata."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Per %1$d minuti (fino alle ore <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Per un minuto (fino alle ore <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Per %1$d ore (fino alla ore <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Per un\'ora (fino alle ore <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Per %d minuti</item>
<item quantity="one">Per un minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Per %d ore</item>
<item quantity="one">Per un\'ora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Fino alla disattivazione"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Comprimi"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Non disturbare"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tempo di inattività"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Notte di un giorno feriale"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fine settimana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Audio disattivato da <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Si è verificato un problema interno con il dispositivo, che potrebbe essere instabile fino al ripristino dei dati di fabbrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Si è verificato un problema interno con il dispositivo. Per informazioni dettagliate, contatta il produttore."</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index de0f975..6fb63d1 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"אפליקציות אישיות"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"עבודה"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"אנשי קשר"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"גישה אל אנשי הקשר ושינוי שלהם"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"גישה אל אנשי הקשר"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"מיקום"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"גישה אל המיקום שלך"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"מידע על הקשרים החברתיים שלך"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"גישה ישירה למידע על אנשי קשר וקשרים חברתיים שלך."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"יומן"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"גישה אל היומן וביצוע שינויים בו"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"גישה אל היומן"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"גישה אל הודעות SMS ושינוי שלהן"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"הצגה וניהול של הודעות SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"מילון משתמש"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"קריאה או כתיבה של מילים במילון המשתמש."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"סימניות והיסטוריה"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"גישה ישירה אל סימניות והיסטוריית דפדפן."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"מיקרופון"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"שימוש במיקרופון המכשיר"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"הקלטת אודיו"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"מצלמה"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"שימוש במצלמת המכשיר"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"צילום תמונות והקלטת וידאו"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"טלפון"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"שימוש ביכולות הטלפוניה של המכשיר"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"התקשרות וניהול של שיחות טלפון"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"חיישנים"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"גישה אל חיישנים וגאדג\'טים לבישים"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"גישה לנתונים מחיישנים וממכשירים לבישים"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"אחזר תוכן של חלון"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"בדוק את התוכן של חלון שאיתו אתה מבצע אינטראקציה."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"הפעל את \'גילוי באמצעות מגע\'"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטאבלט, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי יומן או לשנות אירועים ללא ידיעת הבעלים."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"מאפשרת לאפליקציה להוסיף, להסיר ולשנות אירועים הניתנים לשינוי בטלוויזיה, כולל אלו של חברים ועמיתים. הרשאה זו עלולה לאפשר לאפליקציה לשלוח הודעות שנראות כאילו הגיעו מבעלי היומן, או לשנות אירועים ללא ידיעת הבעלים."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"מאפשר לאפליקציה להוסיף, להסיר ולשנות אירועים שאתה יכול לשנות בטלפון, כולל אלה של חברים או עמיתים לעבודה. הדבר עשוי להתיר לאפליקציה לשלוח הודעות הנראות כאילו שנשלחו מבעלי יומן או לשנות אירועים ללא ידיעת הבעלים."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"צור מקורות מיקום מדומים לצורך בדיקה"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"צור מקורות מיקום מדומים לבדיקה, או התקן ספק מיקום חדש. פעולה זו מאפשרת לאפליקציה לעקוף את המיקום ו/או הסטטוס המוחזרים על ידי מקורות מיקום אחרים כמו GPS או ספקי מיקום."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"גישה לפקודות ספק מיקום נוספות"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"מאפשרת לאפליקציה לגשת לפקודות נוספות של ספק המיקום. הרשאה זו עשויה לאפשר לאפליקציה לשבש את פעולת ה-GPS או מקורות מיקום אחרים."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"מיקום מדויק (מבוסס GPS ורשת)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"פעולת טביעת האצבע בוטלה."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"יותר מדי ניסיונות. נסה שוב מאוחר יותר."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"נסה שוב."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"קרא את הגדרות הסינכרון"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"אם תפעיל אחסון USB, אפליקציות מסוימות שבהן אתה משתמש יפסיקו לפעול, וייתכן שהן לא יהיו זמינות עד שתכבה את אחסון ה-USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"פעולת USB נכשלה"</string>
<string name="dlg_ok" msgid="7376953167039865701">"אישור"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"מחובר כמכשיר מדיה"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"מחובר כמצלמה"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"מחובר כהתקן MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"מחובר כמתקין"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"מחובר לאביזר USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"גע לקבלת אפשרויות USB נוספות."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"לפרמט את אמצעי האחסון מסוג USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"לפרמט את כרטיס ה-SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"כל הקבצים ששמורים באמצעי האחסון מסוג USB שלך יימחקו. פעולה זו היא בלתי הפיכה!"</string>
@@ -1486,24 +1492,28 @@
<item quantity="other">למשך %1$d דקות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">למשך דקה אחת (עד <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="two">למשך %d שעות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">למשך %d שעות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">למשך %d שעות (עד <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">למשך שעה אחת (עד <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="two">למשך %d דקות</item>
<item quantity="many">למשך %d דקות</item>
<item quantity="other">למשך %d דקות</item>
<item quantity="one">למשך דקה אחת</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="two">למשך %d שעות</item>
<item quantity="many">למשך %d שעות</item>
<item quantity="other">למשך %d שעות</item>
<item quantity="one">למשך שעה אחת</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"עד שתכבה"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f952fb6..39b663f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"プライベートアプリ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"職場"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"連絡先"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"連絡先へのアクセスと変更を行います"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"連絡先へのアクセス"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置情報"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"位置情報にアクセスします"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ソーシャル情報"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"連絡先とソーシャルコネクションに関する情報に直接アクセスします。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"カレンダー"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"カレンダーへのアクセスと変更を行います"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"カレンダーへのアクセス"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMSへのアクセスと変更を行います"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMSメッセージの表示と管理"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"単語リスト"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"単語リストの語句の読み取りまたは書き込みを行います"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ブックマークと履歴"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ブックマークとブラウザの履歴に直接アクセスします。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"マイク"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"端末のマイクを使用します"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"音声の録音"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"カメラ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"端末のカメラを使用します"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"写真の撮影と動画の記録"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"端末の電話機能を使用します"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"通話の発信と管理"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"センサー"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"センサーとウェアラブルにアクセスします"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"センサーやウェアラブル端末のデータへのアクセス"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ウィンドウコンテンツの取得"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ユーザーがアクセスしているウィンドウのコンテンツを検査します。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"タッチガイドの有効化"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ユーザーがタブレットから編集できる予定(友だちや同僚の予定も含む)を追加、削除、変更することをアプリに許可します。これによりアプリは、カレンダーの所有者から発信されたかのようなメッセージを送信したり、所有者の知らないうちに予定を変更したりできるようになる可能性があります。"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ユーザーがテレビから編集できる予定(友だちや同僚の予定も含む)を追加、削除、変更することをアプリに許可します。これによりアプリは、カレンダーの所有者から発信されたかのようなメッセージを送信したり、所有者の知らないうちに予定を変更したりできるようになる可能性があります。"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ユーザーが携帯端末から編集できる予定(友だちや同僚の予定も含む)を追加、削除、変更することをアプリに許可します。これによりアプリは、カレンダーの所有者から発信されたかのようなメッセージを送信したり、所有者の知らないうちに予定を変更したりできるようになる可能性があります。"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"仮の位置情報でテスト"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"テスト用に仮の位置情報源を作成するか、新しい位置情報提供元をインストールします。これにより、他の位置情報源(GPS、位置情報提供元など)から返された位置情報やステータスのオーバーライドをアプリに許可することになります。"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"位置情報提供者の追加コマンドアクセス"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"位置情報提供元の追加のコマンドにアクセスすることをアプリに許可します。許可すると、アプリがGPSなどの位置情報源の動作を妨害する恐れがあります。"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"正確な位置情報(GPSとネットワーク基地局)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋の操作をキャンセルしました。"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"所定の回数以上間違えました。しばらくしてからもう一度お試しください。"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"もう一度お試しください。"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"同期設定の読み取り"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USBストレージをONにすると、使用中のアプリの一部が停止し、USBストレージをOFFにするまで使用できなくなる場合があります。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB操作に失敗しました"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"メディアデバイスとして接続"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"カメラとして接続"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDIデバイスとして接続"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"インストーラとして接続"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBアクセサリを接続しました"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"USB接続方法を変更するにはタップしてください。"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USBストレージをフォーマットしますか?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SDカードをフォーマットしますか?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USBストレージに保存されているファイルはすべて消去されます。この操作は元に戻せません。"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d分間(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>まで)</item>
<item quantity="one">1分間(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>まで)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d時間(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>まで)</item>
<item quantity="one">1時間(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>まで)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d分</item>
<item quantity="one">1分</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d時間</item>
<item quantity="one">1時間</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ユーザーがOFFにするまで"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"通知を非表示"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ダウンタイム"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"平日の夜"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"予定"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>によりミュートになっています"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"端末で内部的な問題が発生しました。データが初期化されるまで不安定になる可能性があります。"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"端末で内部的な問題が発生しました。詳しくはメーカーにお問い合わせください。"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index b88ff5b..ed7ce45 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"პერსონალური აპები"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"სამსახური"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"კონტაქტები"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"თქვენს კონტაქტებზე წვდომა და შეცვლა"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"თქვენს კონტაქტებზე წვდომა"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"მდებარეობა"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"თქვენს მდებარეობაზე წვდომა"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"თქვენი სოციალური ინფორმაცია"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"თქვენს კონტაქტებისა და სოციალურ კავშირების შესახებ ინფორმაციაზე პირდაპირი წვდომა."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"კალენდარი"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"თქვენს კალენდარზე წვდომა და შეცვლა"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"თქვენს კალენდარზე წვდომა"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS-ებზე წვდომა და შეცვლა"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS შეტყობინებების ნახვა და მართვა"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"მომხმარებლის ლექსიკონი"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"მომხმარებლის ლექსიკონში სიტყვების წაკითხვა ან ჩაწერა."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"სანიშნეები და ისტორია"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"პირდაპირი წვდომა სანიშნეებსა და ბრაუზერის ისტორიაზე"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"მიკროფონი"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"მოწყობილობის მიკროფონის გამოყენება"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"აუდიოს ჩწერა"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"კამერა"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"მოწყობილობის კამერის გამოყენება"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ფოტოებისა და ვიდეოების გადაღება"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ტელეფონი"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"მოწყობილობის ტელეფონიის გამოყენება"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"სატელეფონო ზარების განხორციელება და მართვა"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"სენსორები"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"სენსორებსა და ტარებად მოწყობილობებზე წვდომა"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"სენსორებიდან და ტარებადი მოწყობილობებიდან მონაცემებზე წვდომა"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ფანჯრის კონტენტის მოძიება"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"შეამოწმეთ იმ ფანჯრის კონტექტი, რომელშიც მუშაობთ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"„შეხებით აღმოჩენის“ ჩართვა"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტაბლეტზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ნებას რთავს აპლიკაციას დაუმატოს, წაშალოს, შეცვალოს ის მოვლენები, რომლებიც თქვენ ტელევიზორში დააყნეთ, მეგობრებისა თუ თანამშრომლების ჩათვლით. შესაძლოა ნება დართოს აპლიკაციას, გააგზავნოს შეტყობინებები, რომელბიც კალენდარის მფლობელისგან გამომდინარეობს ან მფლობელის გაფრთხილების გარეშე შეცვალოს მოვლენები."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"აპს შეეძლება იმ ღონისძიებების დამატება, წაშლა და შეცვლა, რომლებსაც თქვენს ტელეფონზე ქმნით, ასევე თქვენი მეგობრების და თანამშრომლების ღონისძიებებიც. ამგვარად, აპს ექნება შესაძლებლობა ისე დააგზავნოს შეტყობინებები კალენდრის მფლობელის სახელით ან შეცვალოს ღონისძიებები, რომ მფლობელმა ამის შესახებ არაფერი იცოდეს."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"მდებარეობის წყაროების იმიტირება ტესტირებისთვის"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"აპს შეეძლება ტესტირებისთვის ყალბი ლოკაციების შექმნა, ან მდებარეობის ახალი პროვაიდერის დაყენება. ეს უფლებას მისცემს აპს, შეცვალოს მდებარეობის სხვა წყაროების მიერ, მაგ. GPS ან მდებარეობის პროვაიდერების მიერ მოწოდებული მდებარეობა და/ ან სტატუსი."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"მდებარეობის პროვაიდერის დამატებით ბრძანებებზე წვდომა"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"აპს შეეძლება წვდომა ჰქონდეს მდებარეობის სერვისის დამატებით ბრძანებებზე. შესაძლოა აპმა ეს გამოიყენოს GPS-ისა და მდებარეობის სხვა წყაროების მუშაობის პროცესში ჩარევისთვის."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ზუსტი მდებარეობა (GPS და ქსელის კოორდინატების მიხედვით)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"თითის ანაბეჭდის აღების ოპერაცია გაუქმდა."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ძალიან ბევრი მცდელობა იყო. სცადეთ მოგვიანებით."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ხელახლა სცადეთ"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"სინქრონიზაციის პარამეტრების წაკითხვა"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"თუ USB მეხსიერებას ჩართავთ, თქვენ მიერ მოხმარებადი რამდენიმე აპი შეწყვეტს მუშაობას და შესაძლოა მიუწვდომელი გახდეს USB მეხსიერების გამორთვამდე."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ოპერაცია წარუმატებელი იყო"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"დაკავშირებულია როგორც მედია მოწყობილობა"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"დაკავშირებულია როგორც კამერა"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"დაკავშირებული როგორც MIDI მოწყობილობა"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"დაკავშირებულია როგორც დამყენებელი"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"დაკავშირებულია USB აქსესუართან"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"შეეხეთ USB-ის სხვა პარამეტრების სანახავად."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"დავაფორმატო USB მეხსიერება?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"გსურთ SD ბარათის დაფორმატება?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"თქვენ USB მეხსიერებაში შენახული ყველა ფაილი წაიშლება. ეს მოქმედება ვეღარ შეიცვლება!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>-მდე)</item>
<item quantity="one">ერთი წუთის განმავლობაში (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>-მდე)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d საათის განმავლობაში (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>-მდე)</item>
<item quantity="one">ერთი საათის განმავლობაში (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>-მდე)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d წუთის განმავლობაში</item>
<item quantity="one">ერთი წუთის განმავლობაში</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d საათის განმავლობაში</item>
<item quantity="one">ერთი საათის განმავლობაში</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"სანამ ამას გამორთავდეთ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"აკეცვა"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"არ შემაწუხოთ"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ავარიული პაუზა"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"სამუშაო კვირის ღამე"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"შაბათ-კვირა"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"მოვლენა"</string>
<string name="muted_by" msgid="6147073845094180001">"დადუმებულია <xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ის მიერ"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ფიქსირდება თქვენი მ ოწყობილობის შიდა პრობლემა და შეიძლება არასტაბილური იყოს, სანამ ქარხნულ მონაცემების არ განაახლებთ."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ფიქსირდება თქვენი მოწყობილობის შიდა პრობლემა. დეტალებისათვის, მიმართეთ თქვენს მწარმოებელს."</string>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 34a44c2..ff87d06 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Жеке қолданбалар"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Жұмыс"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактілер"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"Контактілеріңізге кіру және өзгерту"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"контактілерге кіру"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Орын"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"орныңызға кіру"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Сіздің әлеуметтік ақпаратыңыз"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Байланыстарыңыз бен әлеуметтік контактілеріңіз туралы ақпаратқа тікелей қол жетімділік."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнтізбе"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"Күнтізбеңізге кіру және өзгерту"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнтізбеге кіру"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS кіру және өзгерту"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS хабарларды қарау және басқару"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Пайдаланушы сөздігі"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Пайдаланушы сөздігінде сөздерді оқыңыз не жазыңыз."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Бетбелгілер және Тарих"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Бетбелгілер мен браузерге тікелей қол жетімділік."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"құрылғы микрофонын пайдалану"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио жазу"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"құрылғы камерасын пайдалану"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"суретке түсіріп, бейне жазу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"құрылғы телефониясын пайдалану"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"қоңырау шалу және телефон қоңырауларын басқару"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлар"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"сенсорлы және киілетін құрылғыларға кіру"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"датчиктер мен киілетін құрылғылардан деректерге кіру"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терез мазмұнына қол жеткізу"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Сіз қатынасып отырған терезе мазмұнын тексеру."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Шарлауды Түрту арқылы қосыңыз"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Қолданбаға планшеттегі сізге өзгертуге болатын шараларды, достарыңыз бен әріптестеріңіздің шараларын қоса, қосу, алу және өзгерту мүмкіндігін береді. Бұл қолданбаға күнтізбе иелерінен келген сияқты көрсетілетін хабарлар жіберу немесе иесінің хабарынсыз шараларды өзгерту мүмкіндігін береді."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Қолданбаға сіз теледидарда өзгерте алатын оқиғаларды, соның ішінде, достардың немесе әріптестердің оқиғаларын қосуға, жоюға, өзгертуге рұқсат етеді. Бұл қолданбаға күнтізбе иелерінен келген болып көрінетін хабарларды жіберуге немесе иесінің білуінсіз оқиғаларды өзгертуге мүмкіндік беруі мүмкін."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Қолданбаға телефондағы сізге өзгертуге болатын шараларды, достарыңыз бен әріптестеріңіздің шараларын қоса, қосу, алу және өзгерту мүмкіндігін береді. Бұл қолданбаға күнтізбе иелерінен келген сияқты көрсетілетін хабарлар жіберу немесе иесінің хабарынсыз шараларды өзгерту мүмкіндігін береді."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"тест үшін аймақ көздеріне еліктеу"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Тексеру үшін жасанды аймақ көздерін жасақтаңыз немесе жаңа аймақ жабдықтаушы орнатыңыз. Бұл қолданбаға аймақты және/немесе GPS немесе аймақ жабдықтаушы сияқты аймақ көздерінен оралған күйлерін үстінен жазу мүмкіндігін береді."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"қосымша аймақ жабдықтаушы пәрмендеріне қол жетімділік"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Қолданбаға орын жеткізушісінің қосымша пәрмендеріне қатынасуға рұқсат береді. Бұл қолданбаға GPS немесе басқа орын көздерінің жұмысына кедергі келтіруге рұқсат беруі мүмкін."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"нақты аймақ (GPS және желі негізделген)"</string>
@@ -397,7 +395,7 @@
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"Қолданбаға байланысқан желілік қосылымның күйін өзгертуге рұқсат береді."</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi байланыстарын көру"</string>
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"Қолданбаға Wi-Fi желісі туралы, мысалы, Wi-Fi байланысының қосылғаны немесе қосылған Wi-Fi құрылғыларының атаулары сияқты, ақпаратты көру мүмкіндігін береді."</string>
- <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi жалғану және ажырау"</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi желісіне қосылу/ажырау"</string>
<string name="permdesc_changeWifiState" msgid="7137950297386127533">"Қолданбаларға Wi-Fi нүктелеріне қосылу және ажырау және Wi-Fi желілеріне арналған құрылғы конфигурацияларына өзгерістер енгізу мүмкіндігін береді."</string>
<string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi бірнеше мекенжайға ақпарат тарату мүмкіндігі"</string>
<string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Қолданбаға Wi-Fi желісіндегі барлық құрылғыларға мекенжайлар тобы арқылы, сіздің планшетіңіз арқылы ғана емес, жіберілген жинақтарды алу мүмкіндігін береді. Бұл мекенжайлар тобы емес режимге қарағанда қуатты көбірек тұтынуы мүмкін."</string>
@@ -417,7 +415,7 @@
<string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Қолданбаға планшеттегі Bluetooth конфигурациясын көру және жұпталған құрылғымен байланыс орнату немесе қабылдау мүмкіндігін береді."</string>
<string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Қолданбаға теледидардағы Bluetooth конфигурациясын көруге және жұпталған құрылғылармен байланыстарды қабылдауға рұқсат етеді."</string>
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Қолданбаға телефондағы Bluetooth конфигурациясын көру және жұпталған құрылғымен байланыс орнату немесе қабылдау мүмкіндігін береді"</string>
- <string name="permlab_nfc" msgid="4423351274757876953">"Жақын Өріс Байланысын басқару"</string>
+ <string name="permlab_nfc" msgid="4423351274757876953">"NFC функциясын басқару"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"Қолданбаға NFC белгілерімен, карталармен және оқу құралдарымен байланысуға рұқсат береді."</string>
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"экран бекітпесін істен шығару"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Қолданбаларға кілтперне және басқа кілтсөзге қатысты қауіпсіздік шараларын өшіру мүмкіндігін береді. Мысалы, телефон кіріс қоңырауларын алғанда кілтпернені өшіреді және қоңырау аяқталғанда қайта қосады."</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Саусақ ізі операциясынан бас тартылған."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Талпыныстар тым көп. Кейінірек қайталап көріңіз."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Әрекетті қайталаңыз."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"синх параметрлерін оқу"</string>
@@ -446,7 +446,7 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Қолданбаға есептік жазбаның синхрондау параметрлерін жөндеу мүмкіндігін береді. Мысалы, бұл People қолданбасын есептік жазбамен синхрондауды қосу үшін қолданылуы мүмкін."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"үйлестіру санақтық ақпаратын оқу"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Қолданбаға есептік жазбаның синхрондалу статистикаларын, оның ішінде синхрондау шараларының тарихы және қанша дерек синхрондалғаны жайлы, оқу мүмкіндігін береді."</string>
- <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"жазылма материалдарын жазу"</string>
+ <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"жазылған ағындарды жазу"</string>
<string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Қолданбаға қазіргі уақытта синхрондалған арналарды өзгертуге рұқсат береді. Зиянкес қолданбалар синхрондалған арналарды өзгертуі мүмкін."</string>
<string name="permlab_readDictionary" msgid="4107101525746035718">"сөздікке сіз қосқан шарттарды оқу"</string>
<string name="permdesc_readDictionary" msgid="659614600338904243">"Қолданбаға пайдаланушы сөздігінде сақталған барлық сөздер, аттар және фразаларды оқу мүмкіндігін береді."</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Егер USB жадын қоссаңыз, қолданыстағы қолданбалар тоқтайды және USB жадын қайта қосқанша қол жетімсіз болады."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB жұмысы сәтсіз"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Жарайды"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Медиа құралы ретінде қосылған"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Камера ретінде жалғанған"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI құрылғысы ретінде қосылу орындалды"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Орнату құрылғысына жалғанған"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB жабдығына қосылған"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Басқа USB oпцияларын түрту."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB қой. піш. к. пе?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD картасын пішімдеу керек пе?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB қоймасында сақталған бүкіл файлдар өшіріледі. Бұл әрекетті қайтару мүмкін емес!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d минут бойы (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> дейін)</item>
<item quantity="one">Бір минут бойы (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> дейін)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d сағат бойы (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> дейін)</item>
<item quantity="one">Бір сағат бойы (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> дейін)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d минут бойы</item>
<item quantity="one">Бір минут бойы</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d сағат бойы</item>
<item quantity="one">Бір сағат бойы</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Сіз осыны өшіргенше"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Мазаламауыңызды сұраймын"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Бос тұру уақыты"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Апта түндері"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Апта соңы"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Оқиға"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> үнін өшірген"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"There\'s an internal problem with your device, and it may be unstable until you factory data reset."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"There\'s an internal problem with your device. Contact your manufacturer for details."</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index c0ea059..47413b7 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"កម្មវិធីផ្ទាល់ខ្លួន"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"កន្លែងធ្វើការ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ទំនាក់ទំនង"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"ចូលដំណើរការ និងកែប្រែទំនាក់ទំនងរបស់អ្នក"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ចូលប្រើទំនាក់ទំនងរបស់អ្នក"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ទីតាំង"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"ចូលដំណើរការទីតាំងរបស់អ្នក"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ព័ត៌មានសង្គមរបស់អ្នក"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ចូលដំណើរការព័ត៌មានដោយផ្ទាល់អំពីទំនាក់ទំនង និងការភ្ជាប់សង្គមរបស់អ្នក។"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ប្រតិទិន"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"ចូលដំណើរការ និងកែប្រែប្រតិទិនរបស់អ្នក"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ចូលប្រើប្រិតិទិនរបស់អ្នក"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"សារ SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"ចូលដំណើរការ និងកែប្រែសារ SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"មើល និងគ្រប់គ្រប់សារ SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"វចនានុក្រមអ្នកប្រើ"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"អាន ឬសរសេរនៅក្នុងវចនានុក្រមអ្នកប្រើ។"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ចំណាំ និងប្រវត្តិ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ចូលដំណើរការចំណាំ និងប្រវត្តិកម្មវិធីអ៊ីនធឺណិតដោយផ្ទាល់។"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"មីក្រូហ្វូន"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ប្រើមីក្រូហ្វូនរបស់ឧបករណ៍"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ថតសំឡេង"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ម៉ាស៊ីនថត"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ប្រើកាមេរ៉ារបស់ឧបករណ៍"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ថតរូប និងថតវីដេអូ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ទូរស័ព្ទ"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ប្រើមុខងារទូរស័ព្ទរបស់ឧបករណ៍"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ហៅទូរស័ព្ទ និងគ្រប់គ្រងការហៅទូរស័ព្ទ"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"ឧបករណ៍ចាប់សញ្ញា"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"ចួលដំណើរការឧបករណ៍ចាប់សញ្ញា និងនាឡិកាឆ្លាតវៃ"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ចូលប្រើទិន្នន័យពីឧបករណ៍ចាប់សញ្ញា និងឧបករណ៍សម្រាប់ពាក់"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ទៅយកមាតិកាបង្អួច"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ពិនិត្យមាតិកាបង្អួចដែលអ្នកកំពុងទាក់ទងជាមួយ។"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"បើកការរកមើលដោយប៉ះ"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ឲ្យកម្មវិធីបន្ថែម លុប ឬប្ដូរព្រឹត្តិការណ៍ដែលអ្នកអាចកែលើកុំព្យូទ័របន្ទះរបស់អ្នក រួមមានមិត្តភ័ក្ដិ ឬមិត្តរួមការងារ។ វាអាចឲ្យកម្មវិធីផ្ញើសារដែលបង្ហាញថាមកពីម្ចាស់ប្រតិទិន ឬកែព្រឹត្តិការណ៍ដោយមិនឲ្យម្ចាស់ដឹង។"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"អនុញ្ញាតឲ្យកម្មវិធីបន្ថែម យកចេញ និងផ្លាស់ប្តូរព្រឹត្តិការណ៍ដែលអ្នកបានកែសម្រួលនៅលើទូរទស្សន៍របស់អ្នក ដោយរាប់បញ្ចូលទាំងព្រឹត្តិការណ៍របស់មិត្តភ័ក្ត និងមិត្តរួមការងាររបស់អ្នក។ វាអាចអនុញ្ញតឲ្យកម្មវិធីផ្ញើសារដែលបានមកពីម្ចាស់ប្រតិទិន ឬកែសម្រួលដោយមិនមានការដឹងលឺពីម្ចាស់ទាំងនោះ។"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ឲ្យកម្មវិធីបន្ថែម លុប ឬប្ដូរព្រឹត្តិការណ៍ដែលអ្នកអាចកែប្រែលើទូរស័ព្ទរបស់អ្នក រួមមានមិត្តភ័ក្ដិ ឬមិត្តរួមការងារ។ វាអាចឲ្យកម្មវិធីផ្ញើសារដែលបង្ហាញថាមកពីម្ចាស់ប្រតិទិន ឬកែព្រឹត្តិការណ៍ដោយមិនឲ្យអ្នកដឹង។"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ក្លែងប្រភពទីតាំងសម្រាប់សាកល្បង"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"បង្កើតប្រភពទីតាំងក្លែងក្លាយសម្រាប់សាកល្បង ឬដំឡើងក្រុមហ៊ុនផ្ដល់ទីតាំងថ្មី។ វាអនុញ្ញាតឲ្យកម្មវិធីបដិសេធទីតាំង និង/ឬស្ថានភាពបានត្រឡប់ដោយប្រភពទីតាំងផ្សេងដូចជា GPS ឬក្រុមហ៊ុនផ្ដល់ទីតាំង។"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ចូលដំណើរការពាក្យបញ្ជាក្រុមហ៊ុនផ្ដល់ទីតាំង"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ឲ្យកម្មវិធីចូលដំណើរការពាក្យបញ្ជាកម្មវិធីផ្ដល់ទីតាំងបន្ថែម។ វាអាចអនុញ្ញាតឲ្យកម្មវិធីទាក់ទងជាមួយប្រតិបត្តិការជីភីអេស ឬប្រភពទីតាំងផ្សេង។"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ទីតាំងពិតប្រាកដ (GPS និងមានមូលដ្ឋានលើបណ្ដាញ)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"បានបោះបង់ប្រតិបត្តិការស្នាមម្រាមដៃ។"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ព្យាយាមចូលច្រើនពេកហើយ។ សូមព្យាយាមម្តងទៀតពេលក្រោយ។"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ព្យាយាមម្ដងទៀត។"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"អានការកំណត់ធ្វើសមកាលកម្ម"</string>
@@ -1044,12 +1044,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"បើអ្នកបើកឧបករណ៍ផ្ទុកយូអេសប៊ី កម្មវិធីមួយចំនួនដែលអ្នកកំពុងប្រើនឹងបញ្ឈប់ ហើយអាចប្រើលែងបានរហូតដល់អ្នកបិទឧបករណ៍ផ្ទុកយូអេសប៊ី។"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"ប្រតិបត្តិការយូអេសប៊ីបរាជ័យ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"យល់ព្រម"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"បានតភ្ជាប់ជាឧបករណ៍ផ្ទុក"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"បានភ្ជាប់ជាម៉ាស៊ីនថត"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"បានភ្ជាប់ជាឧបករណ៍មីឌី"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"បានភ្ជាប់ជាកម្មវិធីដំឡើង"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"បានភ្ជាប់ឧបករណ៍យូអេសប៊ី"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ប៉ះ ដើម្បីមើលជម្រើសយូអេសប៊ីផ្សេង។"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ធ្វើទ្រង់ទ្រាយឧបករណ៍ផ្ទុកយូអេសប៊ី?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ធ្វើទ្រង់ទ្រាយកាតអេសឌី?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ឯកសារទាំងអស់ដែលបានរក្សាទុកក្នុងឧបករណ៍ផ្ទុកយូអេសប៊ីនឹងត្រូវបានលុប។ សកម្មភាពនេះមិនអាចត្រឡប់វិញបានទេ!"</string>
@@ -1468,30 +1474,31 @@
<item quantity="other">រយៈពេល %1$d នាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">រយៈពេលមួយនាទី (រហូតដល់ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">រយៈពេល %1$d ម៉ោង (រហូតដល់ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">រយៈពេលមួយម៉ោង (រហូតដល់ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">រយៈពេល %d នាទី</item>
<item quantity="one">រយៈពេលមួយនាទី</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">រយៈពេល %d ម៉ោង</item>
<item quantity="one">រយៈពេលមួយម៉ោង</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"រហូតដល់ពេលអ្នកបិទវា"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"បង្រួម"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"កុំរំខាន"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ពេលមិនដំណើរការ"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"យប់ថ្ងៃធម្មតា"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ចុងសប្ដាហ៍"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ព្រឹត្តិការណ៍"</string>
<string name="muted_by" msgid="6147073845094180001">"បានបិទសំឡេងដោយ <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ហើយវាអ្នកមិនមានស្ថេរភាព រហូតទាល់តែអ្នកកំណត់ដូចដើមវិញទាំងស្រុង។"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"មានបញ្ហាខាងក្នុងឧបករណ៍របស់អ្នក ទំនាក់ទំនងក្រុមហ៊ុនផលិតឧបករណ៍របស់អ្នកសម្រាប់ព័ត៌មានបន្ថែម។"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index 41fe302..cd0b73c 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ವೈಯಕ್ತಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ಕಚೇರಿ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ಸಂಪರ್ಕಗಳು"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಿ ಮತ್ತು ಮಾರ್ಪಡಿಸಿ"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ಸ್ಥಳ"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಮಾಹಿತಿ"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳು ಮತ್ತು ಸಾಮಾಜಿಕ ಸಂಪರ್ಕಗಳ ಕುರಿತ ಮಾಹಿತಿಗೆ ನೇರ ಪ್ರವೇಶ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ಕ್ಯಾಲೆಂಡರ್"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಿ ಮತ್ತು ಮಾರ್ಪಡಿಸಿ"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಪ್ರವೇಶಿಸಿ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS ಪ್ರವೇಶಿಸಿ ಮತ್ತು ಮಾರ್ಪಡಿಸಿ"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS ಸಂದೇಶಗಳನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"ಬಳಕೆದಾರರ ನಿಘಂಟು"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ಬಳಕೆದಾರರ ನಿಘಂಟಿನಲ್ಲಿನ ಪದಗಳನ್ನು ಓದಿ ಮತ್ತು ಬರೆಯಿರಿ."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಇತಿಹಾಸ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಬ್ರೌಸರ್ ಇತಿಹಾಸಕ್ಕೆ ನೇರ ಪ್ರವೇಶ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ಮೈಕ್ರೋಫೋನ್"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ಸಾಧನ ಮೈಕ್ರೊಫೋನ್ ಬಳಸಿ"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ಕ್ಯಾಮರಾ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ಸಾಧನ ಕ್ಯಾಮರಾ ಬಳಸಿ"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ಚಿತ್ರಗಳನ್ನು ತೆಗೆಯಿರಿ ಹಾಗೂ ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ಫೋನ್"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ಸಾಧನ ದೂರವಾಣಿ ಬಳಸಿ"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"ಸಂವೇದಕಗಳು"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"ಸಂವೇದಕಗಳು ಮತ್ತು ವೇರಬಲ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ಸೆನ್ಸಾರ್ಗಳು ಹಾಗೂ ಧರಿಸುವಂತಹ ಸಾಧನಗಳಿಂದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳಿ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ನೀವು ಸಂವಹನ ನಡೆಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯವನ್ನು ಪರೀಕ್ಷಿಸಿ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ಸ್ಪರ್ಶಿಸುವ ಮೂಲಕ ಎಕ್ಸ್ಪ್ಲೋರ್ ಆನ್ ಮಾಡಿ"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ನಿಮ್ಮ ಸ್ನೇಹಿತರು ಅಥವಾ ಸಹೋದ್ಯೋಗಿಗಳ ಈವೆಂಟ್ಗಳೂ ಸೇರಿದಂತೆ, ನೀವು ಮಾರ್ಪಡಿಸಬಹುದಾದ ಈವೆಂಟ್ಗಳನ್ನು ಸೇರಿಸಲು, ತೆಗೆದುಹಾಕಲು, ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದು ಕ್ಯಾಲೆಂಡರ್ ಮಾಲೀಕರಿಂದ ಬಂದಿರುವಂತೆ ಗೋಚರಿಸುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಇಲ್ಲವೇ ಮಾಲೀಕರ ಗಮನಕ್ಕೆ ತರದೆಯೇ, ಈವೆಂಟ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಮಾರ್ಪಡಿಸಬಹುದಾದ ಸ್ನೇಹಿತರು ಅಥವಾ ಸಹದ್ಯೋಗಿಗಳು ಸೇರಿದಂತೆ ಸೇರಿಸಲು, ತೆಗೆದುಹಾಕಲು, ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಮಾರ್ಪಡಿಸಬಹುದಾದ ಈವೆಂಟ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅನುಮತಿಸುತ್ತದೆ. ಕ್ಯಾಲೆಂಡರ್ನ ಮಾಲೀಕರಿಂದ ಬಂದಿರಬಹುದು ಎಂದು ಪರಿಗಣಿಸಲಾಗುವಂತಹ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಅಥವಾ ಮಾಲೀಕರ ಅರಿವಿಲ್ಲದೆಯೆ ಈವೆಂಟ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಇದು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ನಿಮ್ಮ ಸ್ನೇಹಿತರು ಅಥವಾ ಸಹೋದ್ಯೋಗಿಗಳ ಈವೆಂಟ್ಗಳೂ ಸೇರಿದಂತೆ, ನೀವು ಮಾರ್ಪಡಿಸಬಹುದಾದ ಈವೆಂಟ್ಗಳನ್ನು ಸೇರಿಸಲು, ತೆಗೆದುಹಾಕಲು, ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದು ಕ್ಯಾಲೆಂಡರ್ ಮಾಲೀಕರಿಂದ ಬಂದಿರುವಂತೆ ಗೋಚರಿಸುವ ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಇಲ್ಲವೇ ಮಾಲೀಕರ ಗಮನಕ್ಕೆ ತರದೆಯೇ, ಈವೆಂಟ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ಪರೀಕ್ಷೆಗಾಗಿ ಅಣಕು ಸ್ಥಾನ ಮೂಲಗಳು"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ಹೊಸ ಪೂರೈಕೆದಾರರನ್ನು ಪರೀಕ್ಷಿಸಲು ಅಥವಾ ಸ್ಥಾಪಿಸಲು ಅಣಕು ಸ್ಥಾನ ಮೂಲಗಳನ್ನು ರಚಿಸಿ. GPS ಅಥವಾ ಸ್ಥಾನ ಪೂರೈಕೆದಾರರಂತಹ ಇತರ ಸ್ಥಾನ ಮೂಲಗಳ ಮೂಲಕ ಹಿಂತಿರುಗಿಸಲಾದ ಸ್ಥಾನ ಮತ್ತು/ಅಥವಾ ಸ್ಥಿತಿಯನ್ನು ಅತಿಕ್ರಮಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಇದು ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ಹೆಚ್ಚುವರಿ ಸ್ಥಾನ ಪೂರೈಕೆದಾರರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ಹೆಚ್ಚಿನ ಸ್ಥಾನ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಾನ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ನಿಖರ ಸ್ಥಳ (GPS ಮತ್ತು ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ಹಲವಾರು ಪ್ರಯತ್ನಗಳು. ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ಸಿಂಕ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ರೀಡ್ ಮಾಡು"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ನೀವು USB ಸಂಗ್ರಹಣೆಯನ್ನು ಆನ್ ಮಾಡಿದರೆ, ನೀವು ಬಳಸುತ್ತಿರುವ ಕೆಲವು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಸ್ಥಗಿತಗೊಳ್ಳಬಹುದು ಮತ್ತು ನೀವು USB ಸಂಗ್ರಹಣೆಯನ್ನು ಆಫ್ ಮಾಡುವವರೆಗೆ ಅಲಭ್ಯವಾಗಿಯೇ ಇರಬಹುದು."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ಕಾರ್ಯಾಚರಣೆ ವಿಫಲವಾಗಿದೆ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ಸರಿ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ಮಾಧ್ಯಮ ಸಾಧನದ ರೂಪದಲ್ಲಿ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ಕ್ಯಾಮರಾದಂತೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI ಸಾಧನದಂತೆ ಸಂಪರ್ಕಪಡಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ಸ್ಥಾಪಕದಂತೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ಪರಿಕರಕ್ಕೆ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ಇತರ USB ಆಯ್ಕೆಗಳಿಗಾಗಿ ಸ್ಪರ್ಶಿಸಿ."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB ಸಂಗ್ರಹಣೆಯನ್ನು ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡುವುದೇ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD ಕಾರ್ಡ್ ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡುವುದೇ?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ನಿಮ್ಮ USB ಸಂಗ್ರಹಣೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಎಲ್ಲಾ ಫೈಲ್ಗಳನ್ನು ಅಳಿಸಿಹಾಕಲಾಗುವುದು. ಈ ಕ್ರಿಯೆಯನ್ನು ಹಿಂತಿರುಗಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
<item quantity="other">%1$d ನಿಮಿಷಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d ಗಂಟೆಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
<item quantity="other">%1$d ಗಂಟೆಗಳವರೆಗೆ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ವರೆಗೆ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d ನಿಮಿಷಗಳವರೆಗೆ</item>
<item quantity="other">%d ನಿಮಿಷಗಳವರೆಗೆ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d ಗಂಟೆಗಳವರೆಗೆ</item>
<item quantity="other">%d ಗಂಟೆಗಳವರೆಗೆ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ನೀವಿದನ್ನು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ಸಂಕುಚಿಸು"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ಸ್ಥಗಿತಕಾಲ"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ವಾರದ ರಾತ್ರಿ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ವಾರಾಂತ್ಯ"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ಈವೆಂಟ್"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ಅವರಿಂದ ಮ್ಯೂಟ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ ಹಾಗೂ ನೀವು ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾವನ್ನು ಮರುಹೊಂದಿಸುವರೆಗೂ ಅದು ಅಸ್ಥಿರವಾಗಬಹುದು."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಆಂತರಿಕ ಸಮಸ್ಯೆಯಿದೆ. ವಿವರಗಳಿಗಾಗಿ ನಿಮ್ಮ ತಯಾರಕರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 7b5aec8..d1e06fe 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"개인 앱"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"직장"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"주소록"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"내 주소록 액세스 및 수정"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"주소록 액세스"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"위치"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"내 위치 액세스"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"소셜 정보"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"내 연락처 및 소셜 친구의 개인 정보에 직접 액세스합니다."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"캘린더"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"내 캘린더 액세스 및 수정"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"캘린더 액세스"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS 액세스 및 수정"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS 메시지 보기 및 관리"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"사용자 사전"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"사용자 사전의 단어를 읽거나 씁니다."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"북마크 및 기록"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"북마크 및 브라우저 기록에 직접 액세스합니다."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"마이크"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"기기 마이크 사용"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"오디오 녹음"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"카메라"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"기기 카메라 사용"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"사진 찍기 및 동영상 녹화"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"전화"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"기기 전화 기능 사용"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"전화 걸기 및 관리"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"센서"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"센서 및 웨어러블 액세스"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"센서 및 웨어러블 기기의 데이터 액세스"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"창 콘텐츠 가져오기"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"상호작용 중인 창의 콘텐츠를 검사합니다."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"터치하여 탐색 사용"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"앱이 친구나 동료의 일정을 포함하여 태블릿에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자가 보내는 것처럼 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"앱이 친구나 동료의 일정을 비롯하여 TV에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 발신자가 캘린더 소유자인 메시지를 전송하거나 소유자가 모르는 사이에 일정을 수정할 수 있습니다."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"앱이 친구나 동료의 일정을 포함하여 휴대전화에서 수정할 수 있는 일정을 추가, 삭제, 변경할 수 있도록 허용합니다. 이 경우 앱이 캘린더 소유자가 보내는 것처럼 메시지를 전송하거나 소유자 모르게 일정을 수정할 수도 있습니다."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"테스트를 위해 위치 정보제공자로 가장"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"테스트용 가상 위치 소스를 만들거나 새로운 위치 정보 제공업체를 설치합니다. 이 경우 앱이 GPS 또는 위치 정보 제공업체 등 기타 위치 소스가 반환한 위치 또는 상태를 덮어쓸 수 있습니다."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"추가 위치 제공업체 명령에 액세스"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"앱이 추가 위치 정보 제공 기능의 명령에 액세스하도록 허용합니다. 이 경우 앱이 GPS 또는 기타 위치 소스의 작동을 방해할 수 있습니다."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"정확한 위치(GPS 및 네트워크 기반)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"지문 인식 작업이 취소되었습니다."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"시도 횟수가 너무 많습니다. 나중에 다시 시도하세요."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"다시 시도해 보세요."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"동기화 설정 읽기"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB 저장소를 사용하면 사용 중인 일부 애플리케이션이 중지되며 USB 저장소를 사용중지할 때까지 사용하지 못할 수 있습니다."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB 작업을 하지 못했습니다."</string>
<string name="dlg_ok" msgid="7376953167039865701">"확인"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"미디어 기기로 연결됨"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"카메라로 연결됨"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI 기기로 연결됨"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"설치 프로그램으로 연결됨"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB 액세서리에 연결됨"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"다른 USB 옵션을 보려면 터치하세요."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB 저장소를 포맷하시겠습니까?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD 카드를 포맷하시겠습니까?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB 저장소에 저장된 파일이 모두 삭제됩니다. 이 작업은 되돌릴 수 없습니다."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d분 동안(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>까지)</item>
<item quantity="one">1분 동안(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>까지)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d시간 동안(<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>까지)</item>
<item quantity="one">1시간 동안(<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>까지)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d분 동안</item>
<item quantity="one">1분 동안</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d시간 동안</item>
<item quantity="one">1시간 동안</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"이 기능을 사용 중지할 때까지"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"접기"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"알림 일시중지"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"다운타임"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"평일 밤"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"주말"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"일정"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>에서 알림음 음소거"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"사용 중인 기기 내부에 문제가 발생했습니다. 초기화할 때까지 불안정할 수 있습니다."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"사용 중인 기기 내부에 문제가 발생했습니다. 자세한 내용은 제조업체에 문의하세요."</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 3776ef2..1f4e835 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -328,27 +328,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Жеке колдономолор"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Жумуш"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Байланыштар"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"байланыштарыңызга кирип, өзгөртүңүз"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"байланыштарыңызга уруксат"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"жайгашкан жериңизге кирүү"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Сиздин социалдык маалыматыңыз"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Сиздин байланыштарыңыз жана социалдык байланыштарыңыз тууралуу маалыматтарга түз жетки алуу."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнбарак"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"жылнаамаңызга кирип, өзгөртүңүз"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"күнбарагыңызга уруксат"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS\'ке кирип, өзгөртүү"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS билдирүүлөрдү көрүү жана башкаруу"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Колдонуучунун сөздүгү"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Колдонуучунун сөздүгүндөгү сөздөрдү окуу же жазуу"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Бүктөмөлөр жана тарых"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Бүктөмөлөргө же серепчи тарыхына түз жетки алуу."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"түзмөктүн микрофонун колдонуу"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио жаздыруу"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"түзмөктүн камерасын колдонуу"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"сүрөт тартуу жана видео жаздыруу"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"түзмөктүн телефониясын колдонуу"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"телефон чалуу жана аларды башкаруу"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Сенсорлор"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"сенсорлор менен тагынмаларга кирүү"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"сенсорлордон жана тагынма түзмөктөрдөн маалымат алуу"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Терезе мазмунун алуу"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Сиз иштеп жаткан терезенин мазмунун изилдөө."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Сыйпалап изилдөөнү жандыруу"</string>
@@ -449,9 +449,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Колдонмого сиз планшетиңизден өзгөртө ала турган, сиздин, досторуңуздун же кесиптештериңиздин күнбарак окуяларын кошуу, жок кылуу, өзгөртүү уруксатын берет. Бул, колдонмого күнбарак ээлеринен келген сыяктуу көрүнгөн билдирүүлөрдү жөнөтүү, же ээсине билгизбей окуяларды өзгөртүү уруксатын берет."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Колдонмого сыналгыңызда өзгөрүлө турган окуяларды, ошондой эле досторуңуз же кесиптештериңиздин окуяларын кошуу, алып салуу жана өзгөртүү мүмкүнчүлүгүн берет. Ушуну менен колдонмо жылнаама ээлеринен келген билдирүүлөрдү жөнөтүп же окуяларды ээсине билгизбестен өзгөртө алат."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Колдонмого сиз телефонуңуздан өзгөртө ала турган, сиздин, досторуңуздун же кесиптештериңиздин күнбарак окуяларын кошуу, жок кылуу, өзгөртүү уруксатын берет. Бул, колдонмого күнбарак ээлеринен келген сыяктуу көрүнгөн билдирүүлөрдү жөнөтүү, же ээсине билгизбей окуяларды өзгөртүү уруксатын берет."</string>
- <!-- no translation found for permlab_accessMockLocation (8688334974036823330) -->
- <skip />
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Сыноо максатында жайгашуунун жасалма булактарын түзүңүз же башка жайгаштыруу камсыздоочусун орнотуңуз. Бул колдонмого GPS же башка жайгашууну аныктоочу булактар кайтарган жайгашууну жана/же абалдарын кайта жазууга уруксат берет."</string>
<!-- no translation found for permlab_accessLocationExtraCommands (2836308076720553837) -->
<skip />
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Колдонмого жайгашкан жерди табуучу кошумча жабдуучулардын буйруктарын колдонуу мүмкүнчүлүгүн берет. Ушуну менен колдонмо GPS\'тин ишине жана башка жайгашкан жерлерди аныктоо кызматтарына кийлигише алат."</string>
@@ -566,6 +563,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Манжа изи иш-аракети жокко чыгарылды."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Аракеттер өтө көп болду. Кийинчерээк кайра аракет кылыңыз."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Кайра бир аракеттениңиз."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<!-- no translation found for permlab_readSyncSettings (6201810008230503052) -->
@@ -1386,15 +1385,19 @@
<string name="dlg_error_title" msgid="7323658469626514207">"USB иши ийгиликсиз болду"</string>
<!-- no translation found for dlg_ok (7376953167039865701) -->
<skip />
- <!-- no translation found for usb_mtp_notification_title (3699913097391550394) -->
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
<skip />
- <!-- no translation found for usb_ptp_notification_title (1960817192216064833) -->
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
<skip />
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI түзмөк катары туташкан"</string>
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<!-- no translation found for usb_cd_installer_notification_title (6774712827892090754) -->
<skip />
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB аксессуарга байланышты"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Башка USB опцияларды көрүү үчүн басыңыз."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB сактагычы форматталсынбы?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD карта форматталсынбы?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB сактагычыңызда сакталган бардык файлдар тазаланып салынат. Бул аракетти артка кайтаруу мүмкүн эмес!"</string>
@@ -1883,30 +1886,31 @@
<item quantity="other">%1$d мүнөткө (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> чейин)</item>
<item quantity="one">Бир мүнөткө (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> чейин)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d саатка (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> чейин)</item>
<item quantity="one">Бир саатка (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> чейин)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d мүнөткө</item>
<item quantity="one">Бир мүнөткө</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d саатка</item>
<item quantity="one">Бир саатка</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Бул өчүрүлгөнгө чейин"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Жыйнап коюу"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Тынчымды алба"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Аракетсиз убакыт"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Иш күндөрүнүн кечтери"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Дем алыш"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Иш-чара"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> тарабынан үнсүздөлдү"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Түзмөгүңүздө ички көйгөй бар жана ал баштапкы абалга кайтарылмайынча туруктуу иштебей коюшу мүмкүн."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Түзмөгүңүздө ички көйгөй бар. Анын чоо-жайын билүү үчүн өндүрүүчүңүзгө кайрылыңыз."</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 3a59800..4e560b0 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ແອັບຯສ່ວນໂຕ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ບ່ອນເຮັດວຽກ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ລາຍຊື່"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"ເຂົ້າຫາ ແລະແກ້ໄຂລາຍຊື່ຂອງທ່ານ"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ເຂົ້າຫາລາຍຊື່ຂອງທ່ານ"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ສະຖານທີ່"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"ເຂົ້າຫາທີ່ຕັ້ງຂອງທ່ານ"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ຂໍ້ມູນສັງຄົມຂອງທ່ານ"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ເຂົ້າເຖິງຂໍ້ມູນກ່ຽວກັບລາຍຊື່ຜູ່ຕິດຕໍ່ ແລະການເຊື່ອມຕໍ່ທາງສັງຄົມຂອງທ່ານໂດຍກົງ."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ປະຕິທິນ"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"ເຂົ້າຫາ ແລະແກ້ໄຂປະຕິທິນຂອງທ່ານ"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ເຂົ້າຫາປະຕິທິນຂອງທ່ານ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"ເຂົ້າຫາ ແລະແກ້ໄຂ SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ເບິ່ງ ແລະຈັດການຂໍ້ຄວາມ SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"ວັດຈະນານຸກົມຜູ່ໃຊ້"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ອ່ານ ຫຼືຂຽນຄຳສັບໃນວັດຈະນານຸກົມຜູ້ໃຊ້."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ບຸກມາກ ແລະປະຫວັດເວັບໄຊ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ເຂົ້ານຳໃຊ້ບຸກແລະປະຫວັດການທ່ອງເວັບໂດຍກົງ."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ໄມໂຄຣໂຟນ"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ໃຊ້ໄມໂຄຣໂຟນຂອງອຸປະກອນ"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ບັນທຶກສຽງ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ກ້ອງ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ໃຊ້ກ້ອງຖ່າຍຮູບຂອງອຸປະກອນ"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ຖ່າຍຮູບ ແລະບັນທຶກວິດີໂອ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ໂທລະສັບ"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ໃຊ້ລະບົບໂທລະສັບຂອງອຸປະກອນ"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ໂທ ແລະຈັດການການໂທລະສັບ"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"ເຊັນເຊີ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"ເຂົ້າຫາເຊັນເຊີ ແລະສິ່ງທີ່ສາມາດສວມໃສ່ໄດ້"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ເຂົ້າຫາຂໍ້ມູນຈາກເຊັນເຊີ ແລະອຸປະກອນສວມໃສ່ໄດ້"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ດຶງຂໍ້ມູນເນື້ອຫາໃນໜ້າຈໍ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ກວດກາເນື້ອຫາຂອງໜ້າຈໍທີ່ທ່ານກຳລັງມີປະຕິສຳພັນນຳ."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ເປີດໃຊ້ \"ການສຳຫຼວດໂດຍສຳພັດ\""</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ອະນຸຍາດໃຫ້ແອັບຯເພີ່ມ, ລຶບ ແລະປ່ຽນກິດຈະກຳທີ່ທ່ານສາມາດແກ້ໄຂ ໃນແທັບເລັດຂອງທ່ານໄດ້ ຮວມທັງກິດຈະກຳຂອງໝູ່ ຫຼືໝູ່ຮ່ວມເຮັດວຽກ ເຊິ່ງອາດອະນຸຍາດໃຫ້ແອັບຯສົ່ງຂໍ້ຄວາມທີ່ຄືກັບວ່າ ມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂການນັດໝາຍໄດ້ ໂດຍບໍ່ໃຫ້ເຈົ້າຂອງຮັບຮູ້."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ອະນຸຍາດໃຫ້ແອັບເພີ່ມ, ລຶບ, ປ່ຽນແປງເຫດການທີ່ທ່ານສາມາດແກ້ໄຂໃນໂທລະພາບຂອງທ່ານໄດ້, ລວມທັງອັນທີ່ເປັນຂອງໝູ່ ແລະຂອງເພື່ອນຮ່ວມງານ. ອັນນີ້ອາດຈະອະນຸຍາດໃຫ້ແອັບສົ່ງຂໍ້ຄວາມໃນຖານະເຈົ້າຂອງປະຕິທິນ ຫຼືປ່ຽນແປງເຫດການໂດຍທີ່ເຈົ້າຂອງບໍ່ຮູ້ໄດ້."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມ, ລຶບ, ປ່ຽນແປງນັດໝາຍທີ່ທ່ານສາມາດແກ້ໄຂໄດ້ໃນໂທລະສັບຂອງທ່ານ, ຮວມທັງຂອງໝູ່ຄູ່ ຫຼືເພື່ອນຮ່ວມວຽກ. ນີ້ອາດເຮັດໃຫ້ແອັບຯສາມາດສົ່ງຂໍ້ຄວາມ ທີ່ເບິ່ງຄືວ່າມາຈາກເຈົ້າຂອງປະຕິທິນ ຫຼືແກ້ໄຂນັດໝາຍໂດຍທີ່ທ່ານບໍ່ໄດ້ຮັບຮູ້ໄດ້."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ຈຳລອງແຫລ່ງຂໍ້ມູນສະຖານທີ່ເພື່ອການທົດສອບ"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ສ້າງແຫລ່ງຂໍ້ມູນຈຳລອງຂອງສະຖານທີ່ ເພື່ອການທົດສອບ ຫຼືຕິດຕັ້ງແຫລ່ງຂໍ້ມູນສະຖານທີ່ໃໝ່. ນີ້ຈະອະນຸຍາດໃຫ້ແອັບຯສາມາດຂຽນທັບຂໍ້ມູນຂອງສະຖານທີ່ ແລະ/ຫຼື ຂໍ້ມູນທີ່ສົ່ງກັບມາຈາກແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນ ເຊັ່ນ: GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໄດ້."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ເຂົ້າເຖິງຄຳສັ່ງຜູ່ໃຫ້ບໍລິການພິກັດສະຖານທີ່"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຄຳສັ່ງເພີ່ມເຕີມຂອງຜູ່ໃຫ້ບໍລິການສະຖານທີ່. ນີ້ອາດຈະເປັນການເຮັດໃຫ້ແອັບຯ ລົບກວນການເຮັດວຽກຂອງ GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໆໄດ້."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ສະຖານທີ່ແນ່ນອນ (ອ້າງອີງຈາກ GPS ແລະເຄືອຂ່າຍ)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ຍົກເລີກການດຳເນີນການລາຍນີ້ວມືແລ້ວ."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ມີຄວາມພະຍາຍາມຫຼາຍຄັ້ງເກີນໄປ. ລອງໃໝ່ພາຍຫຼັງ."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ລອງໃໝ່ອີກຄັ້ງ."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ອ່ານການຕັ້ງຄ່າຊິ້ງຂໍ້ມູນ"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ຫາກທ່ານເປີດນຳໃຊ້ບ່ອນຈັດເກັບຂໍ້ມູນ USB ຈະເຮັດໃຫ້ບາງແອັບຯທີ່ທ່ານເຮັດວຽກຢູ່ນັ້ນ ຢຸດເຮັດວຽກ ແລະອາດຈະບໍ່ສາມາດໃຊ້ໄດ້ຈົນກວ່າທ່ານປິດບ່ອນຈັດເກັບຂໍ້ມູນ USB ກ່ອນ."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"ປະຕິບັດການ USB ບໍ່ສຳເລັດ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ຕົກລົງ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ເຊື່ອມຕໍ່ເປັນອຸປະກອນສື່"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບແລ້ວ"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"ເຊື່ອມຕໍ່ເປັນອຸປະກອນ MIDI ແລ້ວ"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ເຊື່ອມຕໍ່ໃນນາມຕົວຕິດຕັ້ງ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ເຊື່ອມຕໍ່ກັບອຸປະກອນເສີມ USB ແລ້ວ"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ແຕະເພື່ອເບິ່ງໂຕເລືອກເລືອກ USB ອື່ນໆ."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ຟໍແມັດ ບ່ອນຈັດເກັບຂໍ້ມູນ USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ຟໍແມັດ SD card?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ໄຟລ໌ທັງໝົດທີ່ຢູ່ໃນບ່ອນຈັດເກັບຂໍ້ມູນ USB ຂອງທ່ານຈະຖືກລຶບອອກໝົດ. ການກະທຳຈະບໍ່ສາມາດຍົກເລີກໄດ້!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">ເປັນເວລາ %1$d ນາທີ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">ເປັນເວລາ 1 ນາທີ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">ເປັນເວລາ %1$d ຊົ່ວໂມງ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">ເປັນເວລາ 1 ຊົ່ວໂມງ (ຈົນຮອດ <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">ເປັນເວລາ %d ນາທີ</item>
<item quantity="one">ເປັນເວລາໜຶ່ງນາທີ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">ເປັນເວລາ %d ຊົ່ວໂມງ</item>
<item quantity="one">ເປັນເວລາໜຶ່ງຊົ່ວໂມງ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າທ່ານຈະປິດ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ຫຍໍ້"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ຫ້າມລົບກວນ"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ເວລາປິດເຮັດວຽກ"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ຄ່ຳຄືນໃນອາທິດ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ທ້າຍອາທິດ"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ການນັດໝາຍ"</string>
<string name="muted_by" msgid="6147073845094180001">"ຖືກປິດສຽງໂດຍ <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ມີບັນຫາພາຍໃນກັບອຸປະກອນຂອງທ່ານ, ແລະມັນອາດຈະບໍ່ສະຖຽນຈົນກວ່າທ່ານຕັ້ງເປັນຂໍ້ມູນໂຮງງານຄືນແລ້ວ."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ມີບັນຫາພາຍໃນກັບອຸປະກອນຂອງທ່ານ. ຕິດຕໍ່ຜູ້ຜະລິດຂອງທ່ານສຳລັບລາຍລະອຽດຕ່າງໆ."</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 8bb6d1c..12d288f 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Asmeninės programos"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Darbo"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktai"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"pasiekti ir keisti kontaktus"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pasiekti kontaktus"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vietovė"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"pasiekti vietovę"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Socialinė informacija"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Tiesioginė prieiga prie kontaktų ir socialinių ryšių informacijos."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendorius"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"pasiekti ir keisti kalendorių"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"pasiekti kalendorių"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"pasiekti ir keisti SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"žiūrėti ir tvarkyti SMS pranešimus"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Naudotojo žodynas"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Skaityti arba rašyti žodžius naudotojo žodyne."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Žymės ir istorija"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Tiesioginė prieiga prie žymių ir naršyklės istorijos."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonas"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"naudoti įrenginio mikrofoną"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"įrašyti garso įrašą"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparatas"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"naudoti įrenginio fotoaparatą"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografuoti ir filmuoti"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefonas"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"naudoti įrenginio telefonijos funkcijas"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"skambinti ir tvarkyti telefonų skambučius"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Jutikliai"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"pasiekti jutiklius ir nešiojamuosius"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"pasiekti duomenis iš jutiklių ir nešiojamųjų įrenginių"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gauti lango turinį"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tikrinti lango, su kuriuo sąveikaujate, turinį."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Įjungti „Naršyti paliečiant“"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Leidžiama programai pridėti, pašalinti ir keisti įvykius, kuriuos galite keisti planšetiniame kompiuteryje, įskaitant draugų ir bendradarbių įvykius. Dėl to programa gali siųsti pranešimus, kurie atrodo lyg būtų siunčiami kalendorių savininkų, arba keisti įvykius be savininko žinios."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Programai leidžiama pridėti, pašalinti ir keisti įvykius, kuriuos galite keisti naudodami TV, įskaitant draugų arba bendradarbių įvykius. Taip programai gali būti leidžiama siųsti pranešimus, kurie atrodys kaip gauti iš kalendoriaus savininkų, arba keisti įvykius be savininko žinios."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Leidžiama programai pridėti, pašalinti ir keisti įvykius, kuriuos galite keisti telefone, įskaitant draugų ir bendradarbių įvykius. Dėl to programa gali siųsti pranešimus, kurie atrodo lyg būtų siunčiami kalendorių savininkų, arba keisti įvykius be savininko žinios."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imituoti vietos šaltinius bandymui"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Kurti bandomuosius imituojančius vietos nustatymo šaltinius arba įdiegti naują vietos nustatymo paslaugų teikėją. Programai leidžiama nepaisyti vietos ir (arba) būsenos, kurią pateikia kiti vietos nustatymo šaltiniai, pvz., GPS arba vietos nustatymo paslaugų teikėjai."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"pasiekti papildomas vietos teikimo įrankio komandas"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Programai leidžiama pasiekti papildomas vietovės nustatymo paslaugų teikėjų komandas. Dėl to programa gali trukdyti veikti GPS ar kitiems vietovės nustatymo šaltiniams."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"tiksli vieta (pagrįsta pagal GPS ir tinklą)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Kontrolinio kodo operacija atšaukta."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bandykite dar kartą."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"skaityti sinchronizavimo nustatymus"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jei įjungsite USB atmintį, kai kurios naudojamos programos sustos ir gali būti negalimos, kol ją išjungsite."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Nesėkminga USB operacija"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Gerai"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Prij. kaip medijos įrenginys"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Prij. kaip fotoap."</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Prijungtas kaip MIDI įrenginys"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Prij. kaip diegimo programa"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Prijungta prie USB priedo"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Jei norite matyti kitas USB parinktis, palieskite."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatuoti USB atmintį?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatuoti SD kortelę?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Bus ištrinti visi USB atmintyje saugomi failai. Šio veiksmo negalima atšaukti!"</string>
@@ -1486,36 +1492,37 @@
<item quantity="many">%1$d minutės (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d minučių (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d valandą (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d valandas (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d valandos (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d valandų (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d minutę</item>
<item quantity="few">%d minutes</item>
<item quantity="many">%d minutės</item>
<item quantity="other">%d minučių</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d valandą</item>
<item quantity="few">%d valandas</item>
<item quantity="many">%d valandos</item>
<item quantity="other">%d valandų</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Kol išjungsite"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sutraukti"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Netrukdyti"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Prastova"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Savaitgalio vakarą"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Savaitgalį"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Įvykis"</string>
<string name="muted_by" msgid="6147073845094180001">"Nutildė <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Iškilo vidinė su jūsų įrenginiu susijusi problema, todėl įrenginys gali veikti nestabiliai, kol neatkursite gamyklinių duomenų."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Iškilo vidinė su jūsų įrenginiu susijusi problema. Jei reikia išsamios informacijos, susisiekite su gamintoju."</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index cf758c0..11c2814 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -221,27 +221,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personīgās lietotnes"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Darba"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersonas"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"piekļūt jūsu kontaktpersonām un tās mainīt"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"piekļūt jūsu kontaktpersonu datiem"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Atrašanās vieta"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"piekļūt jūsu atrašanās vietas informācijai"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Jūsu sociālo tīklu informācija"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Tieša piekļuve informācijai par jūsu kontaktpersonām un sociālajiem savienojumiem."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendārs"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"piekļūt jūsu kalendāram un to mainīt"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"piekļūt jūsu kalendāram"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Īsziņas"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"piekļūt īsziņām un tās mainīt"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"skatīt un pārvaldīt īsziņas"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Lietotāja vārdnīca"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Lasīt vai rakstīt vārdus lietotāja vārdnīcā."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Grāmatzīmes un vēsture"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Tieša piekļuve grāmatzīmēm un pārlūkprogrammas vēsturei."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofons"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"izmantot ierīces mikrofonu"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ierakstīt audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"izmantot ierīces kameru"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"uzņemt attēlus un ierakstīt videoklipus"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Tālrunis"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"izmantot ierīces tālruņa funkcijas"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"veikt un pārvaldīt tālruņa zvanus"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensori"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"piekļūt sensoriem un valkājamām ierīcēm"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"piekļūt sensoru un valkājamo ierīču datiem"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Izgūt loga saturu."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Skatīt tā loga saturu, ar kuru mijiedarbojaties."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizēt funkciju “Pārlūkot pieskaroties”."</string>
@@ -336,8 +336,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Ļauj lietotnei pievienot, noņemt, mainīt notikumus, kurus varat pārveidot planšetdatorā, tostarp draugu vai kolēģu notikumus. Tas var ļaut lietotnei sūtīt ziņojumus, norādot, ka tos sūta kalendāru īpašnieki, vai pārveidot notikumus bez īpašnieka atļaujas."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Ļauj lietotnei pievienot, noņemt un mainīt pasākumus, kurus jūs varat pārveidot savā televizorā, tostarp draugu un kolēģu pasākumus. Ar šo atļauju lietotne var sūtīt ziņojumus, ko šķietami sūtījuši kalendāru īpašnieki, vai pārveidot pasākumus bez īpašnieku ziņas."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ļauj lietotnei pievienot, noņemt, mainīt notikumus, kurus varat pārveidot tālrunī, tostarp draugu vai kolēģu notikumus. Tas var ļaut lietotnei sūtīt ziņojumus, norādot, ka tos sūta kalendāru īpašnieki, vai pārveidot notikumus bez īpašnieka atļaujas."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imitēt atrašanās vietu avotus pārbaudes nolūkos"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Izveido neīstus atrašanās vietas noteikšanas avotus testēšanas nolūkiem vai instalē jaunu atrašanās vietas noteikšanas nodrošinātāju. Tas ļauj lietotnei ignorēt atrašanās vietu un/vai statusu, ko norādīja citi atrašanās vietas noteikšanas avoti, piemēram, GPS vai atrašanās vietas noteikšanas nodrošinātāji."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"piekļūt atrašanās vietas nodrošinātāja papildu komandām"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ļauj lietotnei piekļūt papildu atrašanās vietas noteikšanas nodrošinātāju komandām. Tas var ļaut lietotnei traucēt GPS vai citu atrašanās vietas noteikšanas avotu darbību."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precīza atrašanās vieta (GPS un tīklā)"</string>
@@ -439,6 +437,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Nospieduma darbība neizdevās."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Pārāk daudz mēģinājumu. Vēlāk mēģiniet vēlreiz."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Mēģiniet vēlreiz."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lasīt sinhronizācijas iestatījumus"</string>
@@ -1049,12 +1049,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ja ieslēgsiet USB atmiņu, dažu izmantoto lietotņu darbība tiks apturēta un tās var nebūt pieejamas līdz brīdim, kad USB atmiņa tiks izslēgta."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB atmiņas darbība neizdevās."</string>
<string name="dlg_ok" msgid="7376953167039865701">"Labi"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Pievienots kā multivides ierīce"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Pievienots kā kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Ierīce tika pievienota kā MIDI ierīce."</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Pievienots kā instalēšanas programma"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ir izveidots savienojums ar USB piederumu."</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Pieskarieties, lai skatītu citas USB opcijas."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Vai formatēt USB atmiņu?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vai formatēt SD karti?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Visi USB atmiņā saglabātie faili tiks dzēsti. Šo darbību nevar atsaukt."</string>
@@ -1476,33 +1482,34 @@
<item quantity="one">%1$d minūti (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d minūtes (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="zero">%1$d stundas (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">%1$d stundu (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d stundas (līdz <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="zero">%d minūtes</item>
<item quantity="one">%d minūti</item>
<item quantity="other">%d minūtes</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="zero">%d stundas</item>
<item quantity="one">%d stundu</item>
<item quantity="other">%d stundas</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Līdz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Līdz brīdim, kad izslēgsiet"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Sakļaut"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Netraucēt"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Dīkstāve"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Darbadienas vakarā"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Nedēļas nogalē"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Pasākums"</string>
<string name="muted_by" msgid="6147073845094180001">"Skaņu izslēdza <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Jūsu ierīcē ir radusies iekšēja problēma, un ierīce var darboties nestabili. Lai to labotu, veiciet rūpnīcas datu atiestatīšanu."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Jūsu ierīcē ir radusies iekšēja problēma. Lai iegūtu plašāku informāciju, lūdzu, sazinieties ar ražotāju."</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 3937ee1..855b003 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Лични апликации"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"пристапи до и менувај ги контактите"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"пристапи до контактите"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"пристапи до локацијата"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Тво социјални информации"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Директен пристап до информации за вашите контакти и социјални врски."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"пристапи до и менувај го календарот"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"пристапи до календарот"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"СМС"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"пристапи до и менувај СМС"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"прегледај и управувај со СМС пораки"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Кориснички речник"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Читајте или пишувајте зборови во корисничкиот речник."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Обележувачи и историја"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Директен пристап до обележувачи и историја на прелистувач."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"користи го микрофонот на уредот"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимај аудио"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Фотоапарат"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"користи го фотоапаратот на уредот"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографирај и снимај видео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"користи ја телефонијата на уредот"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"повикувај и управувај со телефонски повици"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"пристапи до сензорите и уредите за носење"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"пристапи до податоци од сензори и уреди за носење"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Врати содржина на прозорец"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Провери ја содржината на прозорецот со кој се комуницира."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Вклучи „Истражувај со допир“"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Овозможува апликацијата да додава, отстранува, менува настани кои може да ги менувате на вашиот таблет, вклучувајќи ги и оние на пријатели или соработници. Ова може да овозможи апликацијата да праќа пораки за кои се чини дека доаѓаат од сопственици на календар или да менува настани без знаење на сопствениците."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Дозволува апликацијата да додава, отстранува и менува настани кои може да ги менувате на вашиот телевизор, вклучувајќи ги и оние на пријателите и соработниците. Ова може да ѝ дозволи на апликацијата да испраќа пораки кои изгледаат како да доаѓаат од сопствениците на календарот или да менува настани без знаење на сопствениците."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Овозможува апликацијата да додава, отстранува, менува настани кои може да ги менувате на вашиот телефон, вклучувајќи ги и оние на пријатели или соработници. Ова може да овозможи апликацијата да праќа пораки за кои се чини дека доаѓаат од сопственици на календар или да менува настани без знаење на сопствениците."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"извори на лажна локација за тестирање"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Создадете извори на лажна локација за тестирање или инсталирајте нов давател на локација. Ова ѝ овозможува на апликацијата да ги избегне локацијата и / или статусот вратени од друга локација извори како што се GPS или локација на даватели."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"пристапи кон наредби на давателот на дополнителна локација"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Овозможува апликацијата да пристапи кон дополнителни наредби на давател на локација. Ова може да овозможи апликацијата да го попечи функционирањето на ГПС или други извори на локација."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"прецизна локација (ГПС и базирана на мрежа)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операцијата со отпечаток од прст се откажа."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Премногу обиди. Обидете се повторно подоцна."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Обидете се повторно."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"прочитај синхронизирани подесувања"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ако вклучите УСБ меморија, некои апликации што ги користите ќе запрат и може да се недостапни додека не ја исклучите УСБ меморијата."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Операцијата со УСБ уредот е неуспешна"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Во ред"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Поврзан како уред за медиуми"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Поврзан како фотоапарат"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Поврзан како уред со MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Поврзан како инсталатор"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Поврзан со УСБ додаток"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Допри за други опции на УСБ."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Форматирај УСБ-склад?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Да се форматира СД-картичката?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Сите датотеки складирани на УСБ-склад ќе се избришат. Дејството не може да се отповика."</string>
@@ -1468,30 +1474,31 @@
<item quantity="one">За %1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">За %1$d минути (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">За %1$d час (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">За %1$d часа (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">За %d минута</item>
<item quantity="other">За %d минути</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">За % d час</item>
<item quantity="other">За % d часа</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Додека не го исклучите"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Собери"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Не вознемирувај"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Пауза"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Вечер од седмицата"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Викенд"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Настан"</string>
<string name="muted_by" msgid="6147073845094180001">"Звукот го исклучи <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Настана внатрешен проблем со уредот и може да биде нестабилен сè додека не ресетирате на фабричките податоци."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Настана внатрешен проблем со уредот. Контактирајте го производителот за детали."</string>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 93a3a0f..77971b2 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"വ്യക്തിഗത അപ്ലിക്കേഷനുകൾ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"കോൺടാക്റ്റുകൾ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ്സ് ചെയ്ത് പരിഷ്ക്കരിക്കുക"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ലൊക്കേഷൻ"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"നിങ്ങളുടെ ലൊക്കേഷൻ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"നിങ്ങളുടെ സോഷ്യൽ വിവരം"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"നിങ്ങളുടെ കോൺടാക്റ്റുകളേയും സോഷ്യൽ കണക്ഷനുകളേയും സംബന്ധിച്ച വിവരങ്ങളിലേക്കുള്ള നേരിട്ടുള്ള ആക്സസ്സ്."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"കലണ്ടർ"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ്സ് ചെയ്ത് പരിഷ്ക്കരിക്കുക"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ്സ് ചെയ്യുക"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS ആക്സസ്സുചെയ്ത് പരിഷ്ക്കരിക്കുക"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS സന്ദേശങ്ങൾ കാണുക, നിയന്ത്രിക്കുക"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"ഉപയോക്തൃ നിഘണ്ടു"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ഉപയോക്തൃ നിഘണ്ടുവിലെ പദങ്ങൾ വായിക്കുകയോ എഴുതുകയോ ചെയ്യുക."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ബുക്ക്മാർക്കുകളും ചരിത്രവും"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ബുക്ക്മാർക്കുകളിലേക്കും ബ്രൗസർ ചരിത്രത്തിലേക്കുമുള്ള നേരിട്ടുള്ള ആക്സസ്സ്."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"മൈക്രോഫോണ്"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ഉപകരണ മൈക്രോഫോൺ ഉപയോഗിക്കുക"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ഓഡിയോ റെക്കോർഡ് ചെയ്യുക"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ക്യാമറ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ഉപകരണ ക്യാമറ ഉപയോഗിക്കുക"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ചിത്രങ്ങളെടുത്ത് വീഡിയോ റെക്കോർഡുചെയ്യുക"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ഫോണ്"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ഉപകരണ ടെലിഫോണി ഉപയോഗിക്കുക"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ഫോൺ വിളിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യുക"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"സെൻസറുകൾ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"സെൻസറുകളും ധരിക്കാനാകുന്നവയും ആക്സസ്സ് ചെയ്യുക"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"സെൻസറുകളിൽ നിന്നും ധരിക്കാനാവുന്ന ഉപകരണങ്ങളിൽ നിന്നും വിവരം ആക്സസ്സ് ചെയ്യുക"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"വിൻഡോ ഉള്ളടക്കം വീണ്ടെടുക്കുക"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"നിങ്ങൾ സംവദിക്കുന്ന ഒരു വിൻഡോയുടെ ഉള്ളടക്കം പരിശോധിക്കുക."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"സ്പർശനം വഴി പര്യവേക്ഷണം ചെയ്യുക ഓൺ ചെയ്യുക"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"സുഹൃത്തുക്കളുടെയും സഹപ്രവർത്തകരുടെയും ഉൾപ്പെടെ, നിങ്ങളുടെ ടാബ്ലെറ്റിൽ പരിഷ്ക്കരിക്കാനാകുന്ന ഇവന്റുകൾ ചേർക്കാനും നീക്കംചെയ്യാനും മാറ്റാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. കലണ്ടർ ഉടമകളിൽ നിന്നുള്ളതായി തോന്നുന്ന സന്ദേശങ്ങൾ അയയ്ക്കാനോ ഉടമയുടെ അറിവില്ലാതെ ഇവന്റുകൾ പരിഷ്ക്കരിക്കാനോ ഇത് അപ്ലിക്കേഷനെ അനുവദിച്ചേക്കാം."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"സുഹൃത്തുക്കളുടെതോ സഹപ്രവർത്തകരുടെതോ ഉൾപ്പെടെ, നിങ്ങളുടെ ടിവിയിൽ പരിഷ്ക്കരിക്കാനാകുന്ന ഇവന്റുകൾ ചേർക്കുന്നതിനും നീക്കംചെയ്യുന്നതിനും മാറ്റുന്നതിനും അപ്ലിക്കേഷനെ അനുവദിക്കുക. ഇത്, കലണ്ടർ ഉടമകളിൽ നിന്നും വരുന്ന സന്ദേശങ്ങൾ അയയ്ക്കുന്നതിനോ ഉടമയുടെ അറിവില്ലാതെ ഇവന്റുകൾ പരിഷ്ക്കരിക്കുന്നതിനോ അപ്ലിക്കേഷനെ അനുവദിച്ചേക്കാം."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"സുഹൃത്തുക്കളുടെയും സഹപ്രവർത്തകരുടെയും ഉൾപ്പെടെ, നിങ്ങളുടെ ഫോണിൽ പരിഷ്ക്കരിക്കാനാകുന്ന ഇവന്റുകൾ ചേർക്കാനും നീക്കംചെയ്യാനും മാറ്റാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. കലണ്ടർ ഉടമകളിൽ നിന്നുള്ളതായി തോന്നുന്ന സന്ദേശങ്ങൾ അയയ്ക്കാനോ ഉടമയുടെ അറിവില്ലാതെ ഇവന്റുകൾ പരിഷ്ക്കരിക്കാനോ ഇത് അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"പരിശോധിക്കുന്നതിനായുള്ള വ്യാജ ലൊക്കേഷൻ ഉറവിടങ്ങൾ"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"പുതിയ ലൊക്കേഷൻ ദാതാവിനെ പരിശോധിക്കാനോ ഇൻസ്റ്റാളുചെയ്യാനോ യഥാർത്ഥമല്ലാത്ത ലൊക്കേഷൻ ഉറവിടങ്ങൾ സൃഷ്ടിക്കുന്നു. ഇത് GPS അല്ലെങ്കിൽ ലൊക്കേഷൻ ദാതാക്കൾ പോലുള്ള മറ്റ് ലൊക്കേഷൻ ഉറവിടങ്ങൾ നൽകുന്ന ലൊക്കേഷനോ കൂടാതെ/അല്ലെങ്കിൽ നിലയോ അസാധുവാക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ലൊക്കേഷൻ ദാതാവിന്റെ അധിക കമാൻഡുകൾ ആക്സസ്സുചെയ്യുക"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ലൊക്കേഷൻ ദാതാവിന്റെ അധിക കമാൻഡുകൾ ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് GPS-ന്റെയോ മറ്റ് ലൊക്കേഷൻ ഉറവിടങ്ങളുടെയോ പ്രവർത്തനത്തിൽ ഇടപെടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"കൃത്യമായ ലൊക്കേഷൻ (GPS-ഉം നെറ്റ്വർക്കും അടിസ്ഥാനമാക്കിയുള്ളത്)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ഫിംഗർപ്രിന്റ് പ്രവർത്തനം റദ്ദാക്കി."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"നിരവധി തവണ ശ്രമിച്ചു. പിന്നീട് വീണ്ടും ശ്രമിക്കുക."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"വീണ്ടും ശ്രമിക്കൂ."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"സമന്വയ ക്രമീകരണങ്ങൾ റീഡുചെയ്യുക"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"നിങ്ങൾ USB സംഭരണം ഓൺ ചെയ്യുകയാണെങ്കിൽ, നിങ്ങൾ ഉപയോഗിക്കുന്ന ചില അപ്ലിക്കേഷനുകൾ USB സംഭരണം ഓഫുചെയ്യുന്നതുവരെ പ്രവർത്തനം നിർത്താനും ലഭ്യമാകാതിരിക്കാനും ഇടയുണ്ട്."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB പ്രവർത്തനം പരാജയപ്പെട്ടു"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ശരി"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"മീഡിയ ഉപകരണമായി കണക്റ്റുചെയ്തു"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ഒരു ക്യാമറയായി കണക്റ്റുചെയ്തു"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI ഉപകരണമായി കണക്റ്റുചെയ്തു"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ഇൻസ്റ്റാളറായി കണക്റ്റുചെയ്തു"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ഒരു USB ആക്സസ്സറി കണക്റ്റുചെയ്തു"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"മറ്റ് USB ഓപ്ഷനുകൾക്കായി സ്പർശിക്കുക."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB സംഭരണം ഫോർമാറ്റുചെയ്യണോ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD കാർഡ് ഫോർമാറ്റുചെയ്യണോ?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB സംഭരണത്തിൽ ശേഖരിച്ചിട്ടുള്ള നിങ്ങളുടെ എല്ലാ ഫയലുകളും മായ്ക്കും. ഈ പ്രവർത്തനം പഴയപടിയാക്കാനാവില്ല!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d മിനിറ്റ് സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> വരെ)</item>
<item quantity="one">ഒരു മിനിറ്റ് സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> വരെ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d മണിക്കൂർ സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> വരെ)</item>
<item quantity="one">ഒരു മണിക്കൂർ സമയത്തേക്ക് (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> വരെ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d മിനിറ്റ് സമയത്തേക്ക്</item>
<item quantity="one">ഒരു മിനിറ്റ് സമയത്തേക്ക്</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d മണിക്കൂർ സമയത്തേക്ക്</item>
<item quantity="one">ഒരു മണിക്കൂർ സമയത്തേക്ക്</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"നിങ്ങൾ ഇത് ഓഫാക്കും വരെ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ചുരുക്കുക"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ശല്യപ്പെടുത്തരുത്"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"പ്രവർത്തനരഹിതമായ സമയം"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"പ്രവൃത്തിദിനരാവ്"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"വാരാന്ത്യം"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ഇവന്റ്"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>, മ്യൂട്ടുചെയ്തു"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്നമുണ്ട്, ഫാക്ടറി വിവര പുനഃസജ്ജീകരണം ചെയ്യുന്നതുവരെ ഇതു അസ്ഥിരമായിരിക്കാനിടയുണ്ട്."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"നിങ്ങളുടെ ഉപകരണത്തിൽ ഒരു ആന്തരിക പ്രശ്നമുണ്ട്. വിശദാംശങ്ങൾക്കായി നിർമ്മാതാവിനെ ബന്ധപ്പെടുക."</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 47ddb37..bfd996c 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Хувийн апп-ууд"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Ажил"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Харилцагчдын хаяг"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"өөрийн харилцагчийн хаягт хандах, өөрчлөх"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"өөрийн харилцагчдад нэвтрэх"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Байршил"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"Байршилдаа хандах"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Таны нийтийн мэдээлэл"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Таны харилцагчид болон нийтийн холбооны тухай мэдээлэлд шууд хандах."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"өөрийн хуанлид хандах, өөрчлөх"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"Хуанлид нэвтрэх"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Мессеж"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"Мессеждээ хандах,өөрчлөх"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"Өөрин SMS мессежийг харж, удирдах"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Хэрэглэгчийн толь бичиг"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Хэрэглэгчийн толь бичигт үг унших,бичих"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Хавчуурга болон түүх"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Хавчуурга болон хөтчийн түүхрүү шууд хандах."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"төхөөрөмжийн микрофонийг ашиглах"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"аудио бичих"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камер"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"төхөөрөмжийн камерыг ашиглах"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"зураг авч бичлэг хийх"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Утас"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"төхөөрөмжийн телефоныг ашиглах"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"утасны дуудлага хийх болон удирдах"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Мэдрэгчүүд"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"мэдрэгч болон wearables-д хандах"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"мэдрэгч болон зүүсгэл төхөөрөмжөөс өгөгдөлд нэвтрэх"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны контентыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Хүрч танихыг асаах"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Апп нь таблет дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчд нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Апп-д таны телевиз дээрээ өөрчилж болох найз эсвэл хамтран ажиллагсдын үйл явдлыг нэмэх, устгах, өөрчлөхийг зөвшөөрдөг. Энэ нь апп-д хуанлийн үйл явдлын эзэд явуулсан мэт харагдах зурвасыг илгээхийг зөвшөөрдөг бөгөөд тухайн эздэд мэдэгдэлгүйгээр үйл явдлыг өөрчлөхийг зөвшөөрдөг."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Апп нь утсан дээр та болон таны найзууд, хамтран ажиллагсдын өөрчилж чадах үйл явдлуудыг нэмэх, хасах болон солих боломжтой. Энэ нь апп-д, календарь эзэмшигчээс ирсэн мэт харагдах мессежийг илгээх эсвэл эзэмшигчид нь мэдэгдэлгүйгээр үйл явдлуудыг өөрчлөх боломжийг олгоно."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"тест хийх байршлын эх үүсвэрийг үүсгэх"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Тестэд ашиглах хуурамч байршлын эх үүсвэрийг үүсгэх болон шинэ байршил өгөгчийг суулгах боломжтой. Ингэснээр апп нь GPS эсвэл байршил өгөгч зэрэг бусад байршлын эх үүсвэрээс ирсэн байршил болон статусыг өөрчлөх боломжтой."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"байршил нийлүүлэгчийн нэмэлт тушаалд хандах"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"Тодорхой байршил(GPS болон сүлжээнд суурилсан)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Хурууны хээний бүртгэл амжилтгүй боллоо."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Хэтэрхий олон оролдлоо. Түр хүлээгээд дахин оролдоно уу."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Дахин оролдно уу."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"синк тохиргоог унших"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Хэрэв та USB санг асуувал таны ашиглаж байга зарим апп зогсох ба та USB сангаа унтраатал ашиглах боломжгүй байж болзошгүй."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ажиллагаа бүтэлгүйтэв"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Тийм"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Медиа төхөөрөмж болон холбогдов"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Камер болгон холбов"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI төхөөрөмж хэлбэрээр холбогдсон байна"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Суулгагч болгон холбогдсон"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB төхөөрөмжид холбогдов"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Бусад USB сонголт хийх бол хүрнэ үү."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB санг форматлах уу?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD картыг форматлах уу?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Таны USB санд хадгалагдсан бүх файл арилгагдана. Энэ үйлдлийг буцаах боломжгүй!"</string>
@@ -1466,28 +1472,29 @@
<item quantity="other"> %1$d минутын турш ( <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> хүртэл)</item>
<item quantity="one">нэг минутын турш (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> хүртэл)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d цагийн турш (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> хүртэл)</item>
<item quantity="one">Нэг цагийн турш (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> хүртэл)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d минутын турш</item>
<item quantity="one">Нэг минутын турш</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<!-- String.format failed for translation -->
<!-- no translation found for zen_mode_duration_hours (3938821308277433854) -->
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Таныг унтраах хүртэл"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Хумих"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Бүү саад бол"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Сул зогсолт"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Ажлын өдрийн шөнө"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Амралтын өдөр"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Үйл явдал"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>-с хаасан"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Таны төхөөрөмжид дотоод алдаа байна.Та төхөөрөмжөө үйлдвэрээс гарсан төлөвт шилжүүлэх хүртэл таны төхөөрөмж чинь тогтворгүй байж болох юм."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Таны төхөөрөмжид дотоод алдаа байна. Дэлгэрэнгүй мэдээлэл авахыг хүсвэл үйлдвэрлэгчтэйгээ холбоо барина уу."</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 507d38c..c7a1753 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"वैयक्तिक अॅप्स"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"कार्य"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"आपल्या संपर्कांमध्ये प्रवेश करा आणि सुधारित करा"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"आपल्या संपर्कांवर प्रवेश करा"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"आपल्या स्थानामध्ये प्रवेश करा"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"आपली सामाजिक माहिती"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"आपले संपर्क आणि सामाजिक कनेक्शनविषयीच्या माहितीवर प्रत्यक्ष प्रवेश करेल."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"कॅलेंडर"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"आपल्या कॅलेंडरमध्ये प्रवेश करा आणि सुधारित करा"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"आपल्या कॅलेंडरवर प्रवेश करा"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS मध्ये प्रवेश करा आणि सुधारित करा"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS संदेश पहा आणि व्यवस्थापित करा"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"वापरकर्ता शब्दकोश"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"वापरकर्ता शब्दकोशामध्ये शब्द वाचा किंवा लिहा."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्क आणि इतिहास"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कवर आणि ब्राउझर इतिहासावर प्रत्यक्ष प्रवेश करेल."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"मायक्रोफोन"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"डिव्हाइस मायक्रोफोनचा वापर करा"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ऑडिओ रेकॉर्ड करा"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"कॅमेरा"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"डिव्हाइस कॅमेरा वापरा"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"चित्रे घ्या आणि व्हिडिओ रेकॉर्ड करा"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"डिव्हाइस टेलिफोनी वापरा"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कॉल करा आणि व्यवस्थापित करा"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सर"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"सेन्सर आणि घालण्यायोग्यमध्ये प्रवेश करा"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"सेन्सर आणि घालण्यायोग्य डिव्हाइसेसवरून डेटावर प्रवेश करा"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विंडो सामग्री पुनर्प्राप्त करा"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"आपण परस्परसंवाद करीत असलेल्या विंडोची सामग्री तपासा."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"स्पर्श करून अन्वेषण चालू करा"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"मित्र किंवा सहकर्मी यांच्यासह, आपण आपल्या टॅब्लेटवर सुधारित करू शकता असे इव्हेंट जोडण्यासाठी, काढण्यासाठी, बदलण्यासाठी अॅप ला अनुमती देते. हे कॅलेंडर मालकांकडून येत असल्याचे दिसणारे संदेश पाठविण्यासाठी किंवा मालकांच्या माहितीशिवाय इव्हेंट सुधारित करण्यासाठी अॅप ला अनुमती देऊ शकते."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"आपल्या टीव्हीवर मित्रांसह किंवा सहकर्मींसह, आपण सुधारित करू शकता अशा इव्हेंट जोडण्यासाठी, काढण्यासाठी, बदलण्यासाठी अॅपला अनुमती देते. हे कॅलेंडर मालकांकडून येत आहे असे वाटणारे किंवा मालकांना न कळविता सुधारित करण्यासाठी अॅपला अनुमती देऊ शकते."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"मित्र किंवा सहकर्मी यांच्यासह, आपण आपल्या फोनवर सुधारित करू शकता असे इव्हेंट जोडण्यासाठी, काढण्यासाठी, बदलण्यासाठी अॅप ला अनुमती देते. हे कॅलेंडर मालकांकडून येत असल्याचे दिसणारे संदेश पाठविण्यासाठी किंवा मालकांच्या माहितीशिवाय इव्हेंट सुधारित करण्यासाठी अॅप ला अनुमती देऊ शकते."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"चाचणीसाठी बनावट स्थान स्त्रोत"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"चाचणीसाठी किंवा नवीन स्थान प्रदाता स्थापित करण्यासाठी बनावट स्थान स्त्रोत तयार करा. हे GPS किंवा स्थान प्रदात्यांसारख्या स्थान आणि/किंवा अन्य स्थान स्त्रोतांकडून मिळालेली स्थिती अधिशून्य करण्यास अॅप ला अनुमती देते."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अतिरिक्त स्थान प्रदाता आदेशांवर प्रवेश करा"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अॅपला अतिरिक्त स्थान प्रदाता आदेशावर प्रवेश करण्याची अनुमती देते. हे कदाचित अॅपला GPS किंवा इतर स्थान स्त्रोत च्या ऑपरेशनमध्ये हस्तक्षेप करण्याची अनुमती देऊ शकते."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"अचूक स्थान (GPS आणि नेटवर्क-आधारित)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"फिंगरप्रिंट ऑपरेशन रद्द झाले."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"खूप प्रयत्न केले. नंतर पुन्हा प्रयत्न करा."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन्हा प्रयत्न करा."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"संकालन सेटिंग्ज वाचा"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"आपण USB संचयन चालू केल्यास, आपण वापरत असलेले काही अॅप्स थांबतील आणि आपण USB संचयन बंद करेपर्यंत अनुपलब्ध होऊ शकतात."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB कार्य अयशस्वी झाले"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ठीक"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"मीडिया हिव्हाइस म्हणून कनेक्ट केले"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"कॅमेरा म्हणून कनेक्ट केले"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"एक MIDI डिव्हाइस म्हणून कनेक्ट केले आहे"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"स्थापनकर्ता म्हणून कनेक्ट केले"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB उपसाधनावर कनेक्ट केले"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"अन्य USB पर्यायांसाठी स्पर्श करा."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB संचयनाचे स्वरूपन करायचे?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्डचे स्वरूपन करायचे?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"आपल्या USB संचयनामध्ये संचयित केलेल्या सर्व फायली मिटविल्या जातील. ही क्रिया उलट करणे शक्य नाही!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">%1$d मिनिटासाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
<item quantity="other">%1$d मिनिटांसाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d तासासाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
<item quantity="other">%1$d तासांसाठी (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> पर्यंत)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d मिनिटासाठी</item>
<item quantity="other">%d मिनिटांसाठी</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d तासासाठी</item>
<item quantity="other">%d तासांसाठी</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"आपण हे बंद करेपर्यंत"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"व्यत्यय आणू नका"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"कार्य न करण्याचा कालावधी"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"आठवड्याची शेवटची रात्र"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"आठवड्याच्या शेवटी"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इव्हेंट"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारे नि:शब्द केले"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"आपल्या डिव्हाइसमध्ये अंतर्गत समस्या आहे आणि आपला फॅक्टरी डेटा रीसेट होईपर्यंत ती अस्थिर असू शकते."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"आपल्या डिव्हाइसमध्ये अंतर्गत समस्या आहे. तपशीलांसाठी आपल्या निर्मात्याशी संपर्क साधा."</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 1900a85..d73c559 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Apl peribadi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Tempat Kerja"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kenalan"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"akses dan ubah suai kenalan anda"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"akses kenalan anda"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"akses lokasi anda"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Maklumat sosial anda"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Akses langsung ke maklumat tentang kenalan anda dan sambungan sosial."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"akses dan ubah suai kalendar anda"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"akses kalendar anda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"akses dan ubah suai SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"lihat dan urus mesej SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamus Pengguna"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Baca atau tulis perkataan dalam kamus pengguna."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Penanda halaman dan Sejarah"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Akses langsung ke penanda halaman dan sejarah penyemak imbas."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"gunakan mikrofon peranti"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"rakam audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"gunakan kamera peranti"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ambil gambar dan rakam video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"gunakan telefoni peranti"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"buat dan urus panggilan telefon"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Penderia"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"akses penderia dan item boleh dipakai"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"akses data daripada penderia dan peranti boleh dipakai"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Dapatkan kembali kandungan tetingkap"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Periksa kandungan tetingkap yang berinteraksi dengan anda."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Hidupkan Jelajah melalui Sentuhan"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Membenarkan apl menambah, mengalih keluar, mengubah acara yang anda boleh ubah suai pada tablet anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl menghantar mesej yang kelihatan seperti datang dari pemilik kalendar atau mengubah suai acara tanpa pengetahuan pemilik."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Membenarkan apl untuk menambah, mengalih keluar dan menukar acara yang boleh anda ubah suai pada TV anda, termasuk milik rakan atau rakan sekerja. Ini mungkin membenarkan apl untuk menghantar mesej yang kelihatan seperti datang daripada pemilik kalendar atau mengubah suai acara tanpa pengetahuan pemilik."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Membenarkan apl menambah, mengalih keluar, mengubah acara yang anda boleh ubah suai pada telefon anda, termasuk milik rakan atau rakan sekerja. Ini boleh membenarkan apl menghantar mesej yang kelihatan seperti datang dari pemilik kalendar atau mengubah suai acara tanpa pengetahuan pemilik."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"gunakan sumber lokasi olok-olok untuk pengujian"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Buat sumber lokasi palsu untuk menguji atau memasang pembekal lokasi baharu. Ini membenarkan apl untuk membatalkan lokasi dan/atau status yang dikembalikan oleh sumber lokasi lain seperti GPS atau pembekal lokasi."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"akses perintah tambahan pembekal lokasi"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Membenarkan apl mengakses arahan pembekal lokasi tambahan. Ini boleh membenarkan apl untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"lokasi tepat (GPS dan berasaskan rangkaian)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Pengendalian cap jari dibatalkan."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Terlalu banyak percubaan. Cuba sebentar lagi."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Cuba lagi."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"membaca tetapan penyegerakan"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Jika anda menghidupkan storan USB, sesetengah apl yang sedang anda gunakan akan terhenti dan mungkin tidak akan tersedia sehingga anda mematikan storan USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operasi USB tidak berjaya"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Disambungkan sebagai peranti media"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Disambungkan sebagai kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Disambungkan sebagai peranti MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Disambungkan sebagai pemasang"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Disambungkan kepada aksesori USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Sentuh untuk mendapatkan pilihan USB yang lain."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format storan USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Format kad SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Semua fail yang disimpan dalam storan USB anda akan dipadamkan. Tindakan ini tidak boleh diterbalikkan!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Selama %1$d minit (sehingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Selama satu minit (sehingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Selama %1$d jam (sehingga <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Selama satu jam (sehingga <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Selama %d minit</item>
<item quantity="one">Selama satu minit</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Selama %d jam</item>
<item quantity="one">Selama satu jam</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Sehingga anda matikan"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Runtuhkan"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Jangan ganggu"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Waktu gendala"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Malam selain hujung minggu"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Hujung minggu"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Acara"</string>
<string name="muted_by" msgid="6147073845094180001">"Diredam oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Terdapat masalah dalaman dengan peranti anda. Peranti mungkin tidak stabil sehingga anda membuat tetapan semula data kilang."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Terdapat masalah dalaman dengan peranti anda. Hubungi pengilang untuk mengetahui butirannya."</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 4ec9749..2bfe5cd 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ကိုယ်ပိုင် appများ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"အလုပ်"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"အဆက်အသွယ်များ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"သင့် အဆက်အသွယ်များအား ဝင်ရောက်သုံးရန်နှင့် ပြင်ဆင်ရန်"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"သင့် အဆက်အသွယ်များအား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"တည်နေရာ"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"သင်၏ တည်နေရာအား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"သင်၏ ဆိုရှယ် သတင်းအချက်အလက်"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"သင်၏ အဆက်အသွယ်များနှင့် ဆိုရှယ်လ် အဆက်အသွယ်များအား၏ သတင်းအချက်အလက်များအား တိုက်ရိုက်အသုံးပြုခွင့် ရယူရန်"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ပြက္ခဒိန်"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"သင်၏ ပြက္ခဒိန်သို့ ဝင်ရောက်သုံးရန်နှင့် ပြင်ဆင်ရန်"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"သင့်ပြက္ခဒိန်အား ဝင်ရောက်သုံးရန်"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"စာတိုစနစ်"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS အား ဝင်ရောက်သုံးရန်နှင့် ပြင်ဆင်ရန်"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS စာတိုများအား ကြည့်ပြီး စီမံရန်"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"သုံးစွဲသူ အဘိဓာန်"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"သုံးစွဲသူ အဘိဓာန်တွင် စာလုံးများ ဖတ်ရန် သို့မဟုတ် ရေးရန်"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"မှတ်တမ်း နှင့် အမှတ်အသား နေရာများ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ဘရောင်ဇာ မှတ်တမ်း နှင့် အမှတ်နေရာများအား တိုက်ရိုက် ရယူရန်"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"မိုက်ခရိုဖုန်း"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"စက်ကိရိယာ၏ မိုက်ကရိုဖုန်းအား သုံးရန်"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"အသံဖမ်းခြင်း"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ကင်မရာ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"စက်ကိရိယာ၏ ကင်မရာအား သုံးရန်"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ဓာတ်ပုံ ရိုက်ပြီးနောက် ဗွီဒီယို မှတ်တမ်းတင်ရန်"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ဖုန်း"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"စက်ကိရိယာ၏ ဖုန်းခေါ်မှုဆိုင်ရာများအား သုံးရန်"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ဖုန်းခေါ်ဆိုမှုများ ပြုလုပ်ရန်နှင့် စီမံရန်"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"အာရုံခံကိရိယာများ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"အာရုံခံကိရိယာများနှင့် wearable များအား ဝင်ရောက်သုံးရန်"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"အာရုံခံများနှင့် ဝတ်ဆင်ထားနိုင်သည့် ကိရိယာများမှ ဒေတာအား ဝင်ရောက်သုံးရန်"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ဝင်းဒိုးမှာပါရှိသည်များကို ထုတ်ယူခြင်း"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"သင် အပြန်အလှန်လုပ်နေသော ဝင်းဒိုးမှာပါရှိသည်များကို သေချာစွာ ကြည့်ရှုစစ်ဆေးပါ"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ထိတို့ခြင်းဖြင့် ရှာဖွေပေးနိုင်တာကို ဖွင့်လိုက်ပါ"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"အပလီကေးရှင်းအား သင်၏ တက်ဘလက်တွင် သူငယ်ချင်း အလုပ်ဖော်များ အပါအဝင် သင်၏ ပြောင်းလဲအဖြစ်အပျက်များအား ထည့်ခြင်း၊ ထုတ်ခြင်းအား ခွင့်ပြုရန်။ ဤခွင့်ပြုချက်သည် အပလီကေးရှင်းအား သတင်းများပို့ခြင်းကို ပြက္ခဒိန်ပိုင်ရှင်ဆီမှ လာသလို အနေဖြင့် ပေးပို့ခြင်း သို့မဟုတ် အဖြစ်အပျက်များကို ပိုင်ရှင်မသိပဲ ပြင်ဆင်နိုင်ပါသည်။"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"သင့် သူငယ်ချင်းများ သို့မဟုတ် လုပ်ဖော်ကိုင်ဖက်များ၏ လှုပ်ရှားမှုများ အပါအဝင်၊ သင့်တီဗွီရှိ လှုပ်ရှားမှုများကို ထပ်ထည့်ရန်၊ ဖယ်ထုတ်ရန်၊ ပြောင်းလဲရန် app အား ခွင့်ပြုပါ။ ဤသို့ပြုပါက ပြက္ခဒိန် ပိုင်ရှင်ဆီမှ စာတိုများ လာသကဲ့သို့ စာများပို့ရန်၊ သို့မဟုတ် ပိုင်ရှင်၏ ခွင့်ပြုချက်မရှိဘဲ လှုပ်ရှားမှုများကို ပြင်ဆင်ရန် app အား ခွင့်ပြုထားခြင်း ဖြစ်၏။"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"အပလီကေးရှင်းအား သင်၏ ဖုန်းတွင် သူငယ်ချင်း အလုပ်ဖော်များ အပါအဝင် သင်၏ ပြောင်းလဲအဖြစ်အပျက်များအား ထည့်ခြင်း၊ ထုတ်ခြင်းအား ခွင့်ပြုရန်။ ဤခွင့်ပြုချက်သည် အပလီကေးရှင်းအား သတင်းများပို့ခြင်းကို ပြက္ခဒိန်ပိုင်ရှင်ဆီမှ လာသလို အနေဖြင့် ပေးပို့ခြင်း သို့မဟုတ် အဖြစ်အပျက်များကို ပိုင်ရှင်မသိပဲ ပြင်ဆင်နိုင်ပါသည်။"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"စမ်းသပ်ရန်အတွက် တည်နေရာပုံစံတုမူရင်း"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"စမ်းသပ်ရန် သို့ နေရာပြပံ့ပို့းမှု အသစ်သွင်းရန် တည်နေရာဇစ်မြစ်အတုကို ဖန်တီးပါ။ ဤသို့လုပ်ခြင်းအားဖြင့် အပလီကေးရှင်းမှ တည်နေရာကို ကျော်ဖြတ်ပြင်ဆင်ခြင်းနှင်ူ ဂျီပီအက်စ် သို့ နေရာပြပံ့ပိုးမှုကဲ့သို့သော အခြား တည်နေရာဇစ်မြစ်များ၏ အခြေအနေကို ပြန်ပို့ပေးနိုင်မည်ဖြစ်သည်။"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"တည်နေရာပံ့ပိုးမှုညွှန်ကြားချက်အပိုအား ဝင်ရောက်ကြည့်ခြင်း"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"appအား တည်နေရာ စီမံပေးရေး ညွှန်ကြားချက် အပိုများကို ရယူခွင့်ပြုသည်။ သို့ဖြစ်၍ appသည် GPS သို့မဟုတ် အခြား တည်နေရာ ရင်းမြစ်ကို သုံးကြသူတို့၏ လုပ်ငန်းများကို ဝင်စွက်ခွင့် ပြုနိုင်သည်။"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"တည်နေရာ အတိအကျ (ဂျီပီအက်စ် နှင့် ကွန်ရက်အခြေခံ)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"လက်ဗွေရာ လုပ်ငန်း ဖျက်သိမ်းခဲ့၏။"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ကြိုးစာမှု အကြိမ်များနေ၏။ နောက်မှ ထပ်မံကြိုးစားပါ။"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ပြန်ကြိုးစားပါ"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ထပ်တူပြုအဆင်အပြင်အားဖတ်ခြင်း"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"သင် ယူအက်စ်ဘီ နဲ့ သိမ်းဆည်းမှုကို ဖွင့်လိုက်ပါက တချို့ အပလီကေးရှင်းများ က ယူအက်စ်ဘီ နဲ့ သိမ်းဆည်းမှု ပြန်ပိတ်သည်အထိ အလုပ်မလုပ် သို့ သုံးစွဲရန် ရှိနေမည် မဟုတ်ပါ"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USBဆောင်ရွက်မှုမအောင်မြင်ပါ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ကောင်းပြီ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"မီဒီယာစက်အနေဖြင့် ချိတ်ဆက်သည်"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ကင်မရာအနေဖြင့်ဆက်သွယ်ခြင်း"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI စက်ပစ္စည်းအဖြစ် ချိတ်ဆက်ထားသည်"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"installerအနေဖြင့် ချိတ်ဆက်သည်"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USBတွဲဖက်ပစ္စည်းအား ချိတ်ဆက်ထားသည်"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"အခြား USB စိတ်ကြိုက်ရွေးချယ်ခွင့်များ အတွက် တို့ထိပါ။"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB သိုလှောင်ခန်းကို ပုံစံပြန်ချမလား?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD ကဒ်ကို ပုံစံပြန်ချမလား?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"သင်၏ USB သိုလှောင်ခန်းထဲ သိုလှောင်ထားသည့် ဖိုင်အားလုံး ဖျက်ခံရမည်။ ဒီလုပ်ရပ်ကို ပြန်ပြီး ပြောင်းလဲ မရနိုင်ပါ။"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d မိနစ်တွင် (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>အထိ)</item>
<item quantity="one">တစ်မိနစ်တွင် (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> အထိ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d နာရီကြာ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>အထိ)</item>
<item quantity="one">တစ်နာရီကြာ (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> အထိ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d မိနစ်တွင်</item>
<item quantity="one">တစ်မိနစ်တွင်</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d နာရီကြာ</item>
<item quantity="one">တစ်နာရီကြာ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"သင်က ဒါကို ပိတ်မပစ်သည့် အထိ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"မနှောက်ယှက်ပါနှင့်"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ကျချိန်"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ကြားရက်ည"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"စနေ၊တနင်္ဂနွေ"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ဖြစ်ရပ်"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> အသံပိတ်သည်"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေပြီး၊ မူလစက်ရုံထုတ်အခြေအနေအဖြစ် ပြန်လည်ရယူနိုင်သည်အထိ အခြေအနေမတည်ငြိမ်နိုင်ပါ။"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"သင့်ကိရိယာအတွင်းပိုင်းတွင် ပြဿနာရှိနေ၏။ အသေးစိတ်သိရန်အတွက် ပစ္စည်းထုတ်လုပ်သူအား ဆက်သွယ်ပါ။"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 623df7b..013782f 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personlige apper"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Jobb"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"få tilgang til og endre kontakene dine"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"få tilgang til kontaktene dine"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"få tilgang til posisjonen din"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Den sosiale informasjonen din"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkte tilgang til informasjon om kontaktene og de sosiale forbindelsene dine."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenderen"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"få tilgang til og endre kalenderen din"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tilgang til kalenderen din"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"få tilgang til og endre SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"se og administrer SMS-meldinger"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Brukerordlisten"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Les eller skriv inn ord i brukerordlisten."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bokmerkene og loggen"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direkte tilgang til bokmerker og nettleserloggen."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofonen"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"bruke mikrofonen på enheten"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"spill inn lyd"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kameraet"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"bruke kameraet på enheten"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder og ta opp video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"bruke enhetstelefoni"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ring og administrer anrop"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"få tilgang til sensorer og hapå-teknologi"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"få tilgang til data fra sensorer og enheter du har på deg"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hent innholdet i vinduet"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspiser innholdet i et vindu du samhandler med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Slå på for Berøringsutforsking"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Lar appen legge til, fjerne og endre aktiviteter du kan redigere på nettbrettet ditt, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen sender meldinger som ser ut som om de kommer fra kalendereiere eller endre aktiviteter uten at eierne vet om det."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Gjør at appen kan legge til, fjerne eller endre aktiviteter du kan endre på TV-en, herunder aktivitetene til venner eller kollegaer. Dette kan føre til at appen kan sende meldinger som viser seg å komme fra eiere av kalendere eller at den kan moderere hendelser uten at eieren vet om det."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Lar appen legge til, fjerne og endre aktiviteter du kan redigere på telefonen din, inkludert aktiviteter for venner eller kolleger. Dette kan gjøre at appen sender meldinger som ser ut som om de kommer fra kalendereiere eller endre aktiviteter uten at eierne vet om det."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"lage simulerte posisjonskilder for testing"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Opprette fiktive posisjonskilder for testing eller installere en ny posisjonsangiver. Dette gjør at appen kan overstyre posisjonen eller statusen som rapporteres av ekte posisjonskilder, som for eksempel GPS eller posisjonsangivere."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"bruke ekstra posisjonskommandoer"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Appen gis tillatelse til å bruke ekstra kommandoer fra posisjonsleverandører. Dette kan gi appen tillatelse til å påvirke bruken av GPS eller andre posisjonskilder."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"presis posisjon (GPS- og nettverksbasert)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeravtrykk-operasjonen ble avbrutt."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"For mange forsøk. Prøve på nytt senere."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Prøv igjen."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lese synkroniseringsinnstillinger"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du aktiverer USB-lagring, virker ikke enkelte av appene du bruker lenger, og de kan forbli utilgjengelige inntil du deaktiverer USB-lagringen."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-handling mislyktes"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilkoblet som medieenhet"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Tilkoblet som kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Koblet til som MIDI-enhet"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Tilkoblet som installasjonsprogram"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Koblet til et USB-tilbehør"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Trykk for få andre USB-alternativer."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatere USB-lagr.?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vil du formatere SD-kortet?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle filer som er lagret på USB-lagringen blir slettet. Denne handlingen kan ikke angres."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">I %1$d minutter (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">I 1 minutt (til <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">For %1$d timer (til <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">I 1 time (til <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">I %d minutter</item>
<item quantity="one">I 1 minutt</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">I %d timer</item>
<item quantity="one">I 1 time</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Inntil du slår av funksjonen"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"«Ikke forstyrr»"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Nedetid"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Hverdagskveld"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Helg"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Aktivitet"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> har kuttet lyden"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Det har oppstått et internt problem på enheten din, og den kan være ustabil til du tilbakestiller den til fabrikkdata."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Det har oppstått et internt problem på enheten din. Ta kontakt med produsenten for mer informasjon."</string>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 8a72ae2..31cb81b 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"व्यक्तिगत अनुप्रयोगहरू"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"काम"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"सम्पर्कहरू"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"तपाईँको सम्पर्कहरूका पहुँच गरी परिमार्जन गर्नुहोस्"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"तपाईँको सम्पर्कमा पहुँच"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"तपाईँको स्थान पहुँच गर्नुहोस्"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"तपाईँको सामाजिक सूचना"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"तपाईँको सम्पर्कहरू र सामाजिक जडानहरूको बारेको जानकारीमा सिधा पहुँच पुर्याउनुहोस्।"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"पात्रो"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"तपाईँको पात्रोलाई पहुँच गरी परिमार्जन गर्नुहोस्"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"तपाईँको पात्रोमा पहुँच"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS पहुँच गरी परिमार्जन गर्नुहोस्"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS सन्देशहरू हेर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"प्रयोगकर्ता शब्दकोश"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"प्रयोगकर्ता शब्दकोशमा शब्दहरू पढ्नुहोस् वा लेख्नुहोस्।"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"बुकमार्कहरू र इतिहास"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"बुकमार्कहरू र ब्राउजर इतिहासमा सिधा पहुँच।"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"माइक्रोफोन"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"यन्त्र माइक्रोफोन प्रयोग गर्नुहोस्"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"अडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"क्यामेरा"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"यन्त्र क्यामेरा प्रयोग गर्नुहोस्"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"तस्वीर तथा भिडियो रेकर्ड गर्नुहोस्"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"फोन"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"यन्त्र टेलिफोनी प्रयोग गर्नुहोस्"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"फोन कलहरू गर्नुहोस् र व्यवस्थापन गर्नुहोस्"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"सेन्सरहरू"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"सेन्सर र पहिरनयोग्यहरू पहुँच गर्नुहोस्"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"सेंसर र पहिरनयोग्य यन्त्रहरूबाट डेटा पहुँच"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"विन्डो सामग्रीको पुनःबहाली गर्नुहोस्।"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"तपाईँको अन्तरक्रिया भइरहेको विन्डोको सामग्रीको निरीक्षण गर्नुहोस्।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"छोएर गरिने खोजलाई सुचारु गर्नुहोस्"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ती साथीहरू वा सहकर्मीहरूसहितका घटनाहरू जसलाई तपाईँले आफ्नो ट्याब्लेटमा परिमार्जन गर्न सक्ने अनुमति अनुप्रयोगलाई दिन्छ। यसले अनुप्रयोगलाई सन्देशहरू जुन पात्राको मालिकहरूबाट आएका देखिनेलाई पठाउने वा मालिकहरूको ज्ञान बेगर घटनालाई परिमार्जन गर्ने अनुमित दिन्छ।"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"अनुप्रयोगलाई अनुमति दिन्छ थप्न, हटाउन र घटनाहरू, तपाईँका साथीहरू वा सहकर्मी लगायत, परिर्वतन गर्न, जुन तपाईँले तपाईँको TV मा परिमार्जन गर्न सक्नुहुन्छ। यसले अनुप्रयोगलाई सन्देशहरू पठाउन अनुमति दिन सक्छ जुन पात्रोको मालिकबाट आएको झैं देखिन सक्छ, वा मालिकको ज्ञान बिना घटनाहरू परिमार्जन गर्न सक्छ।"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ती साथीहरू वा सहकर्मीहरूसहित तपाईँको फोनका घटनाहरू जसलाई थप्न, हटाउन र परिवर्तन गर्न अनुप्रयोगलाई अनुमति दिन्छ। पात्रो मालिकबाट देखा परेका वा मालिकको ज्ञान बिना परिवर्तन भएका घटनाहरू सन्देश पठाउन यसले अनुप्रयोगलाई अनुमति दिन सक्छ।"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"परीक्षणको लागि स्थान स्रोतहरू मक गर्नुहोस्"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"परीक्षणको लागि मक स्थान स्रोतहरू सिर्जना गर्नुहोस् वा नयाँ स्थान प्रदायक स्थापना गर्नुहोस्। यसले अनुप्रयोगलाई स्थानमा ओभरराइड गर्दछ र/वा स्थिति अन्य स्थान स्रोतहरू जस्तै GPS वा स्थान प्रदायकबाट फर्काइएका।"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"अधिक स्थान प्रदायक आदेशहरू पहुँच गर्नुहोस्"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अनुप्रयोगलाई अतिरिक्त स्थान प्रदायक आदेशहरू पहुँच गर्न अनुमति दिन्छ। यो अनुप्रयोगलाई GPS वा अन्य स्थान स्रोतहरूको संचालन साथै हस्तक्षेप गर्न अनुमति दिन सक्छ।"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"सटिक स्थान (GPS र नेटवर्क आधारित)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"औँठाछाप सञ्चालन रद्द गरियो।"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"धेरै प्रयासहरू। केहि समय पछि पुन: प्रयास गर्नुहोला"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"पुन: प्रयास गर्नुहोला।"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"समीकरण सेटिङहरू पढ्नुहोस्"</string>
@@ -1048,12 +1048,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"यदि तपाईँले USB भण्डारण खोल्नु भयो भने तपाईँले प्रयोग गरिरहनु भएका केही अनुप्रयोगहरू रोकिने छन् र तपाईँले USB भण्डारण बन्द नगरेसम्म अनुपलब्ध हुन सक्छन्।"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB संचालन असफल"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ठिक छ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"मिडिया उपकरणको रूपमा जडित"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"क्यामेराको रूपमा जडान भएको"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI यन्त्रको रूपमा जडान गरियो"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"एउटा स्थापनकर्ताको रूपमा जोडिएको छ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB सहायकमा जोडिएको छ"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"अन्य USB विकल्पहरूको लागि टच गर्नुहोस्।"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB भण्डारणलाई फर्म्याट गर्न चाहनु हुन्छ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD कार्ड फर्म्याट गर्ने?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"तपाईंको USBमा सङ्ग्रह भएका सबै फाइलहरू मेटिने छन्। यो कार्य उल्टाउन सकिँदैन!"</string>
@@ -1472,30 +1478,31 @@
<item quantity="other"> %1$d मिनेटको लागि (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> सम्म)</item>
<item quantity="one">एक मिनेटको लागि (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> सम्म)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other"> %1$d घण्टाको लागि (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> सम्म)</item>
<item quantity="one">एक घण्टाको लागि (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> सम्म)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d मिनेटको लागि</item>
<item quantity="one">एक मिनेटको लागि</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d घण्टाको लागि</item>
<item quantity="one">एक घण्टाको लागि</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"तपाईँले यसलाई बन्द नगरेसम्म"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त पार्नुहोस्"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"अवरोध नपुर्याउँनुहोस्"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"डाउनटाइम"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"हरेक हप्तादिनको राति"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"शनिवार"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"घटना"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा मौन गरिएको"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ, र तपाईंले फ्याक्ट्री डाटा रिसेट नगर्दासम्म यो अस्थिर रहन्छ।"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"तपाईंको यन्त्रसँग आन्तरिक समस्या छ। विवरणहरूको लागि आफ्नो निर्मातासँग सम्पर्क गर्नुहोस्।"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ad2a492..034d66c 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Persoonlijke apps"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Werk"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacten"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"toegang krijgen tot uw contacten en wijzigingen aanbrengen"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot uw contacten"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"toegang krijgen tot uw locatie"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Uw sociale informatie"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Rechtstreeks toegang krijgen tot informatie over uw contacten en sociale connecties."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"toegang krijgen tot uw agenda en wijzigingen aanbrengen"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"toegang krijgen tot uw agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"toegang krijgen tot sms en wijzigingen aanbrengen"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"sms\'jes bekijken en beheren"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Gebruikerswoordenboek"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Woorden lezen of schrijven in gebruikerswoordenboek."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bladwijzers en geschiedenis"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Rechtstreeks toegang krijgen tot bladwijzers en browsergeschiedenis."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfoon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"microfoon van apparaat gebruiken"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"audio opnemen"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"camera van apparaat gebruiken"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"foto\'s maken en video opnemen"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"telefoonfuncties van apparaat gebruiken"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"bellen en telefoontjes beheren"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensoren"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"toegang krijgen tot sensoren en wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"toegang krijgen tot gegevens van sensoren en wearable-apparaten"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Inhoud van vensters ophalen"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"De inhoud inspecteren van een venster waarmee u interactie heeft."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Verkennen via aanraking inschakelen"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw tablet, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u op uw tv kunt aanpassen, inclusief afspraken van vrienden of collega\'s. Met deze toestemming zou de app berichten kunnen verzenden die afkomstig lijken te zijn van agenda-eigenaren of afspraken kunnen aanpassen zonder medeweten van de eigenaar."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Hiermee kan de app afspraken toevoegen, verwijderen en wijzigen die u kunt bewerken op uw telefoon, inclusief afspraken van vrienden of collega\'s. Zo kan de app berichten verzenden die afkomstig lijken te zijn van agenda-eigenaren, of afspraken aanpassen zonder medeweten van de eigenaar."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"neplocatiebronnen voor test"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Voorbeeld-locatiebronnen maken voor tests of een nieuwe locatieprovider instellen. Hiermee kan de app de locatie en/of status overschrijven van andere locatiebronnen zoals GPS of locatieproviders."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"toegang tot extra opdrachten van locatieaanbieder"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van GPS of andere locatiebronnen te verstoren."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"precieze locatie (GPS- en netwerkgebaseerd)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Vingerafdrukbewerking geannuleerd."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Te veel pogingen. Probeer het later opnieuw."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Probeer het opnieuw."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"synchronisatie-instellingen lezen"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Als u USB-opslag inschakelt, worden bepaalde apps die u gebruikt, gestopt en zijn deze mogelijk pas weer beschikbaar wanneer u USB-opslag uitschakelt."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-bewerking mislukt"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Gekoppeld als media-apparaat"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Gekoppeld als camera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Verbonden als MIDI-apparaat"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Gekoppeld als installatieprogramma"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Aangesloten op een USB-accessoire"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Raak aan voor andere USB-opties."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB-opslag formatteren?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD-kaart formatteren?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle bestanden die in uw USB-opslag zijn opgeslagen, worden gewist. Deze actie kan niet ongedaan worden gemaakt."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d minuten (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Eén minuut (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d uur (tot <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Eén uur (tot <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d minuten</item>
<item quantity="one">Eén minuut</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d uur</item>
<item quantity="one">Eén uur</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Totdat u dit uitschakelt"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Samenvouwen"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Niet storen"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Downtime"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Doordeweekse avond"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evenement"</string>
<string name="muted_by" msgid="6147073845094180001">"Gedempt door <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Er is een intern probleem met uw apparaat. Het apparaat kan instabiel zijn totdat u het apparaat terugzet naar de fabrieksinstellingen."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Er is een intern probleem met uw apparaat. Neem contact op met de fabrikant voor meer informatie."</string>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 0e9658b..89799c6 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -129,6 +129,7 @@
<string-array name="wfcOperatorErrorNotificationMessages">
</string-array>
<string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string>
+ <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ਬੰਦ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"ਤਰਜੀਹੀ ਸੈਲਿਊਲਰ"</string>
@@ -219,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ਨਿੱਜੀ ਐਪਸ"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ਕੰਮ"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚੋ ਅਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਨੂੰ ਐਕਸੈਸ ਕਰੋ"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"ਆਪਣੇ ਸਥਾਨ ਤੱਕ ਪਹੁੰਚੋ"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ਤੁਹਾਡੀ ਸਮਾਜਿਕ ਜਾਣਕਾਰੀ"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਅਤੇ ਸਮਾਜਿਕ ਕਨੈਕਸ਼ਨਾਂ ਬਾਰੇ ਜਾਣਕਾਰੀ ਤੱਕ ਸਿੱਧੀ ਪਹੁੰਚ।"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ਕੈਲੰਡਰ"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"ਆਪਣੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚੋ ਅਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ਆਪਣੇ ਕੈਲੰਡਰ ਦੀ ਐਕਸੈਸ ਕਰੋ"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS ਤੱਕ ਪਹੁੰਚੋ ਅਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰੋ"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS ਸੁਨੇਹੇ ਵੇਖੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"ਉਪਭੋਗਤਾ ਸ਼ਬਦਕੋਸ਼ ਵਿੱਚ ਸ਼ਬਦ ਪੜ੍ਹੋ ਜਾਂ ਲਿਖੋ।"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"ਬੁੱਕਮਾਰਕਸ ਅਤੇ ਇਤਿਹਾਸ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"ਬੁੁੱਕਮਾਰਕਾਂ ਅਤੇ ਬ੍ਰਾਊਜ਼ਰ ਇਤਿਹਾਸ ਤੱਕ ਸਿੱਧੀ ਪਹੁੰਚ।"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ਮਾਈਕ੍ਰੋਫੋਨ"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ਡਿਵਾਈਸ ਮਾਈਕ੍ਰੋਫੋਨ ਵਰਤੋ"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ਔਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"ਕੈਮਰਾ"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ਡਿਵਾਈਸ ਕੈਮਰਾ ਵਰਤੋ"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ਤਸਵੀਰਾਂ ਖਿੱਚੋ ਅਤੇ ਵੀਡੀਓ ਰਿਕਾਰਡ ਕਰੋ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ਫੋਨ"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ਡਿਵਾਈਸ ਟੈਲੀਫੋਨੀ ਵਰਤੋ"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰੋ ਅਤੇ ਉਹਨਾਂ ਨੂੰ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"ਸੰੰਵੇਦਕ"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"ਸੰਵੇਦਕ ਅਤੇ ਪਹਿਨਣਯੋਗ ਤੱਕ ਪਹੁੰਚੋ"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ਸੈਂਸਰ ਅਤੇ ਪਾਉਣਯੋਗ ਡਿਵਾਈਸਾਂ ਤੋਂ ਡੇਟਾ ਨੂੰ ਐਕਸੈਸ ਕਰੋ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ਵਿੰਡੋ ਸਮੱਗਰੀ ਮੁੜ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ਇੱਕ ਵਿੰਡੋ ਦੀ ਸਮੱਗਰੀ ਦੀ ਜਾਂਚ ਕਰੋ, ਜਿਸ ਨਾਲ ਤੁਸੀਂ ਇੰਟਰੈਕਟ ਕਰ ਰਹੇ ਹੋ।"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ਐਕਸਪਲੋਰ ਬਾਇ ਟਚ ਚਾਲੂ ਕਰੋ"</string>
@@ -334,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ਐਪ ਨੂੰ ਉਹ ਇਵੈਂਟਾਂ ਜੋੜਨ, ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਹਨਾਂ ਨੂੰ ਤੁਸੀਂ ਆਪਣੀ ਟੈਬਲੇਟ ਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰ ਸਕਦੇ ਹੋ, ਦੋਸਤਾਂ ਜਾਂ ਸਹਿਯੋਗੀਆਂ ਦੀਆਂ ਇਵੈਂਟਾਂ ਸਮੇਤ। ਇਹ ਐਪ ਨੂੰ ਮਾਲਕ ਦੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਉਹ ਸੁਨੇਹੇ, ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪਦੇ ਹਨ, ਭੇਜਣ ਦੀ ਜਾਂ ਇਵੈਂਟਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ਐਪ ਨੂੰ ਉਹ ਇਵੈਂਟਾਂ ਜੋੜਨ, ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਹਨਾਂ ਨੂੰ ਤੁਸੀਂ ਆਪਣੇ TV ਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰ ਸਕਦੇ ਹੋ, ਦੋਸਤਾਂ ਜਾਂ ਸਹਿਯੋਗੀਆਂ ਦੀਆਂ ਇਵੈਂਟਾਂ ਸਮੇਤ। ਇਹ ਐਪ ਨੂੰ ਮਾਲਕ ਦੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਉਹ ਸੁਨੇਹੇ, ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪਦੇ ਹਨ, ਭੇਜਣ ਦੀ ਜਾਂ ਇਵੈਂਟਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ਐਪ ਨੂੰ ਉਹ ਇਵੈਂਟਾਂ ਜੋੜਨ, ਹਟਾਉਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ, ਜਿਹਨਾਂ ਨੂੰ ਤੁਸੀਂ ਆਪਣੇ ਫੋਨ ਤੇ ਸੰਸ਼ੋਧਿਤ ਕਰ ਸਕਦੇ ਹੋ, ਦੋਸਤਾਂ ਜਾਂ ਸਹਿਯੋਗੀਆਂ ਦੀਆਂ ਇਵੈਂਟਾਂ ਸਮੇਤ। ਇਹ ਐਪ ਨੂੰ ਮਾਲਕ ਦੀ ਜਾਣਕਾਰੀ ਤੋਂ ਬਿਨਾਂ ਉਹ ਸੁਨੇਹੇ, ਜੋ ਕੈਲੰਡਰ ਮਾਲਕਾਂ ਤੋਂ ਆਉਂਦੇ ਜਾਪਦੇ ਹਨ, ਭੇਜਣ ਦੀ ਜਾਂ ਇਵੈਂਟਾਂ ਸੰਸ਼ੋਧਿਤ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ਜਾਂਚ ਲਈ ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸ੍ਰੋਤ"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ਜਾਂਚ ਲਈ ਜਾਂ ਇੱਕ ਨਵਾਂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ ਇੰਸਟੌਲ ਕਰਨ ਲਈ ਨਕਲੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸ੍ਰੋਤ ਬਣਾਓ। ਇਹ ਐਪ ਨੂੰ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਅਤੇ/ਜਾਂ ਹੋਰਾਂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸ੍ਰੋਤਾਂ ਵੱਲੋਂ ਵਾਪਸ ਕੀਤੀ ਸਥਿਤੀ ਨੂੰ ਓਵਰਰਾਈਡ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ ਜਿਵੇਂ GPS ਜਾਂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ।"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ਵਾਧੂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ਐਪ ਨੂੰ ਵਾਧੂ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ GPS ਜਾਂ ਹੋਰ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸ੍ਰੋਤਾਂ ਦੇ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ਨਿਯਤ ਨਿਰਧਾਰਿਤ ਸਥਾਨ (GPS ਅਤੇ ਨੈਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
@@ -437,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ਫਿੰਗਰ"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ਬਹੁਤ ਸਾਰੀਆਂ ਕੋਸ਼ਿਸ਼ਾਂ. ਬਾਅਦ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ਸਿੰਕ ਸੈਟਿੰਗਾਂ ਪੜ੍ਹੋ"</string>
@@ -1041,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ਜੇਕਰ ਤੁਸੀਂ USB ਸਟੋਰੇਜ ਚਾਲੂ ਕਰਦੇ ਹੋ, ਤਾਂ ਕੁਝ ਐਪਸ, ਜੋ ਤੁਸੀਂ ਵਰਤ ਰਹੇ ਹੋ, ਬੰਦ ਹੋ ਜਾਣਗੇ ਅਤੇ ਅਣਉਪਲਬਧ ਕੀਤੇ ਜਾ ਸਕਦੇ ਹਨ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ USB ਸਟੋਰੇਜ ਬੰਦ ਨਹੀਂ ਕਰਦੇ।"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ਓਪਰੇਸ਼ਨ ਅਸਫਲ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ਠੀਕ"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ਇੱਕ ਮੀਡੀਆ ਡਿਵਾਈਸ ਦੇ ਤੌਰ ਤੇ ਕਨੈਕਟ ਕੀਤਾ"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ਇੱਕ ਕੈਮਰੇ ਦੇ ਤੌਰ ਤੇ ਕਨੈਕਟ ਕੀਤਾ"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"ਇੱਕ MIDI ਡਿਵਾਈਸ ਦੇ ਤੌਰ ਤੇ ਕਨੈਕਟ ਕੀਤਾ"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ਇੱਕ ਇੰਸਟੌਲਰ ਦੇ ਤੌਰ ਤੇ ਕਨੈਕਟ ਕੀਤਾ"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ਇੱਕ USB ਐਕਸੈਸਰੀ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ਹੋਰ USB ਚੋਣਾਂ ਲਈ ਛੋਹਵੋ।"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ਕੀ USB ਸਟੋਰੇਜ ਨੂੰ ਫੌਰਮੈਟ ਕਰਨਾ ਹੈ?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ਕੀ SD ਕਾਰਡ ਨੂੰ ਫੌਰਮੈਟ ਕਰਨਾ ਹੈ?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ਤੁਹਾਡੀ USB ਸਟੋਰੇਜ ਵਿੱਚ ਸਟੋਰ ਕੀਤੀਆਂ ਸਾਰੀਆਂ ਫਾਈਲਾਂ ਮਿਟਾ ਦਿੱਤੀਆਂ ਜਾਣਗੀਆਂ। ਇਹ ਕਿਰਿਆ ਉਲਟਾਈ ਨਹੀਂ ਜਾ ਸਕਦੀ!"</string>
@@ -1078,22 +1085,14 @@
<string name="ext_media_init_action" msgid="8317198948634872507">"ਸੈੱਟਅੱਪ"</string>
<string name="ext_media_unmount_action" msgid="1121883233103278199">"ਬਾਹਰ ਕੱਢੋ"</string>
<string name="ext_media_browse_action" msgid="8322172381028546087">"ਐਕਸਪਲੋਰ ਕਰੋ"</string>
- <!-- no translation found for ext_media_missing_title (620980315821543904) -->
- <skip />
- <!-- no translation found for ext_media_missing_message (5761133583368750174) -->
- <skip />
- <!-- no translation found for ext_media_move_specific_title (1471100343872375842) -->
- <skip />
- <!-- no translation found for ext_media_move_title (1022809140035962662) -->
- <skip />
- <!-- no translation found for ext_media_move_success_title (8575300932957954671) -->
- <skip />
- <!-- no translation found for ext_media_move_success_message (4199002148206265426) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_title (7613189040358789908) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_message (1978096440816403360) -->
- <skip />
+ <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> ਲਾਪਤਾ"</string>
+ <string name="ext_media_missing_message" msgid="5761133583368750174">"ਇਸ ਡਿਵਾਈਸ ਨੂੰ ਮੁੜ ਸੰਮਿਲਿਤ ਕਰੋ"</string>
+ <string name="ext_media_move_specific_title" msgid="1471100343872375842">"<xliff:g id="NAME">%s</xliff:g> ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="ext_media_move_title" msgid="1022809140035962662">"ਡੇਟਾ ਮੂਵ ਕਰ ਰਿਹਾ ਹੈ"</string>
+ <string name="ext_media_move_success_title" msgid="8575300932957954671">"ਮੂਵ ਸੰਪੂਰਣ"</string>
+ <string name="ext_media_move_success_message" msgid="4199002148206265426">"ਡੇਟਾ ਨੂੰ <xliff:g id="NAME">%s</xliff:g> ਵਿੱਚ ਮੂਵ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="ext_media_move_failure_title" msgid="7613189040358789908">"ਡੇਟਾ ਨੂੰ ਮੂਵ ਨਹੀਂ ਕਰ ਸਕਿਆ"</string>
+ <string name="ext_media_move_failure_message" msgid="1978096440816403360">"ਡੇਟਾ ਮੂਲ ਸਥਾਨ \'ਤੇ ਛੱਡਿਆ ਗਿਆ"</string>
<string name="activity_list_empty" msgid="1675388330786841066">"ਕੋਈ ਮੇਲ ਖਾਂਦੀਆਂ ਗਤੀਵਿਧੀਆਂ ਨਹੀਂ ਮਿਲੀਆਂ।"</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"ਰੂਟ ਮੀਡੀਆ ਆਊਟਪੁਟ"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"ਇੱਕ ਐਪਲੀਕੇਸ਼ਨ ਨੂੂੰ ਹੋਰਾਂ ਬਾਹਰੀ ਡਿਵਾਈਸਾਂ ਲਈ ਮੀਡੀਆ ਆਊਟਪੁਟ ਰੂਟ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
@@ -1466,32 +1465,38 @@
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪੈਟਰਨ ਅਨਲੌਕ ਕਰਨ ਲਈ ਪੁੱਛੋ"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ਅਨਪਿਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"ਤੁਹਾਡੇ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਇੰਸਟੌਲ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="package_updated_device_owner" msgid="8856631322440187071">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਪਡੇਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"ਤੁਹਾਡੇ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"ਬੈਟਰੀ ਸਮਰੱਥਾ ਨੂੰ ਬਿਹਤਰ ਸਹਾਇਤਾ ਕਰਨ ਲਈ, ਬੈਟਰੀ ਸੇਵਰ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦਾ ਪ੍ਰਦਰਸ਼ਨ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ ਵਾਈਬ੍ਰੇਸ਼ਨ, ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾਵਾਂ ਅਤੇ ਜ਼ਿਆਦਾਤਰ ਪਿਛੋਕੜ ਡਾਟਾ ਨੂੰ ਸੀਮਿਤ ਕਰਦਾ ਹੈ। ਈਮੇਲ, ਮੈਸੇਜਿੰਗ ਅਤੇ ਹੋਰ ਐਪਸ, ਜੋ ਸਿੰਕਿੰਗ ਤੇ ਨਿਰਭਰ ਹਨ, ਉਹ ਉਦੋਂ ਤੱਕ ਅਪਡੇਟ ਨਹੀਂ ਕੀਤੇ ਜਾ ਸਕਦੇ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਉਹਨਾਂ ਨੂੰ ਖੋਲ੍ਹਦੇ ਨਹੀਂ।\n\nਬੈਟਰੀ ਸੇਵਰ ਆਟੋਮੈਟਿਕਲੀ ਬੰਦ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਚਾਰਜ ਹੋ ਰਹੀ ਹੁੰਦੀ ਹੈ।"</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
<item quantity="one">%1$d ਮਿੰਟਾਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ) </item>
<item quantity="other">%1$d ਮਿੰਟਾਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d ਘੰਟਿਆਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ)</item>
<item quantity="other">%1$d ਘੰਟਿਆਂ ਤੱਕ (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> ਤੱਕ)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d ਮਿੰਟਾਂ ਤੱਕ</item>
<item quantity="other">%d ਮਿੰਟਾਂ ਤੱਕ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d ਘੰਟਿਆਂ ਤੱਕ</item>
<item quantity="other">%d ਘੰਟਿਆਂ ਤੱਕ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ਨਸ਼ਟ ਕਰੋ"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ਡਾਊਨਟਾਈਮ"</string>
- <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"ਵੀਕਨਾਈਟਸ"</string>
- <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"ਵੀਕੈਂਡ"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ਵੀਕਨਾਈਟ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ਹਫ਼ਤੇ ਦਾ ਅੰਤਲਾ ਦਿਨ"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ਇਵੈਂਟ"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ਵੱਲੋਂ ਮਿਊਟ ਕੀਤਾ ਗਿਆ"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਹੈ ਅਤੇ ਇਹ ਅਸਥਿਰ ਹੋ ਸਕਦੀ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਫੈਕਟਰੀ ਡਾਟਾ ਰੀਸੈਟ ਨਹੀਂ ਕਰਦੇ।"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਨਾਲ ਇੱਕ ਅੰਦਰੂਨੀ ਸਮੱਸਿਆ ਸੀ। ਵੇਰਵਿਆਂ ਲਈ ਆਪਣੇ ਨਿਰਮਾਤਾ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 8aa5eaa..6fc75c1 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplikacje osobiste"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Praca"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"dostęp do kontaktów i ich modyfikowanie"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostęp do kontaktów"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokalizacja"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"dostęp do informacji o Twojej lokalizacji"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Twoje informacje społecznościowe"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Bezpośredni dostęp do informacji o Twoich kontaktach i powiązaniach społecznościowych."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendarz"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"otwieranie i modyfikowanie Twojego kalendarza"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostęp do kalendarza"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"dostęp do SMS-ów i ich modyfikowanie"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"przeglądanie SMS-ów i zarządzanie nimi"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Słownik użytkownika"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Odczytywanie lub zapisywanie słów w słowniku użytkownika."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Zakładki i historia"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Bezpośredni dostęp do zakładek i historii przeglądarki."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"używanie mikrofonu urządzenia"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"nagrywanie dźwięku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Aparat"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"używanie aparatu fotograficznego urządzenia"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"robienie zdjęć i nagrywanie filmów"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"korzystanie z funkcji telefonu urządzenia"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"nawiązywanie połączeń telefonicznych i zarządzanie nimi"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Czujniki"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"dostęp do czujników i akcesoriów do noszenia"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"dostęp do danych z czujników i urządzeń do noszenia"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pobieranie zawartości okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Sprawdzanie zawartości okna, z którego korzystasz."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Włączenie czytania dotykiem"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Pozwala aplikacji na dodawanie, usuwanie i zmienianie zdarzeń, które możesz modyfikować na swoim tablecie, w tym pochodzących od znajomych i współpracowników. Aplikacja z tym uprawnieniem może wysyłać wiadomości, które wyglądają jak pochodzące od właścicieli kalendarza, a także modyfikować zdarzenia bez wiedzy właścicieli."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Pozwala aplikacji dodawać, usuwać i zmieniać wydarzenia, które możesz modyfikować na telewizorze, w tym wydarzenia należące do znajomych lub współpracowników. Może to pozwolić aplikacji na wysyłanie wiadomości wyglądających jak utworzone przez właścicieli kalendarza lub modyfikować wydarzenia bez wiedzy ich właścicieli."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Pozwala aplikacji na dodawanie, usuwanie i zmienianie zdarzeń, które możesz modyfikować na swoim telefonie, w tym pochodzących od znajomych i współpracowników. Aplikacja z tym uprawnieniem może wysyłać wiadomości, które wyglądają jak pochodzące od właścicieli kalendarza, a także modyfikować zdarzenia bez wiedzy właścicieli."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"udawanie źródeł położenia dla testów"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Tworzenie pozorowanych źródeł lokalizacji dla potrzeb testów lub instalacji nowego dostawcy informacji o lokalizacji. Aplikacje z tym uprawnieniem mogą zastąpić lokalizację i/lub stan zwracany przez inne źródła lokalizacji, takie jak GPS lub dostawcy danych o lokalizacji."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"dostęp do dodatkowych poleceń dostawcy informacji o lokalizacji"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Pozwala aplikacji na dostęp do dodatkowych poleceń dostawcy informacji o lokalizacji. Aplikacje z tym uprawnieniem mogą wpływać na działanie GPS-u lub innych źródeł lokalizacji."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"dokładna lokalizacja (na podstawie sygnału GPS i sieci)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Odczyt odcisku palca został anulowany."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Zbyt wiele prób. Spróbuj ponownie później."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Spróbuj ponownie."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"czytanie ustawień synchronizacji"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Po włączeniu nośnika USB niektóre używane aplikacje zostaną zatrzymane i mogą być niedostępne do chwili jego wyłączenia."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operacja USB zakończona niepowodzeniem"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Podłączono urządzenie multimedialne"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Podłączono jako aparat."</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Podłączono jako urządzenie MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Podłączono jako nośnik instalacyjny."</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Podłączono akcesorium USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dotknij, aby wyświetlić inne opcje USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Czy sformatować nośnik USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Czy sformatować kartę SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Wszystkie pliki zapisane na nośniku USB zostaną usunięte. Tej czynności nie można cofnąć."</string>
@@ -1486,36 +1492,37 @@
<item quantity="other">Przez %1$d minuty (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Przez minutę (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="few">Przez %1$d godziny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">Przez %1$d godzin (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Przez %1$d godziny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Przez godzinę (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="few">Przez %d minuty</item>
<item quantity="many">Przez %d minut</item>
<item quantity="other">Przez %d minuty</item>
<item quantity="one">Przez minutę</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="few">Przez %d godziny</item>
<item quantity="many">Przez %d godzin</item>
<item quantity="other">Przez %d godziny</item>
<item quantity="one">Przez godzinę</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dopóki nie wyłączysz"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Zwiń"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Nie przeszkadzać"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Powiadomienia wyłączone"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noc poza weekendem"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Wydarzenie"</string>
<string name="muted_by" msgid="6147073845094180001">"Ściszone przez: <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"W Twoim urządzeniu wystąpił problem wewnętrzny. Może być ono niestabilne, dopóki nie przywrócisz danych fabrycznych."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"W Twoim urządzeniu wystąpił problem wewnętrzny. Skontaktuj się z jego producentem, by otrzymać szczegółowe informacje."</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index a7f9eb9..b30d3cf 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicações pessoais"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"aceder e modificar os contactos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"aceder aos contactos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Localização"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"aceder à sua localização"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"As suas informações sociais"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acesso direto às informações sobre os seus contactos e ligações sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendário"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"aceder e modificar o calendário"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"aceder ao calendário"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"aceder e modificar SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ver e gerir mensagens SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionário do Utilizador"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escrever palavras no dicionário do utilizador."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcadores e Histórico"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acesso direto aos marcadores e histórico do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"utilizar o microfone do dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmara"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"utilizar a câmara do dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotografias e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telemóvel"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"utilizar a telefonia do dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerir chamadas"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"aceder a sensores e a dispositivos de vestir"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"aceder aos dados de sensores e dispositivos de vestir"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Obter conteúdo da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo de uma janela com a qual está a interagir."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar Através do Toque"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite que a aplicação adicione, remova e altere eventos que pode modificar no tablet, incluindo eventos relacionados com amigos ou colegas de trabalho. Pode permitir que a aplicação envie mensagens que parecem ser enviadas pelos proprietários dos calendários ou modifique eventos sem o conhecimento do proprietário."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite à aplicação adicionar, remover ou alterar eventos que pode modificar na TV, incluindo os que pertencem a amigos ou a colegas de trabalho. Isto pode permitir à aplicação enviar mensagens que parecem vir de proprietários do calendário ou modificar eventos sem o conhecimento do proprietário."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite que a aplicação adicione, remova e altere eventos que pode modificar no telemóvel, incluindo eventos relacionados com amigos ou colegas de trabalho. Pode permitir que a aplicação envie mensagens que parecem ser enviadas pelos proprietários dos calendários ou modifique eventos sem o conhecimento do proprietário."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fontes de localização fictícias para teste"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Criar fontes de localização fictícias para fins de teste ou instalar um novo fornecedor de localização. Isto permite que a aplicação substitua a localização e/ou o estado devolvido por outras fontes de localização como, por exemplo, GPS ou fornecedores de localização."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"aceder a comandos adicionais do fornecedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que a aplicação aceda a comandos adicionais do fornecedor de localização. Esta opção pode permitir que a aplicação interfira com o funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"localização exata (baseada no GPS e na rede)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Demasiadas tentativas. Tente novamente mais tarde."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler definições de sincronização"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se ativar a memória de armazenamento USB, algumas aplicações que estiver a utilizar serão paradas e poderão ficar indisponíveis até desativar a memória de armazenamento USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operação USB sem êxito"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ligado como um dispositivo multimédia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ligado como uma câmara"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Ligado como um dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ligado como um instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ligado a um acessório USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toque para ver outras opções USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatar unidade de armazenamento USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatar cartão SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Todos os ficheiros armazenados na sua USB de armazenamento serão apagados. Não é possível reverter a ação!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Durante %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante um minuto (até às <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Durante %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Durante uma hora (até às <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Durante %d minutos</item>
<item quantity="one">Durante um minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Durante %d horas</item>
<item quantity="one">Durante uma hora</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Até que o utilizador desative"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Reduzir"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Não incomodar"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Período de inatividade"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Dias da semana à noite"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fim de semana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Som desativado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Existe um problema interno no seu dispositivo e pode ficar instável até efetuar uma reposição de dados de fábrica."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Existe um problema interno no seu dispositivo. Contacte o fabricante para obter mais informações."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index a64b183..b841b46 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Apps pessoais"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabalho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"acessar e modificar seus contatos"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acessar seus contatos"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"acessar seu local"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Suas informações sociais"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acesso direto às informações de seus contatos e conexões sociais."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Agenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"acessar e modificar sua agenda"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"acessar sua agenda"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"acessar e modificar SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ver e gerenciar mensagens SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicionário do usuário"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Ler ou escrever as palavras do dicionário do usuário."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Favoritos e histórico"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acesso direto aos favoritos e histórico do navegador."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"usar o microfone do dispositivo"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"gravar áudio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Câmera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"usar a câmera do dispositivo"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"tirar fotos e gravar vídeos"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefone"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"usar a telefonia do dispositivo"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"fazer e gerenciar chamadas telefônicas"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensores"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"acessar sensores e wearables"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"acessar dados de sensores e dispositivos wearable"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar cont. da janela"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecionar o conteúdo da janela com que você está interagindo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ativar Explorar por toque"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite que o app adicione, remova e altere eventos que você pode modificar em seu tablet, incluindo os de amigos e colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem ser de autoria do proprietário do calendário, ou modifique eventos sem conhecimento do proprietário."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite que o app adicione, remova ou altere eventos que podem ser modificados na sua TV, incluindo eventos de amigos ou colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem vir dos proprietários de agendas ou modifique eventos sem o conhecimento dos proprietários."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite que o app adicione, remova e altere eventos que você pode modificar em seu telefone, incluindo os de amigos e colegas de trabalho. Isso pode permitir que o app envie mensagens que parecem ser de autoria do proprietário do calendário, ou modifique eventos sem conhecimento do proprietário."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"fontes de locais fictícios para teste"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Criar fontes de localização simuladas para testar ou instalar um novo provedor de localização. Isso permite que o app substitua a localização e/ou o status retornado por outras fontes de localização, como o GPS ou provedores de localização."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"acessar comandos extras do provedor de localização"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"localização precisa (GPS e com base na rede)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operação de impressão digital cancelada."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Excesso de tentativas. Tente novamente mais tarde."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tente novamente."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ler as configurações de sincronização"</string>
@@ -897,7 +897,7 @@
<string name="whichHomeApplication" msgid="4307587691506919691">"Selecione um app de Página inicial"</string>
<string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Usar %1$s como Página inicial"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Usar como padrão para esta ação."</string>
- <string name="use_a_different_app" msgid="8134926230585710243">"Usar um app diferente"</string>
+ <string name="use_a_different_app" msgid="8134926230585710243">"Usar outro app"</string>
<string name="clearDefaultHintMsg" msgid="3252584689512077257">"Padrão claro em Configurações do sistema > Apps > Baixado."</string>
<string name="chooseActivity" msgid="7486876147751803333">"Escolher uma ação"</string>
<string name="chooseUsbActivity" msgid="6894748416073583509">"Selecione um app para o dispositivo USB"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Se você ativar o armazenamento USB, alguns apps que estão em uso serão interrompidos e poderão ficar indisponíveis até você desativar o armazenamento USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Falha na operação do USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectado como disp. de mídia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectado como câmera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Conectado como dispositivo MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectados como um instalador"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectado a um acessório USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Toque para obter outras opções USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatar armaz. USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formatar cartão SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Todos os arquivos armazenados em sua unidade armazenamento USB serão apagados. Não é possível reverter essa ação."</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Por %1$d minutos (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Por %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Por %1$d horas (até às <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Por %d minutos</item>
<item quantity="other">Por %d minutos</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Por %d horas</item>
<item quantity="other">Por %d horas</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Até você desativar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Recolher"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Não perturbe"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Tempo de inatividade"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Durante a semana à noite"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fim de semana"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Evento"</string>
<string name="muted_by" msgid="6147073845094180001">"Som desativado por <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Há um problema interno com seu dispositivo. Ele pode ficar instável até que você faça a redefinição para configuração original."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Há um problema interno com seu dispositivo. Entre em contato com o fabricante para saber mais detalhes."</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index e77e85f..385b8fd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -221,27 +221,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplicații personale"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Serviciu"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Persoane de contact"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"accesează și modifică persoanele de contact"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accesează persoanele de contact"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Locație"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"accesează locația dvs."</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informaţiile dvs. sociale"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acces direct la informaţii despre persoanele de contact și conexiunile dvs. sociale."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendarul"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"accesează și modifică calendarul"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesează calendarul"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"accesează și modifică mesajele SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"vede și gestionează mesajele SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Dicţionarul utilizatorului"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Citește sau scrie cuvinte în dicționarul utilizatorului."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Marcajele și Istoricul"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Acces direct la marcaje și la istoricul navigării."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Microfonul"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"folosește microfonul dispozitivului"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"înregistrează conținut audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera foto"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"folosește camera foto a dispozitivului"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiază și înregistrează videoclipuri"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"folosește serviciul de telefonie al dispozitivului"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"inițiază și gestionează apeluri telefonice"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzori"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"accesează senzorii și accesoriile inteligente"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accesează datele de la senzori și dispozitivele portabile"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperează conținutul ferestrei"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspectează conținutul unei ferestre cu care interacționați."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activează funcția Explorați prin atingere"</string>
@@ -336,8 +336,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteţi modifica pe tabletă, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteți modifica pe televizor, inclusiv pe cele ale prietenilor sau ale colegilor. Cu această permisiune, aplicația poate să trimită mesaje care par că vin din partea proprietarilor calendarului sau să modifice evenimentele fără cunoștința acestora."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Permite aplicației să adauge, să elimine și să modifice evenimentele pe care le puteţi modifica pe telefon, inclusiv cele ale prietenilor sau colegilor dvs. În acest fel, aplicația poate trimite mesaje care par să vină de la proprietarii calendarelor sau să modifice evenimentele fără ştirea proprietarilor."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"surse de locaţii pentru testare"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Creează surse de locaţii pentru testare sau instalează un furnizor de locaţie nou. Acest lucru permite aplicației să înlocuiască locaţia și/sau starea returnate de alte surse de locaţii, cum ar fi GPS sau furnizorii de locaţii."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"accesare comenzi suplimentare ale furnizorului locaţiei"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"locaţia exactă (bazată pe reţea și GPS)"</string>
@@ -439,6 +437,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operațiunea privind amprenta a fost anulată."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Prea multe încercări. Încercați din nou mai târziu."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Încercați din nou."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"citire setări sincronizare"</string>
@@ -1049,12 +1049,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Dacă activaţi stocarea USB, unele aplicații pe care le utilizaţi în prezent se vor opri și pot să nu fie disponibile până când dezactivaţi stocarea USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operaţie USB nereuşită"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Conectat ca dispozitiv media"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Conectat ca aparat foto"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Conectat ca dispozitiv MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Conectat ca program de instalare"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Conectat la un accesoriu USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Atingeţi pentru alte opţiuni USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Format. stoc. USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formataţi cardul SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Toate fişierele stocate în stocarea USB vor fi şterse. Această acţiune nu poate fi anulată!"</string>
@@ -1476,33 +1482,34 @@
<item quantity="other">Timp de %1$d de minute (până la <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Timp de un minut (până la <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="few">Timp de %1$d ore (până la <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Timp de %1$d de ore (până la <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Timp de o oră (până la <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="few">Timp de %d minute</item>
<item quantity="other">Timp de %d de minute</item>
<item quantity="one">Timp de un minut</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="few">Timp de %d ore</item>
<item quantity="other">Timp de %d de ore</item>
<item quantity="one">Timp de o oră</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Până la dezactivare"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Restrângeți"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Nu deranja"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Inactivitate"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Nopțile din zilele lucrătoare"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Eveniment"</string>
<string name="muted_by" msgid="6147073845094180001">"Dezactivate de <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"A apărut o problemă internă pe dispozitiv, iar acesta poate fi instabil până la revenirea la setările din fabrică."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"A apărut o problemă internă pe dispozitiv. Pentru detalii, contactați producătorul."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 9270d76..8810e44 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Персональные приложения"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Работа"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакты"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"доступ к контактам и их изменение"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"доступ к контактам"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"доступ к данным о местоположении"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Информация о моих контактах"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Прямой доступ к информации о моих контактах и социальных связях."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календарь"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"доступ к календарю и его изменение"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"доступ к календарю"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"доступ к SMS и их изменение"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"просмотр SMS-сообщений и управление ими"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Пользовательский словарь"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Чтение слов в пользовательском словаре или их запись."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Закладки и история"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Прямой доступ к закладкам и истории браузера."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"доступ к микрофону устройства"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"запись аудио"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"доступ к камере устройства"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"фото- и видеосъемка"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"доступ к телефонной сети"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"осуществление телефонных звонков и управление ими"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"доступ к датчикам и носимым устройствам"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"доступ к данным с датчиков и носимых устройств"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Читать содержимое окна."</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Распознавать содержимое окна, в котором вы находитесь."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Включать аудиоподсказки."</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Приложение сможет добавлять, удалять и изменять мероприятия, доступные для редактирования на вашем планшетном ПК, включая мероприятия, добавленные другими людьми. Так приложение сможет рассылать сообщения от имени владельца календаря и изменять мероприятия без его ведома."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Добавление, удаление и изменение сохраненных на телевизоре мероприятий, к которым у вас есть доступ для записи, в том числе добавленных друзьями или коллегами. Приложение сможет отправлять сообщения от имени владельцев календарей, а также изменять мероприятия без ведома владельца."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Приложение сможет добавлять, удалять и изменять мероприятия, доступные для редактирования на вашем телефоне, включая мероприятия, добавленные другими людьми. Так приложение сможет рассылать сообщения от имени владельца календаря и изменять мероприятия без его ведома."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"Установка фиктивного местоположения для отладки"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Приложение сможет создавать фиктивные местоположения для тестирования или установки нового источника геоданных и переопределять местоположение и/или статус, возвращаемые другими источниками, такими как система GPS."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"Доступ к дополнительным командам управления источниками геоданных"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Доступ к дополнительным командам управления источниками геоданных и вмешательство в работу системы GPS или других источников геоданных."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"Точное местоположение (на основе сети и сигналов GPS)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Операция с отпечатком отменена."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Слишком много попыток. Повторите позже."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Повторите попытку."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"Просмотр настроек синхронизации"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"При подключении USB-накопителя некоторые приложения могут прекратить работу и оставаться недоступными до его отключения."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Ошибка при подключении USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ОК"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Подключен как устройство хранения данных"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Подключен как камера"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Подключено как MIDI-устройство"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Подключен как установщик"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB-устройство подключено"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Нажмите, чтобы открыть список опций."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Отформатировать USB-накопитель?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Отформатировать SD-карту?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Все файлы, сохраненные на USB-накопителе, будут удалены. Это действие невозможно отменить."</string>
@@ -1486,36 +1492,37 @@
<item quantity="many">%1$d минут (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d минут (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d час (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d часа (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d часов (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d часов (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d минута</item>
<item quantity="few">%d минуты</item>
<item quantity="many">%d минут</item>
<item quantity="other">%d минут</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d час</item>
<item quantity="few">%d часа</item>
<item quantity="many">%d часов</item>
<item quantity="other">%d часов</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Пока я не отключу"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Свернуть"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Не беспокоить"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Режим оповещения"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Будний вечер"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Выходные"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Мероприятие"</string>
<string name="muted_by" msgid="6147073845094180001">"Звук отключен приложением \"<xliff:g id="THIRD_PARTY">%1$s</xliff:g>\""</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Произошла внутренняя ошибка, и устройство может работать нестабильно, пока вы не выполните сброс настроек."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Произошла внутренняя ошибка. Обратитесь к производителю устройства за подробными сведениями."</string>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 0939f33..9ff419d 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"පුද්ගලික යෙදුම්"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"කාර්යාලය"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"සම්බන්ධතා"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"ඔබේ සම්බන්ධතා ප්රවේශ කරන්න සහ වෙනස් කරන්න"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ඔබේ සම්බන්ධතාවලට පිවිසෙන්න"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ස්ථානය"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"ඔබගේ ස්ථානය ප්රවේශ කිරීම"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ඔබගේ සමාජයීය තොරතුරු"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"ඔබගේ සම්බන්ධතා සහ සාමාජ සම්බන්ධයන් ගැන තොරතුරු වෙත ඍජු ප්රවේශය."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"දින දර්ශනය"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"ඔබේ දින දර්ශනය ප්රවේශ කරන්න සහ වෙනස් කරන්න"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ඔබේ දින දර්ශනයට පිවිසෙන්න"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"කෙටි පණිවිඩ"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"කෙටි පණිවුඩ ප්රවේශ කිරීම සහ වෙනස් කිරීම"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS පණිවිඩ බැලීම සහ කළමනාකරණය කිරීම"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"පරිශීලක ශබ්ද කෝෂය"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"පරිශීලක ශබ්ද කෝෂයේ වචන කියවීම සහ ලිවිම."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"පිටුසන් සහ ඉතිහාසය"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"පිටුසන් සහ බ්රව්සර ඉතිහාසය වෙත ඍජු ප්රවේශය."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"මයික්රොෆෝනය"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"උපාංග මයික්රෝෆෝනය භාවිතය"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ශ්රව්ය පටිගත කරන්න"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"කැමරාව"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"උපාංග කැමරා භාවිතය"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"පින්තූර ගැනීම සහ වීඩියෝ පටිගත කිරීම"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"දුරකථනය"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"උපාංග දුරකථන භාවිතය"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"දුරකථන ඇමතුම් සිදු කිරීම සහ කළමනාකරණය කිරීම"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"සංවේදක"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"සංවේදක සහ පැළඳිය හැකි උපාංග ප්රවේශ කරන්න"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"සංවේදක සහ පැළඳිය හැකි උපාංගවලින් දත්තවලට පිවිසෙන්න"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"කවුළු අන්න්තර්ගතය ලබාගන්න"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ඔබ අන්තර්ක්රියාකාරී වන කවුළුවේ අන්තර්ගතය පරීක්ෂා කරන්න."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ස්පර්ශයෙන් ගවේෂණය සක්රිය කරන්න"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"යහළුවන් හෝ එකට-වැඩකරන්නන් ඇතුළත්ව ඔබට ටැබ්ලටයේ වෙනස් කළ හැකි සිද්ධි එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමඟින් දින දර්ශන හිමිකරුවන්ගෙන් පණිවිඩ යවන පරිදි මෙන් මවාපෑමට හෝ හිමිකරුගේ අනුදැනුමකින් තොරව සිද්ධි වෙනස් කිරීමට යෙදුමට අවසර ලැබේ."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"මිතුරන්ගේ හෝ එක්ව කටයුතු කරන්නන්ගේද ඇතුළුව උපාංගය මත ඔබට වෙනස් කිරීමට හැකි සිද්ධි එකතු කිරීමට, ඉවත් කිරීමට සහ වෙනස් කිරීමට යෙදුමට අවසර දේ. මෙමඟින් යෙදුම හට දින දසුන් හිමිකරු ලෙස පෙනී සිටිමින් පණිවිඩ යැවීම, හිමිකරුගේ අනුදැනුම නොමැතිව සිද්ධි වෙනස් කිරීම කළ හැක."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ඔබගේ යහළුවන් හෝ සමකාලීනයන් ඇතුළත් ඔබගේ දුරකථනයේ ඔබට වෙනස් කළ හැකි සිදු වීම් එකතු කිරීමට, ඉවත් කිරීමට, වෙනස් කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් දින දර්ශන හිමිකරුවන්ගෙන් පැමිණෙන සේ පෙනෙන පණිවිඩ යැවීමට හෝ හිමිකරුගේ දැනුමකින් තොරව සිදුවීම් වෙනස් කිරීමට යෙදුමට අවසර දෙයි."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"පරීක්ෂණ සඳහා ආදර්ශ ස්ථාන මූලාශ්ර"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"පරීක්ෂණයට ව්යාජ ස්ථාන මූලාශ්ර සාදන්න හෝ නව ස්ථාන සැපයුම්කරුවෙකු ස්ථාපනය කරන්න. GPS හෝ ස්ථාන සැපයුම්කරුවන් ආදී වෙනත් ස්ථාන මූලාශ්ර විසින් ලබා දෙන ස්ථානය සහ/හෝ තත්වය ප්රතිස්ථාපනය කිරීමට යෙදුමට මෙය අවසර දෙයි."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"අමතර ස්ථාන සැපයුම්කරු විධාන වෙත ප්රවේශ වීම"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ස්ථානය සපයන අමතර අණ වලට ප්රවේශය කිරීමට යෙදුමට අවසර දෙන්න. GPS ක්රියාවන් හෝ වෙනත් ස්ථාන මූලාශ්ර සමඟ මැදිහත් වීමට මෙයින් යෙදුමට ඉඩ ලැබේ."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"නිවැරදි ස්ථානය (GPS සහ ජාලය පදනම් කරගත්)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ඇඟිලි සලකුණු මෙහෙයුම අවලංගු කරන ලදී."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"උත්සාහයන් ඉතා වැඩි ගණනකි. කරුණාකර පසුව නැවත උත්සාහ කරන්න."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"නැවත උත්සාහ කරන්න."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"සමමුහුර්ත සැකසීම් කියවන්න"</string>
@@ -1044,12 +1044,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"ඔබ USB ආචයනය සක්රිය නම්, ඔබ භාවිතා කරන සමහර යෙදුම් නැවතීම සහ ඔබ USB ආචයනය අක්රිය කරන තුරු නොතිබේවී."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB ක්රියාවලිය අසාර්ථකයි"</string>
<string name="dlg_ok" msgid="7376953167039865701">"හරි"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"මාධ්ය උපාංගයක් ලෙස සම්බන්ධිතයි"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"කැමරාවක් ලෙස සම්බන්ධ කර ඇත"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI උපාංගයක් ලෙස සම්බන්ධ වන ලදි"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ස්ථාපිතයක් ලෙස සම්බන්ධයි"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB මෙවලමකට සම්බන්ධිතයි"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"අනෙක් USB විකල්පය සඳහා ස්පර්ශ කරන්න."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB ආචයනය ෆෝමැට් කරන්නද?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD පත ෆෝමැට් කරන්නද?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ඔබගේ USB ආචයනයේ ඇති සියලුම ගොනු මැකී යනු ඇත. මෙම ක්රියාව ආපසු හැරවිය නොහැක!"</string>
@@ -1468,30 +1474,31 @@
<item quantity="one">මිනිත්තු %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
<item quantity="other">මිනිත්තු %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">පැය %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
<item quantity="other">පැය %1$d ක් සඳහා (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> තෙක්)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">මිනිත්තු %d ක් සඳහා</item>
<item quantity="other">මිනිත්තු %d ක් සඳහා</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">පැය %d ක් සඳහා</item>
<item quantity="other">පැය %d ක් සඳහා</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"ඔබ මෙය අක්රිය කරන තුරු"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"හකුළන්න"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"බාධා නොකරන්න"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"බිඳවැටුම් කාලය"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Weeknight"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"සති අන්තය"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"සිදුවීම"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> විසින් නිශ්ශබ්ද කරන ලදි"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"ඔබේ උපාංගය සමගින් ගැටලුවක් ඇති අතර, ඔබේ කර්මාන්තශාලා දත්ත යළි සකසන තෙක් එය අස්ථායි විය හැකිය."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"ඔබේ උපාංගය සමගින් අභ්යන්තර ගැටලුවක් ඇත. විස්තර සඳහා ඔබේ නිෂ්පාදක අමතන්න."</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 41d8409..261701d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Osobné aplikácie"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Práca"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"prístup ku kontaktom a ich úprava"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"prístup k vašim kontaktom"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"prístup k polohe"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Vaše sociálne informácie"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Priamy prístup k informáciám o vašich kontaktoch a sociálnych prepojeniach."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"prístup ku kalendáru a jeho úprava"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"prístup ku kalendáru"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"prístup k správam SMS a ich úprava"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"zobrazenie a správa správ SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Používateľský slovník"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Čítanie a zadávanie slov v používateľskom slovníku."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Záložky a história"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Priamy prístup k záložkám a histórii prehliadača."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofón"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"používanie mikrofónu zariadenia"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"zaznamenávanie zvuku"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparát"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"používanie fotoaparátu zariadenia"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotenie a zaznamenávanie videí"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefón"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"používanie telefonických služieb zariadenia"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonovanie a správa hovorov"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Senzory"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"prístup k senzorom a nositeľným zariadeniam"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"prístup k údajom zo senzorov a nositeľných zariadení"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Načítať obsah okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preskúmať obsah okna s ktorým interagujete."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Zapnúť funkciu Preskúmanie dotykom"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Umožňuje aplikácii pridávať, odstraňovať alebo meniť udalosti, ktoré môžete v tablete upravovať, a to vrátane udalostí priateľov a spolupracovníkov. Toto povolenie umožňuje aplikácii odosielať správy, ktoré budú zdanlivo prichádzať od vlastníkov kalendára, alebo upravovať udalosti bez vedomia vlastníkov."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Umožňuje aplikácii pridať, odstrániť a meniť udalosti, ktoré môžete upraviť vo svojom televízore, vrátane udalostí priateľov a spolupracovníkov. Toto povolenie môže aplikácii umožniť posielať správy, ktoré vyzerajú ako správy od vlastníkov kalendárov, alebo upravovať udalosti bez vedomia vlastníkov."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Umožňuje aplikácii pridávať, odstraňovať alebo meniť udalosti, ktoré môžete v telefóne upravovať, a to vrátane udalostí priateľov a spolupracovníkov. Toto povolenie umožňuje aplikácii odosielať správy, ktoré budú zdanlivo prichádzať od vlastníkov kalendára, alebo upravovať udalosti bez vedomia vlastníkov."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"simulácia zdrojov polohy na účely testovania"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Vytváranie simulovaných zdrojov polohy na testovanie alebo inštalácia nového poskytovateľa informácií o polohe. Aplikácii to umožní nahradiť polohu a stav, ktoré vracajú iné zdroje informácií o polohe, ako sú napríklad systém GPS alebo poskytovatelia informácií o polohe."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"prístup k ďalším príkazom poskytovateľa polohy"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Umožňuje aplikácii pristupovať k ďalším príkazom poskytovateľa informácií o polohe. Aplikácii to môže umožniť zasahovať do činnosti systému GPS alebo iných zdrojov informácií o polohe."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"zistiť presnú polohu (pomocou GPS a siete)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operácia týkajúca sa odtlačku prsta bola zrušená"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Príliš veľa pokusov. Skúste to znova neskôr."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Skúste to znova"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítať nastavenia synchronizácie"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ak zapnete úložisko USB, dôjde k zastaveniu niektorých používaných aplikácií. Tieto aplikácie pravdepodobne nebudú k dispozícii až do vypnutia úložiska USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operácia rozhrania USB bola neúspešná"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Pripojené ako mediálne zariadenie"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Pripojené ako fotoaparát"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Pripojené ako zariadenie MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Pripojené ako inštalátor"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Pripojené k periférnemu zariadeniu USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dotykom zobrazíte ďalšie možnosti USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formátovať ukladací priestor USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formátovať kartu SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Všetky súbory uložené v ukladacom priestore USB budú vymazané. Táto akcia sa nedá vrátiť späť!"</string>
@@ -1486,36 +1492,37 @@
<item quantity="other">%1$d minút (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Minútu (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="few">%1$d hodiny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d hodiny (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d hodín (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Hodinu (do <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="few">%d minúty</item>
<item quantity="many">%d minúty</item>
<item quantity="other">%d minút</item>
<item quantity="one">Minútu</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="few">%d hodiny</item>
<item quantity="many">%d hodiny</item>
<item quantity="other">%d hodín</item>
<item quantity="one">Hodinu</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokým túto funkciu nevypnete"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Zbaliť"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Nerušiť"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Doba pokoja"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noc pracovného dňa"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Víkend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Udalosť"</string>
<string name="muted_by" msgid="6147073845094180001">"Stlmené aplikáciou <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Vo vašom zariadení došlo k internému problému. Môže byť nestabilné, kým neobnovíte jeho továrenské nastavenia."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Vo vašom zariadení došlo k internému problému. Ak chcete získať podrobné informácie, obráťte sa na jeho výrobcu."</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 234bd6a..13b2d16 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Osebne aplikacije"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Služba"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Stiki"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"dostop do stikov in njihovo spreminjanje"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostop do stikov"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"dostop do vaše lokacije"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Podatki v družabnih omrežjih"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Neposreden dostop do podatkov o stikih in družabnih povezav."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Google Koledar"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"dostop do koledarja in njegovo spreminjanje"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"dostop do koledarja"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"dostop do SMS-jev in njihovo spreminjanje"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ogled in upravljanje sporočil SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Uporabniški slovar"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Branje besed iz uporabniškega slovarja ali pisanje besed vanj."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Zaznamki in zgodovina"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Neposreden dostop do zaznamkov in zgodovine brskalnika."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"uporaba mikrofona naprave"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"snemanje zvoka"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Fotoaparat"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"uporaba fotoaparata naprave"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotografiranje in snemanje videoposnetkov"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"uporaba telefonije naprave"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"opravljanje in upravljanje telefonskih klicev"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Tipala"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"dostop do tipal in nosljivih naprav"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"dostop do podatkov tipal in nosljivih naprav"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pridobivanje vsebine okna"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preverite vsebino okna, ki ga uporabljate."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklop raziskovanja z dotikom"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Aplikaciji omogoča dodajanje, odstranjevanje in spreminjanje dogodkov, ki jih je mogoče spreminjati v tabličnem računalniku, vključno z dogodki prijateljev in sodelavcev. S tem lahko aplikacija pošilja sporočila, za katera je videti, da jih pošiljajo lastniki koledarjev, ali spreminjajo dogodke brez vednosti lastnikov."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Aplikaciji dovoljuje dodajanje, odstranjevanje in spreminjanje dogodkov, ki jih lahko spremenite v televizorju, vključno z dogodki prijateljev in sodelavcev. S tem lahko aplikacija pošilja sporočila, ki so videti, kot da jih pošiljajo lastniki koledarjev, ali spreminja dogodke brez vednosti lastnikov."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Aplikaciji omogoča dodajanje, odstranjevanje in spreminjanje dogodkov, ki jih je mogoče spreminjati v telefonu, vključno z dogodki prijateljev in sodelavcev. S tem lahko aplikacija pošilja sporočila, za katera je videti, da jih pošiljajo lastniki koledarjev, ali spreminjajo dogodke brez vednosti lastnikov."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"simulirani viri lokacije za preverjanje"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Ustvarjanje simuliranih virov lokacije za preverjanje ali namestitev novega ponudnika lokacije. S tem lahko aplikacija preglasi lokacijo in/ali stanje, ki ga vrnejo drugi viri lokacije, kot so GPS in ponudniki lokacij."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"dostopanje do ukazov ponudnika dodatnih lokacij"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Aplikaciji omogoča dostop do dodatnih ukazov ponudnika lokacij. S tem lahko aplikacija moti delovanje sistema GPS ali drugih virov lokacije."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"natančna lokacija (na podlagi podatkov GPS in omrežja)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Dejanje s prstnim odtisom je bilo preklicano."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Preveč poskusov. Poskusite znova pozneje."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Poskusite znova."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"branje nastavitev sinhronizacije"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Če vklopite pomnilnik USB, se bodo nekatere aplikacije, ki jih uporabljate, ustavile in ne bodo na voljo, dokler ne izklopite pomnilnika USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operacija v pomnilniku USB ni uspela"</string>
<string name="dlg_ok" msgid="7376953167039865701">"V redu"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Povezan kot predstavnostna naprava"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Povezan kot fotoaparat"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Povezano kot naprava MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Povezan kot namestitveni program"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Priključen na dodatek USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Dotaknite se za prikaz drugih možnosti za USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Ali želite formatirati pomnilnik USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Želite formatirati kartico SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Vse datoteke, shranjene v v pomnilniku USB, bodo izbrisane. Tega dejanja ni mogoče razveljaviti!"</string>
@@ -1486,36 +1492,37 @@
<item quantity="few">%d minute (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%d minut (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d uro (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="two">%1$d uri (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d ure (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d ur (do <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d minuto</item>
<item quantity="two">%d minuti</item>
<item quantity="few">%d minute</item>
<item quantity="other">%d minut</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d uro</item>
<item quantity="two">%d uri</item>
<item quantity="few">%d ure</item>
<item quantity="other">%d ur</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Dokler tega ne izklopite"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Strni"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne moti"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Čas nedelovanja"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Večer med tednom"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Konec tedna"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Dogodek"</string>
<string name="muted_by" msgid="6147073845094180001">"Izklop zvoka: <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Vaša naprava ima notranjo napako in bo morda nestabilna, dokler je ne ponastavite na tovarniške nastavitve."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Vaša naprava ima notranjo napako. Če želite več informacij, se obrnite na proizvajalca."</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index ea04ad8..627bca6d 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -129,6 +129,7 @@
<string-array name="wfcOperatorErrorNotificationMessages">
</string-array>
<string name="wfcSpnFormat" msgid="8211621332478306568">"%s"</string>
+ <string name="wfcDataSpnFormat" msgid="1118052028767666883">"%s"</string>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Çaktivizuar"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferohet Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"Preferohet rrjeti celular"</string>
@@ -219,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Aplikacione personale"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Puna"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktet"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"të qaset dhe të modifikojë kontaktet e tua"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"qasu te kontaktet e tua"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"të qaset te vendondodhja jote"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informacionet e tua sociale"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Qasje e drejtpërdrejtë në informacionin e kontakteve të tua dhe lidhjeve sociale."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"të qaset dhe të modifikojë kalendarin tënd"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasu te kalendari yt"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"të qaset dhe të modifikojë mesazhet SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"shiko dhe menaxho mesazhet SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Fjalori i përdoruesit"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Të lexojë ose të shkruajë fjalë në fjalorin e përdoruesit."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Faqeshënuesit dhe historiku"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Qasje të drejtpërdrejtë në faqet e ruajtura si dhe historinë e shfletuesit."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofoni"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"të përdorë mikrofonin e pajisjes"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"regjistro audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"të përdorë kamerën e pajisjes"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"bëj fotografi dhe regjistro video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefoni"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"të përdorë telefoninë e pajisjes"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"kryej dhe menaxho telefonata"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorët"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"të qaset te sensorët dhe pajisjet që vishen"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"qasu te të dhënat nga sensorët dhe pajisjet që vishen"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gjej përmbajtjen e dritares"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekto përmbajtjen e dritares me të cilën po bashkëvepron."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizo \"Eksploro me prekje\""</string>
@@ -334,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Lejon aplikacionin të shtojë, të heqë ose të ndryshojë ngjarje që mund t\'i modifikosh në tabletin tënd, përfshirë ato të miqve apo kolegëve të punës. Kjo mund ta lejojë aplikacionin të dërgojë mesazhe që duket se vijnë nga zotëruesit e kalendarëve, ose të modifikojë ngjarje pa dijeninë e zotëruesve."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Lejon aplikacionin të shtojë, të heqë ose të ndryshojë ngjarje që mund t\'i modifikosh në televizorin tënd, përfshirë ato të miqve apo kolegëve të punës. Kjo mund ta lejojë aplikacionin të dërgojë mesazhe që duket se vijnë nga zotëruesit e kalendarëve, ose të modifikojë ngjarje pa dijeninë e zotëruesve."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Lejon aplikacionin të shtojë, heqë, ndryshojë ngjarje që mund t\'i modifikosh në telefonin tënd, përfshi ato të miqve ose kolegëve. Kjo mund ta lejojë aplikacionin të dërgojë mesazhe që duken se vijnë nga zotëruesit e kalendarëve, ose të modifikojë ngjarje pa dijeninë e zotëruesve."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"imito burimet e vendndodhjes për testim"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Krijo burime imituese të vendndodhjes për testim ose instalo një ofrues të ri për vendndodhjen. Kjo lejon aplikacionin të mos refuzojë vendndodhjen dhe/ose statusin e rezultuar nga burime të tjera të vendndodhjes si GPS-ja ose ofruesit të saj."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"qasje në komandat shtesë të ofruesit të vendndodhjes"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Lejon aplikacionin të ketë qasje në komandat shtesë të ofruesit për vendndodhjen. Kjo mund ta lejojë aplikacionin të ndërhyjë në operacionin e GPS-së apo të burimeve të tjera për vendndodhjen."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"vendndodhja e përpiktë (në bazë të GPS-së dhe rrjetit)"</string>
@@ -437,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Operacioni i gjurmës së gishtit u anulua."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Keni bërë shumë tentativa. Provo përsëri më vonë."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Provo përsëri."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"lexo cilësimet e sinkronizimit"</string>
@@ -1041,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Nëse aktivizon USB-në, disa aplikacione që po përdor do të ndalojnë. Ata mund të jenë të papërdorshëm derisa ta çaktivizosh sërish USB-në."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Operacioni i USB-së nuk pati sukses"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Në rregull!"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Lidhur si pajisje e jashtme"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Lidhur si kamerë"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"U lidh si një pajisje MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"I lidhur si instalues"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"U lidh me një ndihmës USB-je"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Prek për opsione të tjera të USB-së."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Të formatohet USB-ja?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Të formatohet karta SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Të gjithë skedarët e ruajtur në USB do të fshihen. Ky veprim nuk mund të kthehet mbrapsht!"</string>
@@ -1078,22 +1085,14 @@
<string name="ext_media_init_action" msgid="8317198948634872507">"Konfigurimi"</string>
<string name="ext_media_unmount_action" msgid="1121883233103278199">"Nxirr"</string>
<string name="ext_media_browse_action" msgid="8322172381028546087">"Eksploro"</string>
- <!-- no translation found for ext_media_missing_title (620980315821543904) -->
- <skip />
- <!-- no translation found for ext_media_missing_message (5761133583368750174) -->
- <skip />
- <!-- no translation found for ext_media_move_specific_title (1471100343872375842) -->
- <skip />
- <!-- no translation found for ext_media_move_title (1022809140035962662) -->
- <skip />
- <!-- no translation found for ext_media_move_success_title (8575300932957954671) -->
- <skip />
- <!-- no translation found for ext_media_move_success_message (4199002148206265426) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_title (7613189040358789908) -->
- <skip />
- <!-- no translation found for ext_media_move_failure_message (1978096440816403360) -->
- <skip />
+ <string name="ext_media_missing_title" msgid="620980315821543904">"<xliff:g id="NAME">%s</xliff:g> mungon"</string>
+ <string name="ext_media_missing_message" msgid="5761133583368750174">"Fute përsëri këtë pajisje"</string>
+ <string name="ext_media_move_specific_title" msgid="1471100343872375842">"Po zhvendos <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_title" msgid="1022809140035962662">"Po zhvendos të dhënat"</string>
+ <string name="ext_media_move_success_title" msgid="8575300932957954671">"Zhvendosja përfundoi"</string>
+ <string name="ext_media_move_success_message" msgid="4199002148206265426">"Të dhënat u zhvendosën te <xliff:g id="NAME">%s</xliff:g>"</string>
+ <string name="ext_media_move_failure_title" msgid="7613189040358789908">"Të dhënat nuk mund të zhvendoseshin"</string>
+ <string name="ext_media_move_failure_message" msgid="1978096440816403360">"U lanë të dhëna në vendndodhjen origjinale"</string>
<string name="activity_list_empty" msgid="1675388330786841066">"Nuk u gjet asnjë aktivitet që përputhet."</string>
<string name="permlab_route_media_output" msgid="1642024455750414694">"Kalo daljet e medias"</string>
<string name="permdesc_route_media_output" msgid="4932818749547244346">"Lejon një aplikacion të kalojë daljet mediatike në pajisje të tjera të jashtme."</string>
@@ -1466,32 +1465,38 @@
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Kërko model shkyçjeje para heqjes së gozhdimit"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"U instalua nga administratori yt"</string>
+ <string name="package_updated_device_owner" msgid="8856631322440187071">"Përditësuar nga administratori"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"U fshi nga administratori yt"</string>
<string name="battery_saver_description" msgid="1960431123816253034">"Për të përmirësuar jetëgjatësinë e baterisë, opsioni i kursimit të baterisë ul rendimentin e pajisjes tënde dhe kufizon dridhjen, shërbimet e vendndodhjes dhe shumicën e të dhënave në sfond. Mail-i, mesazhet dhe aplikacione të tjera që mbështeten në sinkronizim mund të mos përditësohen pa i hapur.\n\nKursimi i baterisë çaktivizohet automatikisht kur pajisja vihet në ngarkim."</string>
<plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848">
<item quantity="other">Për %1$d minuta (deri në <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Për një minutë (deri në <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Për %1$d orë (deri në <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Për një orë (deri në <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Për %d minuta</item>
<item quantity="one">Për një minutë</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Për %d orë</item>
<item quantity="one">Për një orë</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Deri sa ta çaktivizosh këtë"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Shpalos"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Mos shqetëso"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"periudha joaktive"</string>
- <string name="zen_mode_default_weeknights_name" msgid="2069189413656431610">"Natën gjatë javës"</string>
- <string name="zen_mode_default_weekends_name" msgid="2377398437072017011">"Fundjava"</string>
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Netët e javës"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Fundjava"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Ngjarje"</string>
<string name="muted_by" msgid="6147073845094180001">"Lënë në heshtje nga <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Ka një problem të brendshëm me pajisjen tënde. Ajo mund të jetë e paqëndrueshme derisa të rivendosësh të dhënat në gjendje fabrike."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Ka një problem të brendshëm me pajisjen tënde. Kontakto prodhuesin tënd për detaje."</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index b5c17f9..f799772 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -221,27 +221,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Личне апликације"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Посао"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"приступ контактима и њихова измена"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"приступ контактима"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"приступ вашој локацији"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Информације са друштвених мрежа"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Директан приступ информацијама о контактима и друштвеним везама."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"приступ календару и његова измена"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"приступ календару"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"приступ SMS-овима и њихова измена"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"приказ SMS порука и управљање њима"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Кориснички речник"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Читање или писање речи у корисничком речнику."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Обележивачи и историја"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Директан приступ обележивачима и историји прегледача."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Микрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"коришћење микрофона уређаја"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"снимање аудио снимака"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"коришћење камере уређаја"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"снимање слика и видео снимака"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"коришћење телефоније уређаја"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"упућивање телефонских позива и управљање њима"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Сензори"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"приступ сензорима и уређајима за ношење"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"приступ подацима са сензора и носивих уређаја"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преузимање садржаја прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Укључивање Истраживања додиром"</string>
@@ -336,8 +336,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Дозвољава апликацији да додаје, уклања и мења догађаје које можете да измените на таблету, укључујући догађаје пријатеља и колега. Ово може да омогући апликацији да шаље поруке које изгледају као да их шаљу власници календара или мења догађаје без знања власника."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Дозвољава апликацији да додаје, уклања и мења догађаје које можете да измените на ТВ-у, укључујући догађаје пријатеља или колега. Ово може да дозволи апликацији да шаље поруке које изгледају као да их шаљу власници календара или да мења догађаје без знања власника."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Дозвољава апликацији да додаје, уклања и мења догађаје које можете да измените на телефону, укључујући догађаје пријатеља и колега. Ово може да омогући апликацији да шаље поруке које изгледају као да их шаљу власници календара или мења догађаје без знања власника."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"лажни извори локација у сврхе тестирања"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Прављење лажних извора локација у сврху тестирања или инсталирање новог добављача локације. Ово омогућава апликацији да замени локацију и/или статус који пријављују други извори локација, као што су GPS или добављачи локације."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"приступ додатним командама добављача локације"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Омогућава апликацији да приступа додатним командама даваоца услуга локације. То може да омогући апликацији да утиче на рад GPS-а или других извора локације."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"прецизна локација (заснована на GPS-у и мрежи)"</string>
@@ -439,6 +437,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Радња са отиском прста је отказана."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Превише покушаја. Покушајте поново касније."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Покушајте поново."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"читање подешавања синхронизације"</string>
@@ -1049,12 +1049,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ако укључите USB меморију, поједине апликације које користите ће се зауставити и могу да буду недоступне док је поново не укључите."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB радња није успела"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Потврди"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Повезан као медијски уређај"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Повезан као камера"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Повезано је као MIDI уређај"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Повезан као инсталациони програм"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Повезано са USB додатком"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Додирните за друге опције USB-а."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Желите да формат. USB меморију?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Желите ли да форматирате SD картицу?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Све датотеке ускладиштене на USB меморији биће избрисане. Ова радња не може да се опозове!"</string>
@@ -1476,33 +1482,34 @@
<item quantity="few">%1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d минута (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d сат (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d сата (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d сати (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d минут</item>
<item quantity="few">%d минута</item>
<item quantity="other">%d минута</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d сат</item>
<item quantity="few">%d сата</item>
<item quantity="other">%d сати</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Док не искључите"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Скупи"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Не узнемиравај"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Одмор"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Радни дан увече"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Викенд"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Догађај"</string>
<string name="muted_by" msgid="6147073845094180001">"Звук је искључио/ла <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Дошло је до интерног проблема у вези са уређајем и можда ће бити нестабилан док не обавите ресетовање на фабричка подешавања."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Дошло је до интерног проблема у вези са уређајем. Потражите детаље од произвођача."</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 57a833b..c446b43 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Personliga appar"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Arbetet"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"få åtkomst till och ändra dina kontakter"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"få tillgång till dina kontakter"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Plats"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"få åtkomst till din plats"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Dina sociala uppgifter"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direktåtkomst till information om dina kontakter och sociala kontakter."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalender"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"få åtkomst till och ändra kalendern"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"få tillgång till din kalender"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Sms"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"få åtkomst till och ändra sms"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"visa och hantera sms"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Egen ordlista"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Läsa eller skriva ord i användarordlistan."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Bokmärken och historik"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direktåtkomst till bokmärken och webbläsarhistorik."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"använda enhetens mikrofon"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"spela in ljud"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"använda enhetens kamera"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ta bilder och spela in video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Mobil"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"använda enhetens telefonfunktion"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ringa och hantera telefonsamtal"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorer"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"få åtkomst till sensorer och smarta accessoarer"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"få tillgång till data från sensorer och smarta accessoarer"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Hämta fönsterinnehåll"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Granska innehållet i ett fönster som du interagerar med."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivera Explore by Touch"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Tillåter att appen lägger till, tar bort och ändrar sådana händelser som du kan ändra på surfplattan, inklusive dina vänners eller kollegors uppgifter. Detta kan innebära att appen tillåts skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra händelser utan ägarens vetskap."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Tillåter att appen lägger till, tar bort och ändrar händelser som du kan ändra på tv:n, inklusive dina vänners eller kollegors uppgifter. Appen kan på så sätt skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra uppgifter utan ägarens vetskap."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Tillåter att appen lägger till, tar bort och ändrar sådana händelser som du kan ändra på mobilen, inklusive dina vänners eller kollegors uppgifter. Detta kan innebära att appen tillåts skicka meddelanden som ser ut att komma från kalenderns ägare eller ändra händelser utan ägarens vetskap."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"skenplatser för att testa"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Skapa skenplatser för tester eller installera en ny platsleverantör. Detta innebär att appen tillåts åsidosätta den plats och/eller status som returneras av andra platskällor, till exempel GPS eller platsleverantörer."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"få åtkomst till extra kommandon för platsleverantör"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tillåter att appen får åtkomst till extra kommandon för platsleverantör. Detta kan innebära att appen tillåts störa funktionen för GPS eller andra platskällor."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"exakt plats (GPS- och nätverksbaserad)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeravtrycksåtgärden avbröts."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Du har gjort för många försök. Försök igen senare."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Försök igen."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"läsa synkroniseringsinställningar"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Om du aktiverar USB-lagring avbryts några av apparna som körs och de kanske inte blir tillgängliga igen förrän du inaktiverar USB-lagring."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB-åtgärd misslyckades"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ansluten som en mediaenhet"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ansluten som en kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Ansluten som en MIDI-enhet"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ansluten som installationsprogram"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ansluten till ett USB-tillbehör"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Tryck om du vill visa andra USB-alternativ."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formatera USB-enhet?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Vill du formatera SD-kortet?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alla filer på USB-lagringsenheten kommer att raderas. Åtgärden kan inte ångras!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">I %1$d minuter (till kl. <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">I en minut (till kl. <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">I %1$d timmar (till kl. <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">I en timme (till kl. <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">I %d minuter</item>
<item quantity="one">I en minut</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">I %d timmar</item>
<item quantity="one">I en timme</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Tills du inaktiverar detta"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Komprimera"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Stör ej"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Avbrottstid"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Vardagskväll"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"I helgen"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Händelse"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> har stängt av ljudet"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Ett internt problem har uppstått i enheten, och det kan hända att problemet kvarstår tills du återställer standardinställningarna."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Ett internt problem har uppstått i enheten. Kontakta tillverkaren om du vill veta mer."</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 28d9429..73d35d0 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Programu binafsi"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Kazini"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Anwani"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"kufikia na kurekebisha anwani zako"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"fikia anwani zako"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Mahali"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"kufikia mahali ulipo"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Taarifa yako ya kijamii"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kufikia moja kwa moja taarifa kuhusu anwani zako na miunganisho ya kijamii."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"kufikia na kurekebisha kalenda yako"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"fikia kalenda yako"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"kufikia na kurekebisha SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"angalia na udhibiti ujumbe wa SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kamusi ya Mtumiaji"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kusoma au kuandika maneno katika kamusi ya mtumiaji."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Alamisho na Historia"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Kufikia, moja kwa moja, alamisho na historia ya kivinjari."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Kipokea sauti"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"kutumia maikrofoni ya kifaa"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekodi sauti"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"kutumia kamera ya kifaa"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"piga picha na urekodi video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Simu"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"kutumia simu ya kifaa"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"piga na udhibiti simu"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Vihisi"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"kufikia vihisi na vifaa vya kuvaliwa"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"fikia data kutoka vihisi na vifaa vya kuvaliwa"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Rejesha maudhui ya dirisha"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Chunguza maudhui ya dirisha unaloingiliana nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Washa Chunguza kwa Mguso"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye kompyuta kibao yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujua."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Huruhusu programu kuongeza, kuondoa, kubadilisha matukio unayoweza kurekebisha kwenye runinga chako, ikiwa ni pamoja na yale ya marafiki au wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaoonekana kutoka kwa wamiliki wa kalenda, au kurekebisha matukio bila ya wamiliki kufahamu."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Inaruhusu programu kuongeza, kuondoa, kubadilisha matukio ambayo unaweza kurekebisha kwenye simu yako, yakijumulisha yale ya marafiki na wafanyakazi wenza. Hii inaweza kuruhusu programu kutuma ujumbe unaonekana kuwa unatoka kwa mmiliki wa kalenda, au kurekebisha matukio bila mmiliki kujia."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"vyanzo vya jaribio la mahali kwa lengo la majaribio"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Unda vyanzo vya majaribio ya eneo vya kujaribia au usakinishe mtoaji huduma mpya wa eneo. Hii inaruhusu programu kufuta eneo na/au hali inayorudishwa na vyanzo vingine vya eneo kama vile GPS au watoaji huduma wa eneo."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"fikia amri za ziada za mtoa huduma ya mahali"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ruhusu programu kufikia amri za ziada za mtoa huduma za mahali. Hii huenda ikaruhusu programu ikatize matumizi ya GPS au vyanzo vingine vya eneo."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"kutambua eneo sahihi (GPS na mtandao)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Utendaji wa kitambulisho imeghairiwa."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Majaribio mengi mno. Jaribu tena baadaye."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Jaribu tena."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"kusoma mipangilio ya usawazishaji"</string>
@@ -1044,14 +1044,20 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Ukiwasha hifadhi ya USB, baadhi ya programu unazozitumia zitakoma na huenda zisipatikane hadi uzime hifadhi ya USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Uendeshaji wa USB hujafanikiwa"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Sawa"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Imeunganishwa kama kifaa cha midia"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Imeunganishwa kama kamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Kimeunganishwa kama kifaa cha MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Imeunganishwa kama kisakinishi"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Imeunganishwa kwa kifuasi cha USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Gusa ili uone chaguo zingine za USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Fomati hifadhi ya USB?"</string>
- <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Umbiza kadi ya SD."</string>
+ <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Ungependa kutayarisha kadi ya SD ili iweze kutumika?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Faili zote zilizohifadhiwa katika hifadhi yako ya USB zitafutwa. Hatua hii haiwezi kubadilishwa!"</string>
<string name="extmedia_format_message" product="default" msgid="14131895027543830">"Data yote kwenye kadi yako itapotea."</string>
<string name="extmedia_format_button_format" msgid="4131064560127478695">"Fomati"</string>
@@ -1468,30 +1474,31 @@
<item quantity="other">Kwa dakika %1$d (hadi <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Kwa dakika moja (hadi <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Kwa saa %1$d (hadi <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Kwa saa moja (hadi <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Kwa dakika %d</item>
<item quantity="one">Kwa dakika moja</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Kwa saa %d</item>
<item quantity="one">Kwa saa moja</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hadi utakapozima hili"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Kunja"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Usinisumbue"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Wakati wa hali tuli"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Usiku wa wiki"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Wikendi"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Tukio"</string>
<string name="muted_by" msgid="6147073845094180001">"Sauti imezimwa na <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Kuna hitilafu ya ndani ya kifaa chako, na huenda kisiwe thabiti mpaka urejeshe mipangilio ya kiwandani."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Kuna hitilafu ya ndani ya kifaa chako. Wasiliana na mtengenezaji wa kifaa chako kwa maelezo."</string>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 88a8b91..dc68bc4 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"தனிப்பட்ட பயன்பாடுகள்"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"பணியிடம்"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"தொடர்புகள்"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"தொடர்புகளை அணுகும், மாற்றும்"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"தொடர்புகளை அணுகும்"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"இருப்பிடம்"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"இருப்பிடத்தை அணுகும்"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"உங்கள் சமூகத் தகவல்"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"உங்கள் தொடர்புகள் மற்றும் சமூக இணைப்புகள் குறித்த தகவலுக்கான நேரடி அணுகல்."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"கேலெண்டர்"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"கேலெண்டரை அணுகும், மாற்றும்"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"கேலெண்டரை அணுகும்"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMSஐ அணுகும், மாற்றும்"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS செய்திகளைப் படிக்கும், நிர்வகிக்கும்"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"பயனர் அகராதி"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"பயனர் அகராதியில் சொற்களைப் படிக்கும் அல்லது எழுதும்."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"புத்தகக்குறிகள் மற்றும் வரலாறு"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"புத்தகக்குறிகள் மற்றும் உலாவியின் வரலாற்றுக்கான நேரடி அணுகல்."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"மைக்ரோஃபோன்"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"சாதனத்தின் மைக்ரோஃபோனை அணுகும்"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ஆடியோவைப் பதிவுசெய்யும்"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"கேமரா"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"சாதனத்தின் கேமராவைப் பயன்படுத்தும்"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"படங்களை எடுக்கும், வீடியோவைப் பதிவுசெய்யும்"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ஃபோன்"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"சாதனத்தின் டெலிஃபோனியைப் பயன்படுத்தும்"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"மொபைல் அழைப்புகளைச் செய்யும், பெறும்"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"உணர்விகள்"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"உணர்விகளையும் அணியக்கூடிய சாதனங்களையும் அணுகும்"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"சென்சார்கள், அணியக்கூடிய சாதனங்களிலிருந்து தரவை அணுகும்"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"சாளர உள்ளடக்கத்தைப் பெறவும்"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"நீங்கள் ஊடாடிக்கொண்டிருக்கும் சாளரத்தின் உள்ளடக்கத்தைப் பார்க்கலாம்."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"தொடுவதன் மூலம் அறிவதை இயக்கவும்"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"நண்பர்கள் அல்லது சகப் பணியாளர்கள் உள்பட உங்கள் டேப்லெட்டில் நீங்கள் திருத்தக்கூடிய நிகழ்வுகளைச் சேர்க்கவும், அகற்றவும், மேலும் மாற்றவும் பயன்பாட்டை அனுமதிக்கிறது. இது கேலெண்டர் உரிமையாளர்களிடமிருந்து வரும் செய்திகளை அனுப்பவும் அல்லது உரிமையாளரின் ஒப்புதல் இல்லாமல் நிகழ்வுகளைத் திருத்தவும் பயன்பாட்டை அனுமதிக்கலாம்."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"நண்பர்கள் அல்லது சகப் பணியாளர்களின் நிகழ்வுகள் உள்ளிட்ட உங்கள் டிவியில் நீங்கள் மாற்றக்கூடிய நிகழ்வுகளைச் சேர்க்க, அகற்ற மற்றும் மாற்ற, பயன்பாட்டை அனுமதிக்கிறது. இது கேலெண்டர் உரிமையாளர்கள் அனுப்புவது போன்ற செய்திகளை அனுப்ப அல்லது உரிமையாளரின் அனுமதி இல்லாமல் நிகழ்வுகளை மாற்ற, அனுமதிக்கிறது."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"நண்பர்கள் அல்லது சகப் பணியாளர்கள் உள்பட உங்கள் மொபைலில் நீங்கள் திருத்தக்கூடிய நிகழ்வுகளைச் சேர்க்கவும், அகற்றவும், மேலும் மாற்றவும் பயன்பாட்டை அனுமதிக்கிறது. இது கேலெண்டர் உரிமையாளர்களிடமிருந்து வரும் செய்திகளை அனுப்பவும் அல்லது உரிமையாளரின் ஒப்புதல் இல்லாமல் நிகழ்வுகளைத் திருத்தவும் பயன்பாட்டை அனுமதிக்கலாம்."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"சோதனைக்கான போலி இட மூலங்கள்"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"சோதனைக்காக போலி இருப்பிட மூலங்களை உருவாக்கவும் அல்லது புதிய இருப்பிட வழங்குநரை நிறுவவும். இது, இருப்பிடத்தை மற்றும்/அல்லது GPS அல்லது இருப்பிட வழங்குநர்கள் போன்ற பிற இருப்பிட மூலங்கள் மூலம் வழங்கப்பட்ட நிலையை மேலெழுதப் பயன்பாட்டை அனுமதிக்கிறது."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"கூடுதல் இட வழங்குநரின் கட்டளைகளின் அணுகல்"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"கூடுதல் இட வழங்குநர் கட்டளைகளை அணுகப் பயன்பாட்டை அனுமதிக்கிறது. இது, GPS அல்லது பிற இருப்பிட மூலங்களின் செயல்பாட்டை இடைமறிக்க பயன்பாட்டை அனுமதிக்கலாம்."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"துல்லியமான இருப்பிடம் (GPS மற்றும் நெட்வொர்க் சார்ந்தது)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"கைரேகை செயல்பாடு ரத்துசெய்யப்பட்டது."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"அதிகமான முயற்சிகள். பிறகு முயற்சிக்கவும்."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"மீண்டும் முயற்சிக்கவும்."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"ஒத்திசைவு அமைப்புகளைப் படித்தல்"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"நீங்கள் USB சேமிப்பிடத்தை இயக்கினால், நீங்கள் பயன்படுத்தும் சில பயன்பாடுகள் நின்றுவிடும், மேலும் நீங்கள் USB சேமிப்பிடத்தை முடக்கும்வரை அவை கிடைக்காமல் இருக்கலாம்."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB செயல்முறை தோல்வியடைந்தது"</string>
<string name="dlg_ok" msgid="7376953167039865701">"சரி"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"மீடியா சாதனமாக இணைக்கப்பட்டது"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"கேமராவாக இணைக்கப்பட்டுள்ளது"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI சாதனமாக இணைக்கப்பட்டது"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"நிறுவியாக இணைக்கப்பட்டது"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB துணைக்கருவியுடன் இணைக்கப்பட்டுள்ளது"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"மற்ற USB விருப்பங்களுக்குத் தொடவும்."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB சேமிப்பகத்தில் உள்ளவற்றை அழிக்கவா?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD கார்டில் உள்ளவற்றை அழிக்கவா?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB சேமிப்பகத்தில் சேமித்த எல்லா கோப்புகளும் அழிக்கப்படும். இந்தச் செயலைச் செயல்தவிர்க்க முடியாது."</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d நிமிடங்களுக்கு (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> வரை)</item>
<item quantity="one">ஒரு நிமிடத்திற்கு (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> வரை)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d மணிநேரத்திற்கு (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> வரை)</item>
<item quantity="one">ஒரு மணிநேரத்திற்கு (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> வரை)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d நிமிடங்களுக்கு</item>
<item quantity="one">ஒரு நிமிடத்திற்கு</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d மணிநேரத்திற்கு</item>
<item quantity="one">ஒரு மணிநேரத்திற்கு</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"இதை முடக்கும்வரை"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"தொந்தரவு செய்ய வேண்டாம்"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"செயலற்ற நேரம்"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"வார இரவு"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"வார இறுதி"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"நிகழ்வு"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ஒலியடக்கினார்"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது, அதனை ஆரம்பநிலைக்கு மீட்டமைக்கும் வரை நிலையற்று இயங்கலாம்."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"சாதனத்தில் அகச் சிக்கல் இருக்கிறது. விவரங்களுக்கு சாதன தயாரிப்பாளரைத் தொடர்புகொள்ளவும்."</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 685d75f..418eab3 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"వ్యక్తిగత అనువర్తనాలు"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"కార్యాలయం"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"పరిచయాలు"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"మీ పరిచయాలను ప్రాప్యత చేస్తుంది మరియు సవరిస్తుంది"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"మీ పరిచయాలను ప్రాప్యత చేస్తుంది"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"మీ స్థానాన్ని ప్రాప్యత చేస్తుంది"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"మీ సామాజిక సమాచారం"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"మీ పరిచయాలు మరియు సామాజిక బాంధవ్యాలకు సంబంధించిన సమాచారానికి ప్రత్యక్ష ప్రాప్యత."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"క్యాలెండర్"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"మీ క్యాలెండర్ను ప్రాప్యత చేస్తుంది మరియు సవరిస్తుంది"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"మీ క్యాలెండర్ను ప్రాప్యత చేస్తుంది"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMSను ప్రాప్యత చేస్తుంది మరియు సవరిస్తుంది"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS సందేశాలను వీక్షిస్తుంది మరియు నిర్వహిస్తుంది"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"వినియోగదారు నిఘంటువు"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"వినియోగదారు నిఘంటువులో పదాలు చదువుతుంది లేదా వ్రాస్తుంది."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"బుక్మార్క్లు మరియు చరిత్ర"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"బుక్మార్క్లు మరియు బ్రౌజర్ చరిత్రకు ప్రత్యక్ష ప్రాప్యత."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"మైక్రోఫోన్"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"పరికర మైక్రోఫోన్ను ఉపయోగిస్తుంది"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ఆడియోను రికార్డ్ చేస్తుంది"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"కెమెరా"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"పరికర కెమెరాను ఉపయోగిస్తుంది"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"చిత్రాలను తీస్తుంది మరియు వీడియోను రికార్డ్ చేస్తుంది"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ఫోన్"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"పరికర టెలిఫోనీ సాంకేతికతను ఉపయోగిస్తుంది"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ఫోన్ కాల్లను చేస్తుంది మరియు నిర్వహిస్తుంది"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"సెన్సార్లు"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"సెన్సార్లను మరియు ధరింపదగిన వాటిని ప్రాప్యత చేస్తుంది"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"సెన్సార్లు మరియు వేరబుల్ పరికరాల డేటాను ప్రాప్యత చేస్తుంది"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్ను మరలా పొందండి"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్ను పరిశీలించండి."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభించండి"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"స్నేహితులు లేదా సహోద్యోగులకు సంబంధించిన ఈవెంట్లతో సహా మీరు మీ టాబ్లెట్లో సవరించగల ఈవెంట్లను జోడించడానికి, తీసివేయడానికి, మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా కనిపించే రీతిలో సందేశాలను పంపడానికి లేదా యజమానికి తెలియకుండానే ఈవెంట్లను సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"స్నేహితులు లేదా సహోద్యోగులకు సంబంధించిన ఈవెంట్లతో సహా మీరు మీ టీవీలో సవరించగల ఈవెంట్లను జోడించడానికి, తీసివేయడానికి, మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా కనిపించే సందేశాలను పంపడానికి లేదా యజమానికి తెలియకుండానే ఈవెంట్లను సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"స్నేహితులు లేదా సహోద్యోగులకు సంబంధించిన ఈవెంట్లతో సహా మీరు మీ ఫోన్లో సవరించగల ఈవెంట్లను జోడించడానికి, తీసివేయడానికి, మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది క్యాలెండర్ యజమానుల నుండి వచ్చినట్లుగా కనిపించే రీతిలో సందేశాలను పంపడానికి లేదా యజమానికి తెలియకుండానే ఈవెంట్లను సవరించడానికి అనువర్తనాన్ని అనుమతించవచ్చు."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"పరీక్షించడం కోసం స్థాన మూలాలను మాక్ చేయడం"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"పరీక్షించడం కోసం అనుకృత స్థాన మూలాలను సృష్టించండి లేదా కొత్త స్థాన ప్రదాతను ఇన్స్టాల్ చేయండి. ఇది GPS లేదా స్థాన ప్రదాతల వంటి ఇతర స్థాన మూలాల ద్వారా అందించబడిన స్థానం మరియు/లేదా స్థితిని భర్తీ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"అదనపు స్థాన ప్రదాత ఆదేశాలను ప్రాప్యత చేయడం"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"అదనపు స్థాన ప్రదాత ఆదేశాలను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో అనువర్తనం ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ఖచ్చితమైన స్థానం (GPS మరియు నెట్వర్క్-ఆధారితం)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"వేలిముద్ర కార్యాచరణ రద్దయింది."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"చాలా ఎక్కువ ప్రయత్నాలు చేసారు. తర్వాత మళ్లీ ప్రయత్నించండి."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"మళ్లీ ప్రయత్నించండి."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"సమకాలీకరణ సెట్టింగ్లను చదవడం"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"మీరు USB నిల్వను ప్రారంభిస్తే, మీరు ఉపయోగిస్తున్న కొన్ని అనువర్తనాలు ఆగిపోతాయి మరియు మీరు USB నిల్వను ఆపివేసే వరకు అందుబాటులో ఉండకపోవచ్చు."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB చర్య విజయవంతం కాలేదు"</string>
<string name="dlg_ok" msgid="7376953167039865701">"సరే"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"మీడియా పరికరంగా కనెక్ట్ చేయబడింది"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"కెమెరాగా కనెక్ట్ చేయబడింది"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI పరికరం వలె కనెక్ట్ చేయబడింది"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ఇన్స్టాలర్గా కనెక్ట్ చేయబడింది"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB ఉపకరణానికి కనెక్ట్ చేయబడింది"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"ఇతర USB ఎంపికల కోసం తాకండి."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB నిల్వను ఫార్మాట్ చేయాలా?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD కార్డుని ఫార్మాట్ చేయాలా?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"మీ USB నిల్వలో నిల్వ చేసిన అన్ని ఫైల్లు ఎరేజ్ చేయబడతాయి. ఈ చర్యను రద్దు చేసి పూర్వ స్థితికి తీసుకురావడం సాధ్యపడదు!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d నిమిషాల పాటు (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> వరకు)</item>
<item quantity="one">ఒక నిమిషం పాటు (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> వరకు)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d గంటల పాటు (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> వరకు)</item>
<item quantity="one">ఒక గంట పాటు (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> వరకు)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d నిమిషాల పాటు</item>
<item quantity="one">ఒక నిమిషం పాటు</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d గంటల పాటు</item>
<item quantity="one">ఒక గంట పాటు</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"మీరు దీన్ని ఆఫ్ చేసే వరకు"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"కుదించండి"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"అంతరాయం కలిగించవద్దు"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ముఖ్యమైన పనిలో ఉన్నప్పుడు"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"వారపు రోజుల్లో రాత్రి"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"వారాంతం"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ఈవెంట్"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> ద్వారా మ్యూట్ చేయబడింది"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది మరియు మీరు ఫ్యాక్టరీ డేటా రీసెట్ చేసే వరకు అస్థిరంగా ఉంటుంది."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"మీ పరికరంతో అంతర్గత సమస్య ఏర్పడింది. వివరాల కోసం మీ తయారీదారుని సంప్రదించండి."</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a658c19..9e6fa6c 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"แอปส่วนตัว"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"ที่ทำงาน"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"รายชื่อติดต่อ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"เข้าถึงและปรับเปลี่ยนรายชื่อติดต่อของคุณ"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"เข้าถึงรายชื่อติดต่อ"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"เข้าถึงตำแหน่งของคุณ"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"ข้อมูลทางสังคมของคุณ"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"เข้าถึงข้อมูลเกี่ยวกับผู้ติดต่อและเครือข่ายสังคมของคุณโดยตรง"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"ปฏิทิน"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"เข้าถึงและปรับเปลี่ยนปฏิทินของคุณ"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"เข้าถึงปฏิทิน"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"เข้าถึงและปรับเปลี่ยน SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"ดูและจัดการข้อความ SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"พจนานุกรมผู้ใช้"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"อ่านหรือเขียนคำในพจนานุกรมผู้ใช้"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"บุ๊กมาร์กและประวัติ"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"เข้าถึงบุ๊กมาร์กและประวัติของเบราว์เซอร์โดยตรง"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"ไมโครโฟน"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"ใช้ไมโครโฟนของอุปกรณ์"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"บันทึกเสียง"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"กล้องถ่ายรูป"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"ใช้กล้องของอุปกรณ์"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"ถ่ายภาพและบันทึกวิดีโอ"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"โทรศัพท์"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"ใช้โทรศัพท์ของอุปกรณ์"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"โทรและจัดการการโทร"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"เซ็นเซอร์"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"เข้าถึงเซ็นเซอร์และอุปกรณ์ที่สวมใส่ได้"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"เข้าถึงข้อมูลจากเซ็นเซอร์และอุปกรณ์ที่สวมใส่ได้"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"เรียกข้อมูลเนื้อหาของหน้าต่าง"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ตรวจสอบเนื้อหาของหน้าต่างที่คุณกำลังโต้ตอบอยู่"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"เปิด \"แตะเพื่อสำรวจ\""</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"อนุญาตให้แอปพลิเคชันเพิ่ม ลบ เปลี่ยนกิจกรรมที่คุณสามารถเปลี่ยนแปลงในแท็บเล็ตได้ รวมถึงกิจกรรมของเพื่อนหรือเพื่อนร่วมงานด้วย การอนุญาตนี้อาจทำให้แอปพลิเคชันสามารถส่งข้อความที่มาจากเจ้าของปฏิทิน หรือเปลี่ยนแปลงกิจกรรมโดยที่เจ้าของไม่ทราบ"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"อนุญาตให้แอปเพิ่ม นำออก เปลี่ยนแปลงกิจกรรมที่คุณสามารถแก้ไขได้บนทีวี ซึ่งรวมถึงกิจกรรมของเพื่อนหรือเพื่อนร่วมงาน สิทธิ์นี้จะทำให้แอปสามารถส่งข้อความที่ดูเหมือนว่ามาจากเจ้าของปฏิทิน หรือแก้ไขกิจกรรมโดยที่เจ้าของไม่รู้ตัว"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"อนุญาตให้แอปพลิเคชันเพิ่ม ลบ เปลี่ยนกิจกรรมที่คุณสามารถเปลี่ยนแปลงในโทรศัพท์ได้ รวมถึงกิจกรรมของเพื่อนหรือเพื่อนร่วมงานด้วย การอนุญาตนี้อาจทำให้แอปพลิเคชันสามารถส่งข้อความที่มาจากเจ้าของปฏิทิน หรือเปลี่ยนแปลงกิจกรรมโดยที่เจ้าของไม่ทราบ"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"จำลองที่มาของตำแหน่งเพื่อทดสอบ"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"สร้างต้นทางของตำแหน่งจำลองสำหรับการทดสอบหรือติดตั้งผู้ให้บริการตำแหน่งรายใหม่ ซึ่งจะทำให้แอปพลิเคชันสามารถแทนที่ตำแหน่งและ/หรือสถานะที่ส่งกลับมาจากต้นทางของตำแหน่งอื่นๆ เช่น GPS หรือผู้ให้บริการตำแหน่งได้"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"เข้าถึงคำสั่งของโปรแกรมแจ้งตำแหน่งพิเศษ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"อนุญาตให้แอปเข้าถึงคำสั่งของผู้ให้บริการตำแหน่งเพิ่มเติม ซึ่งอาจทำให้แอปสามารถแทรกแซงการทำงานของ GPS หรือต้นทางของตำแหน่งอื่นๆ ได้"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"ตำแหน่งที่แม่นยำ (อิงตาม GPS และเครือข่าย)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"ยกเลิกการทำงานของลายนิ้วมือ"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"ดำเนินการหลายครั้งเกินไป ลองอีกครั้งในภายหลัง"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"ลองอีกครั้ง"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"อ่านการตั้งค่าการซิงค์แล้ว"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"หากคุณเปิดที่จัดเก็บข้อมูล USB แอปพลิเคชันบางอย่างที่คุณใช้อยู่อาจหยุดทำงานและไม่สามารถใช้ได้จนกว่าจะปิดที่จัดเก็บข้อมูล USB"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"การทำงานของ USB ไม่สำเร็จ"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ตกลง"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"เชื่อมต่อเป็นอุปกรณ์สื่อ"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"เชื่อมต่อเป็นกล้องถ่ายรูป"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"เชื่อมต่อเป็นอุปกรณ์ MIDI แล้ว"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"เชื่อมต่อเป็นตัวติดตั้ง"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"เชื่อมต่อกับอุปกรณ์เสริม USB แล้ว"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"แตะสำหรับตัวเลือก USB อื่นๆ"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"ฟอร์แมต USB หรือไม่"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"ฟอร์แมตการ์ด SD หรือไม่"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"ไฟล์ทั้งหมดที่เก็บไว้ในที่จัดเก็บข้อมูล USB ของคุณจะถูกลบทิ้ง การทำงานนี้ไม่สามารถย้อนกลับได้!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">ระยะเวลา %1$d นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">ระยะเวลา 1 นาที (จนถึงเวลา <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">ระยะเวลา %1$d ชั่วโมง (จนถึงเวลา <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">ระยะเวลา 1 ชั่วโมง (จนถึงเวลา <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">ระยะเวลา %d นาที</item>
<item quantity="one">ระยะเวลา 1 นาที</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">ระยะเวลา %d ชั่วโมง</item>
<item quantity="one">ระยะเวลา 1 ชั่วโมง</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"จนกว่าคุณจะปิดฟังก์ชันนี้"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"ยุบ"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ห้ามรบกวน"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ช่วงเวลาเครื่องไม่ทำงาน"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"คืนวันธรรมดา"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"สุดสัปดาห์"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"กิจกรรม"</string>
<string name="muted_by" msgid="6147073845094180001">"ปิดเสียงโดย <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง อุปกรณ์อาจทำงานไม่เสถียรจนกว่าคุณจะรีเซ็ตข้อมูลเป็นค่าเริ่มต้น"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"อุปกรณ์ของคุณเกิดปัญหาภายในเครื่อง โปรดติดต่อผู้ผลิตเพื่อขอรายละเอียดเพิ่มเติม"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 343344a..e7a7ebf 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Mga personal na app"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Trabaho"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Mga Contact"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"i-access at baguhin ang iyong mga contact"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ina-access ang iyong mga contact"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Lokasyon"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"i-access ang iyong lokasyon"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ang iyong social na impormasyon"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direktang access sa impormasyon tungkol sa iyong mga contact at social na koneksyon."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendaryo"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"i-access at baguhin ang iyong kalendaryo"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"ina-access ang iyong kalendaryo"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"i-access at baguhin ang SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"tumitingin at namamahala sa mga mensaheng SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Diksyunaryo ng User"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Magbasa o magsulat ng mga salita sa diksyunaryo ng user"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Mga Bookmark at Kasaysayan"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Direktang access sa mga bookmark at kasaysayan ng browser."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikropono"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"gumamit ng mikropono sa device"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"nagre-record ng audio"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Camera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"gumamit ng camera sa device"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"kumukuha ng mga larawan at nagre-record ng video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telepono"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"gumamit ng telephony sa device"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"tumatawag sa telepono at namamahala sa mga tawag sa telepono"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Mga Sensor"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"i-access ang mga sensor at nasusuot"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ina-access ang data mula sa mga sensor at nasusuot na device"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Kunin ang nilalaman ng window"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Siyasatin ang nilalaman ng isang window kung saan ka nakikipag-ugnayan."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"I-on ang Explore by Touch"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Pinapayagan ang app na magdagdag, mag-alis, magbago ng mga kaganapang maaari mong baguhin sa iyong tablet, kabilang iyong sa mga kaibigan o katrabaho. Maaari nitong payagan ang app na magpadala ng mga mensaheng lumililitaw na mula sa mga may-ari ng kalendaryo, o magbago ng mga kaganapan nang hindi nalalaman ng mga may-ari."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Nagbibigay-daan sa app na magdagdag, mag-alis o magbago ng mga kaganapan na maaari mong baguhin sa iyong TV, kabilang ang mga kaganapan ng iyong mga kaibigan o katrabaho. Maaari nitong bigyang-daan ang app na magpadala ng mga mensahe na mukhang nagmumula sa mga may-ari ng kalendaryo, o magbago ng mga kaganapan nang hindi alam ng may-ari."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Pinapayagan ang app na magdagdag, mag-alis, magbago ng mga kaganapang maaari mong baguhin sa iyong telepono, kabilang iyong sa mga kaibigan o katrabaho. Maaari nitong payagan ang app na magpadala ng mga mensaheng lumililitaw na mula sa mga may-ari ng kalendaryo, o magbago ng mga kaganapan nang hindi nalalaman ng mga may-ari."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"gayahin ang mga pinagmumulan ng lokasyon para sa pagsusuri"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Lumikha ng mga mock na pinagmulan ng lokasyon para sa pagsubok o mag-install ng bagong provider ng lokasyon. Pinapayagan nito ang app na i-override ang lokasyon at/o katayuan na ibinabalik ng iba pang mga pinagmulan ng lokasyon gaya ng GPS o mga provider ng lokasyon."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"i-access ang mga dagdag na command ng provider ng lokasyon"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Nagbibigay-daan sa app na mag-access ng mga karagdagang command ng provider ng lokasyon. Maaari nitong bigyang-daan ang app na gambalain ang pagpapatakbo ng GPS o ng iba pang mga pinagmulan ng lokasyon."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"tumpak na lokasyon (batay sa GPS at network)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Nakansela ang operasyong ginagamitan ng fingerprint."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Masyadong maraming beses sumubok. Subukang muli sa ibang pagkakataon."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Subukang muli."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"basahin ang mga setting ng sync"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Kung i-on mo ang USB storage, hihinto ang ilang apps na iyong ginagamit at maaaring maging hindi available hanggang sa i-off mo ang USB storage."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Hindi matagumpay ang USB operation"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Nakakonekta bilang isang media device"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Nakakonekta bilang isang camera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Nakakonekta bilang isang MIDI device"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Nakakonekta bilang isang installer"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Nakakonekta sa isang accessory ng USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Pindutin para sa iba pang mga pagpipilian sa USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Iformat USB storage?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"I-format ang SD card?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Mabubura ang lahat ng file na nakaimbak sa iyong USB storage. Hindi mababawi ang pagkilos na ito!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Sa loob ng %1$d minuto (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Sa loob ng %1$d na minuto (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Sa loob ng %1$d oras (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Sa loob ng %1$d na oras (hanggang <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Sa loob ng %d minuto</item>
<item quantity="other">Sa loob ng %d na minuto</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Sa loob ng %d oras</item>
<item quantity="other">Sa loob ng %d na oras</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Hanggang sa i-off mo ito"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"I-collapse"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Huwag istorbohin"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Walang serbisyo"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Weeknight"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Weekend"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Kaganapan"</string>
<string name="muted_by" msgid="6147073845094180001">"Na-mute ng <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"May internal na problema sa iyong device, at maaaring hindi ito maging stable hanggang sa i-reset mo ang factory data."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"May internal na problema sa iyong device. Makipag-ugnayan sa iyong manufacturer upang malaman ang mga detalye."</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 574e45e..f9e291b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Kişisel uygulamalar"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"İş"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kişiler"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"kişilerinize erişme ve değişiklik yapma"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kişilerinize erişme"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Konum"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"konumunuza erişme"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Sosyal bilgileriniz"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kişileriniz ve sosyal bağlantılarınızla ilgili bilgilere doğrudan erişim."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Takvim"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"takviminize erişme ve değişiklik yapma"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"takviminize erişme"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS\'e erişme ve değişiklik yapma"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS iletilerini görüntüleme ve yönetme"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Kullanıcı Sözlüğü"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Kullanıcı sözlüğündeki kelimeleri okuma veya yazma"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Yer İşaretleri ve Geçmiş"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Yer işaretlerine ve tarayıcı geçmişine doğrudan erişim."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"cihaz mikrofonunu kullanma"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ses kaydetme"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"cihaz kamerasını kullanma"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"fotoğraf çekme ve video kaydetme"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"cihaz telefonunu kullanma"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefon aramaları yapma ve çağrıları yönetme"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensörler"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"sensörlere ve giyilebilir cihazlara erişme"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"sensörlerden ve giyilebilir cihazlardan gelen verilere erişme"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pencere içeriğini alma"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Etkileşim kurduğunuz pencerenin içeriğini inceler."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Dokunarak Keşfet\'i açma"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere tabletinizde değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen iletiler göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere cihazınızda değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın, takvim sahiplerinden gelmiş gibi görünen iletiler göndermesine veya takvim sahiplerinin bilgisi olmadan etkinlikleri değiştirmesine olanak sağlayabilir."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Uygulamaya, arkadaşlarınızın veya iş arkadaşlarınızın etkinlikleri de dahil olmak üzere telefonunuzda değiştirebileceğiniz etkinlikleri ekleme, kaldırma ve değiştirme izni verir. Bu izin, uygulamanın takvim sahiplerinden geliyormuş gibi görünen iletiler göndermesine veya etkinlikleri sahibinden habersiz olarak değiştirmesine olanak sağlar."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"test için sahte konum kaynakları"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Test amacıyla veya yeni bir konum sağlayıcı yüklemek için sahte konum kaynakları oluşturma. Bu izin, uygulamanın GPS veya konum sağlayıcıları gibi diğer konum kaynakları tarafından döndürülen konum ve/veya durum bilgisini geçersiz kılmasına olanak sağlar."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ek konum sağlayıcı komutlarına eriş"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Uygulamanın, ekstra konum sağlayıcı komutlarına erişmesine izin verir. Bu izin, uygulamanın GPS veya diğer konum kaynaklarının çalışmasını kesmesine olanak sağlayabilir."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"hassas konum (GPS ve ağ tabanlı)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Parmak izi işlemi iptal edildi."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Çok fazla deneme yapıldı. Daha sonra tekrar deneyin."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Tekrar deneyin."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"senk. ayarlarını okuma"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"USB belleği açarsanız, kullanmakta olduğunuz bazı uygulamalar durur ve USB bellek kapatılıncaya kadar kullanılamayabilir."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB işlemi başarısız oldu"</string>
<string name="dlg_ok" msgid="7376953167039865701">"Tamam"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Medya cihazı olarak bağlandı"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera olarak bağlandı"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI cihazı olarak bağlandı"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Yükleyici olarak bağlandı"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB aksesuarına bağlandı"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Diğer USB seçenekleri için dokunun."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB bellek biçimlendirilsin mi?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD kart biçimlendirilsin mi?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB belleğinizdeki tüm dosyalar silinecek. Bu işlem geri alınamaz!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Bir dakika için (şu saate kadar: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d saat için (şu saate kadar: <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Bir saat için (şu saate kadar: <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d dakika süreyle</item>
<item quantity="one">Bir dakika süreyle</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d saat için</item>
<item quantity="one">Bir saat için</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Şu saate kadar: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Siz bunu kapatana kadar"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Daralt"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Rahatsız etmeyin"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Bildirim istenmeyen zaman"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Hafta içi gece"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Hafta sonu"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Etkinlik"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> tarafından kapatıldı"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Cihazınızla ilgili dahili bir sorun oluştu ve fabrika verilerine sıfırlama işlemi gerçekleştirilene kadar kararsız çalışabilir."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Cihazınızla ilgili dahili bir sorun oluştu. Ayrıntılı bilgi için üreticinizle iletişim kurun."</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 02114ec..96ac721 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -222,27 +222,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Особисті додатки"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Службовий профіль"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактні дані"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"відкривати та змінювати контактні дані"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"отримувати доступ до контактів"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Геодані"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"використовувати геодані"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Соціальна інформація"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Безпосередній доступ до інформації про ваші контакти та соціальні зв’язки."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Календар"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"відкривати та змінювати календар"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"отримувати доступ до календаря"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"відкривати та змінювати SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"переглядати SMS і керувати ними"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Словник користувача"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Переглядати або додавати слова в словнику користувача."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Закладки й історія"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Безпосередній доступ до закладок та історії веб-переглядача."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Мікрофон"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"використовувати мікрофон пристрою"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"записувати аудіо"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Камера"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"використовувати камеру пристрою"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"фотографувати та записувати відео"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Телефон"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"використовувати телефонний зв’язок пристрою"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"телефонувати та керувати дзвінками"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Датчики"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"отримувати доступ до датчиків і пристроїв Wear"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"отримувати доступ до даних із датчиків і пристроїв Wear"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Отримувати вміст вікна"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Перевіряти вміст вікна, з яким ви взаємодієте."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Увімкнути функцію дослідження дотиком"</string>
@@ -337,8 +337,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Дозволяє програмі додавати, видаляти та змінювати події, які можна редагувати на планшетному ПК, включно з подіями друзів або співробітників. Це може дозволити програмі надсилати повідомлення, які надходитимуть ніби від власників календарів, або змінювати події без відома власників."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Додаток може додавати, видаляти та змінювати події, які можна редагувати в телевізорі, зокрема події друзів або співробітників. Завдяки цьому додаток зможе надсилати повідомлення, які надходитимуть ніби від власників календарів, або змінювати події без відома власників."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Дозволяє програмі додавати, видаляти та змінювати події, які можна редагувати на телефоні, включно з подіями друзів або співробітників. Це може дозволити програмі надсилати повідомлення, які надходитимуть ніби від власників календарів, або змінювати події без відома власників."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"фіктивні джер. місцезн. для тестув."</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Створювати фіктивні джерела місцезнаходження для тестування або встановлювати нового постачальника даних місцезнаходження. Це може дозволити програмі замінювати місцезнаходження та/чи статус, отриманий від інших джерел даних про місцезнаходження, як-от постачальників послуг GPS або постачальників даних місцезнаходження."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"отр. дост. до додат. команд пров. місцезн."</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Додаток отримуватиме доступ до додаткових команд постачальника геоданих. Можливе втручання додатка в роботу GPS чи інших джерел геоданих."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"точне місцезнаходження (на основі GPS і мережі)"</string>
@@ -440,6 +438,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Дію з відбитком скасовано."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Забагато спроб. Спробуйте пізніше."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Повторіть спробу."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"читати налаштування синхронізації"</string>
@@ -1056,12 +1056,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Якщо ввімкнути носій USB, робота деяких програм, якими ви користуєтеся, припиниться, і вони можуть стати недоступними до вимкнення носія USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Помилка операції з USB"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Під’єднано як носій"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Під’єднано як камеру"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Підключено як пристрій MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Під’єднано як програму встановлення"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Під’єднано до аксесуара USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Торкніться, щоб побачити інші параметри USB."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Форматув. носій USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Форматувати карту SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Усі файли, збережені у вашому носії USB, буде стерто. Цю дію не можна скасувати!"</string>
@@ -1486,36 +1492,37 @@
<item quantity="many">%1$d хвилин (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d хвилини (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">%1$d годину (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="few">%1$d години (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="many">%1$d годин (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">%1$d години (до <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">%d хвилину</item>
<item quantity="few">%d хвилини</item>
<item quantity="many">%d хвилин</item>
<item quantity="other">%d хвилини</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">%d годину</item>
<item quantity="few">%d години</item>
<item quantity="many">%d годин</item>
<item quantity="other">%d години</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Доки ви не вимкнете"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Згорнути"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Не турбувати"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Простій"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Увечері в будні"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"На вихідних"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Подія"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> вимикає звук"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Через внутрішню помилку ваш пристрій може працювати нестабільно. Відновіть заводські налаштування."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"На пристрої сталася внутрішня помилка. Зв’яжіться з виробником пристрою, щоб дізнатися більше."</string>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index f8acd34..a69b73d 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"ذاتی ایپس"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"دفتر"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"رابطے"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"اپنے رابطوں تک رسائی حاصل کریں اور ان میں ترمیم کریں"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"اپنے رابطوں تک رسائی حاصل کریں"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"مقام"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"اپنے مقام تک رسائی حاصل کریں"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"آپ کی سوشل معلومات"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"اپنے رابطوں اور سوشل کنکشنز کے بارے میں معلومات تک براہ راست رسائی۔"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"کیلنڈر"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"اپنے کیلنڈر تک رسائی حاصل کریں اور اس میں ترمیم کریں"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"اپنے کیلنڈر تک رسائی حاصل کریں"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS تک رسائی حاصل کریں اور اس میں ترمیم کریں"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS پیغامات دیکھیں اور ان کا نظم کریں"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"صارف کی لغت"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"صارف کی لغت میں الفاظ پڑھیں یا لکھیں۔"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"بُک مارکس اور سرگزشت"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"بک مارکس اور براؤزر کی سرگزشت تک براہ راست رسائی۔"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"مائکروفون"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"آلہ کا مائیکروفون استعمال کریں"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"آڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"کیمرا"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"آلہ کا کیمرہ استعمال کریں"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"تصاویر لیں اور ویڈیو ریکارڈ کریں"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"فون"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"آلہ کا ٹیلیفونی استعمال کریں"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"فون کالز کریں اور ان کا نظم کریں"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"سینسرز"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"سینسرز اور ویئرایبلز تک رسائی حاصل کریں"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"سینسرز اور ویئرایبل آلات سے ڈیٹا تک رسائی حاصل کریں"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ونڈو مواد کی بازیافت کریں"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"کسی ایسے ونڈو کے مواد کا معائنہ کریں جس کے ساتھ آپ تعامل کر رہے ہیں۔"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ٹچ کے ذریعے دریافت کریں کو آن کریں"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"ایپ کو وہ ایونٹس جن میں آپ اپنے ٹیبلٹ پر ترمیم کرسکتے ہیں، بشمول دوسروں یا ساتھی کارکنوں کے ایونٹس شامل کرنے، ہٹانے، تبدیل کرنے کی اجازت دیتا ہے۔ یہ ایپ کو ایسے پیغامات بھیجنے کی جو کیلنڈر مالکان کی جانب سے آنے والے معلوم پڑتے ہیں یا مالکان کی جانکاری کے بغیر ایونٹس میں ترمیم کرنے کی اجازت دے سکتا ہے۔"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"ایپ کو وہ ایونٹس جن میں آپ TV پر ترمیم کر سکتے ہیں بشمول دوستوں یا ساتھی کارکنان کے ایونٹس شامل کرنے، ہٹانے، تبدیل کرنے کی اجازت دیتا ہے۔ یہ ایپ کو ایسے پیغامات بھیجنے کی جو کیلنڈر مالکان کی جانب سے آئے ہوئے معلوم پڑتے ہیں، یا مالکان کی جانکاری کے بغیر ایونٹس میں ترمیم کرنے کی اجازت دے سکتا ہے۔"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"ایپ کو وہ ایونٹس جن میں آپ اپنے فون پر ترمیم کرسکتے ہیں، بشمول دوسروں یا ساتھی کارکنوں کے ایونٹس شامل کرنے، ہٹانے، تبدیل کرنے کی اجازت دیتا ہے۔ یہ ایپ کو ایسے پیغامات بھیجنے کی جو کیلنڈر مالکان کی جانب سے آئے ہوئے معلوم پڑتے ہیں یا مالکان کی جانکاری کے بغیر ایونٹس میں ترمیم کرنے کی اجازت دے سکتا ہے۔"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"ٹیسٹنگ کیلئے فرضی مقام کے ذرائع"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"ٹیسٹ کرنے کیلئے فرضی مقام کے مآخذ بنائیں یا ایک نیا مقام فراہم کنندہ انسٹال کریں۔ یہ ایپ کو مقام کے دوسرے مآخذ جیسے GPS یا مقام فراہم کنندگان کے ذریعہ واپس کردہ مقام اور/یا اسٹیٹس کو اوور رائیڈ کرنے کی اجازت دیتا ہے۔"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"اضافی مقام فراہم کنندہ کی کمانڈز تک رسائی حاصل کریں"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ایپ کو اضافی مقام فراہم کنندہ کی کمانڈز تک رسائی حاصل کرنے کی اجازت دیتی ہے۔ یہ ایپ کو GPS یا دوسرے مقام کے مآخذ کے عمل کے ساتھ مداخلت کرنے کی اجازت دے سکتی ہے۔"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"قطعی مقام (GPS اور نیٹ ورک پر مبنی)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"فنگر پرنٹ کی کارروائی منسوخ ہوگئی۔"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"کافی زیادہ کوششیں کی گئیں۔ بعد میں دوباہ کوشش کریں۔"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"دوبارہ کوشش کریں۔"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"مطابقت پذیری کی ترتیبات پڑھیں"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"اگر آپ USB اسٹوریج کو آن کرتے ہیں تو آپ کے زیر استعمال کچھ ایپس بند ہو جائیں گے اور جب تک آپ USB اسٹوریج آف نہ کر دیں تب تک غیر دستیاب رہ سکتی ہیں۔"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB کارروائی ناکام رہی"</string>
<string name="dlg_ok" msgid="7376953167039865701">"ٹھیک ہے"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"ایک میڈیا آلہ کے بطور مربوط کر دیا گیا"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"ایک کیمرہ کے بطور مربوط ہے"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI آلہ کے بطور منسلک"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"ایک انسٹالر کے بطور مربوط ہے"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"ایک USB لوازم سے مربوط ہے"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"USB کے دوسرے اختیارات کیلئے چھوئیں۔"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB اسٹوریج فارمیٹ کریں؟"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD کارڈ فارمیٹ کریں؟"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"آپ کی USB اسٹوریج میں اسٹور کردہ سبھی فائلوں کو ہٹا دیا جائے گا۔ اس کارروائی کو لوٹایا نہیں جا سکتا ہے!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d منٹ کیلئے (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> تک)</item>
<item quantity="one">ایک منٹ کیلئے (تک <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d گھنٹے کیلئے (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> تک)</item>
<item quantity="one">ایک گھنٹہ کیلئے (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> تک)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d منٹ کیلئے</item>
<item quantity="one">ایک منٹ کیلئے</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d گھنٹے کیلئے</item>
<item quantity="one">ایک گھنٹہ کیلئے</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"جب تک آپ اسے آف نہ کر دیں"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"سکیڑیں"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"ڈسٹرب نہ کریں"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ڈاؤن ٹائم"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"ویک نائٹ"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"ویک اینڈ"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"ایونٹ"</string>
<string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> کے ذریعے خاموش کردہ"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"آپ کے آلہ میں ایک داخلی مسئلہ ہے اور جب تک آپ فیکٹری ڈیٹا کو دوبارہ ترتیب نہیں دے دیتے ہیں، ہوسکتا ہے کہ یہ غیر مستحکم رہے۔"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"آپ کے آلہ میں ایک داخلی مسئلہ ہے۔ تفصیلات کیلئے اپنے مینوفیکچرر سے رابطہ کریں۔"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 6731d33..683b688 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -202,8 +202,8 @@
<string name="global_action_lock" msgid="2844945191792119712">"Ekranni qulflash"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"O‘chirish"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Nosozlik haqida ma’lumot berish"</string>
- <string name="bugreport_title" msgid="2667494803742548533">"Xatoliklar hisobotini olish"</string>
- <string name="bugreport_message" msgid="398447048750350456">"U e-pochta xabari sifatida yuborish uchun joriy qurilmangiz holati to‘g‘risidagi ma’lumotlarni to‘playdi. Xatoliklar hisobotini to‘plash boshlanganidan uni yuborishga tayyorlaguncha biroz vaqt ketadi; iltimos, sabrli bo‘ling."</string>
+ <string name="bugreport_title" msgid="2667494803742548533">"Xatoliklar hisoboti"</string>
+ <string name="bugreport_message" msgid="398447048750350456">"Qurilmangiz holati haqidagi ma’lumotlar to‘planib, e-pochta orqali yuboriladi. Hisobotni tayyorlash biroz vaqt olishi mumkin."</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Ovozsiz usul"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Tovush o‘chirilgan"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Tovush yoqilgan"</string>
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Shaxsiy ilovalar"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Ish"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"kontaktlaringizni ko‘rish va o‘zgartirish"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarga kirish"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Joylashuv"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"joylashuvingizni ko‘rish"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ijtimoiy ma’lumotingiz"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Kontaktlaringiz va ijtimoiy aloqalaringiz haqidagi ma’lumotga to‘g‘ridan to‘g‘ri o‘tadi."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Taqvim"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"taqvimingizni ko‘rish va o‘zgartirish"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"taqvimga kirish"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"SMS xabarlarni ko‘rish va o‘zgartirish"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"SMS xabarlarni ko‘rish va boshqarish"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Foydalanuvchi lug‘ati"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Foydalanuvchi lug‘atida so‘zlarni o‘qish yoki yozish"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Xatcho‘plar va tarix"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Xatcho‘plar va brauzer tarixiga to‘g‘ridan to‘g‘ri kirishga ruxsat."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Mikrofon"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"qurilma mikrofonidan foydalanish"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"audioni yozib olish"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Kamera"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"qurilma kamerasidan foydalanish"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"rasmlar tushirish va videolarga olish"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Telefon"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"qurilma telefon xizmatidan foydalanish"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"telefonda qo‘ng‘iroq qilish va ularni boshqarish"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorlar"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"taqiladigan qurilmalar va sensorlarni ko‘rish"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"Sensor va taqiladigan qurilmalardagi ma’lumotlarga kirish"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Oynadagi kontentni o‘qiydi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Joriy oynadagi kontent mazmunini aniqlaydi."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Tegib o‘rganish xizmatini yoqish"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Ilovaga planshetingizda o‘zgartirishingiz mumkin bo‘lgan, shuningdek, do‘stlaringiz va hamkasblaringizning tadbirlarini qo‘shish, o‘chirish va o‘zgartirish uchun ruxsat beradi. Bu ilovaga go‘yoki taqvim egalari nomidan kelgan xabarlarni jo‘natishga yoki egasiga bildirmasdan tadbirlarni o‘zgartirishga ruxsat berishi mumkin."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Ilovaga televizordagi siz o‘zgartirishingiz mumkin bo‘lgan, jumladan, do‘stlar yoki oila a’zolaringizning tadbirlarini qo‘shish, o‘chirish, o‘zgartirish huquqini beradi. Uning yordamida ilova xabarlarni taqvim egalari nomidan yuborishi yoki tadbirlarni egasidan beruxsat tahrirlashi mumkin bo‘ladi."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ilovaga telefoningizda o‘zgartirishingiz mumkin bo‘lgan, shuningdek, do‘stlaringiz va hamkasblaringizning tadbirlarini qo‘shish, o‘chirish va o‘zgartirish uchun ruxsat beradi. Bu ilovaga go‘yoki taqvim egalari nomidan kelgan xabarlarni jo‘natishga yoki egasiga bildirmasdan tadbirlarni o‘zgartirishga ruxsat berishi mumkin."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"sinash uchun maska manzillari manbalari"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Sinash uchun joylashuv emulyatsiyasi manbalarini yarating yoki yangi joylashuvni aniqlovchi tizimni o‘rnating. Bu ilovaga GPS yoki joylashuvni aniqlovchi tizimlar kabi boshqa joylashuv manbalari tomonidan qaytarilgan joylashuv ma‘lumotlari/yoki holatlarini o‘zgartirishga ruxsat beradi."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"qo‘shimcha manzillarga kirish buyruqlari"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ilovaga qo‘shimcha joylashuv xizmati buyruqlaridan foydalanishga ruxsat beradi. Uning yordamida ilova GPS yoki boshqa joylashuv ma’lumoti manbalarining ishlashiga xalaqit qilishi mumkin."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"aniq joylashuv (GPS va tarmoqqa asoslanib)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Barmoq izi tekshiruvi bekor qilindi."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Urinishlar soni ko‘payib ketdi. Keyinroq qayta urinib ko‘ring."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Qayta urinib ko‘ring."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"sinx-sh sozlamalarini o‘qish"</string>
@@ -517,7 +517,7 @@
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Ekran qulfini o‘zgartiradi."</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Ekranni qulflash"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Ekranning qachon va qanday qulflanishini boshqaradi."</string>
- <string name="policylab_wipeData" msgid="3910545446758639713">"Barcha ma’lumotlarni o‘chirish"</string>
+ <string name="policylab_wipeData" msgid="3910545446758639713">"Barcha ma’lumotlarni tozalash"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Planshet ma’lumotlarini ogohlantirishlarsiz ishlab chiqarilgan holatiga tiklash orqali o‘chirish"</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Zavod sozlamalarini qayta tiklash orqali televizordagi ma’lumotlarni ogohlantirishsiz o‘chirib tashlaydi."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Telefon ma’lumotlarini ogohlantirishlarsiz zavod sozlamalarini tiklash orqali o‘chirish"</string>
@@ -911,7 +911,7 @@
<string name="anr_application_process" msgid="8941757607340481057">"<xliff:g id="APPLICATION">%1$s</xliff:g> javob bermayapti. Uni yopishni xohlaysizmi?"</string>
<string name="anr_process" msgid="6513209874880517125">"<xliff:g id="PROCESS">%1$s</xliff:g> jarayoni javob bermayapti.\n\nUni yopishni xohlaysizmi?"</string>
<string name="force_close" msgid="8346072094521265605">"OK"</string>
- <string name="report" msgid="4060218260984795706">"Ma’lumot berish"</string>
+ <string name="report" msgid="4060218260984795706">"Xabar berish"</string>
<string name="wait" msgid="7147118217226317732">"Kuting"</string>
<string name="webpage_unresponsive" msgid="3272758351138122503">"Sahifa javob bermayapti.\n\nUni yopishni xohlaysizmi?"</string>
<string name="launch_warning_title" msgid="1547997780506713581">"Ilova qayta yo‘naltirildi"</string>
@@ -990,7 +990,7 @@
<string name="wifi_p2p_from_message" msgid="570389174731951769">"Kimdan:"</string>
<string name="wifi_p2p_to_message" msgid="248968974522044099">"Kimga:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"So‘ralgan PIN kodni kiriting:"</string>
- <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
+ <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN-kod:"</string>
<string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Planshet <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ga ulanganligi tufayli vaqtincha Wi-Fi tarmog‘idan uzildi."</string>
<string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"Televizor <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasiga ulangan vaqtda Wi-Fi tarmog‘idan vaqtinchalik uziladi"</string>
<string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Telefon <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ga ulanganligi tufayli vaqtincha Wi-Fi tarmog‘idan uzildi."</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Agar USB xotirani ulasangiz, ba‘zi ishlab turgan ilovalar to‘xtab qolishi hamda USB xotira uzilmaguncha ishlamay qolishi mumkin."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB jarayoni muvaffaqiyatsiz yakunlandi"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Media qurilma sifatida ulangan"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Kamera sifatida ulandi"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"MIDI qurilma sifatida ulandi"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"O‘rnatgich sifatida ulandi"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"USB jihozga ulangan"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Boshqa USB sozlamalarini ko‘rish uchun bosing."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"USB xotira formatlansinmi?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"SD karta formatlansinmi?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB xotiradagi barcha fayllar o‘chirib tashlanadi. Ushbu amalni ortga qaytarib bo‘lmaydi!"</string>
@@ -1234,7 +1240,7 @@
<string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ma’lumot cheklovdan o‘tdi"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Chegaradan <xliff:g id="SIZE">%s</xliff:g> oshib ketdi."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"Orqa fon ma’lumotlari cheklangan"</string>
- <string name="data_usage_restricted_body" msgid="6741521330997452990">"Cheklovni olib tashlash uchun bosing."</string>
+ <string name="data_usage_restricted_body" msgid="6741521330997452990">"Cheklovni olib tashlash…"</string>
<string name="ssl_certificate" msgid="6510040486049237639">"Xavfsizlik sertifikati"</string>
<string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ushbu sertifikat - to‘g‘ri."</string>
<string name="issued_to" msgid="454239480274921032">"Tegishli:"</string>
@@ -1243,12 +1249,12 @@
<string name="org_unit" msgid="7265981890422070383">"Tashkilotning bir qismi:"</string>
<string name="issued_by" msgid="2647584988057481566">"Tegishli:"</string>
<string name="validity_period" msgid="8818886137545983110">"Yaroqliligi:"</string>
- <string name="issued_on" msgid="5895017404361397232">"E’lon qilingan:"</string>
- <string name="expires_on" msgid="3676242949915959821">"Eskirish sanasi:"</string>
+ <string name="issued_on" msgid="5895017404361397232">"Chiqarilgan sana:"</string>
+ <string name="expires_on" msgid="3676242949915959821">"Amal qilish muddati:"</string>
<string name="serial_number" msgid="758814067660862493">"Serial raqam:"</string>
<string name="fingerprints" msgid="4516019619850763049">"Barmoq izlari:"</string>
- <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 imzo:"</string>
- <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 imzo:"</string>
+ <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 barmoq izi:"</string>
+ <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 barmoq izi:"</string>
<string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Barchasini ko‘rish"</string>
<string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Harakat turini tanlang"</string>
<string name="share_action_provider_share_with" msgid="5247684435979149216">"Ulashish"</string>
@@ -1455,7 +1461,7 @@
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ilova qadab qo‘yilgan. Uni ekrandan yechish ushbu qurilmada ta’qiqlangan."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran qadab qo‘yildi"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran bo‘shatildi"</string>
- <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Bo‘shatishdan oldin PIN kod so‘ralsin"</string>
+ <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Yechishda PIN-kod so‘ralsin"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Bo‘shatishdan oldin chizmali parol so‘ralsin"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Bo‘shatishdan oldin parol so‘ralsin"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Administratoringiz tomonidan o‘rnatilgan"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d daqiqa (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> gacha)</item>
<item quantity="one">Bir daqiqa (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> gacha)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d soat (<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g> gacha)</item>
<item quantity="one">Bir soat (<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g> gacha)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d daqiqa</item>
<item quantity="one">Bir daqiqa</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d soat</item>
<item quantity="one">Bir soat</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Men o‘chirmaguncha"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Bezovta qilinmasin"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Nofaol vaqt"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Dam olish kunlari kechqurun"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Dam olish kunlari"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Tadbir"</string>
<string name="muted_by" msgid="6147073845094180001">"“<xliff:g id="THIRD_PARTY">%1$s</xliff:g>” tomonidan ovozsiz qilingan"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. U zavod sozlamalari tiklanmaguncha barqaror ishlamasligi mumkin."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Qurilmangiz bilan bog‘liq ichki muammo mavjud. Tafsilotlar uchun qurilmangiz ishlab chiqaruvchisiga murojaat qiling."</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 7450aee..84995a3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Ứng dụng cá nhân"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Cơ quan"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Danh bạ"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"truy cập và sửa đổi danh bạ của bạn"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"truy cập vào danh bạ của bạn"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Vị trí"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"truy cập vị trí của bạn"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Thông tin xã hội của bạn"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Truy cập trực tiếp vào thông tin về các địa chỉ liên hệ và các kết nối xã hội của bạn."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Lịch"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"truy cập và sửa đổi lịch của bạn"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"truy cập lịch của bạn"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"Tin nhắn SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"truy cập và sửa đổi tin nhắn SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"xem và quản lý tin nhắn SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Từ điển người dùng"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Đọc hoặc viết các từ trong từ điển người dùng."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Dấu trang và lịch sử"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Truy cập trực tiếp vào dấu trang và lịch sử trình duyệt."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"Micrô"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"sử dụng micrô của thiết bị"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"ghi âm"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Máy ảnh"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"sử dụng máy ảnh của thiết bị"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"chụp ảnh và quay video"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Điện thoại"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"sử dụng điện thoại của thiết bị"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"thực hiện và quản lý cuộc gọi điện thoại"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Cảm biến"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"truy cập cảm biến và thiết bị đeo được"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"truy cập dữ liệu từ cảm biến và các thiết bị có thể đeo"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Truy xuất nội dung cửa sổ"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Kiểm tra nội dung của cửa sổ bạn đang tương tác."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Bật Khám phá bằng cách chạm"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Cho phép ứng dụng thêm, xóa, thay đổi các sự kiện mà bạn có thể sửa đổi trên máy tính bảng của mình, bao gồm những sự kiện của bạn bè hoặc đồng nghiệp. Việc này có thể cho phép ứng dụng gửi tin nhắn dường như đến từ chủ sở hữu lịch hoặc sửa đổi các sự kiện mà chủ sở hữu không biết."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Cho phép ứng dụng thêm, xóa, thay đổi các sự kiện mà bạn có thể sửa đổi trên TV của mình, bao gồm những sự kiện của bạn bè hoặc đồng nghiệp. Việc này có thể cho phép ứng dụng gửi tin nhắn mà dường như đến từ chủ sở hữu lịch hoặc sửa đổi các sự kiện mà chủ sở hữu không biết."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Cho phép ứng dụng thêm, xóa, thay đổi các sự kiện mà bạn có thể sửa đổi trên điện thoại của mình, bao gồm những sự kiện của bạn bè hoặc đồng nghiệp. Việc này có thể cho phép ứng dụng gửi tin nhắn dường như đến từ chủ sở hữu lịch hoặc sửa đổi các sự kiện mà chủ sở hữu không biết."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"các nguồn vị trí mô phỏng cho thử nghiệm"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Tạo nguồn vị trí mô phỏng cho thử nghiệm hoặc cài đặt nhà cung cấp vị trí mới. Việc này cho phép ứng dụng ghi đè vị trí và/hoặc trạng thái được trả về bởi các nguồn vị trí khác như GPS hoặc nhà cung cấp vị trí."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"truy cập vào các lệnh của nhà cung cấp vị trí bổ sung"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Cho phép ứng dụng truy cập vào các lệnh của nhà cung cấp vị trí bổ sung. Điều này có thể cho phép ứng dụng can thiệp vào hoạt động của Hệ thống định vị toàn cầu (GPS) hoặc các nguồn vị trí khác."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"vị trí chính xác (dựa vào mạng và GPS)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Thao tác dùng dấu vân tay bị hủy."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Quá nhiều lần thử. Hãy thử lại sau."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Thử lại."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"đọc cài đặt đồng bộ hóa"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Nếu bạn bật bộ lưu trữ USB, một số ứng dụng bạn đang sử dụng sẽ dừng và có thể không khả dụng cho tới khi bạn tắt bộ lưu trữ USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Thao tác USB không thành công"</string>
<string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Được kết nối là thiết bị truyền thông"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Được kết nối là máy ảnh"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Đã kết nối dưới dạng thiết bị MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Được kết nối như trình cài đặt"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Đã kết nối với phụ kiện USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Chạm để có các tùy chọn USB khác."</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Định dạng USB?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Định dạng thẻ SD?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Tất cả các tệp được lưu trữ trong bộ lưu trữ USB sẽ bị xóa. Không thể hoàn nguyên tác vụ này!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">Trong %1$d phút (cho đến <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Trong một phút (cho đến <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">Trong %1$d giờ (cho đến <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">Trong một giờ (cho đến <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">Trong %d phút</item>
<item quantity="one">Trong một phút</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">Trong %d giờ</item>
<item quantity="one">Trong một giờ</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Cho đến <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Cho đến khi bạn tắt tính năng này"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Thu gọn"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Không làm phiền"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Thời gian ngừng hoạt động"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Đêm trong tuần"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Cuối tuần"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Sự kiện"</string>
<string name="muted_by" msgid="6147073845094180001">"Do <xliff:g id="THIRD_PARTY">%1$s</xliff:g> tắt tiếng"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Đã xảy ra sự cố nội bộ với thiết bị của bạn và thiết bị có thể sẽ không ổn định cho tới khi bạn thiết lập lại dữ liệu ban đầu."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Đã xảy ra sự cố nội bộ với thiết bị. Hãy liên hệ với nhà sản xuất của bạn để biết chi tiết."</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 41f7648..6d660e2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"个人应用"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"工作"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"通讯录"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"存取和修改您的通讯录"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"使用您的通讯录"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"存取您的位置信息"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交信息"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接访问与您的联系人和社交人脉相关的信息。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日历"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"存取和修改您的日历"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"访问您的日历"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"短信"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"存取和修改短信"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"查看和管理短信"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"用户字典"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"读取用户字典中的字词或写入新字词。"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"书签和历史记录"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接访问书签和浏览器历史记录。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麦克风"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"使用设备的麦克风"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"录制音频"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相机"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"使用设备的摄像头"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"拍摄照片和录制视频"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"电话"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"使用设备的电话服务"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"拨打电话和管理通话"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"传感器"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"存取传感器和穿戴式设备的数据"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"访问传感器和穿戴式设备的数据"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"检索窗口内容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"检查您正与其进行互动的窗口的内容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"启用触摸浏览"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"允许该应用添加、删除、更改您可在平板电脑上修改的活动,包括朋友或同事的活动。此权限可让该应用冒充日历所有者发送消息,或在所有者不知情的情况下修改活动。"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"允许应用添加、移除和更改您可在电视上修改的活动,包括朋友或同事的活动。此权限可让应用冒充日历所有者来发送消息,或在所有者不知情的情况下修改活动。"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"允许该应用添加、删除、更改您可在手机上修改的活动,包括朋友或同事的活动。此权限可让该应用冒充日历所有者发送消息,或在所有者不知情的情况下修改活动。"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"使用模拟地点来源进行测试"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"创建用于测试的模拟位置源或安装新的位置提供程序。此权限可让该应用覆盖由其他位置源(如GPS)或位置提供程序返回的位置和/或状态信息。"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"获取额外的位置信息提供程序命令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允许该应用使用其他的位置信息提供程序命令。此权限使该应用可以干扰GPS或其他位置信息源的运作。"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"精确位置(基于GPS和网络)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"指纹操作已取消。"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"尝试次数过多,请稍后重试。"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"请重试。"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"读取同步设置"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您打开USB存储设备,您正在使用的某些应用将会停止,并且在您关闭USB存储设备前都将无法使用。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB操作失败"</string>
<string name="dlg_ok" msgid="7376953167039865701">"确定"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"已作为媒体设备连接"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"作为相机连接"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"已作为 MIDI 设备连接"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"作为安装程序连接"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已连接到USB配件"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"触摸可显示其他USB选项。"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"格式化USB存储设备吗?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"要格式化SD卡吗?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"您的USB存储设备中存储的所有文件都将清除。该操作无法撤消!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">%1$d 分钟(到<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">1 分钟(到<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">%1$d 小时(到<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">1 小时(到<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">%d 分钟</item>
<item quantity="one">1 分钟</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">%d 小时</item>
<item quantity="one">1 小时</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"直到您将其关闭"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收起"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"勿扰"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"休息时间"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"周一至周五夜间"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"周末"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"活动"</string>
<string name="muted_by" msgid="6147073845094180001">"已被<xliff:g id="THIRD_PARTY">%1$s</xliff:g>设为静音"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"您的设备内部出现了问题。如果不将设备恢复出厂设置,设备运行可能会不稳定。"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"您的设备内部出现了问题。请联系您的设备制造商了解详情。"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index bf7d8ca..c27013a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"通訊錄"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"存取和修改您的聯絡人"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取你的通訊錄"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"存取您的位置"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交資訊"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接存取您的聯絡人資訊和社交網站資訊。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"存取和修改您的日曆"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取你的日曆"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"短訊"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"存取和修改短訊"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"查看及管理短訊"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"使用者字典"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"讀取或寫入使用者字典中的字詞。"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"書籤和記錄"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接存取書籤和瀏覽器紀錄。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"使用裝置上的麥克風"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄製語音訊息"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"使用裝置上的相機"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照及錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"使用裝置上的電話"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"存取感應器和穿戴式裝置"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"從感應器及穿戴式裝置存取資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您使用中的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"開啟「輕觸探索」功能"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"允許應用程式新增、移除及更改您可以在平板電腦上修改的活動,包括好友或同事的活動。如此一來,應用程式或可偽裝日曆擁有者傳送訊息,或在擁有者不知情下擅自修改活動。"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"允許應用程式新增、移除和更改您可以在電視上修改的活動,包括好友或同事的活動。這可能會讓應用程式冒認日曆擁有者傳送訊息,或擅自修改活動。"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"允許應用程式新增、移除及更改您可以在手機上修改的活動,包括好友或同事的活動。如此一來,應用程式或可偽裝日曆擁有者傳送訊息,或在擁有者不知情下擅自修改活動。"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"用於測試的模擬位置源"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"建立虛構的位置資訊來源以供測試,或安裝新的位置資訊提供程式。這項權限允許應用程式覆寫 GPS 或位置資訊提供程式等其他位置資訊來源所傳回的位置資訊和/或狀態。"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"接收額外的位置提供者指令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允許應用程式存取額外的位置提供者指令。這項設定可能會使應用程式干擾 GPS 或其他位置來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"精確位置 (以 GPS 和網絡為基準)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋操作已取消。"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"嘗試次數過多,請稍後再試。"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"再試一次。"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您開啟 USB 儲存裝置,則某些正在使用中的應用程式會停止運作,而且可能無法使用,直到關閉 USB 儲存裝置後才會恢復正常。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失敗"</string>
<string name="dlg_ok" msgid="7376953167039865701">"確定"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"已作為媒體裝置連線"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"已作為相機連線"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"已連接為 MIDI 裝置"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"已作為安裝程式連線"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接到一個 USB 配件"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"輕觸即可顯示其他 USB 選項。"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"格式化 USB 儲存裝置?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"格式化 SD 記憶卡?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"即將清除所有儲存在 USB 儲存裝置上的檔案。這項操作無法復原!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">需時 %1$d 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">需時 1 分鐘 (完成時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">需時 %1$d 小時 (完成時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">需時 1 小時 (完成時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">需時 %d 分鐘</item>
<item quantity="one">需時 1 分鐘</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">需時 %d 小時</item>
<item quantity="one">需時 1 小時</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"直至您關閉這項設定"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"請勿干擾"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"休息時間"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"平日夜間"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"活動"</string>
<string name="muted_by" msgid="6147073845094180001">"靜音設定者:<xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"您裝置的系統發生問題,回復原廠設定後即可解決該問題。"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"您裝置的系統發生問題,請聯絡您的製造商瞭解詳情。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 9177482..5eb9789 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"個人應用程式"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"公司"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"聯絡人"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"存取及修改您的聯絡人資料"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取您的聯絡人"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"存取您的位置資訊"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"您的社交資訊"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"直接存取您的聯絡人資訊與社交網站資訊。"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"日曆"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"存取及修改您的日曆資料"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"存取您的日曆"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"簡訊"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"存取及修改簡訊"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"查看及管理簡訊"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"使用者字典"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"讀取使用者字典中的字詞或寫入新字詞"</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"書籤與紀錄"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"直接存取書籤和瀏覽器紀錄。"</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"麥克風"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"使用裝置麥克風"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"錄音"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"相機"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"使用裝置相機"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"拍照及錄製影片"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"電話"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"使用裝置電話通訊系統"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"撥打電話及管理通話"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"感應器"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"存取感應器和穿戴式裝置"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"存取感應器和穿戴式裝置的資料"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"擷取視窗內容"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"檢查您存取的視窗內容。"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"啟用輕觸探索功能"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"允許應用程式新增、移除、變更您可以在平板電腦上修改的活動,包括好友或同事的活動。這項設定可能會讓應用程式偽裝日曆擁有者傳送訊息,或私自修改活動。"</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"允許應用程式新增、移除、變更您可以在電視上修改的活動,包括好友或同事的活動。應用程式可能會藉此偽裝日曆擁有者傳送訊息,或逕自修改活動。"</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"允許應用程式新增、移除、變更您可以在手機上修改的活動,包括好友或同事的活動。這項設定可能會讓應用程式偽裝日曆擁有者傳送訊息,或私自修改活動。"</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"模擬位置來源以供測試"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"建立虛構的位置資訊來源以供測試,或安裝新的位置資訊提供者。這項設定可讓應用程式覆寫 GPS 或位置資訊提供者等其他位置資訊來源所傳回的位置資訊和/或狀態。"</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"接收額外的位置提供者指令"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允許應用程式存取額外位置資訊提供者指令。這項設定可能會造成應用程式干擾 GPS 或其他位置資訊來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"精確位置 (以 GPS 和網路為基準)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"指紋作業已取消。"</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"嘗試次數過多,請稍後再試。"</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"請再試一次。"</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"讀取同步處理設定"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您開啟 USB 儲存裝置,則某些正在使用中的應用程式會停止運作,而且可能無法使用,直到關閉 USB 儲存裝置後才會恢復正常。"</string>
<string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失敗"</string>
<string name="dlg_ok" msgid="7376953167039865701">"確定"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"已視為媒體裝置連線"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"已視為相機連線"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"已採用 MIDI 模式連接到電腦"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"已視為安裝程式連線"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"已連接 USB 配件"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"輕觸即可顯示其他 USB 選項。"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"將 USB 儲存裝置格式化?"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"將 SD 卡格式化?"</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"USB 儲存裝置上儲存的所有檔案即將遭到清除。這項動作無法復原!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="other">持續 %1$d 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">持續 1 分鐘 (結束時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="other">持續 %1$d 小時 (結束時間:<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="one">持續 1 小時 (結束時間:<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="other">持續 %d 分鐘</item>
<item quantity="one">持續 1 分鐘</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="other">持續 %d 小時</item>
<item quantity="one">持續 1 小時</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"手動關閉這項設定前一律啟用"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"零打擾"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"停機"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"週間晚上"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"活動"</string>
<string name="muted_by" msgid="6147073845094180001">"由 <xliff:g id="THIRD_PARTY">%1$s</xliff:g> 設為靜音"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"您的裝置發生內部問題,必須將裝置恢復原廠設定才能解除不穩定狀態。"</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"您的裝置發生內部問題,詳情請洽裝置製造商。"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 822d842..d5dff4b 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -220,27 +220,27 @@
<string name="user_owner_label" msgid="6465364741001216388">"Izinhlelo zokusebenza zomuntu siqu"</string>
<string name="managed_profile_label" msgid="6260850669674791528">"Umsebenzi"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Oxhumana nabo"</string>
- <string name="permgroupdesc_contacts" msgid="1437393511338346185">"finyelela uphinde ulungise oxhumana nabo"</string>
+ <string name="permgroupdesc_contacts" msgid="6951499528303668046">"finyelela koxhumana nabo"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Indawo"</string>
<string name="permgroupdesc_location" msgid="536889867433972794">"finyelela kundawo yakho"</string>
<string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ulwazi lakho lomphakathi"</string>
<string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Ukufinyelela okuqondile kulwazi mayelana noxhumana nabo bomphakathi."</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Ikhalenda"</string>
- <string name="permgroupdesc_calendar" msgid="2116049656685591803">"finyelela uphinde ulungise ikhalenda yakho"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"finyelela kukhalenda yakho"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"I-SMS"</string>
- <string name="permgroupdesc_sms" msgid="3695085582674524761">"finyelela uphinde ulungise i-SMS"</string>
+ <string name="permgroupdesc_sms" msgid="3714409903876407981">"buka uphinde uphathe imilayezo ye-SMS"</string>
<string name="permgrouplab_dictionary" msgid="8114410334955871144">"Isichazamazwi somsebenzisi"</string>
<string name="permgroupdesc_dictionary" msgid="7586787746354378335">"Funda noma bhala amagama kusichazamazwi somsebenzisi."</string>
<string name="permgrouplab_bookmarks" msgid="1949519673103968229">"Amabhukhimakhi nomlando"</string>
<string name="permgroupdesc_bookmarks" msgid="4169771606257963028">"Ukufinyelela okuqondile kumlando wamabhukimakhi nesiphequluli."</string>
<string name="permgrouplab_microphone" msgid="171539900250043464">"I-Microphone"</string>
- <string name="permgroupdesc_microphone" msgid="1296196977187629181">"sebenzisa imakrofoni yedivayisi"</string>
+ <string name="permgroupdesc_microphone" msgid="4988812113943554584">"rekhoda ividiyo"</string>
<string name="permgrouplab_camera" msgid="4820372495894586615">"Ikhamela"</string>
- <string name="permgroupdesc_camera" msgid="2429930670410559293">"sebenzisa ikhamela yedivayisi"</string>
+ <string name="permgroupdesc_camera" msgid="3250611594678347720">"thatha izithombe uphinde urekhode ividiyo"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"Ifoni"</string>
- <string name="permgroupdesc_phone" msgid="2016641188146068700">"sebenzisa ifoni yedivayisi"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"yenza uphinde uphathe amakholi wefoni"</string>
<string name="permgrouplab_sensors" msgid="7416703484233940260">"Izinzwa"</string>
- <string name="permgroupdesc_sensors" msgid="2987451839455524494">"finyelela izinzwa nokugqokwayo"</string>
+ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"finyelela kudatha esuka kuzinzwa namadivayisi agqokekayo"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Thola okuqukethwe kwewindi"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Hlola okuqukethwe kwewindi ohlanganyela nalo."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vula ukuhlola ngokuthinta"</string>
@@ -335,8 +335,6 @@
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Ivumela uhlelo lokusebenza ukungeza, ukususa, ukushintsha izehlakalo ongazishintsha kuthebhulethi yakho, kufaka phakathi nalezo zabangani noma labo osebenza nabo. Lokhu kungavumela uhlelo lokusebenza ukuthumela imilayezo ebonakala ngathi ivela kubanikazi bekhalenda, noma lishintshe izehlakalo ngaphandle kolwazi labanikazi."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"Ivumela uhlelo lokusebenza ukuthi lungeze, lususe, luguqule imicimbi ongayiguqula ku-TV yakho, okufaka leyo yabangani noma osebenza nabo. Lokhu kungavumela uhlelo lokusebenza ukuthi lithumele imilayezo ebonakala ivela kubanikazi bekhalenda, noma liguqule imicimbi ngaphandle kolwazi lomnikazi."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Ivumela uhlelo lokusebenza ukungeza, ukususa, ukushintsha izehlakalo ongazishintsha efonini yakho, kufaka phakathi nalezo zabangani noma labo osebenza nabo. Lokhu kungavumela uhlelo lokusebenza ukuthumela imilayezo ebonakala ngathi ivela kubanikazi bekhalenda, noma lishintshe izehlakalo ngaphandle kolwazi labanikazi."</string>
- <string name="permlab_accessMockLocation" msgid="8688334974036823330">"lungisela imithombo yendawo ukuhlolwa"</string>
- <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Dala imithombo yendawo ye-mock ngokuhlola noma ukufaka umnikeli wendawo omusha. Lokhu kuvumela uhlelo lokusebenza ukubhala ngaphezulu indawo kanye/noma isimo esibuyiswe eminye imithombo yendawo njenge-GPS noma abanikeli bendawo."</string>
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"finyelela kweminye imiyalo yokunikeza indawo"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ivumela uhlelo lokusebenza ukufinyelela imiyalo eyengeziwe yabahlinzeki bendawo. Lokhu kungase kuvumele uhlelo lokusebenza ukuthi liphazamisane nomsebenzi we-GPS noma eminye imithombo yendawo."</string>
<string name="permlab_accessFineLocation" msgid="1191898061965273372">"indawo eqondile (kususelwe ku-GPS nakunethiwekhi)"</string>
@@ -438,6 +436,8 @@
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Ukusebenza kwezingxivizo zeminwe kukhanseliwe."</string>
<string name="fingerprint_error_lockout" msgid="5536934748136933450">"Imizamo eminingi kakhulu. Zama futhi emuva kwesikhathi."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Zama futhi."</string>
+ <!-- no translation found for fingerprint_name_template (5870957565512716938) -->
+ <skip />
<string-array name="fingerprint_error_vendor">
</string-array>
<string name="permlab_readSyncSettings" msgid="6201810008230503052">"funda izilungiselelo zokuvumelanisa"</string>
@@ -1042,12 +1042,18 @@
<string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Uma uvula okokulondoloza kwe-USB, ezinye izinhlelo zokusebenza ozisebenzisayo ziyoma futhi kungenzeka zingatholakali kuze kube ucisha ukulondoloza kwe-USB."</string>
<string name="dlg_error_title" msgid="7323658469626514207">"Ukusebenza kwe-USB kwehlulekile"</string>
<string name="dlg_ok" msgid="7376953167039865701">"KULUNGILE"</string>
- <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Ixhunyiwe njengedivayisi yemidiya"</string>
- <string name="usb_ptp_notification_title" msgid="1960817192216064833">"Ixhunywe njengekhamera"</string>
- <string name="usb_midi_notification_title" msgid="1399152904227676460">"Kuxhunywe njengedivayisi ye-MIDI"</string>
+ <!-- no translation found for usb_charging_notification_title (4004114449249406402) -->
+ <skip />
+ <!-- no translation found for usb_mtp_notification_title (8396264943589760855) -->
+ <skip />
+ <!-- no translation found for usb_ptp_notification_title (1347328437083192112) -->
+ <skip />
+ <!-- no translation found for usb_midi_notification_title (4850904915889144654) -->
+ <skip />
<string name="usb_cd_installer_notification_title" msgid="6774712827892090754">"Ixhunywe njengesifaki"</string>
<string name="usb_accessory_notification_title" msgid="7848236974087653666">"Ixhunywe ku-accessory ye-USB"</string>
- <string name="usb_notification_message" msgid="2290859399983720271">"Cindezela ukuze ubone ezinye izinketho ze-USB"</string>
+ <!-- no translation found for usb_notification_message (7347368030849048437) -->
+ <skip />
<string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Fometha isitoreji se-USB"</string>
<string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Fometha ikhadi le-SD."</string>
<string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Onke amafayela agcinwe kwi-USB yakho ayosuswa. Lesi senzo ngeke siququleke!"</string>
@@ -1466,30 +1472,31 @@
<item quantity="one">Okwamaminithi angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Okwamaminithi angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_summary_short (6830154222366042597) -->
<plurals name="zen_mode_duration_hours_summary" formatted="false" msgid="8152974162096743862">
<item quantity="one">Kwamahora angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
<item quantity="other">Kwamahora angu-%1$d (kuze kube ngo-<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_summary_short (4787552595253082371) -->
<plurals name="zen_mode_duration_minutes" formatted="false" msgid="5127407202506485571">
<item quantity="one">Amaminithi angu-%d</item>
<item quantity="other">Amaminithi angu-%d</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_minutes_short (2199350154433426128) -->
<plurals name="zen_mode_duration_hours" formatted="false" msgid="3938821308277433854">
<item quantity="one">Amahora angu-%d</item>
<item quantity="other">Amahora angu-%d</item>
</plurals>
+ <!-- no translation found for zen_mode_duration_hours_short (6748277774662434217) -->
<string name="zen_mode_until" msgid="7336308492289875088">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_forever" msgid="7420011936770086993">"Uze uvale lokhu"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Goqa"</string>
<string name="zen_mode_feature_name" msgid="5254089399895895004">"Ungaphazamisi"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Isikhathi sokuphumula"</string>
- <!-- no translation found for zen_mode_default_weeknights_name (3081318299464998143) -->
- <skip />
- <!-- no translation found for zen_mode_default_weekends_name (2786495801019345244) -->
- <skip />
- <!-- no translation found for zen_mode_default_events_name (8158334939013085363) -->
- <skip />
+ <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Ubusuku beviki"</string>
+ <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Ngempelasonto"</string>
+ <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Umcimbi"</string>
<string name="muted_by" msgid="6147073845094180001">"Ithuliswe ngu-<xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
<string name="system_error_wipe_data" msgid="6608165524785354962">"Kukhona inkinga yangaphakathi ngedivayisi yakho, futhi ingase ibe engazinzile kuze kube yilapho usetha kabusha yonke idatha."</string>
<string name="system_error_manufacturer" msgid="8086872414744210668">"Kukhona inkinga yangaphakathi ngedivayisi yakho. Xhumana nomkhiqizi wakho ukuze uthole imininingwane."</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 0b96d22..0d7d868 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2722,21 +2722,21 @@
for example "top|bottom". -->
<attr name="scrollIndicators">
<!-- No scroll indicators are displayed. -->
- <flag name="none" value="0x0000" />
+ <flag name="none" value="0x00" />
<!-- Displays top scroll indicator when view can be scrolled up. -->
- <flag name="top" value="0x0100" />
+ <flag name="top" value="0x01" />
<!-- Displays bottom scroll indicator when vew can be scrolled down. -->
- <flag name="bottom" value="0x0200" />
+ <flag name="bottom" value="0x02" />
<!-- Displays left scroll indicator when vew can be scrolled left. -->
- <flag name="left" value="0x0400" />
+ <flag name="left" value="0x04" />
<!-- Displays right scroll indicator when vew can be scrolled right. -->
- <flag name="right" value="0x0800" />
+ <flag name="right" value="0x08" />
<!-- Displays right scroll indicator when vew can be scrolled in the
start direction. -->
- <flag name="start" value="0x1000" />
+ <flag name="start" value="0x10" />
<!-- Displays right scroll indicator when vew can be scrolled in the
end direction. -->
- <flag name="end" value="0x2000" />
+ <flag name="end" value="0x20" />
</attr>
</declare-styleable>
@@ -4369,6 +4369,17 @@
<!-- Line breaking stratgegy balances line lengths. -->
<enum name="balanced" value="2" />
</attr>
+ <!-- Frequency of automatic hyphenation. -->
+ <attr name="hyphenationFrequency">
+ <!-- No hyphenation. -->
+ <enum name="none" value="0" />
+ <!-- Less frequent hyphenation, useful for informal use cases, such
+ as chat messages. -->
+ <enum name="normal" value="1" />
+ <!-- Standard amount of hyphenation, useful for running text and for
+ screens with limited space for text. -->
+ <enum name="full" value="2" />
+ </attr>
<!-- Array of indents, one dimension value per line, left side. -->
<attr name="leftIndents" format="reference" />
<!-- Array of indents, one dimension value per line, right side. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 59c6e4f..470e345 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1070,29 +1070,29 @@
is launched that task will or will not start depending on whether the package of this
activity has been whitelisted.
<p>Tasks rooted at this activity can only exit lockTask mode using stopLockTask(). -->
- <enum name="lockTaskModeDefault" value="0"/>
+ <enum name="normal" value="0"/>
<!-- Tasks will not launch into lockTask mode and cannot be placed there using
{@link android.app.Activity#startLockTask} or be pinned from the Overview screen.
If the system is already in lockTask mode when a new task rooted at this activity is
launched that task will not be started.
<p>Note: This mode is only available to system and privileged applications.
- Non-privileged apps with this value will be treated as lockTaskModeDefault.
+ Non-privileged apps with this value will be treated as normal.
-->
- <enum name="lockTaskModeNever" value="1"/>
+ <enum name="never" value="1"/>
<!-- Tasks rooted at this activity will always launch into lockTask mode. If the system is
already in lockTask mode when this task is launched then the new task will be launched
on top of the current task. Tasks launched in this mode are capable of exiting
lockTask mode using finish(), whereas tasks entering lockTask mode using
startLockTask() must use stopLockTask() to exit.
<p>Note: This mode is only available to system and privileged applications.
- Non-privileged apps with this value will be treated as lockTaskModeDefault.
+ Non-privileged apps with this value will be treated as normal.
-->
- <enum name="lockTaskModeAlways" value="2"/>
+ <enum name="always" value="2"/>
<!-- If the DevicePolicyManager (DPM) authorizes this package ({@link
android.app.admin.DevicePolicyManager#setLockTaskPackages}) then this mode is
- identical to lockTaskModeAlways. If the DPM does not authorize this package then this
- mode is identical to lockTaskModeDefault. -->
- <enum name="lockTaskModeIfWhitelisted" value="3"/>
+ identical to always. If the DPM does not authorize this package then this
+ mode is identical to normal. -->
+ <enum name="if_whitelisted" value="3"/>
</attr>
<!-- When set installer will extract native libraries. If set to false
libraries in the apk must be stored and page-aligned. -->
@@ -1105,7 +1105,7 @@
intern filter data scheme is set to "http" or "https". When set to true, the intent filter
will need to use its data tag for getting the URIs to verify with.
- For each URI, an HTTPS network request will be done to <code>/.well-known/associations.json</code>
+ For each URI, an HTTPS network request will be done to <code>/.well-known/statements.json</code>
host to verify that the web site is okay with the app intercepting the URI.
-->
<attr name="autoVerify" format="boolean" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 690fd28..84e4ca9 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2144,4 +2144,11 @@
<!-- Whether device supports double tap to wake -->
<bool name="config_supportDoubleTapWake">false</bool>
+
+ <!-- The RadioAccessFamilies supported by the device.
+ Empty is viewed as "all". Only used on devices which
+ don't support RIL_REQUEST_GET_RADIO_CAPABILITY
+ format is UMTS|LTE|... -->
+ <string translatable="false" name="config_radio_access_family"></string>
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e403a16..b60a333 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2688,4 +2688,5 @@
<public type="attr" name="stylusButtonPressable" />
<public type="attr" name="supportsLaunchVoiceAssistFromKeyguard" />
<public type="attr" name="scrollIndicators" />
+ <public type="attr" name="hyphenationFrequency" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 5b564e1..0e6b2df 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -946,14 +946,6 @@
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_accessMockLocation">mock location sources for testing</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessMockLocation">Create mock location sources for
- testing or install a new location provider. This allows the app to
- override the location and/or status returned by other location sources
- such as GPS or location providers.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_accessLocationExtraCommands">access extra location provider commands</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_accessLocationExtraCommands">Allows the app to access
@@ -1255,6 +1247,9 @@
<!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
<string name="fingerprint_error_unable_to_process">Try again.</string>
+ <!-- Template to be used to name enrolled fingerprints by default. -->
+ <string name="fingerprint_name_template">Finger <xliff:g id="fingerId" example="1">%d</xliff:g></string>
+
<!-- Array containing custom error messages from vendor. Vendor is expected to add and translate these strings -->
<string-array name="fingerprint_error_vendor">
</string-array>
@@ -1413,9 +1408,9 @@
<string name="permdesc_bindCarrierMessagingService">Allows the holder to bind to the top-level interface of a carrier messaging service. Should never be needed for normal apps.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_bindCarrierConfigService">bind to a carrier config service</string>
+ <string name="permlab_bindCarrierServices">bind to carrier services</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_bindCarrierConfigService">Allows the holder to bind to a carrier config service. Should never be needed for normal apps.</string>
+ <string name="permdesc_bindCarrierServices">Allows the holder to bind to carrier services. Should never be needed for normal apps.</string>
<!-- Policy administration -->
@@ -2916,18 +2911,20 @@
<!-- USB_STORAGE_ERROR dialog ok button-->
<string name="dlg_ok">OK</string>
+ <!-- USB_PREFERENCES: Notification for when the user connected to the charger only. This is the title -->
+ <string name="usb_charging_notification_title">USB for charging</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MTP mode. This is the title -->
- <string name="usb_mtp_notification_title">Connected as a media device</string>
+ <string name="usb_mtp_notification_title">USB for file transfer</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in PTP mode. This is the title -->
- <string name="usb_ptp_notification_title">Connected as a camera</string>
+ <string name="usb_ptp_notification_title">USB for photo transfer</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in MIDI mode. This is the title -->
- <string name="usb_midi_notification_title">Connected as a MIDI device</string>
+ <string name="usb_midi_notification_title">USB for MIDI</string>
<!-- USB_PREFERENCES: Notification for when the user connects the phone to a computer via USB in mass storage mode (for installer CD image). This is the title -->
<string name="usb_cd_installer_notification_title">Connected as an installer</string>
<!-- USB_PREFERENCES: Notification for when a USB accessory is attached. This is the title -->
<string name="usb_accessory_notification_title">Connected to a USB accessory</string>
<!-- See USB_PREFERENCES. This is the message. -->
- <string name="usb_notification_message">Touch for other USB options.</string>
+ <string name="usb_notification_message">Touch for more options.</string>
<!-- External media format dialog strings -->
<!-- This is the label for the activity, and should never be visible to the user. -->
@@ -4031,24 +4028,48 @@
<item quantity="other">For %1$d minutes (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
</plurals>
+ <!-- Zen mode condition - summary: time duration in minutes (short version). [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_minutes_summary_short">
+ <item quantity="one">For 1 min (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
+ <item quantity="other">For %1$d min (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
+ </plurals>
+
<!-- Zen mode condition - summary: time duration in hours. [CHAR LIMIT=NONE] -->
<plurals name="zen_mode_duration_hours_summary">
<item quantity="one">For one hour (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
<item quantity="other">For %1$d hours (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
</plurals>
+ <!-- Zen mode condition - summary: time duration in hours (short version). [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_hours_summary_short">
+ <item quantity="one">For 1 hr (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
+ <item quantity="other">For %1$d hr (until <xliff:g id="formattedTime" example="10:00 PM">%2$s</xliff:g>)</item>
+ </plurals>
+
<!-- Zen mode condition - line one: time duration in minutes. [CHAR LIMIT=NONE] -->
<plurals name="zen_mode_duration_minutes">
<item quantity="one">For one minute</item>
<item quantity="other">For %d minutes</item>
</plurals>
+ <!-- Zen mode condition - line one: time duration in minutes (short version). [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_minutes_short">
+ <item quantity="one">For 1 min</item>
+ <item quantity="other">For %d min</item>
+ </plurals>
+
<!-- Zen mode condition - line one: time duration in hours. [CHAR LIMIT=NONE] -->
<plurals name="zen_mode_duration_hours">
<item quantity="one">For one hour</item>
<item quantity="other">For %d hours</item>
</plurals>
+ <!-- Zen mode condition - line one: time duration in hours (short version). [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_hours_short">
+ <item quantity="one">For 1 hr</item>
+ <item quantity="other">For %d hr</item>
+ </plurals>
+
<!-- Zen mode condition - line two: ending time. [CHAR LIMIT=NONE] -->
<string name="zen_mode_until">Until <xliff:g id="formattedTime" example="10:00 PM">%1$s</xliff:g></string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 3c3d286..4c02d79 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -498,6 +498,7 @@
<item name="textEditSuggestionItemLayout">?attr/textEditSuggestionItemLayout</item>
<item name="textCursorDrawable">?attr/textCursorDrawable</item>
<item name="breakStrategy">high_quality</item>
+ <item name="hyphenationFrequency">normal</item>
</style>
<style name="Widget.CheckedTextView">
@@ -529,6 +530,7 @@
<item name="textColor">?attr/editTextColor</item>
<item name="gravity">center_vertical</item>
<item name="breakStrategy">simple</item>
+ <item name="hyphenationFrequency">normal</item>
</style>
<style name="Widget.ExpandableListView" parent="Widget.ListView">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 89a871b..64e3964 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1790,6 +1790,7 @@
<java-symbol type="string" name="usb_accessory_notification_title" />
<java-symbol type="string" name="usb_cd_installer_notification_title" />
<java-symbol type="string" name="usb_mtp_notification_title" />
+ <java-symbol type="string" name="usb_charging_notification_title" />
<java-symbol type="string" name="usb_notification_message" />
<java-symbol type="string" name="use_physical_keyboard" />
<java-symbol type="string" name="usb_ptp_notification_title" />
@@ -2060,6 +2061,10 @@
<java-symbol type="plurals" name="zen_mode_duration_hours" />
<java-symbol type="plurals" name="zen_mode_duration_minutes_summary" />
<java-symbol type="plurals" name="zen_mode_duration_hours_summary" />
+ <java-symbol type="plurals" name="zen_mode_duration_minutes_short" />
+ <java-symbol type="plurals" name="zen_mode_duration_hours_short" />
+ <java-symbol type="plurals" name="zen_mode_duration_minutes_summary_short" />
+ <java-symbol type="plurals" name="zen_mode_duration_hours_summary_short" />
<java-symbol type="string" name="zen_mode_until" />
<java-symbol type="string" name="zen_mode_feature_name" />
<java-symbol type="string" name="zen_mode_downtime_feature_name" />
@@ -2108,6 +2113,7 @@
<java-symbol type="array" name="fingerprint_acquired_vendor" />
<java-symbol type="string" name="fingerprint_error_canceled" />
<java-symbol type="string" name="fingerprint_error_lockout" />
+ <java-symbol type="string" name="fingerprint_name_template" />
<!-- From various Material changes -->
<java-symbol type="attr" name="titleTextAppearance" />
@@ -2230,6 +2236,13 @@
<java-symbol type="string" name="storage_usb_drive_label" />
<java-symbol type="string" name="storage_usb" />
+ <java-symbol type="drawable" name="ic_eject_24dp" />
+ <java-symbol type="drawable" name="ic_folder_24dp" />
+ <java-symbol type="drawable" name="ic_sd_card_48dp" />
+ <java-symbol type="drawable" name="ic_settings_24dp" />
+ <java-symbol type="drawable" name="ic_storage_48dp" />
+ <java-symbol type="drawable" name="ic_usb_48dp" />
+
<!-- Floating toolbar -->
<java-symbol type="layout" name="floating_popup_container" />
<java-symbol type="layout" name="floating_popup_menu_button" />
@@ -2263,4 +2276,6 @@
<java-symbol type="color" name="chooser_service_row_background_color" />
<java-symbol type="id" name="target_badge" />
<java-symbol type="bool" name="config_supportDoubleTapWake" />
+ <java-symbol type="drawable" name="ic_perm_device_info" />
+ <java-symbol type="string" name="config_radio_access_family" />
</resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index b07d33833..263ea620 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1117,6 +1117,10 @@
</activity>
<activity android:name="android.app.activity.LaunchpadTabActivity" android:multiprocess="true">
</activity>
+ <activity android:name="com.android.internal.app.WindowDecorActionBarTestActivity">
+ </activity>
+ <activity android:name="com.android.internal.policy.PhoneWindowActionModeTestActivity">
+ </activity>
<receiver android:name="android.app.activity.AbortReceiver">
<intent-filter android:priority="1">
diff --git a/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java b/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java
new file mode 100644
index 0000000..b32de78
--- /dev/null
+++ b/core/tests/coretests/src/android/net/netlink/NetlinkSocketTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkSocket;
+import android.net.netlink.RtNetlinkNeighborMessage;
+import android.net.netlink.StructNdMsg;
+import android.net.netlink.StructNlMsgHdr;
+import android.system.ErrnoException;
+import android.system.NetlinkSocketAddress;
+import android.system.OsConstants;
+import android.util.Log;
+import java.io.InterruptedIOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import junit.framework.TestCase;
+
+
+public class NetlinkSocketTest extends TestCase {
+ private final String TAG = "NetlinkSocketTest";
+
+ public void testBasicWorkingGetNeighborsQuery() throws Exception {
+ NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
+ assertNotNull(s);
+
+ s.connectToKernel();
+
+ NetlinkSocketAddress localAddr = s.getLocalAddress();
+ assertNotNull(localAddr);
+ assertEquals(0, localAddr.getGroupsMask());
+ assertTrue(0 != localAddr.getPortId());
+
+ final int TEST_SEQNO = 5;
+ final byte[] request = RtNetlinkNeighborMessage.newGetNeighborsRequest(TEST_SEQNO);
+ assertNotNull(request);
+
+ final long TIMEOUT = 500;
+ assertTrue(s.sendMessage(request, 0, request.length, TIMEOUT));
+
+ int neighMessageCount = 0;
+ int doneMessageCount = 0;
+
+ while (doneMessageCount == 0) {
+ ByteBuffer response = null;
+ response = s.recvMessage(TIMEOUT);
+ assertNotNull(response);
+ assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
+ assertEquals(0, response.position());
+ assertEquals(ByteOrder.nativeOrder(), response.order());
+
+ // Verify the messages at least appears minimally reasonable.
+ while (response.remaining() > 0) {
+ final NetlinkMessage msg = NetlinkMessage.parse(response);
+ assertNotNull(msg);
+ final StructNlMsgHdr hdr = msg.getHeader();
+ assertNotNull(hdr);
+
+ if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
+ doneMessageCount++;
+ continue;
+ }
+
+ assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
+ assertTrue(msg instanceof RtNetlinkNeighborMessage);
+ assertTrue((hdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0);
+ assertEquals(TEST_SEQNO, hdr.nlmsg_seq);
+ assertEquals(localAddr.getPortId(), hdr.nlmsg_pid);
+
+ neighMessageCount++;
+ }
+ }
+
+ assertEquals(1, doneMessageCount);
+ // TODO: make sure this test passes sanely in airplane mode.
+ assertTrue(neighMessageCount > 0);
+
+ s.close();
+ }
+}
diff --git a/core/tests/coretests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java b/core/tests/coretests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
new file mode 100644
index 0000000..0634281
--- /dev/null
+++ b/core/tests/coretests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.netlink;
+
+import android.net.netlink.NetlinkConstants;
+import android.net.netlink.NetlinkMessage;
+import android.net.netlink.RtNetlinkNeighborMessage;
+import android.net.netlink.StructNdMsg;
+import android.net.netlink.StructNlMsgHdr;
+import android.system.OsConstants;
+import android.util.Log;
+import libcore.util.HexEncoding;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import junit.framework.TestCase;
+
+
+public class RtNetlinkNeighborMessageTest extends TestCase {
+ private final String TAG = "RtNetlinkNeighborMessageTest";
+
+ // Hexadecimal representation of packet capture.
+ public static final String RTM_DELNEIGH_HEX =
+ // struct nlmsghdr
+ "4c000000" + // length = 76
+ "1d00" + // type = 29 (RTM_DELNEIGH)
+ "0000" + // flags
+ "00000000" + // seqno
+ "00000000" + // pid (0 == kernel)
+ // struct ndmsg
+ "02" + // family
+ "00" + // pad1
+ "0000" + // pad2
+ "15000000" + // interface index (21 == wlan0, on test device)
+ "0400" + // NUD state (0x04 == NUD_STALE)
+ "00" + // flags
+ "01" + // type
+ // struct nlattr: NDA_DST
+ "0800" + // length = 8
+ "0100" + // type (1 == NDA_DST, for neighbor messages)
+ "c0a89ffe" + // IPv4 address (== 192.168.159.254)
+ // struct nlattr: NDA_LLADDR
+ "0a00" + // length = 10
+ "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
+ "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
+ "0000" + // padding, for 4 byte alignment
+ // struct nlattr: NDA_PROBES
+ "0800" + // length = 8
+ "0400" + // type (4 == NDA_PROBES, for neighbor messages)
+ "01000000" + // number of probes
+ // struct nlattr: NDA_CACHEINFO
+ "1400" + // length = 20
+ "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
+ "05190000" + // ndm_used, as "clock ticks ago"
+ "05190000" + // ndm_confirmed, as "clock ticks ago"
+ "190d0000" + // ndm_updated, as "clock ticks ago"
+ "00000000"; // ndm_refcnt
+ public static final byte[] RTM_DELNEIGH =
+ HexEncoding.decode(RTM_DELNEIGH_HEX.toCharArray(), false);
+
+ // Hexadecimal representation of packet capture.
+ public static final String RTM_NEWNEIGH_HEX =
+ // struct nlmsghdr
+ "58000000" + // length = 88
+ "1c00" + // type = 28 (RTM_NEWNEIGH)
+ "0000" + // flags
+ "00000000" + // seqno
+ "00000000" + // pid (0 == kernel)
+ // struct ndmsg
+ "0a" + // family
+ "00" + // pad1
+ "0000" + // pad2
+ "15000000" + // interface index (21 == wlan0, on test device)
+ "0400" + // NUD state (0x04 == NUD_STALE)
+ "80" + // flags
+ "01" + // type
+ // struct nlattr: NDA_DST
+ "1400" + // length = 20
+ "0100" + // type (1 == NDA_DST, for neighbor messages)
+ "fe8000000000000086c9b2fffe6aed4b" + // IPv6 address (== fe80::86c9:b2ff:fe6a:ed4b)
+ // struct nlattr: NDA_LLADDR
+ "0a00" + // length = 10
+ "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
+ "84c9b26aed4b" + // MAC Address (== 84:c9:b2:6a:ed:4b)
+ "0000" + // padding, for 4 byte alignment
+ // struct nlattr: NDA_PROBES
+ "0800" + // length = 8
+ "0400" + // type (4 == NDA_PROBES, for neighbor messages)
+ "01000000" + // number of probes
+ // struct nlattr: NDA_CACHEINFO
+ "1400" + // length = 20
+ "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
+ "eb0e0000" + // ndm_used, as "clock ticks ago"
+ "861f0000" + // ndm_confirmed, as "clock ticks ago"
+ "00000000" + // ndm_updated, as "clock ticks ago"
+ "05000000"; // ndm_refcnt
+ public static final byte[] RTM_NEWNEIGH =
+ HexEncoding.decode(RTM_NEWNEIGH_HEX.toCharArray(), false);
+
+ // An example of the full response from an RTM_GETNEIGH query.
+ private static final String RTM_GETNEIGH_RESPONSE_HEX =
+ // <-- struct nlmsghr -->|<-- struct ndmsg -->|<-- struct nlattr: NDA_DST -->|<-- NDA_LLADDR -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO -->|
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000001 0a00 0200 333300000001 0000 0800 0400 00000000 1400 0300 a2280000 32110000 32110000 01000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff000001 0a00 0200 3333ff000001 0000 0800 0400 00000000 1400 0300 0d280000 9d100000 9d100000 00000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0400 80 01 1400 0100 20010db800040ca00000000000000001 0a00 0200 84c9b26aed4b 0000 0800 0400 04000000 1400 0300 90100000 90100000 90080000 01000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff47da19 0a00 0200 3333ff47da19 0000 0800 0400 00000000 1400 0300 a1280000 31110000 31110000 01000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 912a0000 21130000 21130000 00000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 922a0000 22130000 22130000 00000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff5c2a83 0a00 0200 3333ff5c2a83 0000 0800 0400 00000000 1400 0300 391c0000 c9040000 c9040000 01000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 01000000 4000 00 02 1400 0100 00000000000000000000000000000000 0a00 0200 000000000000 0000 0800 0400 00000000 1400 0300 cd180200 5d010200 5d010200 08000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 352a0000 c5120000 c5120000 00000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 982a0000 28130000 28130000 00000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0800 80 01 1400 0100 fe8000000000000086c9b2fffe6aed4b 0a00 0200 84c9b26aed4b 0000 0800 0400 00000000 1400 0300 23000000 24000000 57000000 13000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 992a0000 29130000 29130000 01000000" +
+ "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 2e2a0000 be120000 be120000 00000000" +
+ "44000000 1c00 0200 00000000 3e2b0000 02 00 0000 18000000 4000 00 03 0800 0100 00000000 0400 0200 0800 0400 00000000 1400 0300 75280000 05110000 05110000 22000000";
+ public static final byte[] RTM_GETNEIGH_RESPONSE =
+ HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
+
+ public void testParseRtNetlinkNeighborRtmDelNeigh() {
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkNeighborMessage);
+ final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
+
+ final StructNlMsgHdr hdr = neighMsg.getHeader();
+ assertNotNull(hdr);
+ assertEquals(76, hdr.nlmsg_len);
+ assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type);
+ assertEquals(0, hdr.nlmsg_flags);
+ assertEquals(0, hdr.nlmsg_seq);
+ assertEquals(0, hdr.nlmsg_pid);
+
+ final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
+ assertNotNull(ndmsgHdr);
+ assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family);
+ assertEquals(21, ndmsgHdr.ndm_ifindex);
+ assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
+ final InetAddress destination = neighMsg.getDestination();
+ assertNotNull(destination);
+ assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
+ }
+
+ public void testParseRtNetlinkNeighborRtmNewNeigh() {
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkNeighborMessage);
+ final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
+
+ final StructNlMsgHdr hdr = neighMsg.getHeader();
+ assertNotNull(hdr);
+ assertEquals(88, hdr.nlmsg_len);
+ assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
+ assertEquals(0, hdr.nlmsg_flags);
+ assertEquals(0, hdr.nlmsg_seq);
+ assertEquals(0, hdr.nlmsg_pid);
+
+ final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
+ assertNotNull(ndmsgHdr);
+ assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family);
+ assertEquals(21, ndmsgHdr.ndm_ifindex);
+ assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
+ final InetAddress destination = neighMsg.getDestination();
+ assertNotNull(destination);
+ assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
+ }
+
+ public void testParseRtNetlinkNeighborRtmGetNeighResponse() {
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
+ byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
+
+ int messageCount = 0;
+ while (byteBuffer.remaining() > 0) {
+ final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
+ assertNotNull(msg);
+ assertTrue(msg instanceof RtNetlinkNeighborMessage);
+ final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
+
+ final StructNlMsgHdr hdr = neighMsg.getHeader();
+ assertNotNull(hdr);
+ assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
+ assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
+ assertEquals(0, hdr.nlmsg_seq);
+ assertEquals(11070, hdr.nlmsg_pid);
+
+ messageCount++;
+ }
+ // TODO: add more detailed spot checks.
+ assertEquals(14, messageCount);
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTest.java b/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTest.java
new file mode 100644
index 0000000..57881af
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.internal.app;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * Tests for {@link WindowDecorActionBar}.
+ */
+public class WindowDecorActionBarTest
+ extends ActivityInstrumentationTestCase2<WindowDecorActionBarTestActivity> {
+ private WindowDecorActionBar mWindowDecorActionBar;
+ private MockActionModeCallback mCallback;
+
+ public WindowDecorActionBarTest() {
+ super(WindowDecorActionBarTestActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mWindowDecorActionBar = (WindowDecorActionBar) getActivity().getActionBar();
+ mCallback = new MockActionModeCallback();
+ }
+
+ @UiThreadTest
+ public void testStartActionMode() {
+ ActionMode mode = mWindowDecorActionBar.startActionMode(mCallback);
+
+ assertNotNull(mode);
+ assertTrue(mCallback.mIsCreateActionModeCalled);
+ }
+
+ @UiThreadTest
+ public void testStartActionModeWhenCreateReturnsFalse() {
+ mCallback.mShouldCreateActionMode = false;
+
+ ActionMode mode = mWindowDecorActionBar.startActionMode(mCallback);
+
+ assertNull(mode);
+ assertTrue(mCallback.mIsCreateActionModeCalled);
+ }
+
+ @UiThreadTest
+ public void testStartActionModeFinishesPreviousMode() {
+ ActionMode mode1 = mWindowDecorActionBar.startActionMode(mCallback);
+ ActionMode mode2 = mWindowDecorActionBar.startActionMode(new MockActionModeCallback());
+
+ assertNotNull(mode1);
+ assertNotNull(mode2);
+ assertTrue(mCallback.mIsDestroyActionModeCalled);
+ }
+
+ private static final class MockActionModeCallback implements ActionMode.Callback {
+ private boolean mShouldCreateActionMode = true;
+ private boolean mIsCreateActionModeCalled = false;
+ private boolean mIsDestroyActionModeCalled = false;
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mIsDestroyActionModeCalled = true;
+ }
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mIsCreateActionModeCalled = true;
+ return mShouldCreateActionMode;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTestActivity.java b/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTestActivity.java
new file mode 100644
index 0000000..52bb38b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/WindowDecorActionBarTestActivity.java
@@ -0,0 +1,32 @@
+/*
+ * 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.internal.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.Window;
+
+public class WindowDecorActionBarTestActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
+ setContentView(new View(this));
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
new file mode 100644
index 0000000..b860c20
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTest.java
@@ -0,0 +1,372 @@
+/*
+ * 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.internal.policy;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ActionMode;
+import android.view.ActionMode.Callback;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.SearchEvent;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager.LayoutParams;
+import android.view.accessibility.AccessibilityEvent;
+
+/**
+ * Tests {@link PhoneWindow}'s {@link ActionMode} related methods.
+ */
+public final class PhoneWindowActionModeTest
+ extends ActivityInstrumentationTestCase2<PhoneWindowActionModeTestActivity> {
+
+ private PhoneWindow mPhoneWindow;
+ private MockWindowCallback mWindowCallback;
+ private MockActionModeCallback mActionModeCallback;
+
+ public PhoneWindowActionModeTest() {
+ super(PhoneWindowActionModeTestActivity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mPhoneWindow = (PhoneWindow) getActivity().getWindow();
+ mWindowCallback = new MockWindowCallback();
+ mPhoneWindow.setCallback(mWindowCallback);
+ mActionModeCallback = new MockActionModeCallback();
+ }
+
+ public void testStartActionModeWithCallback() {
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+
+ assertEquals(mWindowCallback.mLastCreatedActionMode, mode);
+ }
+
+ public void testStartActionModePrimaryFinishesPreviousMode() {
+ // Use custom callback to control the provided ActionMode.
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+ ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+
+ assertTrue(mode1 instanceof MockActionMode);
+ assertTrue(((MockActionMode) mode1).mIsFinished);
+ assertNotNull(mode2);
+ }
+
+ public void testStartActionModeFloatingFinishesPreviousMode() {
+ // Use custom callback to control the provided ActionMode.
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+ ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+
+ assertTrue(mode1 instanceof MockActionMode);
+ assertTrue(((MockActionMode) mode1).mIsFinished);
+ assertNotNull(mode2);
+ }
+
+ public void testStartActionModePreservesPreviousModeOfDifferentType1() {
+ // Use custom callback to control the provided ActionMode.
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+ ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+
+ assertTrue(mode1 instanceof MockActionMode);
+ assertFalse(((MockActionMode) mode1).mIsFinished);
+ assertNotNull(mode2);
+ }
+
+ public void testStartActionModePreservesPreviousModeOfDifferentType2() {
+ // Use custom callback to control the provided ActionMode.
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode1 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+ ActionMode mode2 = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+
+ assertTrue(mode1 instanceof MockActionMode);
+ assertFalse(((MockActionMode) mode1).mIsFinished);
+ assertNotNull(mode2);
+ }
+
+ public void testWindowCallbackModesLifecycleIsNotHandled() {
+ mWindowCallback.mShouldReturnOwnActionMode = true;
+
+ ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+
+ assertNotNull(mode);
+ assertEquals(mWindowCallback.mLastCreatedActionMode, mode);
+ assertFalse(mActionModeCallback.mIsCreateActionModeCalled);
+ assertTrue(mWindowCallback.mIsActionModeStarted);
+ }
+
+ @UiThreadTest
+ public void testCreatedPrimaryModeLifecycleIsHandled() {
+ mWindowCallback.mShouldReturnOwnActionMode = false;
+
+ ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_PRIMARY);
+
+ assertNotNull(mode);
+ assertEquals(ActionMode.TYPE_PRIMARY, mode.getType());
+ assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
+ assertTrue(mWindowCallback.mIsActionModeStarted);
+ }
+
+ @UiThreadTest
+ public void testCreatedFloatingModeLifecycleIsHandled() {
+ mWindowCallback.mShouldReturnOwnActionMode = false;
+
+ ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+
+ assertNotNull(mode);
+ assertEquals(ActionMode.TYPE_FLOATING, mode.getType());
+ assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
+ assertTrue(mWindowCallback.mIsActionModeStarted);
+ }
+
+ @UiThreadTest
+ public void testCreatedModeIsNotStartedIfCreateReturnsFalse() {
+ mWindowCallback.mShouldReturnOwnActionMode = false;
+ mActionModeCallback.mShouldCreateActionMode = false;
+
+ ActionMode mode = mPhoneWindow.getDecorView().startActionMode(
+ mActionModeCallback, ActionMode.TYPE_FLOATING);
+
+ assertTrue(mActionModeCallback.mIsCreateActionModeCalled);
+ assertFalse(mWindowCallback.mIsActionModeStarted);
+ assertNull(mode);
+ }
+
+ private static final class MockWindowCallback implements Window.Callback {
+ private boolean mShouldReturnOwnActionMode = false;
+ private MockActionMode mLastCreatedActionMode;
+ private boolean mIsActionModeStarted = false;
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchTrackballEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchGenericMotionEvent(MotionEvent event) {
+ return false;
+ }
+
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ return false;
+ }
+
+ @Override
+ public View onCreatePanelView(int featureId) {
+ return null;
+ }
+
+ @Override
+ public boolean onCreatePanelMenu(int featureId, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onPreparePanel(int featureId, View view, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onMenuOpened(int featureId, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ return false;
+ }
+
+ @Override
+ public void onWindowAttributesChanged(LayoutParams attrs) {}
+
+ @Override
+ public void onContentChanged() {}
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {}
+
+ @Override
+ public void onAttachedToWindow() {}
+
+ @Override
+ public void onDetachedFromWindow() {}
+
+ @Override
+ public void onPanelClosed(int featureId, Menu menu) {}
+
+ @Override
+ public boolean onSearchRequested() {
+ return false;
+ }
+
+ @Override
+ public boolean onSearchRequested(SearchEvent searchEvent) {
+ return false;
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(Callback callback) {
+ if (mShouldReturnOwnActionMode) {
+ MockActionMode mode = new MockActionMode();
+ mLastCreatedActionMode = mode;
+ return mode;
+ }
+ return null;
+ }
+
+ @Override
+ public ActionMode onWindowStartingActionMode(Callback callback, int type) {
+ if (mShouldReturnOwnActionMode) {
+ MockActionMode mode = new MockActionMode();
+ mode.mActionModeType = type;
+ mLastCreatedActionMode = mode;
+ return mode;
+ }
+ return null;
+ }
+
+ @Override
+ public void onActionModeStarted(ActionMode mode) {
+ mIsActionModeStarted = true;
+ }
+
+ @Override
+ public void onActionModeFinished(ActionMode mode) {}
+ }
+
+ private static final class MockActionModeCallback implements ActionMode.Callback {
+ private boolean mShouldCreateActionMode = true;
+ private boolean mIsCreateActionModeCalled = false;
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {}
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ mIsCreateActionModeCalled = true;
+ return mShouldCreateActionMode;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ return false;
+ }
+ }
+
+ private static final class MockActionMode extends ActionMode {
+ private int mActionModeType = ActionMode.TYPE_PRIMARY;
+ private boolean mIsFinished = false;
+
+ @Override
+ public int getType() {
+ return mActionModeType;
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {}
+
+ @Override
+ public void setTitle(int resId) {}
+
+ @Override
+ public void setSubtitle(CharSequence subtitle) {}
+
+ @Override
+ public void setSubtitle(int resId) {}
+
+ @Override
+ public void setCustomView(View view) {}
+
+ @Override
+ public void invalidate() {}
+
+ @Override
+ public void finish() {
+ mIsFinished = true;
+ }
+
+ @Override
+ public Menu getMenu() {
+ return null;
+ }
+
+ @Override
+ public CharSequence getTitle() {
+ return null;
+ }
+
+ @Override
+ public CharSequence getSubtitle() {
+ return null;
+ }
+
+ @Override
+ public View getCustomView() {
+ return null;
+ }
+
+ @Override
+ public MenuInflater getMenuInflater() {
+ return null;
+ }
+ }
+}
diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTestActivity.java
similarity index 64%
copy from keystore/java/android/security/KeyStoreConnectException.java
copy to core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTestActivity.java
index 885f1f7..1516040 100644
--- a/keystore/java/android/security/KeyStoreConnectException.java
+++ b/core/tests/coretests/src/com/android/internal/policy/PhoneWindowActionModeTestActivity.java
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-package android.security;
+package com.android.internal.policy;
-import java.security.ProviderException;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
-/**
- * Indicates a communications error with keystore service.
- *
- * @hide
- */
-public class KeyStoreConnectException extends ProviderException {
- public KeyStoreConnectException() {
- super("Failed to communicate with keystore service");
+public class PhoneWindowActionModeTestActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(new View(this));
}
}
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
new file mode 100644
index 0000000..4a8e18d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarContainerTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.internal.widget;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.view.ActionMode;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Tests for {@link ActionBarContainer}.
+ */
+public class ActionBarContainerTest extends AndroidTestCase {
+ private ActionBarContainer mActionBarContainer;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActionBarContainer = new ActionBarContainer(mContext);
+ }
+
+ public void testPrimaryActionModesAreStopped() {
+ TestViewGroup viewGroup = new TestViewGroup(mContext);
+ viewGroup.addView(mActionBarContainer);
+
+ ActionMode mode = mActionBarContainer.startActionModeForChild(
+ null, null, ActionMode.TYPE_PRIMARY);
+
+ assertNull(mode);
+ // Should not bubble up.
+ assertFalse(viewGroup.isStartActionModeForChildTypedCalled);
+ assertFalse(viewGroup.isStartActionModeForChildTypelessCalled);
+
+ mode = mActionBarContainer.startActionModeForChild(null, null);
+
+ assertNull(mode);
+ // Should not bubble up.
+ assertFalse(viewGroup.isStartActionModeForChildTypedCalled);
+ assertFalse(viewGroup.isStartActionModeForChildTypelessCalled);
+ }
+
+ public void testFloatingActionModesAreBubbledUp() {
+ TestViewGroup viewGroup = new TestViewGroup(mContext);
+ viewGroup.addView(mActionBarContainer);
+
+ ActionMode mode = mActionBarContainer.startActionModeForChild(
+ null, null, ActionMode.TYPE_FLOATING);
+
+ // Should bubble up.
+ assertNotNull(mode);
+ assertTrue(viewGroup.isStartActionModeForChildTypedCalled);
+ }
+
+ private static class TestViewGroup extends ViewGroup {
+ boolean isStartActionModeForChildTypedCalled = false;
+ boolean isStartActionModeForChildTypelessCalled = false;
+
+ public TestViewGroup(Context context) {
+ super(context);
+ }
+
+ @Override
+ public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
+ isStartActionModeForChildTypelessCalled = true;
+ return super.startActionModeForChild(originalView, callback);
+ }
+
+ @Override
+ public ActionMode startActionModeForChild(
+ View originalView, ActionMode.Callback callback, int type) {
+ isStartActionModeForChildTypedCalled = true;
+ return super.startActionModeForChild(originalView, callback, type);
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {}
+ }
+}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 1ea459f..6d8d81f 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -17,6 +17,11 @@
LOCAL_PATH := $(call my-dir)
+# Use full Noto Sans Japanese font on extended footprint
+ifeq ($(EXTENDED_FONT_FOOTPRINT),true)
+FONT_NOTOSANS_JP_FULL := true
+endif
+
##########################################
# create symlink for given font
# $(1): new font $(2): link target
diff --git a/docs/html/design/index.jd b/docs/html/design/index.jd
index 638f35b..1ffb0a3 100644
--- a/docs/html/design/index.jd
+++ b/docs/html/design/index.jd
@@ -41,8 +41,12 @@
</div>
</div>
</section>
-
-<section class="dac-section dac-gray dac-small dac-invert"><div class="wrap">
+<div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button href="#latest">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
+</div>
+<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap">
<h2 class="norule">Latest</h2>
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:design/landing/latest"
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index 970aded..d66f8f4 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -9,41 +9,50 @@
excludeFromSuggestions=true
@jd:body
-<section class="dac-expand dac-hero dac-light">
+ <section class="dac-expand dac-hero dac-blue">
<div class="wrap">
<div class="cols dac-hero-content">
<div class="col-1of2 col-push-1of2 dac-hero-figure">
- <img class="dac-hero-image" src="/images/develop/hero-android-studio-on-device.png">
+ <img class="dac-hero-image" src="{@docRoot}images/develop/studio-open.png">
</div>
<div class="col-1of2 col-pull-1of2">
- <h1 class="dac-hero-title">Start!</h1>
+ <h1 class="dac-hero-title">Get Started with Android Studio</h1>
<p class="dac-hero-description">
- Set up your environment and create an app. Build faster with sample projects and templates.
+ Everything you need to build incredible app experiences on phones and tablets, Wear, TV, and Auto. </p>
</p>
- <a class="dac-hero-cta" href="/sdk/index.html">
+ <a class="dac-hero-cta" href="{@docRoot}sdk/index.html">
<span class="dac-sprite dac-auto-chevron"></span>
Set up Android Studio
</a><br>
- <a class="dac-hero-cta" href="/training/basics/firstapp/index.html">
+ <a class="dac-hero-cta" href="{@docRoot}training/basics/firstapp/index.html">
<span class="dac-sprite dac-auto-chevron"></span>
- Make your first app
+ Build your first app
</a><br>
- <a class="dac-hero-cta" href="/guide/index.html">
+ <a class="dac-hero-cta" href="{@docRoot}guide/index.html">
<span class="dac-sprite dac-auto-chevron"></span>
Learn about Android
</a><br>
+ <a class="dac-hero-cta" href="{@docRoot}samples/index.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Sample projects
+ </a><br>
</div>
</div>
- <div class="dac-section dac-small">
+ <!--<div class="dac-section dac-small">
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:develop/landing/mainlinks"
data-cardSizes="6x2"
data-maxResults="6"></div>
- </div>
+ </div>-->
</div>
</section>
+<div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button href="#latest">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
+</div>
-<section class="dac-section dac-gray dac-small dac-invert"><div class="wrap">
+<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap">
<h2 class="norule">Latest</h2>
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:develop/landing/latest"
@@ -51,6 +60,19 @@
data-maxResults="3"></div>
</div></section>
+<section class="dac-section dac-section-light"><div class="wrap">
+ <h1 class="dac-section-title">Tools for building apps</h1>
+ <div class="dac-section-subtitle">
+ Insights into Android's tools and libraries to speed your development.
+ </div>
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:develop/landing/tools"
+ data-cardSizes="6x6"
+ data-maxResults="3"
+ data-sortOrder="random"></div>
+ <ul class="dac-section-links">
+ </ul>
+</div></section>
<section class="dac-section dac-light"><div class="wrap">
<h1 class="dac-section-title">Android performance patterns</h1>
@@ -69,21 +91,8 @@
</ul>
</div></section>
-<section class="dac-section dac-section-light"><div class="wrap">
- <h1 class="dac-section-title">Tools for building apps</h1>
- <div class="dac-section-subtitle">
- Insights into Android's tools and libraries to speed your development.
- </div>
- <div class="resource-widget resource-flow-layout col-16"
- data-query="collection:develop/landing/tools"
- data-cardSizes="6x6"
- data-maxResults="3"></div>
- <ul class="dac-section-links">
- </ul>
-</div></section>
-
-<section class="dac-section dac-light"><div class="wrap">
- <h1 class="dac-section-title">Ubiquitous computing</h1>
+<section class="dac-section dac-gray"><div class="wrap">
+ <h1 class="dac-section-title">Ubiquitous computing on Android</h1>
<div class="dac-section-subtitle">
Opening up new stuff.
</div>
@@ -107,9 +116,10 @@
</ul>
</div></section>
-<section class="dac-section dac-gray"><div class="wrap">
- <h1 class="dac-section-title">Courses</h1>
- <div class="dac-section-subtitle">Free online courses from Android experts that bring you step-by-step to building your own apps.</div>
+<section class="dac-section dac-light"><div class="wrap">
+ <h1 class="dac-section-title">Online Courses</h1>
+ <div class="dac-section-subtitle">Free online courses from Android
+ experts that bring you step-by-step to building your own apps.</div>
<div class="resource-widget resource-flow-layout col-16"
data-query="collection:develop/landing/courses"
data-cardSizes="6x6"
diff --git a/docs/html/distribute/analyze/understand-user-value.jd b/docs/html/distribute/analyze/understand-user-value.jd
index 30dca9c..e561941 100644
--- a/docs/html/distribute/analyze/understand-user-value.jd
+++ b/docs/html/distribute/analyze/understand-user-value.jd
@@ -71,6 +71,53 @@
<img src="{@docRoot}distribute/analyze/images/demographics.png">
</div>
+<h2 id="change">All Things Change with Time, and So Do Your Users</h2>
+
+<p>
+ Getting users to install and open your app the first time is a big accomplishment;
+ however, it’s only the first step of what is hopefully a long and prosperous
+ relationship. The best apps aren’t just the ones with the most downloads, they are
+ the ones that have users coming back day after day, month after month, and year
+ after year.
+</p>
+
+<p>
+ Google Analytics takes a user-centric approach to reporting to help you explore what
+ keeps users coming back. <strong>Cohort Reporting</strong> allows you to see which users
+ come back over time and when usage tends to fall off. You can easily take this same
+ information and overlay it on any other report.
+</p>
+
+<div>
+<img src="{@docRoot}distribute/analyze/images/cohort_reporting.png">
+</div>
+
+<h2 id="measure-value">Measure Value over Time</h2>
+
+<p>
+ Analyzing retention is a great way to ensure users stick with your app and come back day after
+ day. With <strong>Lifetime Value</strong> reporting, you’ll get a full picture of these users’
+ value over time. To get the most out of this report, it’s important to start with a clear
+ definition of what a user’s value means to you based on your business objectives.
+</p>
+
+<p>
+ Once you’ve defined the value, you can access the report to measure certain variables such as
+ revenue per user and number of screen views per user over a period of 90 days. For example, if
+ the goal of your app is to get users to purchase virtual or material goods, you’ll want to use
+ this report to get a clear view of when they make a purchase and how much they are spending in
+ your app over time.
+</p>
+
+<p>
+ Lifetime Value is a key metric to use to measure the effectiveness of your acquisition
+ campaigns. If your cost to acquire a new user is higher than the average value over time,
+ you might want to optimize your campaigns to meet the lifetime revenue they generate. Lifetime
+ Value is particularly valuable if you offer in-app purchases, but it can be applied to
+ discovering many other useful insights, such as number of times they open your app, total
+ number of screens and goal completions.
+</p>
+
<h2 id="cohort">Segment Your Data</h2>
<p>
diff --git a/docs/html/distribute/engage/ads.jd b/docs/html/distribute/engage/ads.jd
new file mode 100644
index 0000000..9ca72f3
--- /dev/null
+++ b/docs/html/distribute/engage/ads.jd
@@ -0,0 +1,58 @@
+page.title=Drive engagement with AdWords Ads
+page.metaDescription=Keep users coming back. AdWords offers re-engagement tools to help your app stay top of mind with users.
+page.tags="engagement, adwords"
+page.image=images/cards/adwords_2x.jpg
+@jd:body
+
+<p>Successful apps keep users coming back again and again. AdWords offers app
+re-engagement tools to help your app stay top of mind with users who’ve
+already installed it on their phone. AdWords can remind them of key features
+and encourage them to try your app again, or help them complete an activity
+they didn't know your app could handle.</p>
+
+<p>
+ <a href="https://support.google.com/adwords/answer/6032073">Get started with AdWords mobile
+ app engagement campaigns</a>.
+</p>
+
+<div>
+ <div class="figure-left" style="width:46%;">
+ <h3>From search</h3>
+ <img src="/images/distribute/promote_ads.png">
+ <p class="figure-caption">Add deep links to your app, then bring users straight
+ to relevant app content when they’re searching.</p>
+ </div>
+ <div class="figure-right" style="width:46%;">
+ <h3>From apps</h3>
+ <img src="/images/distribute/promote_ads_inapp.png">
+ <p class="figure-caption">Use remarketing and deep links to bring users to just the right
+ place in your app to re-engage and convert, from other apps and games they love.</p>
+ </div>
+</div>
+
+<h3 id="tips">Tips</h2>
+
+<ul>
+ <li> Track what users do in your app after they click an ad, by installing the
+ AdWords <a href="https://developers.google.com/app-conversion-tracking/">conversion tracking
+ SDK</a>.
+ <li> Advertise a compelling reason for users to re-engage with your app, such as a
+ reminder or a special offer.
+ <li> <a href="https://developers.google.com/app-indexing/webmasters/app">Add deep links</a> to
+ your app and bring users directly to the most relevant and interesting
+ parts of your app, where they can easily take action.
+ <li> Re-engage with your app users across the Display Network with remarketing lists
+and search with keywords.
+ <li> Use remarketing lists to target high value users so that you can drive more
+conversions in your app.
+</ul>
+
+<h2 id="related_resources">Related resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/engage/reengage"
+ data-sortorder="-timestamp"
+ data-cardsizes="9x3"
+ data-maxresults="6">
+</div>
+
diff --git a/docs/html/distribute/engage/appindexing.jd b/docs/html/distribute/engage/appindexing.jd
new file mode 100644
index 0000000..2b8f315
--- /dev/null
+++ b/docs/html/distribute/engage/appindexing.jd
@@ -0,0 +1,61 @@
+page.title=Bring Users from Google Search
+page.metaDescription=Use search to bring your existing users back into your app.
+page.image=images/cards/adwords_2x.jpg
+page.tags="engagement, search"
+@jd:body
+
+<p>Use the features of Google Search for Android to drive the use of your apps: </p>
+
+<ul>
+<li>Once users have installed your app, search can bring them back with <strong>deep-links</strong> direct to your app. </li>
+ <li>When users use <strong>voice commands</strong> to ask Google to perform a task, your app can be one of those
+completing the task.</li>
+
+<li>You can also take advantage of <strong>Google Now</strong> to
+display cards for event, flight, hotel, and restaurant reservations you notify
+to users’ gmail addresses, and bring users back from the email linked to the
+card.</li>
+</ul>
+
+<p>Start now by <a href="https://developers.google.com/app-indexing/">indexing your app</a>, then take advantage of <a href="https://developers.google.com/voice-actions/">Voice Actions</a>, the <a href="https://developers.google.com/app-indexing/webmasters/appindexingapi">App Indexing API</a>, and <a href="https://developers.google.com/schemas/now/cards">Google Now Cards</a>.</p>
+
+
+<h2 id="help_users_find_your_information">Help Users Find Your Information</h2>
+
+<p>Re-engage with your users with deep-links displayed in search results, links
+that take users directly to content within your app.</p>
+
+
+<div style="margin-top:1.5em;margin-left:24px">
+<img src="{@docRoot}images/distribute/more-app-engagement.png">
+</div>
+<h2 id="empower_users_in_your_app">Empower your users to get things done in your app</h2>
+
+<p>Brings your users into your app to take action with voice actions such as “Ok
+Google, play a song” with the music app of choice, or “Ok Google, search for
+hotels in Maui on TripAdvisor” in the TripAdvisor app.</p>
+
+<div style="margin-top:1em">
+<img src="{@docRoot}images/distribute/music-action.png">
+</div>
+
+
+<h2 id="assist_your_users">Assist your users where and when they need it</h2>
+
+<div class="figure">
+<img src="https://developers.google.com/schemas/images/now_eventconfirmation.png">
+</div>
+
+<p>Inform your users of their reservations with cards created from structured data
+markup delivered in Gmail notifications. Cards also lead users quickly back to
+your email message, for further engagement.</p>
+
+<h2 style="clear:both" id="related-resources">Related Resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/engage/appindexing"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
+
+
diff --git a/docs/html/distribute/engage/deep-linking.jd b/docs/html/distribute/engage/deep-linking.jd
index ea1f1de..0c78a50 100644
--- a/docs/html/distribute/engage/deep-linking.jd
+++ b/docs/html/distribute/engage/deep-linking.jd
@@ -1,99 +1,76 @@
-page.title=Deep Link to Bring Users Back
-page.metaDescription=Use deep links to bring your users into your apps from social posts, search, or ads.
-page.tags="app indexing, google+ signin"
+page.title=Drive Usage with Search
+page.metaDescription=Use search to bring your existing users back into your app.
page.image=images/cards/google-search_2x.png
-
+page.tags=engagement, appindexing, search
@jd:body
<p>
- Use deep links to bring your users into your apps from social posts,
- search, or ads.
-</p>
-
-<div class="headerLine">
-<h2>Deep Linking from Google+ Posts</h2>
-</div>
-
-<p>
- <a href="https://developers.google.com/+/mobile/android/share/deep-link">Deep
- linking</a> allows the Google+ apps on mobile devices to direct clicks on a
- shared post that contains deep-link information to a resource within your
- apps.
-</p>
-
-<p style="margin-bottom:2em;">
- If the user doesn’t have your app installed, they’re prompted to install it
- before accessing the resource.
-</p>
-
-<div style="padding:2em, auto;width:550px;">
- <div style="float:right; width:260px; padding-left:1em;">
- <img src="{@docRoot}images/gp-engage-5.jpg" class="border-img">
- <p class="img-caption">
- G+ Post with Deep Link to Buy
- </p>
- </div>
-
- <div style="width:260px;float:left;">
- <img src="{@docRoot}images/gp-engage-6.jpg" class="border-img">
- <p class="img-caption">
- Purchase page within app
- </p>
- </div>
-</div>
-
-
-<div class="headerLine">
-<h2>Deep Linking from Google Search — App Indexing</h2>
-</div>
-
-
-<div style="float:right;">
- <img src="/images/gp-listing-4.jpg" style="padding-top:1em;padding-left:2em;">
-</div>
-
-<p>
- Another way to bring users back to your apps is to apply for app indexing.
+ Users who have your app installed might overlook it as a way to get the answers
+ they need. With App Indexing, deep links to your Android app appear in Google Search
+ results so users can get to your native mobile experience quickly, landing exactly
+ on the right content within the app.
</p>
<p>
- When a user searches for content available within your app, Google can show
- an "Open in App" button in in mobile search results. For instance, if a user
- searches for a restaurant and you’ve got that establishment in your dining
- app, a link can be shown to open the page within your app. Learn more about
- <a href="https://developers.google.com/app-indexing/">linking to in-app
- content</a>.
-</p>
+ Google Search for developers can also help you re-engage your users in other ways
+ — by letting them interact with your app from a voice action, get deep into
+ your app from a search suggestion, or go back to your email reminders in Google Now. </p>
-<div class="clearfloat" style="margin-top:2em;"></div>
-<div style="float:right;width:340px;padding-left:2em;">
- <img src="/images/gp-ads-linking2.jpg" style="padding-top:1em;">
+<p>Get started by <a href="https://developers.google.com/app-indexing/">indexing your
+app</a> and then take advantage of <a
+href="https://developers.google.com/voice-actions/">Voice actions</a>, the
+<a href="https://developers.google.com/app-indexing/webmasters/appindexingapi">App
+Indexing API</a>, and <a href="https://developers.google.com/schemas/now/cards">Google
+Now cards</a>.</p>
+
+
+<h2 id="help_users_find_your_information">App Indexing</h2>
+
+<p>Re-engage with your users with deep-links displayed in search results, links
+that take users directly to content within your app.</p>
+
+
+<div style="margin:1em">
+<img src="{@docRoot}images/distribute/app-indexing-deep-links.png">
+</div>
+<h2 id="empower_users_in_your_app">Voice actions</h2>
+
+<p>Brings your users into your app with voice actions such as “Ok
+Google, play a song” or “Ok Google, search for
+hotels in Maui on TripAdvisor”.</p>
+
+<div style="margin-top:1em">
+<img src="{@docRoot}images/distribute/voice-actions-engagement.png">
</div>
-<div class="headerLine ">
-<h2>Deep Linking from Google Ads</h2>
-</div>
-<p>
- Ads can remind users about the apps they already have.
-</p>
-<p>
- As with deep links from Google's organic search results, AdWords deep links
- send users directly to the relevant pages in apps they already have on their
- mobile device. A mobile search for "flights to London," for instance, could
- take a user straight to the London page in a travel app. <a href=
- "http://www.thinkwithgoogle.com/products/ads-apps.html"
- class="external-link">Learn more</a>.
-</p>
+<h2 id="assist_your_users">Google Now</h2>
-<div class="headerLine clearfloat">
- <h2 id="related-resources">
- Related Resources
- </h2>
+<div style="margin-top:1em">
+<img src="{@docRoot}images/distribute/google-now-engagement.png">
</div>
-<div class="resource-widget resource-flow-layout col-13" data-query=
-"collection:distribute/engage/deeplinks" data-sortorder="-timestamp"
-data-cardsizes="9x3" data-maxresults="6">
-</div>
+<p>If you’re building travel, entertainment, or restaurant apps, Google Now cards
+can re-engage your users via structured data markup delivered in email notifications.</p>
+
+
+<h2 id="tips">Tips</h2>
+
+<ul>
+ <li>For users who have viewed pages in your app, and later searches for similar content,
+ you can use the App Indexing API to have deep links appear in search suggestions.</li>
+ <li>App Indexing is flexible—you can direct search users to your app or website on a
+ page by page basis. Moving from search results to apps is seamless, without any pop-ups
+ or extra taps to slow users down.</li>
+</ul>
+
+<h2 style="clear:both" id="related-resources">Related Resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/engage/appindexing"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
+
+
diff --git a/docs/html/distribute/engage/engage_toc.cs b/docs/html/distribute/engage/engage_toc.cs
index eb176f9..7094713 100644
--- a/docs/html/distribute/engage/engage_toc.cs
+++ b/docs/html/distribute/engage/engage_toc.cs
@@ -26,7 +26,26 @@
<li class="nav-section">
<div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
var:toroot?>distribute/engage/deep-linking.html">
- <span class="en">Deep Link to Bring Users Back</span></a>
+ <span class="en">Drive Usage with Search</span></a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
+ var:toroot?>distribute/engage/ads.html">
+ <span class="en">Drive engagement with Ads</span></a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
+ var:toroot?>distribute/engage/intents.html">
+ <span class="en">Use the Power of Intents</span></a>
+ </div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
+ var:toroot?>distribute/engage/analytics.html">
+ <span class="en">Understand User Behavior</span></a>
</div>
</li>
<li class="nav-section">
@@ -37,12 +56,6 @@
</li>
<li class="nav-section">
<div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
- var:toroot?>distribute/engage/analytics.html">
- <span class="en">Understand User Behavior</span></a>
- </div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs
var:toroot?>distribute/engage/app-updates.html">
<span class="en">Update Regularly</span></a>
</div>
diff --git a/docs/html/distribute/engage/index.jd b/docs/html/distribute/engage/index.jd
index 2b103c3..a47e004 100644
--- a/docs/html/distribute/engage/index.jd
+++ b/docs/html/distribute/engage/index.jd
@@ -1,5 +1,5 @@
page.title=Engage & Retain Users
-page.metaDescription=Engaging and retaining active users is the key to success. Here are some resources to help you build an active user base.
+page.metaDescription=Engaging and retaining active users are the keys to success. Here are some resources to help you build an active user base.
section.landing=true
nonavpage=true
@@ -15,8 +15,13 @@
<div class="resource-widget resource-flow-layout landing col-16"
data-query="collection:distribute/engagelanding"
- data-cardSizes="9x6,9x6,6x6,6x6,6x6,9x6,9x6,6x6,6x6,6x6"
- data-maxResults="10">
+ data-cardSizes="6x6"
+ data-maxResults="6">
+ </div>
+ <div class="resource-widget resource-flow-layout landing col-16"
+ data-query="collection:distribute/engagelanding"
+ data-cardSizes="6x2"
+ data-maxResults="20">
</div>
<h3>Related Resources</h3>
diff --git a/docs/html/distribute/engage/intents.jd b/docs/html/distribute/engage/intents.jd
new file mode 100644
index 0000000..e8e49d9
--- /dev/null
+++ b/docs/html/distribute/engage/intents.jd
@@ -0,0 +1,39 @@
+page.title=Drive Discovery through Intents
+page.metaDescription=Make your app available to users as they perform tasks in other apps through Intents.
+page.tags="engagement"
+@jd:body
+
+<p>Let the user choose <em>your app</em> to handle specific tasks from another app,
+such as sharing a picture, sending a message, or playing music. You can do this though
+Android's open Intents system. By adding Intent filters for the tasks your app can handle,
+you make it easy for the user to access your app’s features from other apps and from voice
+commands in Google Now.</p>
+
+<img src="{@docRoot}images/distribute/engage-intents.png">
+
+<p>By declaring Intent Filters in your app, it informs the Android OS about the
+actions it can perform for other apps. And in addition to making it easy for
+your users to make full use of your app’s features, it can help them discover
+features they didn’t know it supported.</p>
+
+<p>To learn about all the ways you can use Intents, check out <a
+href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a>.</p>
+
+<h2 id=tips>Tips</h2>
+
+<ul>
+ <li> Identify and package any features your app can offer to other apps.
+ <li> Use the "view" intent to give users the option to open any links to your
+website within your app instead.
+ <li> Familiarize yourself with actions commonly accomplished with intents, such as
+sharing, so that you can focus on your app's core functionality and outsource
+common actions.
+</ul>
+
+<h2 style="clear:both" id="related-resources">Related Resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/engage/intents"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
diff --git a/docs/html/distribute/googleplay/cardboard.jd b/docs/html/distribute/googleplay/cardboard.jd
new file mode 100644
index 0000000..c187ffd
--- /dev/null
+++ b/docs/html/distribute/googleplay/cardboard.jd
@@ -0,0 +1,51 @@
+page.title=Build VR with Google Cardboard
+page.metaDescription=Build apps and games with VR, for a viewer anyone can buy.
+page.image=images/cards/card-cardboard_2x.jpg
+page.tags=vr, carboard, games
+@jd:body
+
+<p>
+ Virtual reality promises to transform the way players view games, taking them from a
+ flat world into the realm of 3D. And it’s not just games, any application that provides
+ a way to visually explore has the possibility to offer users more immersive experiences
+ with VR — like a virtual tour of a famous landmark or a way to visualise atoms in a
+ chemical compound.
+</p>
+
+<div>
+<img src="{@docRoot}images/distribute/cardboard.jpg" />
+</div>
+
+<p>
+ Google Cardboard and the Cardboard SDK provides you with a practical, accessible way to
+ start developing VR, and your users with a simple, fun, and natural way to experience your
+ VR apps and games.
+</p>
+
+<p>
+ Order or make your own <a href="https://www.google.com/get/cardboard/get-cardboard.html">
+ Viewer that works with Google Cardboard</a>. And then find out more about <a
+ href="https://developers.google.com/cardboard/">developing with the Cardboard SDK</a>.
+</p>
+
+<h2 id="tips">Tips</h2>
+<ul>
+ <li>Review our <a
+href="http://www.google.com/design/spec-vr/designing-for-google-cardboard/a-new-dimension.html">
+ best practices for designing Cardboard apps.</li>
+ <li>Check out our <a href="http://stackoverflow.com/questions/tagged/google-cardboard">Stack
+ Overflow tag</a> to find and ask questions about Cardboard development.</li>
+ <li>Join the <a href="https://plus.google.com/communities/111524380182206513071">Cardboard
+ & VR Developers community</a> on Google+ to stay up-to-date on Cardboard and
+ connect with other developers.</li>
+</ul>
+
+<h2 style="clear:both" id="related-resources">Related Resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/googleplay/cardboard"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
+
+
diff --git a/docs/html/distribute/googleplay/cast.jd b/docs/html/distribute/googleplay/cast.jd
new file mode 100644
index 0000000..68c0584
--- /dev/null
+++ b/docs/html/distribute/googleplay/cast.jd
@@ -0,0 +1,49 @@
+page.title=Stream Your Content with Google Cast
+page.metaDescription=Let users stream your video and audio content to TVs and speakers.
+page.image=images/cards/card-cast_2x.jpg
+page.tags=cast, video, chromecast
+@jd:body
+
+<p>
+ The average person spends 3 hours per day watching the TV. With Google Cast
+ you make it easy for users to include your content as part of their viewing
+ schedule. All they need is an Android TV, a TV with a Chromecast plugged in,
+ or a Cast for audio device connected to their audio system.
+</p>
+
+<div>
+<img src="{@docRoot}images/distribute/cast.jpg">
+</div>
+
+<p>
+ Google Cast is a great way to add value and convenience to your content
+ consumption apps, and extend their engagement with your users.
+</p>
+
+<p>
+ <a href="https://developers.google.com/cast/">Find out how to get your app Google
+ Cast-ready</a>.
+</p>
+
+<h2 id="tips">Tips</h2>
+<ul>
+ <li>Cast devices can be low-power devices with memory, CPU, and GPU limitations,
+ so the receiver application should be as lightweight as possible.</li>
+ <li>User interaction should only take place on the Cast sender (phone, tablet,
+ or Chrome browser), not the Cast receiver.</li>
+ <li>While content is loading, provide animated loading indicators and use transitions
+ to help make things feel faster on the Cast sender interface.</li>
+ <li>Let users know your app is “Google Card-enabled” in your store listing and use
+ the <a href="https://developers.google.com/cast/docs/ux_guidelines#brand-guidelines">Google
+ Cast badge</a> on your website and marketing materials.</li>
+</ul>
+
+<h2 style="clear:both" id="related-resources">Related Resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/googleplay/cast"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
+
+
diff --git a/docs/html/distribute/googleplay/families/about.jd b/docs/html/distribute/googleplay/families/about.jd
index c542e0f..5a15490 100644
--- a/docs/html/distribute/googleplay/families/about.jd
+++ b/docs/html/distribute/googleplay/families/about.jd
@@ -7,15 +7,12 @@
@jd:body
<p>
- In several weeks, a new family-focused experience on Google Play will give
- users new ways to browse, search, and discover high quality apps and games
- for their families.
+ If you got great apps targeting kids and/or families, the family-focused experience
+ on Google Play is a great way to make them discoverable by parents.
</p>
-<p>
- To support a more family-friendly store, developers are invited to opt-in
- family-focused apps and games to the new Designed for Families program. Apps
- that meet the <a href=
+<p>Developers are invited to opt-in these apps and games to the new Designed for
+ Families program. Apps that meet the <a href=
"https://support.google.com/googleplay/android-developer/answer/6184502">program
requirements</a> will be shown in the new family experience so that
parents can find suitable, trusted, high-quality apps and games more easily.
@@ -31,11 +28,62 @@
store.
</p>
+<h2 id="benefits">Benefits</h2>
+
+<p>
+ By opting-in to Designed for Families, parents can easily find your family-friendly
+ content on the Google Play store however they are accessing it.
+</p>
+
+<h3>Search</h3>
+
+<p>
+ Only content opted-in to the Designed for Families program will show up in search results
+ from any of the family sections. This is a huge boost to this content as a majority of
+ searches on the Play Store containing the terms “apps for” or “games for” are related to
+ kids.
+</p>
+
+<h3>Browse</h3>
+
+<p>
+ Family sections within Apps, Games, Movies & TV and Music provide enhanced discovery for
+ parents. These sections act as true home pages and contain unique categories tailored to kids
+ content, specific age-based categories, and merchandised content.
+</p>
+
+<h3>Character pages</h3>
+
+<p>
+ All content for particular popular characters can now be found in one place on character pages,
+ including apps, games, movies, tv, and books. It’s a powerful way to promote children’s brands
+ across content, and allows you to reach a highly relevant and targeted audience. Character
+ pages are also a way to alleviate concerns around IP protection, since only properly licensed
+ content is on these pages.
+</p>
+
+<h3>Merchandising</h3>
+
+<p>
+ The family sections have their own merchandised content, with new opportunities for featuring
+ on the home pages of the family sections and and within the age-specific home pages. The pages
+ are curated to ensure quality and limited to only content opted-in to Designed for Families
+ and appropriate for specific age ranges.
+</p>
+
+<h3>Badging</h3>
+
+<p>
+ Apps opted-in to Designed for Families will receive family-friendly badges, which are a marker
+ of quality and signal to parents that apps are suitable for users of specific ages groups.
+ Clicking on a badge also leads you to other apps and games with that badge.
+</p>
+
<h2 id="elibibility">Eligibility</h2>
<p>
- Apps in the family-friendly experience on Google Play will be more
- discoverable by parents and families, who expect the apps to be age
+ Apps in the family-friendly experience on Google Play are more
+ discoverable by parents and families, who expect the apps to appeal to kids under 13 and be age
appropriate. The Designed for Families program is designed to be inclusive of
apps that are made for kids as well as those that can be enjoyed by the
entire family. To address this audience, there are specific guidelines and
diff --git a/docs/html/distribute/googleplay/families/faq.jd b/docs/html/distribute/googleplay/families/faq.jd
index c6fbf86..9f916a8 100644
--- a/docs/html/distribute/googleplay/families/faq.jd
+++ b/docs/html/distribute/googleplay/families/faq.jd
@@ -78,14 +78,44 @@
</dd>
<dt>
+ If I distribute my apps globally, do I need to provide a translated version
+ of my privacy policy for each separate language APK?
+ </dt>
+ <dd>
+ No, you do not need to translate your privacy policy. However, if you
+ distribute your apps in a few select countries, it is advised that you do
+ translate your privacy policy.
+ </dd>
+
+ <dt>
+ How do I decide what age group to select?
+ </dt>
+
+ <dd>
+ Age groups are: Ages 5 & Under, Ages 6-8, and Ages 9-12. If you select one of these
+ age groups, your content must be appropriate for children in the age ranges. You may
+ select the General Audience category only select if your app targets both children
+ under 13 and adults.
+ </dd>
+
+ <dt>
+ What will be different about my app if I select the General Audience category?
+ </dt>
+
+ <dd>
+ There is not a dedicated section for General Audience apps within the family sections.
+ In addition, you can use Google+ Sign-in or Google Play Game Services as an optional
+ feature, but child users must be able to access the app or game in its entirety
+ without signing into Google+ or Google Play Games Service.
+ </dd>
+
+ <dt>
How many age groups can I select?
</dt>
<dd>
- You can select up to two adjacent age groups. Age groups are: Ages 5 &
- Under, Ages 6-8, and Ages 9-12. However, if your app targets audiences
- comprised of children and older audiences, you must select the <em>General
- Audience</em> category.
+ You can select up to two adjacent age groups only if your app is appropriate for
+ multiple age groups.
</dd>
<dt>
@@ -238,12 +268,12 @@
<dl>
<dt>
- Can you give me more details on the advertising policies for Designed for
+ Are ads allowed? Can you give me more details on the advertising policies for Designed for
Families?
</dt>
<dd>
- Read the <a href=
+ Yes, ads are allowed as long as the adhere to the <a href=
"https://support.google.com/googleplay/android-developer/answer/6184502#ads">
ads policy for Designed for Families</a>.
</dd>
@@ -258,6 +288,23 @@
</dd>
<dt>
+ What about full page ads?
+ </dt>
+
+ <dd>
+ You may use full page ads as long as the ad can be dismissed without the user having to
+ interact with it in other ways.
+
+ <dt>
+ Am I allowed to use house/first party ads and product placements within my app?
+ </dt>
+
+ <dd>
+ House ads are allowed, but they must comply with <a
+ href="https://support.google.com/googleplay/android-developer/answer/6184502#ads">ads policies</a>.
+ </dd>
+
+ <dt>
How do I know that my ad network complies with the advertising
policies for Designed for Families?
</dt>
@@ -328,6 +375,17 @@
a different category in the Play store. Apps that have not selected another
category will be assigned to the Casual Games category.
</dd>
+
+ <dt>
+ How can users find character pages?
+ </dt>
+
+ <dd>
+ Character pages are found through the “Popular Characters” tab within each of
+ the verticals. They can also be accessed from character-specific badges on details
+ pages of character content.
+ </dd>
+
</dl>
<div class="paging-links" style="padding-top:.75em;">
diff --git a/docs/html/distribute/googleplay/families/start.jd b/docs/html/distribute/googleplay/families/start.jd
index af4eb3a..0e773bd 100644
--- a/docs/html/distribute/googleplay/families/start.jd
+++ b/docs/html/distribute/googleplay/families/start.jd
@@ -30,7 +30,7 @@
Now that your app is ready to publish, you can opt-in to Designed for
Families directly from the <a href=
"https://play.google.com/apps/publish/">Developer Console</a>. Opt-in means
- that you want your app to be made available on the new family-friendly
+ that you want your app to be made available on the family-friendly
experience on Google Play in addition to the category you’ve selected on
the Google Play Store.
</p>
@@ -64,9 +64,10 @@
style="border:2px solid #ddd;margin:1em 0;"></li>
<li>Choose your target age groups from: Ages 5 & Under, Ages 6 to 8, Ages 9
to 12, or General Audience (for apps which target children and older
- audiences). If your app targets more than one age group, you can choose up to
- two adjacent age groups. Apps with an ESRB 10+ rating can only choose an
- age target of 9-12 or General Audience.
+ audiences). You can choose up to two adjacent age groups only if your app
+ targets more than one age group. Apps with an ESRB 10+ rating can only choose an
+ age target of 9-12 or General Audience. <!--Apps that are found to be inappropriate
+ for the age groups selected will -->
</li>
<li>Choose a category for your app for the new family-focused experience on
@@ -99,7 +100,7 @@
<p>
If you opt-in an app that's already published on Google Play and it doesn't
meet the program requirements, it will remain available to all users but won't
- be added to the new family experience until you update the app to meet the
+ be added to the family experience until you update the app to meet the
program requirements.
</p>
diff --git a/docs/html/distribute/googleplay/googleplay_toc.cs b/docs/html/distribute/googleplay/googleplay_toc.cs
index 78a3731..8a321bb 100644
--- a/docs/html/distribute/googleplay/googleplay_toc.cs
+++ b/docs/html/distribute/googleplay/googleplay_toc.cs
@@ -19,7 +19,7 @@
</li>
<li class="nav-section">
<div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/guide.html">
- <span class="en">Finding Success on Google Play</span>
+ <span class="en">Finding Success on <span style="white-space:nowrap">Google Play</span></span>
</a>
</div>
</li>
@@ -42,6 +42,18 @@
</div>
</li>
<li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/cast.html">
+ <span class="en">Stream Your Content<span style="white-space:nowrap">with Cast</span></span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/cardboard.html">
+ <span class="en"><span style="white-space:nowrap">Build VR with Cardboard</span></span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
<div class="nav-section-header" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/googleplay/families/about.html">
<span class="en">Designed for Families</span>
</a>
diff --git a/docs/html/distribute/index.jd b/docs/html/distribute/index.jd
index c49fe3e..ce64445 100644
--- a/docs/html/distribute/index.jd
+++ b/docs/html/distribute/index.jd
@@ -10,7 +10,13 @@
<div class="dac-hero-carousel" data-carousel-query="collection:distribute/landing/carousel">
</div>
-<section class="dac-section dac-gray dac-small dac-invert"><div class="wrap">
+<div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button href="#latest">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
+</div>
+
+<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap">
<h2 class="norule">Latest</h2>
<div class="resource-widget resource-flow-layout col-16"
data-query="type:youtube+tag:googleplay+tag:developerstory+tag:featured, type:blog+tag:googleplay+tag:distribute+tag:featured"
@@ -74,7 +80,7 @@
<ul class="dac-section-links">
<li class="dac-section-link"><a href="https://developers.google.com/">
<span class="dac-sprite dac-auto-chevron"></span>
- More on Google Developers
+ More Google services for Android
</a></li>
</ul>
</div></section>
diff --git a/docs/html/distribute/monetize/ads.jd b/docs/html/distribute/monetize/ads.jd
index b5c5f4a..8f6c8b0 100644
--- a/docs/html/distribute/monetize/ads.jd
+++ b/docs/html/distribute/monetize/ads.jd
@@ -1,138 +1,129 @@
-page.title=Monetize with Ads
-page.metaDescription=Ads are a quick and easy way to incorporate a monetization option into both your free and paid apps.
-page.tags="monetizing", "free", "freemium", "ads"
-page.image=/distribute/images/advertising.jpg
-
+page.title=Earn Revenue from AdMob Ads
+page.metaDescription=Gain insights about your users, drive more in-app purchases, and maximize your ad revenue.
+page.tags="monetizing", "ads", "admob", "ads"
+page.image=distribute/images/advertising.jpg
@jd:body
<div class="figure">
<img src="{@docRoot}distribute/images/advertising.jpg" style="width:460px;">
</div>
-<p>
- Ads can be a quick and easy way to earn more from your <a href=
- "{@docRoot}distribute/monetize/freemium.html">freemium</a>, <a href=
- "{@docRoot}distribute/monetize/premium.html">premium</a>, and <a href=
- "{@docRoot}distribute/monetize/subscriptions.html">subscription</a> apps.
- AdMob and the Google Mobile Ads SDK let you add advertising to your apps with
- just a few lines of code.
-</p>
+<p>Ads are an effective and easy way to earn revenue from your apps. AdMob brings
+together best-in-class technology in a single ad platform for your app, so you
+can gain insights about your users, drive more in-app purchases, and maximize
+your ad revenue. You won’t need to rely on a combination of tools or use
+precious development resources to build your own solution.</p>
-<p>
- The question is: which model gets the best results for your app? Google's ad
- tools are made to help you figure out what combination works best for both
- your audience and your bottom line. </p>
-
-<p>Start by linking your AdMob and Google
- Analytics accounts to get better insights and more earning power: for
- instance, AdMob can promote in-app purchases to the people who buy them most
- often, while showing income-generating ads to those less likely to buy right
- now.
-</p>
-
-<p>
- Using <a href=
- "http://www.google.com/ads/admob/monetize.html#subid=us-en-et-dac">AdMob</a>
- and the <a href="{@docRoot}google/play-services/ads.html">Google Mobile Ads
- SDK</a> included in Google Play Services, you’re able to add advertising into
- your apps, with just a few lines of code.
-</p>
-
-<p>
- When including ads in your apps you should consider:
-</p>
+<p>Why choose AdMob?</p>
<ul>
- <li>
- <p>
- <strong>Placement within your apps</strong> — Well-placed ads make
- it more likely that users will click through and convert. Poorly-placed
- ads lead to lower click-through rates, and even poor ratings and users
- abandoning your apps. Our <a href=
- "{@docRoot}training/monetization/ads-and-ux.html">developer training</a>
- on using ads shows some of the best ways to place ads.
- </p>
- </li>
-
- <li>
- <p>
- <strong>Ad formats</strong> — Every app offers a different type of
- experience for users, so it’s important that your ad formats match that
- experience. While banner ads may work well for a flashlight utility app,
- an immersive gaming app may benefit more from a video interstitial.
- Mismatched ad formats can make users unhappy and leave money on the
- table.
- </p>
- </li>
-
- <li>
- <p>
- <strong>Maximizing your performance</strong> — Make sure you’re
- optimizing your advertising revenue by maximizing your CPMs and fill
- rate. Ad providers often cite their very high CPMs but don't mention low
- fill rates that can severely decrease your effective CPM. Be sure to look
- at both of these figures. Consider using a <a href=
- "https://support.google.com/admob/v2/answer/3063564?hl=en&ref_topic=3063091#subid=us-en-et-dac">
- mediation</a> solution if you’d like to use multiple ad providers in your
- apps. Look for solutions that offer yield management or <a href=
- "https://support.google.com/admob/v2/answer/3379794?hl=en&ref_topic=3379793#subid=us-en-et-dac">
- network optimization</a> features to serve the highest paying ad for each
- impression.
- </p>
- </li>
-
- <li>
- <p>
- <strong>Exercising control options</strong> — A variety of ads may
- show up within your app. It may make sense to <a href=
- "https://support.google.com/admob/v2/answer/3150235?hl=enl#subid=us-en-et-dac">
- block</a> certain of those advertisements from appearing, depending on
- your goals and the type of experience you want to provide. Some
- developers, for instance, don’t want ads for apps in their same category
- showing to their users, while others don’t mind at all.
- </p>
- </li>
-
- <li>
- <p>
- <strong>Cross promoting your other apps</strong> — Ads can do more
- than earn revenue. Consider running <a href=
- "https://support.google.com/admob/v2/answer/3210452?hl=en#subid=us-en-et-dac">
- house ads</a> within your apps to promote other apps in your portfolio.
- When you launch a new app, this kind of promotion is a free and easy way
- to attract new users quickly.
- </p>
- </li>
+ <li> Over 650,000 apps use AdMob
+ <li> $1 billion+ paid to developers in the last 2 years
+ <li> Fast, reliable payment in local currencies
+ <li> High CPMs and the best fill rates
+ <li> Industry-leading mediation platform
</ul>
-<p>
- Don't forget that paid channels like AdWords and YouTube can help you cast a
- wider net by reaching targeted audiences outside the app ecosystem. They're a
- great way to find new users at a price that you control. <a href=
- "https://support.google.com/adwords/answer/2549053">Learn more</a>.
-</p>
+<p><a href="http://www.google.com/ads/admob/#subid=us-en-et-dac">Sign-up for AdMob</a>
+today and start showing ads by integrating the <a
+href="https://developers.google.com/mobile-ads-sdk/download">Google Mobile Ads SDK</a>
+in your app with a few lines of code.</p>
-<p>
- To start monetizing with ads, sign up for AdMob and integrate the Google
- Mobile Ads SDK into your apps. If you also need to manage direct deals with
- advertisers, consider using DoubleClick for Publishers Small Business.
-</p>
+<h2 id="key_features">Key features</h2>
+
+<div style="display:inline-block">
+<h3 id="maximize_your_ad_revenue">Maximize your ad revenue</h3>
+
+<div class="col-4">
+ <h4 id="maximize_earnings">Maximize earnings</h4>
+ <p>Earn more with our industry-leading ad service, which includes <a href=
+ "https://support.google.com/admob/answer/3063564">free mediation</a> to
+ automatically improve your earnings, and access to all of Google’s advertiser
+ demand from AdMob, AdWords, and the DoubleClick Ad Exchange.</p>
+</div>
+
+<div class="col-4">
+ <h4 id="get_paid_fast">Get paid fast</h4>
+ <p>Get paid in local currencies quickly and reliably, with no wire fees charged by
+ AdMob.</p>
+</div>
+
+<div class="col-4">
+ <h4 id="easy_and_free">Easy and free</h4>
+ <p>The SDK can be installed quickly, and there are no standard fees for using the
+ platform.</p>
+</div>
+</div>
+
+<div style="display:inline-block">
+<h3 id="grow_your_business_with_a_trusted_partner">Grow your business with a trusted partner</h3>
+
+<div class="col-6">
+ <h4 id="powered_by_googles_ad_technology">Powered by Google’s ad technology</h4>
+ <p>For over a decade, Google has helped millions of developers grow their digital
+ businesses.</p>
+</div>
+
+<div class="col-6">
+<h4 id="auto_updates_on_google_play">Auto updates on Google Play</h4>
+<p>AdMob’s integration with Google Play services pushes automatic performance
+ improvements to Android apps without additional SDK changes.</p>
+</div>
+</div>
+
+<div style="display:inline-block">
+<h3 id="drive_more_in-app_purchases_and_downloads">Drive more in-app purchases and downloads</h3>
+
+<div class="col-6">
+<h4 id="sell_more_in-app_purchases">Sell more in-app purchases</h4>
+<p>Earn more revenue by intelligently promoting your in-app purchases to the users
+most likely to buy them.</p>
+</div>
+
+<div class="col-6">
+<h4 id="promote_your_apps_for_free">Promote your apps for free</h4>
+<p>Cross-sell your other apps (or your friend’s apps) to your existing users,
+using free AdMob <a href="https://support.google.com/admob/answer/3210452">house ads</a>.</p>
+</div>
+</div>
+
+<div style="display:inline-block">
+<h3 id="drive_more_in-app_purchases_and_downloads">Drive more in-app purchases and downloads</h3>
+
+<div class="col-6">
+<h4 id="analytics_for_apps">Analytics for apps</h4>
+<p>Analyze your app’s performance from within AdMob with Google Analytics.
+Discover where people are downloading your app, and the features they use the
+most in real time.</p>
+</div>
+
+<div class="col-6">
+<h4 id="flow_visualization_reports">Flow visualization reports</h4>
+<p>In Analytics, see how people are navigating through your app with graphical
+<a href="https://support.google.com/analytics/answer/2519986">flow reports</a>.
+View the path they take to making a purchase, and the point where they exit
+the app, plus much more.</p>
+</div>
+</div>
-<p>
- To start monetizing with ads sign up for <a href=
- "http://www.google.com/ads/admob/#subid=us-en-et-dac">AdMob</a> and integrate
- the <a href="https://developers.google.com/mobile-ads-sdk/download">Google
- Mobile Ads SDK</a> into your apps. If you also need to manage direct deals
- with advertisers, consider using <a href=
- "http://www.google.com/doubleclick/publishers/small-business/index.html#subid=us-en-et-dac">
- DoubleClick for Publishers Small Business</a>.
-</p>
+<h2 id=tips>Tips</h2>
-<div class="headerLine"><h2 id="related-resources">Related resources</h2></div>
+<ul>
+ <li> Place ads wisely, they shouldn't be too intrusive but still need to be clearly
+visible to attract clickthroughs.
+ <li> Use banner, interstitial, and other ad formats appropriately.
+ <li> Make use of targeting features to match ads with your users and your app.
+ <li> Remember that ads form part of your app and must match its age rating.
+ <li> Exercise control options sensibly, don't get carried away excluding potentially
+competing ads at the expense of revenue.
+</ul>
+
+
+<h2 id=related_resources>Related resources</h2>
<div class="resource-widget resource-flow-layout col-13"
- data-query="collection:distribute/monetize/advertising"
+ data-query="collection:distribute/monetize/admob"
data-sortOrder="-timestamp"
data-cardSizes="9x3"
data-maxResults="6"></div>
diff --git a/docs/html/distribute/monetize/monetize_toc.cs b/docs/html/distribute/monetize/monetize_toc.cs
index 8211689..aa1bdd6 100644
--- a/docs/html/distribute/monetize/monetize_toc.cs
+++ b/docs/html/distribute/monetize/monetize_toc.cs
@@ -24,7 +24,7 @@
</li>
<li class="nav-section">
<div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/monetize/ads.html">
- <span class="en">Ads</span>
+ <span class="en">AdMob Ads</span>
</a>
</div>
</li>
diff --git a/docs/html/distribute/users/appindexing.jd b/docs/html/distribute/users/appindexing.jd
new file mode 100644
index 0000000..6a3fec6
--- /dev/null
+++ b/docs/html/distribute/users/appindexing.jd
@@ -0,0 +1,46 @@
+page.title=Drive installs from Google Search
+page.metaDescription=Surface the content of your apps in Google Search and link it to app installs.
+meta.tags="getusers", "search", "appindexing"
+page.image=images/cards/google-search_2x.png
+@jd:body
+
+<p>Google Search now helps users discover your app, with App Indexing. When users
+search with Google on their Android device the results will include details of
+relevant, indexed apps. The search results will include an install button that
+takes users to your app in the Google Play store. And when your app is
+installed, the user will be taken straight to the right content within it.</p>
+
+<div class="figure-left">
+<img src="{@docRoot}images/distribute/appindexing.gif">
+</div>
+
+<p>This free service expands your opportunities to turn the investment you’ve made
+in creating an outstanding app or game into installs. </p>
+
+<p>Start now by adding deep linking support to your app, verifying your app’s
+official website, and defining deep links. To learn how, check out these <a
+href="https://developers.google.com/app-indexing/webmasters/details">instructions</a>. </p>
+
+<p>Once your app is index, links to its content will join the 30 billion app index
+links already available to Google Search.</p>
+
+<h2 id=tips>Tips</h2>
+
+<ul>
+ <li> App Indexing will also be used as a ranking signal for all users on Android,
+regardless of whether they have your app installed or not.
+ <li> App Indexing also helps drive use of your app — when your app is installed on a
+user’s device, search results will include deep links to your app that bring
+the user straight to the relevant app content.
+ <li> Use the App Indexing API to help users discover relevant content in your app
+before they complete a query with auto-completions.
+</ul>
+
+<h2 id=related_resources>Related resources</h2>
+
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/users/appindexing"
+ data-sortOrder="-timestamp"
+ data-cardSizes="9x3"
+ data-maxResults="6"></div>
+
diff --git a/docs/html/distribute/users/promote-with-ads.jd b/docs/html/distribute/users/promote-with-ads.jd
index c1d79fc..d71b8c9 100644
--- a/docs/html/distribute/users/promote-with-ads.jd
+++ b/docs/html/distribute/users/promote-with-ads.jd
@@ -1,42 +1,125 @@
page.title=Promote Your App with Ads
-page.metaDescription=Promote your app through AdMob, AdWords, and YouTube to find new users at the right moment.
+page.metaDescription=Promote your app with AdWords to find new users at the right moment.
page.image=images/cards/adwords_2x.jpg
-page.tags="users, ads, analytics"
-
+page.tags="users, ads, adwords"
@jd:body
-<p>
- AdMob is Google's advertising platform for mobile apps. You can use it to
- monetize your app and promote your apps, and you can link your Google
- Analytics account to AdMob so you can analyze your apps — all in one
- place.
-</p>
+<p>Users have a huge amount of choice when it comes to which apps they install and
+use, so it’s important to actively find new ways to promote your app and drive
+ongoing engagement. AdWords is a powerful and effective way to do both.</p>
-<p>
- <a href="http://www.google.com/ads/admob/">AdMob</a> is the largest mobile ad
- app network. But you get more than just massive scale: AdMob will soon help
- you find the right users in related apps. If your app is for bicycling, AdMob
- can promote your app on other fitness and cycling-related apps worldwide.
- <a href=
- "https://apps.admob.com/admob/signup?subid=us-en-et-dac&_adc=ww-ww-et-admob2&hl=en">
- Sign up for AdMob</a>.
-</p>
-<p>
- AdMob also offers new solutions to help you achieve app-related goals such as
- downloads, re-engagement and in-app purchases using Google search and the
- Google Display Network. These solutions include streamlined campaign creation
- flows and tools to track performance across the entire app lifecycle.
- <a href="https://support.google.com/adwords/answer/2549053?hl=en">Learn
- More</a>.
-</p>
-<div style="margin-top:2em;">
- <img src="{@docRoot}images/gp-ads-console.jpg">
+<h2 id=drive_installs>Drive installs</h2>
+
+<p><a href="http://adwords.google.com">AdWords</a> promotes your app to interested users where they spend time on phones and
+tablets – with app install ads on Google Search, YouTube, Gmail, and within
+apps and across the web on the Google Display Network. AdWords is a powerful
+way to scale app promotion across Google networks and find customers that are
+most likely to install your app. </p>
+
+<p><a href="https://support.google.com/adwords/answer/6032059">Get started with AdWords app install ads</a>.</p>
+
+<div style="display:inline-block">
+ <div class="figure-left" style="width:40%;">
+ <h3>From Google Play</h3>
+ <img src="/images/distribute/promote_ads_play.png">
+ <p class="figure-caption">Search ads on Google Play are still undergoing testing and not yet available to
+buy. <a href="http://android-developers.blogspot.com/2015/02/a-new-way-to-promote-your-app-on-google.html">Find out more</a>.</p>
+ </div>
+ <div class="figure-right" style="width:40%;">
+ <h3>From apps</h3>
+ <img src="/images/distribute/promote_ads_search.png">
+ <p class="figure-caption">Connect with users as they search for content and services provided by your
+app.</p>
+ </div>
</div>
-<div class="headerLine">
+<div style="display:inline-block">
+ <div class="figure-left" style="width:40%;">
+ <h3>From YouTube</h3>
+ <img src="/images/distribute/promote_ads_youtube.png">
+ <p class="figure-caption">Promote your app when users are watching related videos.</p>
+ </div>
+ <div class="figure-right" style="width:40%;">
+ <h3>From apps</h3>
+ <img src="/images/distribute/promote_ads_apps.png">
+ <p class="figure-caption">Reach users while they’re engaged with apps and games across the AdMob network.</p>
+ </div>
+</div>
+
+<div style="display:inline-block">
+ <div class="figure-left" style="width:40%;">
+ <h3>From the web</h3>
+ <img src="/images/distribute/promote_ads_web.png">
+ <p class="figure-caption">Reach users while they’re engaged with websites across the Google Display Network.</p>
+ </div>
+ <div class="figure-right" style="width:40%;">
+ <h3>From Gmail</h3>
+ <img src="/images/distribute/promote_ads_gmail.png">
+ <p class="figure-caption">Promote your app while users communicate and get things done in Gmail.</p>
+ </div>
+</div>
+
+<h3>Tips</h3>
+
+<ul>
+ <li> Estimate how much an app user is worth to your business, so that you can work
+out an appropriate cost-per-install that you’re willing to pay.
+ <li> Ensure that your ads and Play Store listing are compelling and clearly describe
+your app’s value.
+ <li> Check that you’re accurately tracking and attributing installs by installing
+the AdWords <a href="https://developers.google.com/app-conversion-tracking/">conversion tracking SDK</a>.
+ <li> Promote your app broadly across display, search, and video to reach even more
+potential users and drive a higher volume of installs.
+ <li> Start with broader targeting and then fine tune your bidding once you’ve
+assessed your campaign results.
+ <li> Use Conversion Optimizer to automate your bidding so that your ads target users
+who are most likely to install your app.
+ <li> Use Conversion Optimizer for in-app buyers to automate your bidding so that
+your ads target high value users who are most likely to make purchases in your
+app.
+</ul>
+
+
+<h2 id=engage_with_users>Engage with users</h2>
+
+<p>Getting a user to install an app is one thing, but you'll also want them to
+open it regularly. AdWords offers app re-engagement tools to help your app stay
+in mind with users who’ve already installed it on their phone. AdWords can
+remind them of key features and encourage them to try your app again, or help
+them complete an activity they didn't know your app could handle.</p>
+
+<div>
+ <div class="figure-left" style="width:46%;">
+ <h3>From search</h3>
+ <img src="/images/distribute/promote_ads.png">
+ <p class="figure-caption">Add deep links to your app, then bring users straight
+ to relevant app content when they’re searching.</p>
+ </div>
+ <div class="figure-right" style="width:46%;">
+ <h3>From apps</h3>
+ <img src="/images/distribute/promote_ads_inapp.png">
+ <p class="figure-caption">Use remarketing and deep links to bring users to just the right
+ place in your app to re-engage and convert, from other apps and games they love.</p>
+ </div>
+</div>
+
+<h3>Tips</h3>
+
+<ul>
+ <li> Track what users do in your app after they’ve clicked an ad, by installing the
+AdWords <a href="https://developers.google.com/app-conversion-tracking/">conversion tracking SDK</a>.
+ <li> Advertise a compelling reason for users to re-engage with your app (such as a
+reminder or a special offer).
+ <li> <a href="https://developers.google.com/app-indexing/webmasters/app">Add deep links</a> to your app that’ll take users directly to the parts of your app that will be
+most relevant and interesting to them, where they can easily take action.
+ <li> Re-engage your app users across the display network with remarketing lists and
+search with keywords.
+ <li> Use remarketing lists to target high value users so that you can drive more
+conversions in your app.
+</ul>
+
<h2 id="related-resources">Related Resources</h2>
-</div>
<div class="resource-widget resource-flow-layout col-13"
data-query="collection:distribute/users/promotewithads"
diff --git a/docs/html/distribute/users/users_toc.cs b/docs/html/distribute/users/users_toc.cs
index edfa874..2e796c8 100644
--- a/docs/html/distribute/users/users_toc.cs
+++ b/docs/html/distribute/users/users_toc.cs
@@ -11,18 +11,6 @@
</div>
</li>
<li class="nav-section">
- <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-buzz.html">
- <span class="en">Build Buzz</span>
- </a>
- </div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-community.html">
- <span class="en">Build Community</span>
- </a>
- </div>
- </li>
- <li class="nav-section">
<div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/expand-to-new-markets.html">
<span class="en">Expand to New Markets</span>
</a>
@@ -34,6 +22,24 @@
</a>
</div>
</li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/appindexing.html">
+ <span class="en">Drive Installs through Search</span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-buzz.html">
+ <span class="en">Build Buzz</span>
+ </a>
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/users/build-community.html">
+ <span class="en">Build Community</span>
+ </a>
+ </div>
+ </li>
</ul>
diff --git a/docs/html/google/google_toc.cs b/docs/html/google/google_toc.cs
index 510a755..dd0e735 100644
--- a/docs/html/google/google_toc.cs
+++ b/docs/html/google/google_toc.cs
@@ -1,115 +1,6 @@
-<?cs #########################################################
- ######## ###############
- ######## ATTENTION ###############
- ######## ###############
- #########################################################
-
- IF YOU MAKE CHANGES TO THIS FILE, YOU MUST GENERATE THE
- GMS REFERENCE DOCS, BECAUSE THEY ARE NOT INCLUDED IN THE
- DOCS BUILD RULE.
-
- #########################################################
- #########################################################
-?>
-
<ul id="nav">
<li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/index.html">
- <span class="en">Overview</span>
- </a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/games.html">
- <span class="en">Games</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/location.html">
- <span class="en">Location</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/plus.html">
- <span class="en">Google+</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/maps.html">
- <span class="en">Maps</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/drive.html">
- <span class="en">Drive</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/cast.html">
- <span class="en">Cast</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>google/play-services/ads.html">
- <span class="en">Ads</span></a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot?>google/play-services/id.html">
- <span class="en">Advertising ID</span></a>
- </li>
- </ul>
- </li>
- <li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play-services/wallet.html">
- <span class="en">Wallet</span>
- </a></div>
- </li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot?>google/play/safetynet/index.html">
- <span class="en">SafetyNet</span>
- </a></div>
- <ul>
- <li>
- <a href="<?cs var:toroot ?>google/play/safetynet/start.html">
- <span class="en">Getting Started</span>
- </a>
- </li>
- </ul>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>google/play-services/index.html">
- <span class="en">Google Play Services</span></a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot?>google/play-services/setup.html">
- <span class="en">Setting Up Google Play Services</span></a>
- </li>
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot?>google/auth/api-client.html">
- <span class="en">Accessing Google APIs</span></a>
- </div>
- <ul>
- <li>
- <a href="<?cs var:toroot ?>google/auth/http-auth.html">
- <span class="en">Authorizing with Google for REST APIs</span>
- </a>
- </li>
- </ul>
- </li>
- <li id="gms-tree-list" class="nav-section">
- <div class="nav-section-header">
- <a href="<?cs var:toroot ?>reference/gms-packages.html">
- <span class="en">Reference</span>
- </a>
- <div>
- </li>
- </ul>
- </li>
-
-
- <li class="nav-section">
<div class="nav-section-header"><a href="<?cs var:toroot ?>google/play/billing/index.html" zh-cn-lang="应用内结算">
<span class="en">Google Play In-app Billing</span></a>
</div>
@@ -155,67 +46,31 @@
</ul>
</li>
-
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>google/gcm/index.html">
- <span class="en">Google Cloud Messaging</span></a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot?>google/gcm/gcm.html">
- <span class="en">Overview</span></a>
- </li>
- <li><a href="<?cs var:toroot?>google/gcm/gs.html">
- <span class="en">Getting Started</span></a>
- </li>
- <li><a href="<?cs var:toroot?>google/gcm/client.html">
- <span class="en">Implementing GCM Client</span></a>
- </li>
- <li class="nav-section"><div class="nav-section-header"><a href="<?cs var:toroot?>google/gcm/server.html">
- <span class="en">Implementing GCM Server</span></a></div>
- <ul>
- <li><a href="<?cs var:toroot?>google/gcm/ccs.html">
- <span class="en">CCS (XMPP)</span></a></li>
- <li><a href="<?cs var:toroot?>google/gcm/http.html">
- <span class="en">HTTP</span></a></li>
- </ul>
- </li>
- <li><a href="<?cs var:toroot?>google/gcm/server-ref.html">
- <span class="en">Server Reference</span></a>
- </li>
- <li><a href="<?cs var:toroot?>google/gcm/notifications.html">
- <span class="en">User Notifications</span></a>
- </li>
- <li><a href="<?cs var:toroot?>google/gcm/c2dm.html">
- <span class="en">Migration</span></a>
- </li>
- </ul>
- </li>
-
<li class="nav-section">
- <div class="nav-section-header empty"><a href="<?cs var:toroot ?>google/gcs/index.html">
- <span class="en">Google Cloud Save</span></a>
- </div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header"><a href="<?cs var:toroot ?>google/play/dist.html">
- <span class="en">Google Play Distribution</span></a>
- </div>
- <ul>
- <li><a href="<?cs var:toroot ?>google/play/filters.html">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>google/play/filters.html">
<span class="en">Filters on Google Play</span></a>
- </li>
- <li><a href="<?cs var:toroot?>google/play/billing/gp-purchase-status-api.html">
+ </div>
+ </li>
+
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot?>google/play/developer-api.html">
<span class="en">Google Play Developer API</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>google/play/publishing/multiple-apks.html">
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>google/play/publishing/multiple-apks.html">
<span class="en">Multiple APK Support</span></a>
- </li>
- <li><a href="<?cs var:toroot ?>google/play/expansion-files.html">
+ </div>
+ </li>
+ <li class="nav-section">
+ <div class="nav-section-header empty"><a href="<?cs var:toroot ?>google/play/expansion-files.html">
<span class="en">APK Expansion Files</span></a>
- </li>
- <li class="nav-section">
+ </div>
+ </li>
+
+
+ <li class="nav-section">
+
<div class="nav-section-header"><a href="<?cs var:toroot ?>google/play/licensing/index.html">
<span class="en">Application Licensing</span></a>
</div>
diff --git a/docs/html/google/index.jd b/docs/html/google/index.jd
index cc209cd..1ebb9f8 100644
--- a/docs/html/google/index.jd
+++ b/docs/html/google/index.jd
@@ -1,164 +1,185 @@
+fullpage=true
page.title=Google Services
+section.landing=true
+meta.tags="beautifulapps, design, ux, patterns, holo, appquality, landing"
header.hide=1
+footer.hide=1
@jd:body
-<style>
-div.landing-cell,
-div.cell-icon {
- height:150px;
-}
-div.cell-icon {
- float:left;
- margin-right:20px;
-}
-div.cell-icon img {
- margin:0;
-}
-</style>
-<div class="landing-banner cols">
-
-<div class="col-6" style="min-height:0">
- <img src="{@docRoot}images/google/google-services.png" alt="" width="340" height="193" />
-</div>
-<div class="col-6">
-
- <h1 itemprop="name" style="margin-bottom:0;">Google Services</h1>
- <p itemprop="description">Google offers a variety of services that help you
-build new revenue streams, manage app distribution,
-track app usage, and enhance your app with features such as maps, sign-in, and
-cloud messaging.</p>
- <p>Although these Google services are not included in the Android platform, they are
- supported by most Android-powered devices. When using these services, you can
- distribute your app on Google Play to all devices running Android 2.3
- or higher, and some services support even more devices.</p>
-</div>
-</div>
-<div> </div>
-
-
-
-
-
-<div style="margin-top:10px">
-<div class="col-6 normal-links" style="margin-left:0">
-
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/maps-pin.png" width="40" >
+<section class="dac-expand dac-hero dac-light">
+ <div class="wrap">
+ <div class="cols dac-hero-content">
+ <div class="col-1of2 col-push-1of2 dac-hero-figure">
+ <img class="dac-hero-image" src="/design/media/hero-material-design.png">
+ </div>
+ <div class="col-1of2 col-pull-1of2">
+ <h1 class="dac-hero-title">Build better apps with Google</h1>
+ <p class="dac-hero-description">
+ Add powerful capabilities to your apps, quickly, at low cost. Simplify development,
+grow your user base, and monetize more effectively with Google Play services.
+ </p>
+ <a class="dac-hero-cta" href="https://www.google.com/design/spec/material-design/introduction.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Get Started with Google Play services
+ </a><br>
+ <a class="dac-hero-cta" href="https://www.google.com/design/spec/resources/color-palettes.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ API Reference
+ </a><br>
+ </div>
+ </div>
+ <div class="dac-section dac-small">
+ <!--<div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:google/landing/google"
+ data-cardSizes="6x2"
+ data-maxResults="6"></div>-->
+ </div>
</div>
- <h4><a href="{@docRoot}google/play-services/maps.html"
- >Google Maps</a></h4>
- <p>Include the power of Google Maps in your app
+</section>
+<div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button href="#latest">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
+</div>
+<section class="dac-section dac-gray dac-small dac-invert" id="latest"><div class="wrap">
+ <h2 class="norule">Latest</h2>
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="type:blog+tag:googleservices+tag:featured+tag:develop"
+ data-cardSizes="6x6"
+ data-maxResults="3"></div>
+</div></section>
+
+
+
+<section class="dac-section dac-light"><div class="wrap">
+ <h1 class="dac-section-title">Google APIs and services</h1>
+ <div class="dac-section-subtitle">
+ Design around Android's capabilities and conventions to give users the best experience.
+ </div>
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:google/landing/services"
+ data-cardSizes="6x6"
+ data-maxResults="6"></div>
+ <ul class="dac-section-links">
+ <li class="dac-section-link"><a href="https://developers.google.com/">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ More Google services for Android
+ </a></li>
+ </ul>
+</div></section>
+
+
+<section class="dac-section dac-invert dac-darken-bg" style="background-image: url(/images/distribute/google-play-bg.jpg)"><div class="wrap">
+ <h1 class="dac-section-title">Google Play developer tools</h1>
+ <div class="dac-section-subtitle">
+ Scale your operations. Essential downloads, stencils, and tools to help you create your design.
+ </div>
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:google/landing/googleplay"
+ data-cardSizes="6x6"
+ data-maxResults="6"></div>
+
+ <ul class="dac-section-links">
+ <li class="dac-section-link"><a href="/google/play/filters.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Device filtering
+ </a></li>
+ <li class="dac-section-link"><a href="/google/play/filters.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Multiple APK support
+ </a></li>
+ <li class="dac-section-link"><a href="/google/play/expansion-files.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ APK expansion files
+ </a></li>
+ <li class="dac-section-link"><a href="/google/play/licensing/index.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Licensing library
+ </a></li>
+ </ul>
+</div></section>
+
+<!--
+
+<section class="dac-section dac-light"><div class="wrap">
+ <h1 class="dac-section-title">More</h1>
+ <div class="dac-section-subtitle">
+ Design around Android's capabilities and conventions to give users the best experience.
+ </div>
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:google/landing/more"
+ data-cardSizes="6x6"
+ data-maxResults="6"></div>
+</div></section>
+
+
+
+
+Google Play services
+video video
+
+
+Google Play Publishing Tools
+
+
+
+Distribute your app on Google Play to all devices running Android 2.3
+ or higher, and some services support even more devices.</p>
+
+
+Google Maps
+
+Include the power of Google Maps in your app
with an embeddable map view. You can customize the map with
markers and overlays, control the user's perspective, draw lines
- and shapes, and much more.</p>
-</div>
+ and shapes, and much more.
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/plus-logo.png" width="40" >
- </div>
- <h4><a href="{@docRoot}google/play-services/plus.html"
- >Google+</a></h4>
- <p>Allow users to sign in with their Google account,
+Google+</a></h4>
+
+Allow users to sign in with their Google account,
customize the user experience with Google+ info,
pull people into your app with interactive posts,
and add +1 buttons so users can recommend your content.</p>
-</div>
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/cloud-platform.png" width="40" >
- </div>
- <h4><a class="external-link" href="https://cloud.google.com/solutions/mobile"
- >Google Cloud Platform</a></h4>
- <p>Build and host the backend for your Android app at Google-scale. With an infrastructure
+
+Google Cloud Platform
+
+Build and host the backend for your Android app at Google-scale. With an infrastructure
that is managed automatically, you can focus on your app. Then, scale to support
- millions of users.</p>
-</div>
-
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/gcm-cloud.png" width="40" >
- </div>
- <h4><a href="{@docRoot}google/gcm/index.html"
- >Google Cloud Messaging</a></h4>
- <p>Immediately notify your users about timely events by delivering
- lightweight messages from your web server. There are no quotas or charges
- to use Google Cloud Messaging.</p>
-</div>
-
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/gcs-small.png" width="40" >
- </div>
- <h4><a href="{@docRoot}google/gcs/index.html"
- >Google Cloud Save</a></h4>
- <p>Enable per-user data storage and sync in your apps with no backend programming
- required.</p>
-</div>
-
-</div><!-- col-6 -->
+ millions of users.
-<div class="col-6" style="margin-right:0">
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/iab-99c.png" width="40" />
- </div>
- <h4><a href="{@docRoot}google/play/billing/index.html"
- >Google Play In-App Billing</a></h4>
- <p>Build an app with a steady revenue stream that keeps users engaged
+More
+
+Google Play In-App Billing
+
+Build an app with a steady revenue stream that keeps users engaged
by offering new content or virtual goods directly in your app. All transactions are handled
by Google Play Store for a simple user experience.
- </p>
-</div>
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/wallet.png" width="40" />
- </div>
- <h4><a href="{@docRoot}google/play-services/wallet.html"
- >Google Wallet Instant Buy</a></h4>
- <p>Provide fast and easy checkout in your app when selling physical goods and services.
+
+Android Pay
+
+Provide fast and easy checkout in your app when selling physical goods and services.
Increase conversions by streamlining your purchase flow and reducing the amount of
information your customers need to enter.
- </p>
-</div>
-<div class="landing-cell">
- <div class="cell-icon">
-<img src="{@docRoot}images/google/analytics.png" width="40" />
- </div>
- <h4><a class="external-link"
-href="https://developers.google.com/analytics/devguides/collection/android/v4/"
- >Google Analytics</a></h4>
+Google Analytics
-<p>Measure your success and gain insights into how users engage with your app content
+Measure your success and gain insights into how users engage with your app content
by integrating Google Analytics. You can track in-app purchases, the number of active users,
interaction patterns, and much more.
-</p>
-</div>
-<div class="landing-cell">
- <div class="cell-icon">
- <img src="{@docRoot}images/google/google-mobile-ads.png" width="40" />
- </div>
- <h4><a href="{@docRoot}google/play-services/ads.html"
- >Google Mobile Ads</a></h4>
- <p>Display ads from Google Mobile Ads offer you an alternative revenue opportunity that leverages
+
+Google Mobile Ads
+
+Display ads from Google Mobile Ads offer you an alternative revenue opportunity that leverages
multiple ad networks with targeted ads and several display formats.
- </p>
-</div>
-
-</div><!-- col-6 -->
-
-</div><!-- margin wrapper -->
-
+-->
\ No newline at end of file
diff --git a/docs/html/google/play/billing/billing_reference.jd b/docs/html/google/play/billing/billing_reference.jd
index 01e680f..7884929 100644
--- a/docs/html/google/play/billing/billing_reference.jd
+++ b/docs/html/google/play/billing/billing_reference.jd
@@ -172,8 +172,8 @@
</tr>
<tr>
<td>{@code INAPP_DATA_SIGNATURE}</td>
- <td>String containing the signature of the purchase data that was signed
-with the private key of the developer. The data signature uses the
+ <td>String containing the signature of the purchase data that was signed
+with the private key of the developer. The data signature uses the
RSASSA-PKCS1-v1_5 scheme.</td>
</tr>
</table>
@@ -197,7 +197,13 @@
lose access at that time unless they re-enable automatic renewal
(or manually renew, as described in
<a href="{@docRoot}google/play/billing/billing_subscriptions.html#manual-renewal">Manual
- Renewal</a>).</td>
+ Renewal</a>).
+ If you offer a <a href="{@docRoot}google/play/billing/billing_subscriptions.html#grace-period"
+ >grace period</a>, this value remains set to <code>true</code> for all
+ subscriptions, as long as the grace period has not lapsed. The next billing date
+ is extended dynamically every day until the end of the grace period or until the
+ user fixes their payment method.
+ </td>
</tr>
<tr>
<td>{@code orderId}</td>
diff --git a/docs/html/google/play/billing/billing_subscriptions.jd b/docs/html/google/play/billing/billing_subscriptions.jd
index 8f55354e..51fec09 100644
--- a/docs/html/google/play/billing/billing_subscriptions.jd
+++ b/docs/html/google/play/billing/billing_subscriptions.jd
@@ -10,6 +10,30 @@
<div id="qv-wrapper">
<div id="qv">
<h2>Quickview</h2>
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#overview">Overview</a></li>
+ <li><a href="#administering">Configuring Subscriptions Items</a></li>
+ <li><a href="#cancellation">Subscription Cancellation</a></li>
+ <li><a href="#payment">Payment Processing and Policies</a></li>
+ <li><a href="#strategies">Purchase Verification Strategies</a></li>
+ <li><a href="#play-dev-api">Google Play Developer API</a></li>
+ </ol>
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}google/play/billing/billing_integrate.html#Subs">Implementing Subscriptions (V3)</a></li>
+ <li><a href="https://developers.google.com/android-publisher/">Google Play Developer API</a></li>
+ </ol>
+</div>
+</div>
+
+<p>Subscriptions let you sell content, services, or features in your app with
+automated, recurring billing. You can easily adapt an existing In-app Billing
+implementation to sell subscriptions.</p>
+<p>This document is focused on highlighting implementation details that are
+specific to subscriptions, along with some strategies for the associated billing
+and business models.</p>
+
<ul>
<li>Subscriptions let you sell products with automated, recurring billing
at a variety of intervals.</li>
@@ -29,64 +53,41 @@
<li>You can defer billing for a particular user's subscription, to manage
accounts or offer rewards.</li>
</ul>
- <h2>In this document</h2>
- <ol>
- <li><a href="#overview">Overview of Subscriptions</a></li>
- <li><a href="#administering">Configuring Subscriptions Items</a></li>
- <li><a href="#cancellation">Subscription Cancellation</a></li>
- <li><a href="#payment">Payment Processing and Policies</a></li>
- <li><a href="#strategies">Purchase Verification Strategies</a></li>
- <li><a href="#play-dev-api">Google Play Developer API</a></li>
- </ol>
- <h2>See also</h2>
- <ol>
- <li><a href="{@docRoot}google/play/billing/billing_integrate.html#Subs">Implementing Subscriptions (V3)</a></li>
- <li><a href="https://developers.google.com/android-publisher/">Google Play Developer API</a></li>
- </ol>
-</div>
-</div>
-<p>Subscriptions let you sell content, services, or features in your app with
-automated, recurring billing. You can easily adapt an existing In-app Billing
-implementation to sell subscriptions.</p>
-<p>This document is focused on highlighting implementation details that are
-specific to subscriptions, along with some strategies for the associated billing
-and business models.</p>
-
-<h2 id="overview">Overview of Subscriptions</h2>
-<p>A <em>subscription</em> is a product type offered in In-app Billing that
-lets you sell content, services, or features to users from inside your app with
+<h2 id="overview">Overview</h2>
+<p>A <em>subscription</em> is a product type offered in In-app Billing that
+lets you sell content, services, or features to users from inside your app with
recurring, automated billing at the interval you specify. You can sell subscriptions to almost
any
type of digital content, from any type of app or game.</p>
<p>As with other in-app products, you configure and publish subscriptions using
-the Developer Console and then sell them from inside apps installed on
+the Developer Console and then sell them from inside apps installed on
Android devices. In the Developer console, you create subscription
products and add them to a product list, then set a price and optional trial
period for each, choose a billing interval, and then
-publish. For more information about using the Developer Console, see
+publish. For more information about using the Developer Console, see
<a href="#administering">Configuring Subscription Items</a>.</p>
-<p>When users purchase subscriptions in your apps, Google Play handles all
-checkout details so your apps never have to directly process any financial
-transactions. Google Play processes all payments for subscriptions through
-Google Wallet, just as it does for standard in-app products and app purchases.
+<p>When users purchase subscriptions in your apps, Google Play handles all
+checkout details so your apps never have to directly process any financial
+transactions. Google Play processes all payments for subscriptions through
+Google Wallet, just as it does for standard in-app products and app purchases.
This ensures a consistent and familiar purchase flow for your users.</p>
<img src="{@docRoot}images/in-app-billing/v3/billing_subscription_v3.png" style="float:right; border:4px solid ddd;">
-<p>After users have purchased subscriptions, they can view the subscriptions and
-cancel them from the <strong>My Apps</strong> screen in the Play Store app or
-from the app's product details page in the Play Store app. For more information
+<p>After users have purchased subscriptions, they can view the subscriptions and
+cancel them from the <strong>My Apps</strong> screen in the Play Store app or
+from the app's product details page in the Play Store app. For more information
about handling user cancellations, see <a href="#cancellation">Subscription Cancellation</a>.</p>
-<p>In addition to client-side API calls, you can use the server-side API for
-In-app Billing to provide subscription purchasers with extended access to
+<p>In addition to client-side API calls, you can use the server-side API for
+In-app Billing to provide subscription purchasers with extended access to
content (for example, from your web site or another service).
The server-side API lets you validate the status of a subscription when users
sign into your other services. For more information about the API, see <a
-href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a>. </p>
+href="{@docRoot}google/play/developer-api.html">Google Play Developer API</a>. </p>
<p>You can also build on your existing external subscriber base from inside your
Android apps.</p>
@@ -95,12 +96,12 @@
your own business logic to your Android app to determine whether the user has
already purchased a subscription elsewhere, then allow access to your content if
so or offer a subscription purchase from Google Play if not.</li>
-<li>You can implement your own solution for sharing subscriptions across as
-many different apps or products as you want. For example, you could sell a
-subscription that gives a subscriber access to an entire collection of apps,
-games, or other content for a monthly or annual fee. To implement this solution,
-you could add your own business logic to your app to determine whether the user
-has already purchased a given subscription and if so, allow access to your
+<li>You can implement your own solution for sharing subscriptions across as
+many different apps or products as you want. For example, you could sell a
+subscription that gives a subscriber access to an entire collection of apps,
+games, or other content for a monthly or annual fee. To implement this solution,
+you could add your own business logic to your app to determine whether the user
+has already purchased a given subscription and if so, allow access to your
content.</li>
</ul>
</p>
@@ -111,14 +112,14 @@
href="http://support.google.com/googleplay/android-developer/bin/answer.py?hl=en
&answer=140504">policies document</a>.</p>
-<p>To learn about the minimum system requirements for
+<p>To learn about the minimum system requirements for
subscriptions, see the <a href="{@docRoot}google/play/billing/versions.html#Subs">Version Notes</a>.</p>
<h2 id="administering">Configuring Subscription Items</h2>
<p>To create and manage subscriptions, you can use the Developer Console to set
up a
-product list for the app, then configure these attributes for each subscription
+product list for the app, then configure these attributes for each subscription
product:</p>
<ul>
@@ -133,12 +134,12 @@
<li>Additional currency pricing (can be auto-filled)</li>
</ul>
-<p>For details on how to add and configure products in the Developer Console,
+<p>For details on how to add and configure products in the Developer Console,
see <a href="{@docRoot}google/play/billing/billing_admin.html">Administering
In-app Billing</a>.</p>
<p>You can also create and manage subscriptions using the
-<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">
+<a href="{@docRoot}google/play/developer-api.html">
Google Play Developer API</a>.</p>
<h3 id="pricing">Subscription pricing</h3>
@@ -149,18 +150,20 @@
— for example you could offer a discount on an annual subscription
relative to the monthly equivalent. </p>
-<p class="caution"><strong>Important</strong>: To change the price of a
-subscription, you can publish a new subscription product ID at a new price,
-then offer it in your app instead of the original product. Users who have
-already purchased will continue to be charged at the
+<p class="caution"><strong>Important</strong>: To change the price of a
+subscription, you can publish a new subscription product ID at a new price,
+then offer it in your app instead of the original product. Users who have
+already purchased will continue to be charged at the
original price, but new users will be charged at the new price.</p>
<h3 id="user-billing">User billing</h3>
-<p>In the Developer Console, you can configure subscription products with
+<p>In the Developer Console, you can configure subscription products with
automated recurring billing at your choice of intervals:</p>
<ul>
+ <li>Weekly — Google Play bills the customer’s Google Wallet account at
+ the time of purchase and every week after the original purchase date.</li>
<li>Monthly — Google Play bills the customer’s Google Wallet account at
the time of purchase and monthly subsequent to the purchase date (exact billing
intervals can vary slightly over time).</li>
@@ -183,32 +186,27 @@
cycles, based on the purchase date. (Seasonal subscriptions are charged
annually, on the first day of the season.)</p>
-<p>Over the life of a subscription, the form of payment billed remains the same
-— Google Play always bills the same form of payment (such as credit card
-or by Direct Carrier Billing) that was originally used to purchase the
-subscription.</p>
-
-<p>When the subscription payment is approved by Google Wallet, Google Play
+<p>When the subscription payment is approved, Google Play
provides a purchase token back to the purchasing app through the In-app Billing
-API. Your apps can store the token locally or pass it to your backend servers,
+API. Your apps can store the token locally or pass it to your backend servers,
which can then use it to validate or cancel the subscription remotely using the
<a
-href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play Developer API</a>.</p>
+href="{@docRoot}google/play/developer-api.html">Google Play Developer API</a>.</p>
<p>If a recurring payment fails (for example, because the customer’s credit
-card has become invalid), the subscription does not renew. How your app is
+card has become invalid), the subscription does not renew. How your app is
notified depends on the In-app Billing API version that you are using:</p>
<ul>
-<li>With In-app Billing Version 3, the failed or expired subscription is no longer
+<li>With In-app Billing Version 3, the failed or expired subscription is no longer
returned when you call {@code getPurchases}.</li>
-<li>With In-app Billing Version 2, Google Play notifies your app at the end of
-the active cycle that the purchase state of the subscription is now "Expired".
+<li>With In-app Billing Version 2, Google Play notifies your app at the end of
+the active cycle that the purchase state of the subscription is now "Expired".
</li>
</ul>
-<p class="note"><strong>Recommendation</strong>: Include business logic in your
-app to notify your backend servers of subscription purchases, tokens, and any
-billing errors that may occur. Your backend servers can use the server-side API
+<p class="note"><strong>Recommendation</strong>: Include business logic in your
+app to notify your backend servers of subscription purchases, tokens, and any
+billing errors that may occur. Your backend servers can use the server-side API
to query and update your records and follow up with customers directly, if needed.</p>
<h3 id="manual-renewal">Manual Renewal</h3>
@@ -220,8 +218,8 @@
<p>For example, Achilles has a subscription to the <em>Modern Hoplite</em> app.
His subscription is currently due to expire on August 1. On July 10, he
-purchases a 3-month subscription at the current rate. Those three months are
-added to his existing subscription, so the subscription now expires on November
+purchases a 1-month subscription at the current rate. This one month is
+added to his existing subscription, so the subscription now expires on September
1.</p>
<p>It is up to the app to convey this with an appropriate UI. For example, if a
@@ -273,7 +271,7 @@
<h3 id="deferred-billing">Deferred Billing</h3>
<p>Using the
-<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
+<a href="{@docRoot}google/play/developer-api.html">Google
Play Developer API</a>, you can defer the next billing date for a
subscriber. The user continues to be subscribed to the content, and has full
access to it, but is not charged during the deferral period. This allows you
@@ -311,9 +309,9 @@
<h3 id="trials">Free trials</h3>
<p>In the Developer Console, you can set up a free trial period that lets users
-try your subscription content before buying it. The trial period runs for the
-period of time that you set and then automatically converts to a full
-subscription managed according to the subscription's billing interval and
+try your subscription content before buying it. The trial period runs for the
+period of time that you set and then automatically converts to a full
+subscription managed according to the subscription's billing interval and
price. Free trials are supported for monthly and annual subscriptions only, and are not supported for seasonal subscriptions.</p>
<p>To take advantage of a free trial, a user must "purchase" the full
@@ -328,7 +326,7 @@
period and that the initial charge was $0.00. </p>
<p>When the trial period ends, Google Play automatically initiates billing
-against the credit card that the user provided during the initial purchase, at
+against the credit card that the user provided during the initial purchase, at
the amount set
for the full subscription, and continuing at the subscription interval. If
necessary, the user can cancel the subscription at any time during the trial
@@ -367,15 +365,15 @@
that you must also publish the app itself before Google Play will make the
products available for purchase inside the app. </p>
-<p class="caution"><strong>Important</strong>: You can remove the subscription
-product from the product list offered in your app to prevent users from seeing
+<p class="caution"><strong>Important</strong>: You can remove the subscription
+product from the product list offered in your app to prevent users from seeing
or purchasing it.</p>
<h2 id="cancellation">Subscription Cancellation</h2>
<p>Users can view the status of all of their subscriptions and cancel them if
-necessary from the <strong>My Apps</strong> screen in the Play Store app.
-Currently, the In-app Billing API does not provide support for programatically
+necessary from the <strong>My Apps</strong> screen in the Play Store app.
+Currently, the In-app Billing API does not provide support for programatically
canceling subscriptions from inside the purchasing app.</p>
<p>When the user cancels a subscription, Google Play does not offer a refund for
@@ -404,12 +402,12 @@
<h3 id="uninstall">App uninstallation</h3>
-<p>When the user uninstalls an app that includes purchased subscriptions, the
-Play Store app will notify the user that there are active subscriptions. If the
-user chooses to continue with the uninstallation, the app is removed and the
-subscriptions remain active and recurring billing continues. The user can return
-to cancel the associated subscriptions at any time in the <strong>My Apps</strong>
-screen of the Play Store app. If the user chooses to cancel the uninstallation,
+<p>When the user uninstalls an app that includes purchased subscriptions, the
+Play Store app will notify the user that there are active subscriptions. If the
+user chooses to continue with the uninstallation, the app is removed and the
+subscriptions remain active and recurring billing continues. The user can return
+to cancel the associated subscriptions at any time in the <strong>My Apps</strong>
+screen of the Play Store app. If the user chooses to cancel the uninstallation,
the app and subscriptions remain as they were.</p>
<h3 id="refunds">Refunding and revoking subscriptions</h3>
@@ -419,11 +417,11 @@
Orders</strong> page in the Play Store, or by contacting you directly.</p>
<p>If you receive requests for refunds, you can use the
-<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play
+<a href="{@docRoot}google/play/developer-api.html">Google Play
Developer API</a> or the Merchant Center to cancel the subscription, verify that it
is already canceled, or refund the user's payment without canceling it. You
can also use the
-<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
+<a href="{@docRoot}google/play/developer-api.html">Google
Play Developer API</a> to <em>refund and revoke</em> a
user's subscription. If you refund and revoke a subscription, the user's
subscription is immediately canceled, and the user's most recent subscription
@@ -436,8 +434,8 @@
<h2 id="payment">Payment Processing and Policies</h2>
<p>In general, the terms of Google Play allow you to sell in-app subscriptions
-only through the standard payment processor, Google Wallet. For purchases of
-any subscription products, the transaction fee is the same as the transaction
+only through the standard payment processor, Google Wallet. For purchases of
+any subscription products, the transaction fee is the same as the transaction
fee for application purchases (30%).</p>
<p>Apps published on Google Play that are selling subscriptions must use In-app
@@ -451,7 +449,7 @@
<h3 id="orderId">Subscription order numbers</h3>
<p>To help you track transactions relating to a given subscription, Google
-Wallet provides a base Merchant Order Number for all recurrences of the
+Wallet provides a base Merchant Order Number for all recurrences of the
subscription and denotes
each recurring transaction by appending an integer as follows: </p>
@@ -461,10 +459,29 @@
<code>12999556515565155651.5565135565155651..2</code> (third recurrence orderID)<br />
...<br /></p>
-<p>Google Play provides the order number as the value of the
-{@code orderId} field of the {@code INAPP_PURCHASE_DATA} JSON field (in V3)
+<p>Google Play provides the order number as the value of the
+{@code orderId} field of the {@code INAPP_PURCHASE_DATA} JSON field (in V3)
or the {@code PURCHASE_STATE_CHANGED} intent (in V2).</p>
+<h3 id="grace-period">Grace period for declined payments</h3>
+
+<p>
+ The Developer Console allows you to set a grace period for subscriptions, so you can give
+ your subscribers a chance to update their payment method if a recurring payment is declined.
+ This setting is useful if your subscribers have an expired credit card, subscribed using a
+ prepaid card, or canceled a card without updating their payment information. For
+ information about setting a grace period for subscriptions, see the Developer Console Help
+ topic <a href="https://support.google.com/googleplay/android-developer/answer/140504"
+ class="external-link">Add subscriptions & recurring charges</a>.
+</p>
+
+</p>
+ For information on how setting a grace period affects data returned from the
+ {@code getBuyIntent()} method, see the
+ <a href="{@docRoot}google/play/billing/billing_reference.html#purchase-data-table"
+ >{@code INAPP_PURCHASE_DATA}</a> fields table.
+</p>
+
<h2 id="strategies">Purchase Verification Strategies</h2>
<p>In a typical scenario, your app verifies the order status for new purchases
@@ -496,5 +513,5 @@
other services.</p>
<p>For complete information, see
-<a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google Play
+<a href="{@docRoot}google/play/developer-api.html">Google Play
Developer API</a>.</p>
diff --git a/docs/html/google/play/billing/index.jd b/docs/html/google/play/billing/index.jd
index 47620c8..c671c71 100644
--- a/docs/html/google/play/billing/index.jd
+++ b/docs/html/google/play/billing/index.jd
@@ -7,7 +7,7 @@
<p>In-app Billing is a Google Play service that lets you sell digital content from inside
your applications. You can use the service to sell a wide range of content, including downloadable
-content such as media files or photos, virtual content such as game levels or potions, premium services
+content such as media files or photos, virtual content such as game levels or potions, premium services
and features, and more. You can use In-app Billing to sell products as</p>
<div class="sidebox-wrapper">
@@ -34,17 +34,14 @@
<a href="billing_subscriptions.html#deferred-billing">defer</a> a
subscriber's next billing date until the date you choose. The user still has
access to the content but is not charged during the deferral period.</li>
- <li><strong>Google Play Developer API</strong>—The
- <a href="{@docRoot}google/play/billing/gp-purchase-status-api.html">Google
- Play Developer API</a> allows you to perform a number of publishing and
- app-management tasks. It includes the functionality previously known as the
- <em>Purchase Status API.</em> </li>
- <li><strong>Refund/Revoke subscription</strong>—You can use the
- Google Play Developer API to <a href="billing_subscriptions.html#refunds">refund
- and revoke</a> a user's subscription. If you do this, the user's
- subscription ends
- immediately, and his or her most recent subscription payment is
- refunded.</li>
+ <li><strong>Weekly subscriptions</strong>—You can now set up a
+ recurring <a href="billing_subscriptions.html#user-billing">subscription</a>
+ that bills the user every week.</li>
+ <li><strong>Payment grace period</strong>—If a subscriber misses a
+ subscription payment due to an expired credit card, you can define a
+ <a href="billing_subscriptions.html#grace-period">grace period</a>
+ to the continue the subscription until payment is successful.</li>
+
</ul>
</div>
</div>
@@ -69,7 +66,7 @@
provides a sample application that demonstrates how to sell standard in-app
products and subscriptions from inside an app.</p>
-<p>To get started, read the documents below or take the <a href="{@docRoot}training/in-app-billing/index.html">Selling
+<p>To get started, read the documents below or take the <a href="{@docRoot}training/in-app-billing/index.html">Selling
In-app Products</a> training class.</p>
<dl>
diff --git a/docs/html/google/play/billing/gp-purchase-status-api.jd b/docs/html/google/play/developer-api.jd
similarity index 97%
rename from docs/html/google/play/billing/gp-purchase-status-api.jd
rename to docs/html/google/play/developer-api.jd
index fa0c397..6d12841 100644
--- a/docs/html/google/play/billing/gp-purchase-status-api.jd
+++ b/docs/html/google/play/developer-api.jd
@@ -1,5 +1,7 @@
page.title=Google Play Developer API
page.tags="In-app Billing", "Google Play", "inapp billing", "in app billing", "iab", "billing", "publishing"
+page.image=/images/play_dev.jpg
+page.metaDescription=A REST-based web service for remote app publishing and catalog management through Google Play.
@jd:body
@@ -23,8 +25,8 @@
<h2>See also</h2>
<ol>
- <li><a href="https://developers.google.com/android-publisher/">Google Play
- Developer API</a> documentation</li>
+ <li><a href="https://developers.google.com/android-publisher/">
+ Developer API reference</a></li>
<li><a href="https://support.google.com/googleplay/android-developer/answer/6071616">Google
Help Center</a> overview of the Google Play Developer API</li>
</ol>
@@ -52,8 +54,6 @@
</li>
</ul>
-
-
<p>The Google Play Developer API lets you focus on designing and developing your
app, while spending less time and effort managing your releases, even as you
grow to new markets.</p>
diff --git a/docs/html/guide/index.jd b/docs/html/guide/index.jd
index cb4f65c..b27acbf 100644
--- a/docs/html/guide/index.jd
+++ b/docs/html/guide/index.jd
@@ -3,7 +3,7 @@
@jd:body
-<div class="sidebox" style="width:220px"><!-- width to match col-4 below -->
+<div class="sidebox" style="max-width:30%"><!-- width to match col-4 below -->
<p>To learn how apps work, start with
<a href="{@docRoot}guide/components/fundamentals.html">App Fundamentals</a>.</p>
<p>To begin coding right away, read <a
diff --git a/docs/html/guide/topics/renderscript/compute.jd b/docs/html/guide/topics/renderscript/compute.jd
index 2e7ce56..eef8cda 100644
--- a/docs/html/guide/topics/renderscript/compute.jd
+++ b/docs/html/guide/topics/renderscript/compute.jd
@@ -185,50 +185,101 @@
<p>You can check and update the installed version of these tools in the
<a href="{@docRoot}tools/help/sdk-manager.html">Android SDK Manager</a>.</p>
-<p class="note">
- <strong>Note:</strong> Use of Support Library RenderScript APIs is not currently supported with
- Android Studio or Gradle-based builds.
-</p>
-<p>To use the Support Library RenderScript APIs in Eclipse:</p>
+<p>To use the Support Library RenderScript APIs:</p>
<ol>
<li>Make sure you have the required Android SDK version and Build Tools version installed.</li>
- <li>Open the {@code project.properties} file in the root folder of your application project.</li>
- <li>Add the following lines to the file:
+ <li> Update the settings for the Android build process to include the RenderScript settings:
+
+ <p><strong>For Android Studio or Gradle-based builds</strong></p>
+ <ul>
+ <li>Open the {@code build.gradle} file in the app folder of your application module. </li>
+ <li>Add the following RenderScript settings to the file:
+
+<pre>
+android {
+ compileSdkVersion 19
+ buildToolsVersion "19.0.3"
+
+ defaultConfig {
+ minSdkVersion 8
+ targetSdkVersion 16
+<strong>
+ renderscriptTargetApi 18
+ renderscriptSupportModeEnabled true
+</strong>
+ }
+}
+</pre>
+
+
+ <p>The settings listed above control specific behavior in the Android build process:</p>
+
+ <ul>
+ <li>{@code renderscriptTargetApi} - Specifies the bytecode version to be generated. We
+ recommend you set this value to the highest available API level and set
+ {@code renderscriptSupportModeEnabled}
+ to {@code true}. Valid values for this setting are any integer value
+ from 11 to the most recently released API level. If your minimum SDK version specified in your
+ application manifest is set to a different value, that value is ignored and the target value
+ in the build file is used to set the minimum SDK version.</li>
+ <li>{@code renderscriptSupportModeEnabled} - Specifies that the generated bytecode should fall
+ back to a compatible version if the device it is running on does not support the target
+ version.
+ </li>
+ <li>{@code buildToolsVersion} - The version of the Android SDK build tools to use. This value
+ should be set to {@code 18.1.0} or higher. If this option is not specified, the highest
+ installed build tools version is used. You should always set this value to ensure the
+ consistency of builds across development machines with different configurations.</li>
+ </ul>
+
+ </li>
+
+ <p><strong>For Eclipse</strong></p>
+ <ul>
+ <li>Open the {@code project.properties} file in the root folder of your application project.</li>
+ <li>Add the following lines to the file:
+
<pre>
renderscript.target=18
renderscript.support.mode=true
sdk.buildtools=18.1.0
</pre>
- </li>
+
+ <p>The settings listed above control specific behavior in the Android build process:</p>
+
+ <ul>
+ <li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
+ recommend you set this value to the highest available API level and set
+ {@code renderscript.support.mode} to {@code true}. Valid values for this setting are any
+ integer value from 11 to the most recently released API level. If your minimum SDK version
+ specified in your application manifest is set to a higher value, this value is ignored and
+ the target value is set to the minimum SDK version.</li>
+ <li>{@code renderscript.support.mode} - Specifies that the generated bytecode should fall
+ back to a compatible version if the device it is running on does not support the target version.
+ </li>
+ <li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
+ should be set to {@code 18.1.0} or higher. If this option is not specified, the highest
+ installed build tools version is used. You should always set this value to ensure the
+ consistency of builds across development machines with different configurations.</li>
+ </ul>
+ </li>
+
+ </ul>
+
+ </ul>
+
<li>In your application classes that use RenderScript, add an import for the Support Library
classes:
+
<pre>
import android.support.v8.renderscript.*;
</pre>
+
</li>
-</ol>
-<p>The {@code project.properties} settings listed above control specific behavior in the Android
- build process:</p>
-
-<ul>
- <li>{@code renderscript.target} - Specifies the bytecode version to be generated. We
- recommend you set this value the highest available API level and set {@code
- renderscript.support.mode} to {@code true}. Valid values for this setting are any integer value
- from 11 to the most recently released API level. If your minimum SDK version specified in your
- application manifest is set to a higher value, this value is ignored and the target value is set
- to the minimum SDK version.</li>
- <li>{@code renderscript.support.mode} - Specifies that the generated bytecode should fall
- back to a compatible version if the device it is running on does not support the target version.
- </li>
- <li>{@code sdk.buildtools} - The version of the Android SDK build tools to use. This value
- should be set to {@code 18.1.0} or higher. If this option is not specified, the highest
- installed build tools version is used. You should always set this value to ensure the
- consistency of builds across development machines with different configurations.</li>
-</ul>
-
+ </0l>
<h2 id="using-rs-from-java">Using RenderScript from Java Code</h2>
diff --git a/docs/html/images/cards/card-cardboard_2x.png b/docs/html/images/cards/card-cardboard_2x.png
new file mode 100644
index 0000000..72903f9
--- /dev/null
+++ b/docs/html/images/cards/card-cardboard_2x.png
Binary files differ
diff --git a/docs/html/images/cards/card-cast_2x.jpg b/docs/html/images/cards/card-cast_2x.jpg
new file mode 100644
index 0000000..699048d
--- /dev/null
+++ b/docs/html/images/cards/card-cast_2x.jpg
Binary files differ
diff --git a/docs/html/images/cards/card-places_2x.png b/docs/html/images/cards/card-places_2x.png
new file mode 100644
index 0000000..a9b468c
--- /dev/null
+++ b/docs/html/images/cards/card-places_2x.png
Binary files differ
diff --git a/docs/html/images/develop/studio-open.png b/docs/html/images/develop/studio-open.png
new file mode 100644
index 0000000..2e0f599e
--- /dev/null
+++ b/docs/html/images/develop/studio-open.png
Binary files differ
diff --git a/docs/html/images/distribute/app-indexing-deep-links.png b/docs/html/images/distribute/app-indexing-deep-links.png
new file mode 100644
index 0000000..8ea8071
--- /dev/null
+++ b/docs/html/images/distribute/app-indexing-deep-links.png
Binary files differ
diff --git a/docs/html/images/distribute/appindexing.gif b/docs/html/images/distribute/appindexing.gif
new file mode 100644
index 0000000..6015d14
--- /dev/null
+++ b/docs/html/images/distribute/appindexing.gif
Binary files differ
diff --git a/docs/html/images/distribute/cardboard.jpg b/docs/html/images/distribute/cardboard.jpg
new file mode 100644
index 0000000..36b39db
--- /dev/null
+++ b/docs/html/images/distribute/cardboard.jpg
Binary files differ
diff --git a/docs/html/images/distribute/cast.jpg b/docs/html/images/distribute/cast.jpg
new file mode 100644
index 0000000..d5e4a32
--- /dev/null
+++ b/docs/html/images/distribute/cast.jpg
Binary files differ
diff --git a/docs/html/images/distribute/engage-intents.png b/docs/html/images/distribute/engage-intents.png
new file mode 100644
index 0000000..2889c08
--- /dev/null
+++ b/docs/html/images/distribute/engage-intents.png
Binary files differ
diff --git a/docs/html/images/distribute/google-now-engagement.png b/docs/html/images/distribute/google-now-engagement.png
new file mode 100644
index 0000000..416247b
--- /dev/null
+++ b/docs/html/images/distribute/google-now-engagement.png
Binary files differ
diff --git a/docs/html/images/distribute/more-app-engagement.png b/docs/html/images/distribute/more-app-engagement.png
new file mode 100644
index 0000000..31cbede
--- /dev/null
+++ b/docs/html/images/distribute/more-app-engagement.png
Binary files differ
diff --git a/docs/html/images/distribute/music-action.png b/docs/html/images/distribute/music-action.png
new file mode 100644
index 0000000..24d6dc8
--- /dev/null
+++ b/docs/html/images/distribute/music-action.png
Binary files differ
diff --git a/docs/html/images/distribute/promote-ads-apps.png b/docs/html/images/distribute/promote-ads-apps.png
new file mode 100644
index 0000000..9009a37
--- /dev/null
+++ b/docs/html/images/distribute/promote-ads-apps.png
Binary files differ
diff --git a/docs/html/images/distribute/promote-ads-web.png b/docs/html/images/distribute/promote-ads-web.png
new file mode 100644
index 0000000..2f9630e
--- /dev/null
+++ b/docs/html/images/distribute/promote-ads-web.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads.png b/docs/html/images/distribute/promote_ads.png
new file mode 100644
index 0000000..38517aa
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_apps.png b/docs/html/images/distribute/promote_ads_apps.png
new file mode 100644
index 0000000..2f57865
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_apps.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_gmail.png b/docs/html/images/distribute/promote_ads_gmail.png
new file mode 100644
index 0000000..1d21b4a
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_gmail.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_inapp.png b/docs/html/images/distribute/promote_ads_inapp.png
new file mode 100644
index 0000000..8aeee57
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_inapp.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_play.png b/docs/html/images/distribute/promote_ads_play.png
new file mode 100644
index 0000000..1cf51b2
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_play.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_search.png b/docs/html/images/distribute/promote_ads_search.png
new file mode 100644
index 0000000..27c0b38
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_search.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_web.png b/docs/html/images/distribute/promote_ads_web.png
new file mode 100644
index 0000000..588a3d4
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_web.png
Binary files differ
diff --git a/docs/html/images/distribute/promote_ads_youtube.png b/docs/html/images/distribute/promote_ads_youtube.png
new file mode 100644
index 0000000..e88a796
--- /dev/null
+++ b/docs/html/images/distribute/promote_ads_youtube.png
Binary files differ
diff --git a/docs/html/images/distribute/voice-actions-engagement.png b/docs/html/images/distribute/voice-actions-engagement.png
new file mode 100644
index 0000000..63a2605
--- /dev/null
+++ b/docs/html/images/distribute/voice-actions-engagement.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index cfbe7b6..71f6d58 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -10,7 +10,10 @@
</div>
<div class="actions-bar dac-expand dac-invert">
- <div class="wrap">
+ <div class="wrap dac-offset-parent">
+ <a class="dac-fab dac-scroll-button" data-scroll-button href="#build-apps">
+ <i class="dac-sprite dac-arrow-down-gray"></i>
+ </a>
<div class="actions">
<div><a href="{@docRoot}sdk/index.html">
<span class="dac-sprite dac-auto-chevron-large"></span>
@@ -24,15 +27,14 @@
<span class="dac-sprite dac-auto-chevron-large"></span>
Watch Videos
</a></div>
- <div><a href="{@docRoot}distribute/googleplay/developer-console.html">
- <span class="dac-sprite dac-auto-chevron-large"></span>
- Manage Your Apps
- </a></div>
</div><!-- end .actions -->
</div><!-- end .wrap -->
</div><!-- end .actions-bar -->
-<section class="dac-section dac-section-light"><div class="wrap">
+<div class="dac-hero-carousel" data-carousel-query="collection:distribute/landing/carousel">
+</div>
+
+<section class="dac-section dac-section-light" id="build-apps"><div class="wrap">
<h1 class="dac-section-title">Build Beautiful Apps</h1>
<div class="dac-section-subtitle">
See what’s new or find the resources to get you started with designing and developing for Android.
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 834eac1..a293131 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -104,15 +104,37 @@
"resources": [
"https://www.youtube.com/watch?v=AK38PJZmIW8&list=PLWz5rJ2EKKc-kIrPiq098QH9dOle-fLef",
"https://www.youtube.com/watch?v=6K_jxccHv5M&index=1&list=PLOU2XLYxmsILFBfx66ens76VMLMEPJAB0",
- "https://www.youtube.com/watch?v=KNKGM4ss5Sc&index=4&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM"
+ "https://www.youtube.com/watch?v=ctiaVxgclsg&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM"
]
},
"develop/landing/tools": {
"title": "",
"resources": [
- "https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ&index=1",
- "https://www.youtube.com/watch?v=3PIc-DuEU2s&index=1&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX",
- "https://www.youtube.com/watch?v=FOn64iqlphk&index=1&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf"
+ "https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "https://www.youtube.com/watch?v=3PIc-DuEU2s&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX",
+ "https://www.youtube.com/watch?v=cD7NPxuuXYY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "https://www.youtube.com/watch?v=JLLnhwtDoHw&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "https://www.youtube.com/watch?v=2I6fuD20qlY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "https://www.youtube.com/watch?v=5Be2mJzP-Uw&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX"
+ ]
+ },
+ "google/landing/services": {
+ "title": "",
+ "resources": [
+ "https://developers.google.com/analytics/devguides/collection/android/",
+ "https://developers.google.com/maps/documentation/android/",
+ "https://developers.google.com/+/mobile/android/sign-in",
+ "https://developers.google.com/places/android/",
+ "https://developers.google.com/gcm/android/",
+ "https://developers.google.com/maps/documentation/android/"
+ ]
+ },
+ "google/landing/googleplay": {
+ "title": "",
+ "resources": [
+ "google/play/billing/index.html",
+ "google/play/billing/billing_subscriptions.html",
+ "google/play/developer-api.html"
]
},
"develop/landing/courses": {
@@ -123,6 +145,14 @@
"https://www.udacity.com/course/android-performance--ud825"
]
},
+ "preview/landing/herolinks": {
+ "title": "",
+ "resources": [
+ "https://www.udacity.com/course/ux-design-for-mobile-developers--ud849",
+ "https://www.udacity.com/course/developing-android-apps--ud853",
+ "https://www.udacity.com/course/android-performance--ud825"
+ ]
+ },
"distribute/landing/carousel": {
"title": "",
"resources": [
@@ -143,12 +173,12 @@
"distribute/landing/more": {
"title": "",
"resources": [
- "distribute/users/promote-with-ads.html",
- "distribute/monetize/ads.html",
- "distribute/analyze/index.html",
- "distribute/engage/deep-linking.html",
- "distribute/engage/easy-signin.html",
- "https://cloud.google.com/docs/"
+ "distribute/users/promote-with-ads.html",
+ "distribute/monetize/ads.html",
+ "distribute/analyze/index.html",
+ "distribute/engage/deep-linking.html",
+ "distribute/engage/easy-signin.html",
+ "https://cloud.google.com/docs/"
]
},
"distribute/edu/videos/stories": {
@@ -271,10 +301,11 @@
"resources": [
"distribute/users/know-your-user.html",
"distribute/users/your-listing.html",
- "distribute/users/build-buzz.html",
- "distribute/users/build-community.html",
"distribute/users/expand-to-new-markets.html",
- "distribute/users/promote-with-ads.html"
+ "distribute/users/promote-with-ads.html",
+ "distribute/users/appindexing.html",
+ "distribute/users/build-buzz.html",
+ "distribute/users/build-community.html"
]
},
"distribute/engagelanding": {
@@ -284,8 +315,10 @@
"distribute/engage/gcm.html",
"distribute/engage/easy-signin.html",
"distribute/engage/deep-linking.html",
- "distribute/engage/game-services.html",
+ "distribute/engage/ads.html",
+ "distribute/engage/intents.html",
"distribute/engage/analytics.html",
+ "distribute/engage/game-services.html",
"distribute/engage/app-updates.html",
"distribute/engage/community.html",
"distribute/engage/video.html"
@@ -459,6 +492,22 @@
"https://support.google.com/googleplay/android-developer/answer/138294"
]
},
+ "distribute/googleplay/cast": {
+ "title": "Google Cast",
+ "resources": [
+ "https://developers.google.com/cast/docs/ux_guidelines",
+ "https://developers.google.com/cast/docs/android_sender",
+ "http://www.github.com/googlecast"
+ ]
+ },
+ "distribute/googleplay/cardboard": {
+ "title": "Google Cast",
+ "resources": [
+ "https://www.google.com/get/cardboard/",
+ "https://developers.google.com/cardboard/android/download",
+ "http://www.google.com/design/spec-vr"
+ ]
+ },
"distribute/googleplay/gpfe/highlight": {
"title": "About Google Play for Education",
"resources": [
@@ -541,8 +590,10 @@
"distribute/users/promotewithads": {
"title": "",
"resources": [
- "http://www.google.com/ads/admob/#subid=us-en-et-dac",
- "distribute/essentials/optimizing-your-app.html"
+ "https://support.google.com/adwords/answer/6032059",
+ "https://support.google.com/adwords/answer/6032073",
+ "https://support.google.com/adwords/answer/6167164",
+ "https://support.google.com/adwords/answer/6167162"
]
},
"distribute/users/buildbuzz": {
@@ -574,6 +625,14 @@
"http://www.youtube.com/yt/dev/"
]
},
+ "distribute/users/appindexing": {
+ "title": "",
+ "resources": [
+ "https://developers.google.com/app-indexing/",
+ "https://developers.google.com/app-indexing/webmasters/details",
+ "distribute/engage/search.html"
+ ]
+ },
"distribute/toolsreference/bestpractices/apps": {
"title": "",
"resources": [
@@ -797,6 +856,31 @@
"guide/topics/appwidgets/index.html"
]
},
+ "distribute/engage/reengage": {
+ "title": "",
+ "resources": [
+ "https://support.google.com/adwords/answer/6032073",
+ "distribute/engage/deep-linking.html",
+ "https://support.google.com/adwords/answer/6167162",
+ "distribute/users/promote-with-ads.html"
+ ]
+ },
+ "distribute/engage/appindexing": {
+ "title": "",
+ "resources": [
+ "distribute/engage/intents.html",
+ "distribute/engage/appindexing.html",
+ "distribute/users/appindexing.html"
+ ]
+ },
+ "distribute/engage/intents": {
+ "title": "",
+ "resources": [
+ "guide/components/intents-filters.html",
+ "distribute/engage/appindexing.html",
+ "distribute/engage/ads.html"
+ ]
+ },
"distribute/getusers/expandnewmarkets": {
"title": "",
"resources": [
@@ -1223,6 +1307,17 @@
"training/monetization/ads-and-ux.html"
]
},
+ "distribute/monetize/admob": {
+ "title": "",
+ "resources": [
+ "https://support.google.com/admob/topic/2784623",
+ "https://developers.google.com/mobile-ads-sdk/download",
+ "http://analyticsacademy.withgoogle.com/mobile-app",
+ "http://support.google.com/googleplay/android-developer/topic/2985714",
+ "https://support.google.com/admob/answer/2753860",
+ "https://support.google.com/admob/"
+ ]
+ },
"distribute/monetize/paymentmethods": {
"title": "",
"resources": [
@@ -1233,9 +1328,12 @@
"preview/landing/resources": {
"title": "",
"resources": [
+ "preview/overview.html",
"preview/api-overview.html",
"preview/setup-sdk.html",
- "preview/samples.html"
+ "preview/samples.html",
+ "preview/reference.html",
+ "preview/support.html"
]
},
"autolanding": {
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index cc11da5..cf1da97 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -14,6 +14,8 @@
ALL_RESOURCES_BY_URL. */
DISTRIBUTE_RESOURCES = DISTRIBUTE_RESOURCES.concat([
+ /* TODO Remove standard resources from here, such as below
+ */
{
"title":"Quizlet Developer Story",
"titleFriendly":"",
@@ -29,7 +31,7 @@
"type":"video"
},
{
- "title":"Whats New in Google Play",
+ "title":"What's New in GPFE",
"titleFriendly":"",
"summary":"Learn about the vision and philosophy behind Google Play for Education",
"url":"https://www.youtube.com/watch?v=IKhU180eJMo",
@@ -43,6 +45,124 @@
"type":"video"
},
{
+ "title":"Get started with Google Cast",
+ "titleFriendly":"",
+ "summary":"Build multi-screen experiences, let the user send video and audio content to TVs and speakers.",
+ "url":"https://developers.google.com/cast/docs/ux_guidelines",
+ "group":"",
+ "keywords": ["cast", "chromecast", "video", "audio"],
+ "tags": [],
+ "image":"images/cards/card-cast_2x.jpg",
+ "type":"Guide"
+ },
+ {
+ "title":"Android Sender Applications",
+ "titleFriendly":"",
+ "summary":"Get an overview of how your Android app can act as a Google Cast sender app.",
+ "url":"https://developers.google.com/cast/docs/android_sender",
+ "group":"",
+ "keywords": ["cast", "sender"],
+ "tags": [],
+ "image":"images/cards/card-cast_2x.jpg",
+ "type":"Guide"
+ },
+ {
+ "title":"Cast sample apps",
+ "titleFriendly":"",
+ "summary":"Get example Google Cast applications for both senders and receivers.",
+ "url":"http://www.github.com/googlecast",
+ "group":"",
+ "keywords": ["cast", "samples"],
+ "tags": [],
+ "image":"images/cards/card-cast_2x.jpg",
+ "type":"Samples"
+ },
+ {
+ "title":"Get Cardboard",
+ "titleFriendly":"",
+ "summary":"Get your own Cardboard, today. Buy one from a manufacturer or build your own, and start developing.",
+ "url":"https://www.google.com/get/cardboard/",
+ "group":"",
+ "keywords": ["carboard","vr"],
+ "tags": [],
+ "image":"images/cards/card-cardboard_2x.jpg",
+ "type":"Guide"
+ },
+ {
+ "title":"Download the Cardboard SDK",
+ "titleFriendly":"",
+ "summary":"Grab the Cardboard libraries from GitHub and start creating VR apps in your favorite development environment.",
+ "url":"https://developers.google.com/cardboard/android/download",
+ "group":"",
+ "keywords": ["carboard","vr"],
+ "tags": [],
+ "image":"images/cards/card-cardboard_2x.png",
+ "type":"Guide"
+ },
+ {
+ "title":"Cardboard design guidelines",
+ "titleFriendly":"",
+ "summary":"Focus on overall usability and avoiding common VR pitfalls while creating an immersive experience of your own.",
+ "url":"http://www.google.com/design/spec-vr",
+ "group":"",
+ "keywords": ["carboard","vr"],
+ "tags": [],
+ "image":"images/cards/card-cardboard_2x.png",
+ "type":"Design"
+ },
+
+
+
+ {
+ "title":"Maps",
+ "titleFriendly":"",
+ "summary":"Give users the map that more than a billion people use every month.",
+ "url":"https://developers.google.com/maps/documentation/android/",
+ "group":"",
+ "keywords": ["maps"],
+ "tags": [],
+ "image":"images/google/gps-maps.png",
+ "type":"Guide"
+ },
+ {
+ "title":"Places API",
+ "titleFriendly":"",
+ "summary":"give your users contextual information about where they are, when they’re there.",
+ "url":"https://developers.google.com/places/android/",
+ "group":"",
+ "keywords": ["places","location", "context"],
+ "tags": [],
+ "image":"images/cards/card-places_2x.png",
+ "type":"Guide"
+ },
+ {
+ "title":"Google Cloud Messaging",
+ "titleFriendly":"",
+ "summary":"Send push notifications and pubsub from your server to your users’ devices around the world.",
+ "url":"https://developers.google.com/gcm/android/",
+ "group":"",
+ "keywords": ["push","gcm"],
+ "tags": [],
+ "image":"images/gcm/gcm-logo.png",
+ "type":"Guide"
+ },
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
"title":"ClassDojo Developer Story",
"titleFriendly":"",
"summary":"ClassDojo is a classroom tool that helps teachers improve behavior in their classrooms quickly and easily. See how they optimized for the classroom with Android and the power of Google Play for Education.",
@@ -174,7 +294,7 @@
"title":"Introduction to Android Studio",
"titleFriendly":"",
"summary":"Learn why you should migrate your projects to Android Studio now and how it can help you be more productive as a developer. Rich layout editor, handy suggestions and fixes, new Android project view - these are just some of the things you can expect from the IDE, which is built on the successful IntelliJ IDEA.",
- "url":"https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ&index=1",
+ "url":"https://www.youtube.com/watch?v=K2dodTXARqc&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
"group":"",
"keywords": ["studio", "tools"],
"tags": [
@@ -186,7 +306,7 @@
"title":"Google Play Services 7.3",
"titleFriendly":"",
"summary":"Google Play Services 7.3 brings a ton of great new features to help you BUILD BETTER APPS! This update brings the ability to connect multiple wearables simultaneously to a single phone.",
- "url":"https://www.youtube.com/watch?v=FOn64iqlphk&index=1&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
+ "url":"https://www.youtube.com/watch?v=FOn64iqlphk&list=PLWz5rJ2EKKc9Qk1_iCZNbBp6adYnJf9Vf",
"group":"",
"keywords": ["google play services"],
"tags": [
@@ -219,15 +339,15 @@
"type":"video"
},
{
- "title":"Under the Hood of Android Auto",
+ "title":"Introduction to Android Auto",
"titleFriendly":"",
- "summary":"Your car contains some serious technology. Learn about the Android Auto architecture, which enables you to control Android apps and services running on your phone through your car. ",
- "url":"https://www.youtube.com/watch?v=KNKGM4ss5Sc&index=4&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM",
+ "summary":"Android Auto brings the Android platform to the car in a way that's optimized for the driving experience. It's the same platform you already use for phones, tablets, televisions, wearables, and more. ",
+ "url":"https://www.youtube.com/watch?v=ctiaVxgclsg&list=PLWz5rJ2EKKc9BdE_PSLNIGjXXr3h_orXM",
"group":"",
"keywords": ["auto"],
"tags": [
],
- "image":"http://i1.ytimg.com/vi/KNKGM4ss5Sc/maxresdefault.jpg",
+ "image":"http://i1.ytimg.com/vi/ctiaVxgclsg/maxresdefault.jpg",
"type":"video"
},
{
@@ -1122,7 +1242,7 @@
],
"url": "http://www.google.com/analytics/mobile/",
"timestamp": 1383243492000,
- "image": "http://www.google.com//analytics/images/heros/mobile-index.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Google Mobile App Analytics",
"summary": "Mobile App Analytics measures what matters most at all key stages: from first discovery and download to in-app purchases. ",
"keywords": ["analytics,user behavior"],
@@ -1137,9 +1257,9 @@
],
"url": "https://developers.google.com/app-indexing/",
"timestamp": 1383243492000,
- "image": "https://developers.google.com/app-indexing/images/allthecooks_srp.png",
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/search_64dp.png",
"title": "Sign Up for App Indexing",
- "summary": "Google is working with app developers and webmasters to index the content of apps and relate them to websites. When relevant, Google Search results on Android will include deep links to apps.",
+ "summary": "Surface your app content in Google seaerch. Deep link direct to your apps.",
"keywords": [],
"type": "guide",
"titleFriendly": ""
@@ -1169,7 +1289,7 @@
"url": "https://developers.google.com/+/mobile/android/people",
"timestamp": 1383243492000,
"image": "images/google/gps-googleplus.png",
- "title": "Sign Up for App Indexing",
+ "title": "Google Sign In",
"summary": "After you let users sign in with Google, you can access their age range, language, public profile information, and people that they have circled.",
"keywords": ["googleplus"],
"type": "guide",
@@ -1253,6 +1373,19 @@
"lang": "en",
"group": "",
"tags": [],
+ "url": "https://developers.google.com/+/mobile/android/sign-in",
+ "timestamp": 1194884220000,
+ "image": 'images/google/gps-googleplus.png',
+ "title": "Sign-in with Google",
+ "summary": "Get users into your app quickly and securely.",
+ "keywords": ["signin", "Google+"],
+ "type": "guide",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
"url": "https://support.google.com/googleplay/android-developer/answer/2528691",
"timestamp": 1194884220000,
"image": "images/play_dev.jpg",
@@ -1448,20 +1581,6 @@
"lang": "en",
"group": "",
"tags": ["monetize", "ads"],
- "url": "http://www.google.com/ads/admob/#subid=us-en-et-dac",
- "timestamp": null,
- "image": "distribute/images/advertising.png",
- "title": "AdMob",
- "summary": "Make money by connecting with over a million Google advertisers all over the world, so your revenue scales with your app.",
- "keywords": ["ads"],
- "type": "distribute",
- "titleFriendly": ""
- },
-
- {
- "lang": "en",
- "group": "",
- "tags": ["monetize", "ads"],
"url": "http://www.google.com/doubleclick/publishers/small-business/index.html",
"timestamp": null,
"image": "http://www.google.com/doubleclick/publishers/small-business/images/define_ad.png",
@@ -1478,6 +1597,7 @@
"url": "http://support.google.com/googleplay/android-developer/topic/2985714",
"timestamp": null,
"image": "http://storage.googleapis.com/support-kms-prod/SNP_712EA2784949DDF085C46E3BE7B1DC618A09_4389397_en_v0",
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/play_64dp.png",
"title": "Policy Center: Ads",
"summary": "Introduction to ads and system interference policies in Google Play",
"keywords": ["ads"],
@@ -1552,12 +1672,12 @@
{
"lang": "en",
"group": "",
- "tags": ["analytics"],
+ "tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/",
"timestamp": null,
- "image": "https://developers.google.com/analytics/images/home/gear-logo.png",
- "title": "Google Mobile App Analytics SDK",
- "summary": "Get started with the Google Analytics SDK for Android.",
+ "image": "images/cards/analytics-mobile_2x.jpg",
+ "title": "Mobile App Analytics",
+ "summary": "Measure everything about your app. Get started with the Google Analytics SDK for Android.",
"keywords": ["analytics, user behavior"],
"type": "sdk",
"titleFriendly": ""
@@ -1815,7 +1935,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/solutions/mobile-implementation-guide",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Mobile Analytics Implementation Guide",
"summary": "Learn how you can implement additional Google Analytics features to better understand your users and their behavior.",
"keywords": ["analytics", "Play", "users"],
@@ -1841,7 +1961,7 @@
"tags": [],
"url": "https://analyticsacademy.withgoogle.com/course04",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Mobile App Analytics Fundamentals",
"summary": "This self-paced online course on mobile app measurement shows you how Google Analytics data can help you make your app more discoverable and profitable.",
"keywords": ["analytics"],
@@ -1854,7 +1974,7 @@
"tags": [],
"url": "https://github.com/googleanalytics/google-analytics-plugin-for-unity",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Analytics Plugin for Unity",
"summary": "If you're building games with Unity, you can now implement Analytics once and ship it on multiple platforms automatically.",
"keywords": ["analytics", "unity"],
@@ -1867,7 +1987,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/enhanced-ecommerce",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "In-App Purchases & Ecommerce",
"summary": "If your app sells virtual or real goods, ecommerce tracking can help you understand what behaviors lead to purchases.",
"keywords": ["analytics, ecommerce"],
@@ -1880,7 +2000,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/1032415",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Goals",
"summary": "Track important actions in your app as goals and measure performance against your objectives.",
"keywords": ["analytics"],
@@ -1893,7 +2013,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/2568874?ref_topic=6012392",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Active Users",
"summary": "The active user report displays your 1-day, 7-day, 14-day and 30-day trailing active users next to each other, to help you analyze performance over time.",
"keywords": ["analytics"],
@@ -1906,7 +2026,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/events",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Events",
"summary": "Events let you measure granular in-app activities and understand user journeys.",
"keywords": ["analytics"],
@@ -1919,7 +2039,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/customdimsmets",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Custom Dimensions",
"summary": "Custom dimensions enable the association of metadata with hits, users, and sessions in Google Analytics.",
"keywords": ["analytics"],
@@ -1932,7 +2052,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/user-id",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "User ID",
"summary": "The User ID feature enables Google Analytics to measure user activities that span across devices.",
"keywords": ["analytics"],
@@ -1945,7 +2065,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/display-features",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Demographic Reporting",
"summary": "By enabling display features, you can see just how different user segments engage and monetize.",
"keywords": ["analytics"],
@@ -1958,7 +2078,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/3123906",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "User Segmentation",
"summary": "Segments let you compare metrics for different subsets of users to identify trends and opportunities for your apps.",
"keywords": ["analytics"],
@@ -1971,7 +2091,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Campaign Tracking",
"summary": "Measuring campaigns in Google Analytics enables the attribution of campaigns and traffic sources to user activity within your app.",
"keywords": ["analytics"],
@@ -1997,7 +2117,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/1033961",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "AdWords Integration",
"summary": "Link Analytics and AdWords to see the entire picture of customer behavior, from ad click or impression through your site to conversion. ",
"keywords": ["adwords, analytics"],
@@ -2010,7 +2130,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/devguides/collection/android/v4/campaigns#google-play-url-builder",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Campaign URL builder for Google Play",
"summary": "Easily create your URLs to track install campaigns.",
"keywords": ["play, analytics"],
@@ -2036,7 +2156,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/2785577",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Behavior Flow",
"summary": "The Behavior Flow report visualizes the path users traveled from one Screen or Event to the next. This report can help you discover what content keeps users engaged with your app.",
"keywords": ["analytics"],
@@ -2049,7 +2169,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/1151300",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Custom Reports",
"summary": "Custom Reports let you create your own reports in your Google Analytics account.",
"keywords": ["analytics"],
@@ -2062,7 +2182,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/2611268",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Audience Lists & Remarketing",
"summary": "Remarketing with Google Analytics lets you deliver targeted ads to users who've already been to your site or app. You can even base those ads on the behavior those users displayed during their sessions.",
"keywords": ["analytics"],
@@ -2075,7 +2195,7 @@
"tags": [],
"url": "https://support.google.com/admob/answer/3508177",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "AdMob Integration",
"summary": "With Google Analytics in AdMob, you can view Google Analytics data for your linked apps from within your AdMob account.",
"keywords": ["analytics"],
@@ -2088,7 +2208,7 @@
"tags": [],
"url": "https://developers.google.com/analytics/solutions/mobile-campaign-deep-link",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Deep-Linking",
"summary": "Google Analytics gives you a full view of how returning users are interacting with your app, for a holistic view beyond the install.",
"keywords": ["analytics"],
@@ -2101,7 +2221,7 @@
"tags": [],
"url": "https://support.google.com/admob/answer/3508177",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "AdMob Integration",
"summary": "With Google Analytics in AdMob, you can view Google Analytics data for your linked apps from within your AdMob account.",
"keywords": ["analytics"],
@@ -2114,7 +2234,7 @@
"tags": [],
"url": "https://support.google.com/analytics/answer/2568874",
"timestamp": null,
- "image": "distribute/images/gp-analytics-logo.jpg",
+ "image": "images/cards/analytics-mobile_2x.jpg",
"title": "Active User Report",
"summary": "Active user report displays your 1-day, 7-day, 14-day and 30-day trailing active users next to each other, to help you run benchmark analyses of their performance over time.",
"keywords": ["analytics"],
@@ -2251,7 +2371,7 @@
"type": "materialdesign",
"titleFriendly": ""
},
- {
+ {
"lang": "en",
"group": "",
"tags": [
@@ -2268,6 +2388,187 @@
"type": "material design",
"titleFriendly": ""
},
+
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://support.google.com/adwords/answer/6032059",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "Setting up Mobile App Install Ads",
+ "summary": "With Mobile app installs campaigns on the Search and Display Networks, and TrueView for mobile app promotion on YouTube, you can create custom app install ads that run exclusively on phones and tablets.",
+ "keywords": ["marketing", "admob"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://support.google.com/adwords/answer/6167164",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "Best practices for Mobile App Engagement",
+ "summary": "Learn how to market to your user base to drive re-engagement with your app. ",
+ "keywords": ["marketing", "admob"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [
+ "marketing",
+ "engagement",
+ "adwords1"
+ ],
+ "url": "https://support.google.com/adwords/answer/6032073",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/adwords_64dp.png",
+ "title": "Setting up Mobile App Engagement Ads",
+ "summary": "Mobile app engagement campaigns are a great choice for advertisers focused on connecting with people who already have their app.",
+ "keywords": [
+ "marketing",
+ "engagement",
+ "adwords"
+ ],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [
+ "marketing",
+ "engagement"
+ ],
+ "url": "https://support.google.com/adwords/answer/6167162",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/adwords_64dp.png",
+ "title": "Best Practices for Mobile App Installs",
+ "summary": "Getting your mobile app discovered can be challenging. Learn how to drive downloads of your app and grow a valuable user base.",
+ "keywords": ["marketing", "adwords"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+
+
+
+
+
+
+
+
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://support.google.com/admob/topic/2784623",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "Set up your AdMob account",
+ "summary": "Guide to setting up your account so that you get the most value.",
+ "keywords": ["marketing", "admob"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "http://analyticsacademy.withgoogle.com/mobile-app",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "Analytics Academy for Mobile Apps",
+ "summary": "Learn how to use Google Analytics to make your app more discoverable and profitable.",
+ "keywords": ["marketing", "analytics"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://developers.google.com/mobile-ads-sdk/download",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "Google Mobile Ads SDK",
+ "summary": "Use the Mobile Ads SDK to start showing AdMob ads in your apps.",
+ "keywords": ["marketing", "adwords"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://support.google.com/admob/",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "AdMob Help Center",
+ "summary": "For setup assistance, general info, and fixes for specific problems check out the AdMob Help Center.",
+ "keywords": ["admob"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
+ "url": "https://support.google.com/admob/answer/2753860",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/admob_64dp.png",
+ "title": "AdMob Policy Guidelines",
+ "summary": "Learn about best practices for displaying AdMob ads in your apps to maximize revenue.",
+ "keywords": ["admob"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": ["appindexing", "search", "getusers"],
+ "url": "https://developers.google.com/app-indexing/",
+ "timestamp": 1383243492000,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/search_64dp.png",
+ "title": "Set Up App Indexing",
+ "summary": "Learn more about how Google Search can help users discover your app, along with other ways you can integrate with Google Search.",
+ "keywords": ["search"],
+ "type": "guide",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": ["appindexing", "search", "getusers"],
+ "url": "https://developers.google.com/app-indexing/webmasters/details",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/search_64dp.png",
+ "title": "Verify and Create Deep Links",
+ "summary": "Index your app today by adding deep links and verifying its official web site to ensure it starts appearing in Google Search results.",
+ "keywords": ["search"],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [
+ "appindexing",
+ "search",
+ "getusers",
+ ],
+ "url": "https://support.google.com/admob/answer/2753860",
+ "timestamp": null,
+ "image": "https://www.gstatic.com/images/icons/material/product/2x/search_64dp.png",
+ "title": "Drive use with Google Search",
+ "summary": "More about how app indexing and deep links can drive users directly to the content in your app. ",
+ "keywords": [],
+ "type": "distribute",
+ "titleFriendly": ""
+ },
+ // TODO remove this?
{
"title":"Android Wear Materials",
"titleFriendly":"",
@@ -2328,12 +2629,11 @@
"lang":"en",
"type":"video"
},
-
{
"title":"Android Support Library",
"titleFriendly":"",
"summary":"These essential components help you build a great app that works on the huge variety of Android devices, faster.",
- "url":"https://www.youtube.com/watch?v=3PIc-DuEU2s&index=1&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX",
+ "url":"https://www.youtube.com/watch?v=3PIc-DuEU2s&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX",
"group":"",
"keywords": ["support", "compatibility"],
"tags": [],
@@ -2342,20 +2642,68 @@
"type":"Video"
},
{
+ "title":"Consistent Design with the AppCompat Support Library",
+ "titleFriendly":"",
+ "summary":"Getting a great looking app doesn't have to be hard: AppCompat, part of the Android Support Library, gives you a consistent design baseline that works on all Android 2.1 or higher devices.",
+ "url":"https://www.youtube.com/watch?v=5Be2mJzP-Uw&list=PLWz5rJ2EKKc9e0d55YHgJFHXNZbGHEXJX",
+ "group":"",
+ "keywords": ["support", "compatibility","design-code"],
+ "tags": [],
+ "image":"http://i1.ytimg.com/vi/5Be2mJzP-Uw/maxresdefault.jpg",
+ "lang":"en",
+ "type":"Video"
+ },
+ {
+ "title":"Introducing Gradle",
+ "titleFriendly":"",
+ "summary":"Android Studio uses an entirely new and flexible Gradle-based build system. You will be able to create multiple build variants for a single project, manage library dependencies and always be sure that your application builds correctly across different environments.",
+ "url":"https://www.youtube.com/watch?v=cD7NPxuuXYY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "group":"",
+ "keywords": ["tools", "studio","gradle"],
+ "tags": [],
+ "image":"http://i1.ytimg.com/vi/cD7NPxuuXYY/maxresdefault.jpg",
+ "lang":"en",
+ "type":"Video"
+ },
+ {
+ "title":"Android Studio Layout Editor",
+ "titleFriendly":"",
+ "summary":"Android Studio includes a rich, visual layout editor that helps developers create better user interfaces. It eliminates the need to deploy the APK on a real device with each change, making iterations faster and helping eliminate common errors earlier in the development process.",
+ "url":"https://www.youtube.com/watch?v=JLLnhwtDoHw&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "group":"",
+ "keywords": ["tools", "studio","layout"],
+ "tags": [],
+ "image":"http://i1.ytimg.com/vi/JLLnhwtDoHw/maxresdefault.jpg",
+ "lang":"en",
+ "type":"Video"
+ },
+ {
+ "title":"Debugging and testing in Android Studio",
+ "titleFriendly":"",
+ "summary":"Learn about new debugger features in Android Studio 1.2: value inlining, quick access to referring objects and a Java .class decompiler, just to name a few. See some new tools and views that let you monitor the CPU and memory performance of your app from within the IDE. ",
+ "url":"https://www.youtube.com/watch?v=2I6fuD20qlY&list=PLWz5rJ2EKKc8I9gHTMh5yKkwRRGE8BjbQ",
+ "group":"",
+ "keywords": ["tools", "studio","debugging","profiling","performance"],
+ "tags": [],
+ "image":"http://i1.ytimg.com/vi/2I6fuD20qlY/maxresdefault.jpg",
+ "lang":"en",
+ "type":"Video"
+ },
+ {
"tags": [
"android",
"developerstory",
"googleplay",
"featured"
],
- "title": "Android Developer Storys: Jelly Button Games — Growing globally through data driven development",
+ "title": "Android Developer Story: Jelly Button Games — Growing globally through data driven development",
"type": "youtube",
"url": "http://www.youtube.com/watch?v=Pd49vTkvu0U"
},
{
"title":"Scale with Google Cloud Platform",
"titleFriendly":"",
- "summary":"With Google Cloud Platform, developers can build, test and deploy applications on Google's highly-scalable and reliable infrastructure for your web, mobile and backend solutions.",
+ "summary":"Build, test, and deploy applications on Google's highly-scalable and reliable infrastructure for your web, mobile and backend solutions.",
"url":"https://cloud.google.com/docs/",
"group":"",
"keywords": [],
@@ -2715,21 +3063,21 @@
"title": "Designed for Families",
"summary": "Introducing a new Google Play section to promote family friendly apps. Your apps in the program can benefit from enhanced discoverability in addition to maintaining their existing categories, rankings, and reviews elsewhere on the Google Play store."
},
- "http://www.youtube.com/watch?v=Pd49vTkvu0U": {
+ "http://www.youtube.com/watch?v=Pd49vTkvu0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c": {
"image": "images/distribute/hero-jelly-button.jpg",
"title": "How Jelly Button Games are growing globally through data",
"summary": "To really understand their users, Jelly Button Games analyses over 3 billion events each month using Google Analytics and Google BigQuery."
},
- "http://www.youtube.com/watch?v=700gYRkhkLM": {
+ "http://www.youtube.com/watch?v=700gYRkhkLM&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c": {
"image": "images/distribute/hero-outfit7.jpg",
"title": "Outfit7 — Building an entertainment company with Google",
"summary": "Outfit7, creators of My Talking Tom and My Talking Angela, offer a complete entertainment experience to users spanning mobile apps, user generated and original YouTube content, and a range of toys, clothing, and accessories...."
},
- "http://www.youtube.com/watch?v=MPnH7h12h0U": {
+ "http://www.youtube.com/watch?v=MPnH7h12h0U&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c": {
"image": "images/distribute/hero-haystack.jpg",
"summary": "Haystack TV built a scalable business with six employees and Android TV. Two weeks was all it took for them to bring their mobile app to the big screen."
},
- "http://www.youtube.com/watch?v=ekxABqJeRBc": {
+ "http://www.youtube.com/watch?v=ekxABqJeRBc&list=PLWz5rJ2EKKc9ofd2f-_-xmUi07wIGZa1c": {
"image": "images/distribute/hero-ginlemon.jpg",
"title": "How GinLemon is breaking through with Google Play",
"summary": "Meet Vincenzo Colucci, developer and founder of GinLemon, which started as a summer holiday joke and has now become a successful global app business on Google Play based in Manfredonia, southern Italy."
diff --git a/docs/html/preview/data-binding/guide.jd b/docs/html/preview/data-binding/guide.jd
new file mode 100644
index 0000000..49b690f
--- /dev/null
+++ b/docs/html/preview/data-binding/guide.jd
@@ -0,0 +1,908 @@
+page.title=Data Binding Guide
+
+@jd:body
+<p>Data Binding allows you write declarative layouts and minimize the glue code
+that is necessary to bind your application logic and layouts.</p>
+
+
+<h2 id=build_environment>Build Environment</h2>
+
+
+<p><strong>Setting Up Work Environment:</strong></p>
+
+<p>Data Binding EAP only supports gradle.</p>
+
+<p>To set up your application, unzip the provided bundle to a location. It has 3
+sections</p>
+
+<ul>
+ <li> <em>maven-repo:</em> which keeps the data-binding libraries
+ <li> <em>samples:</em> Sample applications
+ <li> <em>databinding.properties:</em> Properties file that can be used to integrate with your app
+</ul>
+
+<p>Add the following section to the project’s build.gradle file (not the module's
+build.gradle) and replace <code><BUNDLE_FOLDER> </code>with the absolute path of the bundle that you’ve unzipped in the previous step.</p>
+
+<pre class=prettyprint>
+buildscript {
+ <strong>def </strong>eapFolder = '<BUNDLE_FOLDER>'
+<strong> def </strong>Properties props = <strong>new </strong>Properties()
+ props.load(<strong>new </strong>FileInputStream(<strong>"</strong>${eapFolder}<strong>/databinding.properties"</strong>))
+ props.mavenRepoDir = <strong>"</strong>${eapFolder}<strong>/</strong>${props.mavenRepoName}<strong>"
+ </strong>ext.config = props
+ repositories {
+ jcenter()
+ maven {
+ url config.mavenRepoDir
+ }
+ }
+ dependencies {
+ classpath <strong>"com.android.tools.build:gradle:1.1.3"
+ </strong>classpath <strong>"com.android.databinding:dataBinder:</strong>${config.snapshotVersion}<strong>"
+<em></strong> </em>}
+}
+allprojects {
+ repositories {
+ jcenter()
+ maven {
+ url config.mavenRepoDir
+ }
+ }
+}
+</pre>
+
+<p>Next, add the following lines to the <em>build.gradle</em>
+file of each module that will use data-binding. The application module must
+have this, even if only its libraries use data binding.</p>
+
+<pre class=prettyprint>
+apply plugin: <strong>'com.android.databinding'
+</strong>dependencies {
+ compile <strong>"com.android.databinding:library:</strong>${config.snapshotVersion}<strong>"
+</strong> compile <strong>"com.android.databinding:baseLibrary:</strong>${config.snapshotVersion}<strong>"
+</strong> compile <strong>"com.android.databinding:adapters:</strong>${config.snapshotVersion}<strong>"
+</strong> provided <strong>"com.android.databinding:annotationprocessor:</strong>${config.snapshotVersion}<strong>"
+</strong>}
+</pre>
+
+
+<h2 id="data_binding_layout_files">Data Binding Layout Files</h2>
+
+
+<h3 id="writing_expressions">Writing your first data binding expressions:</h3>
+
+<p>Data-binding layout files are slightly different and start with a root tag of
+<strong>layout</strong> followed by a <strong>data</strong> element and a
+<strong>view</strong> root element. This view element is what your root would
+be in a non-binding layout file.A sample file looks like this:</p>
+
+<pre class=prettyprint>
+<em><?<strong></em>xml version="1.0" encoding="utf-8"<em></strong>?>
+</em><<strong>layout xmlns:android="http://schemas.android.com/apk/res/android"</strong>>
+ <<strong>data</strong>>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+ </<strong>data</strong>>
+ <<strong>LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"</strong>>
+ <<strong>TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{user.firstName}"</strong>/>
+ <<strong>TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{user.lastName}"</strong>/>
+ </<strong>LinearLayout</strong>>
+</<strong>layout</strong>>
+</pre>
+
+<p>The user <strong>variable</strong> within <strong>data</strong> describes a property that may be used within this layout.</p>
+
+<pre class=prettyprint>
+<<strong>variable name="user" type="com.example.User"</strong>/>
+</pre>
+
+<p>Expressions within the layout are written in the attribute properties using the
+“<code>@{}</code>” syntax. Here, the TextView’s text is set to the firstName property of user:</p>
+<pre class=prettyprint>
+<<strong>TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{user.firstName}"</strong>/>
+</pre>
+
+
+<h3 id="data_object">Data Object</h3>
+
+<p>Let’s assume for now that you have a plain-old Java object (POJO) for User:</p>
+<pre class=prettyprint>
+<strong>public class </strong>User {
+ <strong>public final </strong>String <strong>firstName</strong>;
+ <strong>public final </strong>String <strong>lastName</strong>;
+ <strong>public </strong>User(String firstName, String lastName) {
+ <strong>this</strong>.<strong>firstName </strong>= firstName;
+ <strong>this</strong>.<strong>lastName </strong>= lastName;
+ }
+}
+</pre>
+
+<p>This type of object has data that never changes. It is common in applications
+to have data that is read once and never changes thereafter. It is also
+possible to use a JavaBeans objects:</p>
+<pre class=prettyprint>
+<strong>public class </strong>User {
+ <strong>private final </strong>String <strong>firstName</strong>;
+ <strong>private final </strong>String <strong>lastName</strong>;
+ <strong>public </strong>User(String firstName, String lastName) {
+ <strong>this</strong>.<strong>firstName </strong>= firstName;
+ <strong>this</strong>.<strong>lastName </strong>= lastName;
+ }
+ <strong>public </strong>String getFirstName() {
+ <strong>return this</strong>.<strong>firstName</strong>;
+ }
+ <strong>public </strong>String getLastName() {
+ <strong>return this</strong>.<strong>lastName</strong>;
+ }
+}
+</pre>
+
+<p>From the perspective of data binding, these two classes are equivalent. The
+expression <strong><code>@{user.lastName}</code></strong> used for the TextView’s <strong><code>android:text</code></strong> attribute will access the <strong><code>firstName</code></strong> field in the former class and the <code>getFirstName()</code> method in the latter class.
+</p><h3 id=binding_data>Binding Data</h3>
+
+<p>By default, a Binding class will be generated based on the name of the layout
+file, converting it to Pascal case and suffixing “Binding” to it. The above
+layout file was <code>activity_main.xml</code> so the generate class was <code>ActivityMainBinding</code>. This class holds all the bindings from the layout properties (e.g. the <code>user</code> variable) to the layout’s Views and knows how to assign values for the binding
+expressions.The easiest means for creating the bindings is to do it while inflating:
+</p>
+
+<pre class=prettyprint>
+@Override
+<strong>protected void </strong>onCreate(Bundle savedInstanceState) {
+ <strong>super</strong>.onCreate(savedInstanceState);
+ ActivityMainBinding binding = DataBindingUtil.<em>setContentView</em>(<strong>this</strong>, R.layout.<em><strong>main_activity</strong></em>);
+ User user = <strong>new </strong>User(<strong>"Test"</strong>, <strong>"User"</strong>);
+ binding.setUser(user);
+}
+</pre>
+
+<p>You’re done! Run the application and you’ll see Test User in the UI.Alternatively, you can get the view via:
+</p><pre class=prettyprint>
+MainActivityBinding binding = MainActivityBinding.<em>inflate</em>(getLayoutInflater());
+</pre>
+
+<p>If you are using data binding items inside a ListView or RecyclerView adapter,
+you may prefer to use:
+</p><pre class=prettyprint>
+ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup,
+false);
+//or
+ListItemBinding binding = DataBindingUtil.<em>inflate</em>(layoutInflater, R.layout.<em><strong>list_item</strong></em>, viewGroup, <strong>false</strong>);
+</pre>
+
+
+<h2 id=layout_details>Layout Details</h2>
+
+
+<h3 id=imports>Imports</h3>
+
+<p>Zero or more <strong><code>import</code></strong> elements may be used inside the <strong><code>data</code></strong> element. These allow easy reference to classes inside your layout file, just
+like in Java.
+</p><pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.view.View"</strong>/>
+</<strong>data</strong>>
+</pre>
+
+<p>Now, View may be used within your binding expression:
+</p><pre class=prettyprint>
+<<strong>TextView
+ android:text="@{user.lastName}"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"</strong>/>
+</pre>
+
+<p>When there are class name conflicts, one of the classes may be renamed to an
+“alias:”</p>
+<pre class=prettyprint>
+<<strong>import type="android.view.View"</strong>/>
+<<strong>import type="com.example.real.estate.View"
+ alias="Vista"</strong>/>
+</pre>
+
+<p>Now, <strong><code>Vista</code></strong> may be used to reference the <code>com.example.real.estate.View</code> and <strong><code>View</code></strong> may be used to reference <code>android.view.View </code>within the layout file.Imported types may be used as type references in variables and expressions:</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="com.example.User"</strong>/>
+ <<strong>import type="java.util.List"</strong>/>
+ <<strong>variable name="user" type="User"</strong>/>
+ <<strong>variable name="userList" type="List<User>"</strong>/>
+</<strong>data</strong>>
+…
+<<strong>TextView
+ android:text="@{((User)(user.connection)).lastName}"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+<p>Imported types may also be used when referencing static fields and methods in
+expressions:</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="com.example.MyStringUtils"</strong>/>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+</<strong>data</strong>>
+…
+<<strong>TextView
+ android:text="@{MyStringUtils.capitalize(user.lastName)}"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+<p>Just as in Java, <code>java.lang.*</code> is imported automatically.</p>
+<h3 id=variables>Variables</h3>
+
+<p>Any number of <strong><code>variable</code></strong> elements may be used inside the <strong><code>data</code></strong> element. Each <strong><code>variable</code></strong> element describes a property that may be set on the layout to be used in
+binding expressions within the layout file.</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.graphics.drawable.Drawable"</strong>/>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+ <<strong>variable name="image" type="Drawable"</strong>/>
+ <<strong>variable name="note" type="String"</strong>/>
+</<strong>data</strong>>
+</pre>
+
+<p>The variable types are inspected at compile time, so if a variable implements <a href="#observable_objects">Observable</a>, <a href="#observable_collections">observable collection</a>, that should be reflected in the type. If the variable is a base class or
+ interface that does not implement the Observable* interface, the variables will <strong>not be</strong> observed!</p>
+
+<p>When there are different layout files for various configurations (e.g.
+landscape or portrait), the variables will be combined. There must not be
+conflicting variable definitions between these layout files.</p>
+
+<p>The generated binding class will have a setter and getter for each of the
+described variables. The variables will take the default Java values until the
+setter is called — <code>null</code> for reference types, <code>0</code> for <code>int</code>, <code>false</code> for <code>boolean</code>, etc.</p>
+
+<h3 id=custom_binding_class_names>Custom Binding Class Names</h3>
+
+<p>By default, a Binding class is generated based on the name of the layout file,
+starting it with upper-case, removing underscores ( _ ) and capitalizing the
+following letter and then suffixing “Binding”. This class will be placed in a
+databinding package under the module package. For example, the layout file <code>contact_item.xml</code> will generate <code>ContactItemBinding</code>. If the module package is <code>com.example.my.app</code>, then it will be placed in <code>com.example.my.app.databinding</code>.</p>
+
+<p>Binding classes may be renamed or placed in different packages by adjusting the <strong><code>class</code></strong> attribute of the <strong><code>data</code></strong> element. For example:</p>
+<pre class=prettyprint>
+<<strong>data class="ContactItem"</strong>>
+ ...
+</<strong>data</strong>>
+</pre>
+
+<p>This generates the binding class as <code>ContactItem</code> in the databinding package in the module package. If the class should be
+generated in a different package within the module package, it may be prefixed
+with “.”:</p>
+<pre class=prettyprint>
+<<strong>data class=".ContactItem"</strong>>
+ ...
+</<strong>data</strong>>
+</pre>
+
+In this case, <code>ContactItem</code> is generated in the module package directly.Any package may be used if the full package is provided:
+<pre class=prettyprint>
+<<strong>data class="com.example.ContactItem"</strong>>
+ ...
+</<strong>data</strong>>
+</pre>
+
+
+<h3 id=includes>Includes</h3>
+
+<p>Variables may be passed into an included layout's binding from the containing
+layout by using the application namespace and the variable name in an
+attribute:</p>
+<pre class=prettyprint>
+<em><?<strong></em>xml version="1.0" encoding="utf-8"<em></strong>?>
+</em><<strong>layout xmlns:android="http://schemas.android.com/apk/res/android"
+</strong> <strong> xmlns:bind="http://schemas.android.com/apk/res-auto"</strong>>
+ <<strong>data</strong>>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+ </<strong>data</strong>>
+ <<strong>LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"</strong>>
+ <<strong>include layout="@layout/name"
+ bind:user="@{user}"</strong>/>
+ <<strong>include layout="@layout/contact"
+ bind:user="@{user}"</strong>/>
+ </<strong>LinearLayout</strong>>
+</<strong>layout</strong>>
+</pre>
+
+<p>Here, there must be a <code>user</code> variable in both the <code>name.xml </code>and <code>contact.xml </code>layout files.</p>
+<h3 id=expression_language>Expression Language</h3>
+
+
+<h4 id=common_features>Common Features</h4>
+
+<p>The expression language looks a lot like a Java expression. These are the same:</p>
+<ul>
+ <li> Mathematical <strong><code>+ - / * %</code></strong>
+ <li> String concatenation <strong><code>+</code></strong>
+ <li> <code>L</code>ogical <strong><code>&& ||</code></strong>
+ <li> Binary <strong><code>&</code> <code>|</code> <code>^</code></strong>
+ <li> Unary <strong><code>+ - ! ~</code></strong>
+ <li> Shift <strong><code>>> >>> <<</code></strong>
+ <li> Comparison <strong><code>== > < >= <=</code></strong>
+ <li> <strong><code>instanceof</code></strong>
+ <li> Grouping <strong><code>()</code></strong>
+ <li> Literals - character, String, numeric, <strong><code>null</code></strong>
+ <li> Cast
+ <li> Method calls
+ <li> Field access
+ <li> Array access <strong><code>[]</code></strong>
+ <li> Ternary operator <strong><code>?:</code></strong>
+</ul>
+<p>Examples:</p>
+<pre class=prettyprint>
+<strong>android:text="@{String.valueOf(index + 1)}"
+android:visibility="@{age < 13 ? View.GONE : View.VISIBLE}"
+android:transitionName='@{"image_" + id}'</strong>
+</pre>
+
+
+<h4 id=missing_operations>Missing Operations</h4>
+
+<p>A few operations are missing from the expression syntax that you can use in
+Java.</p>
+<ul>
+ <li> <strong><code>this</code></strong>
+ <li> <strong><code>super</code></strong>
+ <li> <strong><code>new</code></strong>
+ <li> Explicit generic invocation
+</ul>
+
+<h4 id=null_coalescing_operator>Null Coalescing Operator</h4>
+
+<p>The null coalescing operator (<strong><code>??</code></strong>) chooses the left operand if it is not null or the right if it is null.</p>
+<pre class=prettyprint>
+<strong>android:text="@{user.displayName ?? user.lastName}"</strong>
+</pre>
+
+<p>This is functionally equivalent to:</p>
+<pre class=prettyprint>
+<strong>android:text="@{user.displayName != null ? user.displayName : user.lastName}"</strong>
+</pre>
+
+
+<h4 id=property_reference>Property Reference</h4>
+
+<p>The first was already discussed in the <a href="#writing_your_first_data_binding_expressions">Writing your first data binding expressions</a> above: short form JavaBean references. When an expression references a
+property on a class, it uses the same format for fields, getters, and
+ObservableFields.</p>
+<pre class=prettyprint>
+<strong>android:text="@{user.lastName}"</strong>
+</pre>
+
+
+<h4 id=collections>Collections</h4>
+
+<p>Common collections: arrays, lists, sparse lists, and maps, may be accessed
+using the <code>[]</code> operator for convenience.</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.util.SparseArray"</strong>/>
+ <<strong>import type="java.util.Map"</strong>/>
+ <<strong>import type="java.util.List"</strong>/>
+ <<strong>variable name="list" type="List<String>"</strong>/>
+ <<strong>variable name="sparse" type="SparseArray<String>"</strong>/>
+ <<strong>variable name="map" type="Map<String, String>"</strong>/>
+ <<strong>variable name="index" type="int"</strong>/>
+ <<strong>variable name="key" type="String"</strong>/>
+</<strong>data</strong>>
+…
+<strong>android:text="@{list[index]}"
+</strong>…
+<strong>android:text="@{sparse[index]}"
+</strong>…
+<strong>android:text="@{map[key]}"
+</strong>
+</pre>
+
+
+<h4 id=string_literals>String Literals</h4>
+
+<p>When using single quotes around the attribute value, it is easy to use double
+quotes in the expression:</p>
+<pre class=prettyprint>
+<strong>android:text='@{map["firstName"]}'</strong>
+</pre>
+
+<p>It is also possible to use double quotes to surround the attribute value. When
+doing so, String literals should either use the " or back quote (`).</p>
+<pre class=prettyprint>
+<strong>android:text="@{map[`firstName`}"
+android:text="@{map["firstName"]}"</strong>
+</pre>
+
+
+<h4 id=resources>Resources</h4>
+
+<p>It is possible to access resources as part of expressions using the normal
+syntax:</p>
+<pre class=prettyprint>
+<strong>android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"</strong>
+</pre>
+
+<p>Format strings and plurals may be evaluated by providing parameters:</p>
+<pre class=prettyprint>
+<strong>android:text="@{@string/nameFormat(firstName, lastName)}"
+android:text="@{@plurals/banana(bananaCount)}"</strong>
+</pre>
+
+<p>Some resources require explicit type evaluation.</p>
+
+<table>
+ <tr>
+ <th>Type</th>
+ <th>Normal Reference</th>
+ <th>Expression Reference</th>
+ </tr>
+ <tr>
+ <td>
+<pre class=prettyprint>
+String[]</td>
+ <td>
+@array</td>
+ <td>
+@stringArray</td>
+ </tr>
+ <tr>
+ <td>
+int[]</td>
+ <td>
+@array</td>
+ <td>
+@intArray</td>
+ </tr>
+ <tr>
+ <td>
+TypedArray</td>
+ <td>
+@array</td>
+ <td>
+@typedArray</td>
+ </tr>
+ <tr>
+ <td>
+Animator</td>
+ <td>
+@animator</td>
+ <td>
+@animator</td>
+ </tr>
+ <tr>
+ <td>
+StateListAnimator</td>
+ <td>
+@animator</td>
+ <td>
+@stateListAnimator</td>
+ </tr>
+ <tr>
+ <td>
+</pre>
+
+color <code>int</code></td>
+ <td>
+<pre class=prettyprint>
+@color</td>
+ <td>
+@color</td>
+ </tr>
+ <tr>
+ <td>
+ColorStateList</td>
+ <td>
+@color</td>
+ <td>
+@colorStateList</td>
+ </tr>
+</table>
+
+</pre>
+
+
+<h2 id="data_objects">Data Objects</h2>
+
+
+<p>Any plain old Java object (POJO) may be used for data binding, but modifying a
+POJO will not cause the UI to update. The real power of data binding can be
+used by giving your data objects the ability to notify when data changes. There
+are three different data change notification mechanisms, <code>Observable </code>objects, <code>ObservableField</code>s, and <code>observable collections</code>.</p>
+
+<p>When one of these observable data object is bound to the UI and a property of
+the data object changes, the UI will be updated automatically.</p>
+
+<h3 id=observable_objects>Observable Objects</h3>
+
+
+<p>A class implementing <code>android.databinding.Observable</code> interface will allow the binding to attach a single listener to a bound object
+to listen for changes of all properties on that object.</p>
+
+<p>The <code>Observable</code> interface has a mechanism to add and remove listeners, but notifying is up to
+the developer. To make development easier, a base class, <code>BaseObservable,</code> was created to implement the listener registration mechanism. The data class
+implementer is still responsible for notifying when the properties change. This
+is done by assigning an <code>Bindable </code>annotation to the getter and notifying in the setter.</p>
+
+<pre class=prettyprint>
+<strong>private static class </strong>User <strong>extends </strong>BaseObservable {
+ <strong>private </strong>String <strong>firstName</strong>;
+ <strong>private </strong>String <strong>lastName</strong>;
+ @Bindable
+ <strong>public </strong>String getFirstName() {
+ <strong>return this</strong>.<strong>firstName</strong>;
+ }
+ @Bindable
+ <strong>public </strong>String getFirstName() {
+ <strong>return this</strong>.<strong>lastName</strong>;
+ }
+ <strong>public void </strong>setFirstName(String firstName) {
+ <strong>this</strong>.<strong>firstName </strong>= firstName;
+ notifyPropertyChanged(BR.firstName);
+ }
+ <strong>public void </strong>setLastName(String lastName) {
+ <strong>this</strong>.<strong>lastName </strong>= lastName;
+ notifyPropertyChanged(BR.lastName);
+ }
+}
+</pre>
+
+<p>The <code>Bindable </code>annotation generates an entry in the BR class file during compilation. The BR
+class file will be generated in the module package.If the base class for data classes cannot be changed, the <code>Observable</code> interface may be implemented using the convenient <code>PropertyChangeRegistry</code> to store and notify listeners efficiently.</p>
+
+<h3 id=observablefields>ObservableFields</h3>
+
+<p>A little work is involved in creating Observable classes, so developers who
+want to save time or have few properties may use ObservableFields.
+ObservableFields are self-contained observable objects that have a single
+field. There are versions for all primitive types and one for reference types.
+To use, create a public final field in the data class:</p>
+<pre class=prettyprint>
+<strong>private static class </strong>User <strong>extends </strong>BaseObservable {
+ <strong>public final </strong>ObservableField<String> <strong>firstName </strong>=
+ <strong>new </strong>ObservableField<>();
+ <strong>public final </strong>ObservableField<String> <strong>lastName </strong>=
+ <strong>new </strong>ObservableField<>();
+ <strong>public final </strong>ObservableInt <strong>age </strong>= <strong>new </strong>ObservableInt();
+}
+</pre>
+
+<p>That's it! To access the value, use the set and get accessor methods:</p>
+<pre class=prettyprint>
+user.<strong>firstName</strong>.set(<strong>"Google"</strong>);
+<strong>int </strong>age = user.<strong>age</strong>.get();
+</pre>
+
+
+<h3 id=observable_collections>Observable Collections</h3>
+
+<p>Some applications use more dynamic structures to hold data. Observable
+ collections allow keyed access to these data objects.ObservableArrayMap is useful when the key is a reference type, such as String.</p>
+
+<pre class=prettyprint>
+ObservableArrayMap<String, Object> user = <strong>new </strong>ObservableArrayMap<>();
+user.put(<strong>"firstName"</strong>, <strong>"Google"</strong>);
+user.put(<strong>"lastName"</strong>, <strong>"Inc."</strong>);
+user.put(<strong>"age"</strong>, 17);
+</pre>
+
+In the layout, the map may be accessed through the String keys:
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.databinding.ObservableMap"</strong>/>
+ <<strong>variable name="user" type="ObservableMap<String, Object>"</strong>/>
+</<strong>data</strong>>
+…
+<<strong>TextView
+ android:text='@{user["lastName"]}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+<<strong>TextView
+ android:text='@{String.valueOf(1 + (Integer)user["age"])}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+<p>ObservableArrayList is useful when the key is an integer:</p>
+<pre class=prettyprint>
+ObservableArrayList<Object> user = <strong>new </strong>ObservableArrayList<>();
+user.add(<strong>"Google"</strong>);
+user.add(<strong>"Inc."</strong>);
+user.add(17);
+</pre>
+
+<p>In the layout, the list may be accessed through the indices:</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.databinding.ObservableList"</strong>/>
+ <<strong>import type="com.example.my.app.Fields"</strong>/>
+ <<strong>variable name="user" type="ObservableList<Object>"</strong>/>
+</<strong>data</strong>>
+…
+<<strong>TextView
+ android:text='@{user[Fields.LAST_NAME]}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+<<strong>TextView
+ android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+
+<h2 id=generated_binding>Generated Binding</h2>
+
+<p>The generated binding class links the layout variables with the Views within
+the layout. As discussed earlier, the name and package of the Binding may be <a href="#custom_binding_class_names">customized</a>. The Generated binding classes all extend <code>android.databinding.ViewDataBinding</code>.</p>
+<h3 id=creating>Creating</h3>
+
+<p>The binding should be created soon after inflation to ensure that the View
+hierarchy is not disturbed prior to binding to the Views with expressions
+within the layout. There are a few ways to bind to a layout. The most common is
+to use the static methods on the Binding class.The inflate method inflates the View hierarchy and binds to it all it one step.
+There are versions that attach the View to its parent and that inflate without
+attaching.</p>
+<pre class=prettyprint>
+MyLayoutBinding binding = MyLayoutBinding.<em>inflate</em>(<strong>this</strong>);
+MyLayoutBinding binding = MyLayoutBinding.<em>inflate</em>(viewGroup);
+</pre>
+
+<p>If the layout was inflated using a different mechanism, it may be bound
+separately:</p>
+<pre class=prettyprint>
+MyLayoutBinding binding = MyLayoutBinding.<em>bind</em>(viewRoot);
+</pre>
+
+<p>Sometimes the binding cannot be known in advance. In such cases, the binding
+can be created using the DataBindingUtil class:</p>
+<pre class=prettyprint>
+ViewDataBinding binding = DataBindingUtil.<em>inflate</em>(context, layoutId,
+ parent, attachToParent);
+ViewDataBinding binding = DataBindingUtil.<em>bindTo</em>(viewRoot, layoutId);
+</pre>
+
+
+<h3 id=views_with_ids>Views With IDs</h3>
+
+<p>A public final field will be generated for each View with an ID in the layout.
+The binding does a single pass on the View hierarchy, extracting the Views with
+IDs. This mechanism can be faster than calling findViewById for several Views. For example:</p>
+<pre class=prettyprint>
+<<strong>layout xmlns:android="http://schemas.android.com/apk/res/android"</strong>>
+ <<strong>data</strong>>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+ </<strong>data</strong>>
+ <<strong>LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"</strong>>
+ <<strong>TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{user.firstName}"
+</strong> <strong>android:id="@+id/firstName"</strong>/>
+ <<strong>TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@{user.lastName}"</strong> <strong>android:id="@+id/lastName"</strong>/>
+ </<strong>LinearLayout</strong>>
+</<strong>layout</strong>>
+</pre>
+
+Will generate a binding class with:
+<pre class=prettyprint>
+<strong>public final </strong>TextView <strong>firstName</strong>;
+<strong>public final </strong>TextView <strong>lastName</strong>;
+</pre>
+
+<p>IDs are not nearly as necessary as without data binding, but there are still
+some instances where access to Views are still necessary from code.</p>
+<h3 id=variables>Variables</h3>
+
+<p>Each variable will be given a accessor methods.</p>
+<pre class=prettyprint>
+<<strong>data</strong>>
+ <<strong>import type="android.graphics.drawable.Drawable"</strong>/>
+ <<strong>variable name="user" type="com.example.User"</strong>/>
+ <<strong>variable name="image" type="Drawable"</strong>/>
+ <<strong>variable name="note" type="String"</strong>/>
+</<strong>data</strong>>
+</pre>
+
+<p>will generate setters and getters in the binding:</p>
+<pre class=prettyprint>
+<strong>public abstract </strong>com.example.User getUser();
+<strong>public abstract void </strong>setUser(com.example.User user);
+<strong>public abstract </strong>Drawable getImage();
+<strong>public abstract void </strong>setImage(Drawable image);
+<strong>public abstract </strong>String getNote();
+<strong>public abstract void </strong>setNote(String note);
+</pre>
+
+
+<h3 id=viewstubs>ViewStubs</h3>
+
+<p>ViewStubs are a little different from normal Views. They start off invisible
+and when they either are made visible or are explicitly told to inflate, they
+replace themselves in the layout by inflating another layout.</p>
+
+<p>Because the ViewStub essentially disappears from the View hierarchy, the View
+in the binding object must also disappear to allow collection. Because the
+Views are final, a ViewStubProxy object takes the place of the ViewStub, giving
+the developer access to the ViewStub when it exists and also access to the
+inflated View hierarchy when the ViewStub has been inflated.</p>
+
+<p>When inflating another layout, a binding must be established for the new
+layout. Therefore, the ViewStubProxy must listen to the ViewStub's
+OnInflateListener and establish the binding at that time. Since only one can
+exist, the ViewStubProxy allows the developer to set an OnInflateListener on it
+that it will call after establishing the binding.</p>
+
+<h3 id=advanced_binding>Advanced Binding</h3>
+
+
+<h4 id=dynamic_variables>Dynamic Variables</h4>
+
+<p>At times, the specific binding class won't be known. For example, a
+RecyclerView Adapter operating against arbitrary layouts won't know the
+specific binding class. It still must assign the binding value during the
+onBindViewHolder.</p>
+
+<p>In this example, all layouts that the RecyclerView binds to have an "item"
+variable. The BindingHolder has a getBinding method returning the <code>ViewDataBinding</code> base.</p>
+<pre class=prettyprint>
+<strong>public void </strong>onBindViewHolder(BindingHolder holder, <strong>int </strong>position) {
+ <strong>final </strong>T item = <strong>mItems</strong>.get(position);
+ holder.getBinding().setVariable(BR.item, item);
+ holder.getBinding().executePendingBindings();
+}
+</pre>
+
+
+<h4 id=immediate_binding>Immediate Binding</h4>
+
+<p>When a variable or observable changes, the binding will be scheduled to change
+before the next frame. There are times, however, when binding must be executed
+immediately. To force execution, use the executePendingBindings() method.</p>
+<h2 id=attribute_setters>Attribute Setters</h2>
+
+<p>Whenever a bound value changes, the generated binding class must call a setter
+method on the View with the binding expression. The data binding framework has
+ways to customize which method to call to set the value.</p>
+<h3 id=automatic_setters>Automatic Setters</h3>
+
+For an attribute, data binding tries to find the method setAttribute. The
+namespace for the attribute does not matter, only the attribute name itself.
+
+<p>For example, an expression associated with TextView's attribute <strong><code>android:text</code></strong> will look for a setText(String). If the expression returns an int, data
+binding will search for a setText(int) method. Be careful to have the
+expression return the correct type, casting if necessary.Note that data binding will work even if no attribute exists with the given
+name. You can then easily "create" attributes for any setter by using data
+binding. For example, support DrawerLayout doesn't have any attributes, but
+plenty of setters. You can use the automatic setters to use one of these.</p>
+<pre class=prettyprint>
+<android.support.v4.widget.<strong>DrawerLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:scrimColor="@{@color/scrim}"
+ app:drawerListener="@{fragment.drawerListener}"/></strong>
+</pre>
+
+
+<h3 id=renamed_setters>Renamed Setters</h3>
+
+<p>Some attributes have setters that don't match by name. For these methods, an
+attribute may be associated with the setter through BindingMethods annotation.
+This must be associated with a class and contains BindingMethod annotations,
+one for each renamed method. For example, the <strong><code>android:tint</code></strong> attribute is really associated with setImageTintList, not setTint.</p>
+<pre class=prettyprint>
+@BindingMethods({
+ @BindingMethod(type = <strong>"android.widget.ImageView"</strong>,
+ attribute = <strong>"android:tint"</strong>,
+ method = <strong>"setImageTintList"</strong>),
+})
+</pre>
+
+<p>It is unlikely that developers will need to rename setters; the android
+framework attributes have already been implemented.</p>
+<h3 id=custom_setters>Custom Setters</h3>
+
+<p>Some attributes need custom binding logic. For example, there is no associated
+setter for the <strong><code>android:paddingLeft</code></strong> attribute. Instead, setPadding(left, top, right, bottom) exists. A static
+binding adapter method with the BindingAdapter annotation allows the developer
+to customize how a setter for an attribute is called.</p>
+
+<p>The android attributes have already had BindingAdapters created. For example,
+here is the one for paddingLeft:</p>
+<pre class=prettyprint></p>
+@BindingAdapter(<strong>"android:paddingLeft"</strong>)
+<strong>public static void </strong>setPaddingLeft(View view, <strong>int </strong>padding) {
+ view.setPadding(padding,
+ view.getPaddingTop(),
+ view.getPaddingRight(),
+ view.getPaddingBottom());
+}
+</pre>
+
+<p>Binding adapters are useful for other types of customization. For example, a
+ custom loader can be called off-thread to load an image.</p>
+
+<p>Developer-created binding adapters will override the data binding default
+adapters when there is a conflict.</p>
+
+<p>You can also have adapters that receive multiple parameters. </p>
+<pre class=prettyprint>
+@BindingAdapter(attributes = {<strong>"bind:imageUrl"</strong>, <strong>"bind:error"</strong>})
+<strong>public static void </strong>loadImage(ImageView view, String url, Drawable error) {
+ Picasso.<em>with</em>(view.getContext()).load(url).error(error).into(view);
+}
+</pre>
+
+<p>This adapter will be called if both <strong>imageUrl </strong>and <strong>error </strong>are used for an ImageView and <em>imageUrl </em>is a string and <em>error</em> is a drawable.</p>
+<ul>
+ <li> Custom namespaces are ignore during matching.
+ <li> You can also write adapters for android namespace.
+</ul>
+
+<pre class=prettyprint>
+<ImageView app:imageUrl=“@{venue.imageUrl}”
+app:error=“@{@drawable/venueError}”/>
+</pre>
+
+
+<h2 id=converters>Converters</h2>
+
+
+<h3 id=object_conversions>Object Conversions</h3>
+
+<p>When an Object is returned from a binding expression, a setter will be chosen
+from the automatic, renamed, and custom setters. The Object will be cast to a
+parameter type of the chosen setter.</p><p>This is a convenience for those using ObservableMaps to hold data. for example:</p>
+<pre class=prettyprint>
+<<strong>TextView
+ android:text='@{userMap["lastName"]}'
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+<p>The userMap returns an Object and that Object will be automatically cast to
+parameter type found in the setter <code>setText(CharSequence)</code>. When there may be confusion about the parameter type, the developer will need
+to cast in the expression.</p>
+<h3 id=custom_conversions>Custom Conversions</h3>
+
+<p>Sometimes conversions should be automatic between specific types. For example,
+when setting the background:</p>
+<pre class=prettyprint>
+<<strong>View
+ android:background="@{isError ? @color/red : @color/white}"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
+<p>Here, the background takes a <code>Drawable</code>, but the color is an integer. Whenever a <code>Drawable</code> is expected and an integer is returned, the <code>int</code> should be converted to a <code>ColorDrawable</code>. This conversion is done using a static method with a BindingConversion
+annotation:</p>
+<pre class=prettyprint>
+@BindingConversion
+<strong>public static </strong>ColorDrawable convertColorToDrawable(<strong>int </strong>color) {
+ <strong>return new </strong>ColorDrawable(color);
+}
+</pre>
+
+<p>Note that conversions only happen at the setter level, so it is <strong>not allowed </strong>to mix types like this:</p>
+<pre class=prettyprint>
+<<strong>View
+ android:background="@{isError ? @drawable/error : @color/white}"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"</strong>/>
+</pre>
+
diff --git a/docs/html/preview/images/m-preview-timeline.png b/docs/html/preview/images/m-preview-timeline.png
new file mode 100644
index 0000000..a065c21
--- /dev/null
+++ b/docs/html/preview/images/m-preview-timeline.png
Binary files differ
diff --git a/docs/html/preview/index.html b/docs/html/preview/index.html
deleted file mode 100644
index af99e2d..0000000
--- a/docs/html/preview/index.html
+++ /dev/null
@@ -1,372 +0,0 @@
-<!DOCTYPE html>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=970" />
-
-<meta name="Description" content="Test and build your apps against the next version of Android to ensure they're ready when the platform officially launches.">
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>Android M Developer Preview | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto+Condensed">
-<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold"
- title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//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 = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script>
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
- })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
- ga('create', 'UA-5831155-1', 'android.com');
- ga('create', 'UA-49880327-2', 'android.com', {'name': 'universal'}); // New tracker);
- ga('send', 'pageview');
- ga('universal.send', 'pageview'); // Send page view for new tracker.
-</script>
-
-</head>
-
-<body class="gc-documentation
-
-" itemscope itemtype="http://schema.org/Article">
-
-
-<a name="top"></a>
-<div id="body-content">
-<div class="fullpage" >
-<div id="jd-content">
- <div class="jd-descr" itemprop="articleBody">
- <style>
-.fullpage>#footer,
-#jd-content>.content-footer.wrap {
- display:none;
-}
-</style>
-
-<style>
-#footer {
- display: none;
-}
-.content-footer {
- display: none;
-}
-</style>
-
-<!--
-<div style="height:20px"></div>
-<div id="butterbar-wrapper">
- <div id="butterbar">
- <a href="#" id="butterbar-message">
- butterbar message
- </a>
- </div>
-</div>
--->
-
- <div class="landing-rest-of-page">
- <div class="landing-section" style="padding-top:60px">
- <div class="wrap">
- <div class="landing-section-header">
- <div class="landing-h1">Android M Developer Preview</div>
- <div class="landing-subhead">
- Get an early look at the next release and prepare your apps for the
- official platform launch.
- </div>
-
- <img src="/preview/images/dev-prev.png" style=" margin:0px 0 0 40px" width="860px"/>
- <div class="col-6" style="margin-left:660px; margin-top:-105px">
- <a href="/preview/setup-sdk.html" class="landing-button landing-primary"
- style="position:absolute;z-index:100;float:right;margin-top: 0px;">
- Get Started</a>
- </div>
- </div>
- </div> <!-- end .wrap -->
- </div> <!-- end .landing-section -->
-
-
-
- <div class="landing-section landing-gray-background"
- style="margin-top:-105px; padding-bottom:20px">
- <div class="wrap">
- <div class="cols">
- <div class="landing-body" style="margin-top:-80px" >
-
- <div class="landing-breakout cols">
- <div class="col-4">
- <p>This Feature</p>
- <p class="landing-small">
- Kevin ham hock pig cupim brisket picanha, doner pork tri-tip frankfurter
- leberkas turkey.
- </p>
- <p class="landing-small">
- <a href="/preview/api-overview.html">Learn about this feature</a>
- </p>
- </div>
- <div class="col-4">
- <p>That Feature</p>
- <p class="landing-small">
- Bacon ipsum dolor amet meatball tongue pork loin fatback, andouille shoulder
- chicken picanha pig landjaeger kielbasa shankle pastrami flank meatloaf.
- </p>
- <p class="landing-small">
- <a href="/preview/api-overview.html">Learn about that feature</a>
- </p>
- </div>
- <div class="col-4">
- <p style="width:230px">Another Feature</p>
- <p class="landing-small">
- Landjaeger tri-tip tenderloin pork loin jowl, meatloaf t-bone kielbasa sausage
- swine spare ribs drumstick corned beef ham.
- </p>
- <p class="landing-small">
- <a href="/preview/api-overview.html">Learn about notifications</a>
- </p>
- </div>
- <div class="col-4">
- <p>Moar Features</p>
- <p class="landing-small">
- <b>Feature Name</b> is our effort to meatloaf boudin meatball sausage strip
- steak hamburger, chuck ham pork chop.
- </p>
- <p class="landing-small">
- <a href="/preview/api-overview.html">Learn about moar feature</a>
- </p>
- </div>
- </div>
- <p style="margin-left:20px">See the <a href="/preview/api-overview.html">API
- overview</a> for more information on the rest of the new and updated features.</p>
- </div>
- </div></div></div>
- <div class="landing-section">
- <div class="wrap">
- <div class="cols">
- <div class="landing-body">
- <div class="col-3-wide">
- <a target="_blank" href="https://code.google.com/p/android-developer-preview/">
- <img class="landing-social-image" src="/preview/images/bugs.png" alt="">
- </a>
- <div class="landing-social-copy">
- <p>Issue Tracker</p>
- <p class="landing-small">
- Let us know when you encounter problems, so we can fix them and make
- the platform better for you and your users.
- </p><p class="landing-small">
- <a href="https://code.google.com/p/android-developer-preview/">
- Report Issues</a>
- </p>
- <p></p>
- </div>
- </div>
- <div class="col-3-wide">
- <a target="_blank" href="http://g.co/androidldevpreview">
- <img class="landing-social-image" src="//www.google.com/images/icons/product/gplus-128.png" alt="">
- </a>
- <div class="landing-social-copy">
- <p>Google+ </p>
- <p class="landing-small">
- Join the community of Android developers testing out the M Developer Preview and
- share your thoughts and experiences.
- </p><p class="landing-small">
- <a href="http://g.co/androidldevpreview">
- Discuss on Google+</a>
- </p>
- </div>
- </div>
- <div class="col-3-wide">
- <a target="_blank" href="/preview/support.html">
- <img class="landing-social-image" src="/preview/images/updates.png" alt="">
- </a>
- <div class="landing-social-copy">
- <p>Support and Updates</p>
- <p class="landing-small">
- Updates to the preview are delivered
- in the Android SDK Manager. Check back periodically
- for news about the changes.
- </p>
- <p class="landing-small">
- <a href="/preview/support.html">Get Support</a>
- </p>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="content-footer wrap" itemscope="" itemtype="http://schema.org/SiteNavigationElement">
- <div class="layout-content-col col-16" style="padding-top:4px">
- <style>#___plusone_0 {float:right !important;}</style>
- <div class="g-plusone" data-size="medium"></div>
- </div>
- </div>
- <div id="footer" class="wrap" style="width:940px;position:relative;top:-35px;z-index:-1">
- <div id="copyright">
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
- </div>
- </div> <!-- end landing-body-content -->
-
- <script>
- $("a.landing-down-arrow").on("click", function(e) {
- $("body").animate({
- scrollTop: $(".preview-hero").height() + 76
- }, 1000, "easeOutQuint");
- e.preventDefault();
- });
- </script>
- </div>
-
- <div class="content-footer wrap"
- itemscope itemtype="http://schema.org/SiteNavigationElement">
-
- <div class="paging-links layout-content-col col-10">
-
- </div>
- <div class="layout-content-col plus-container col-2" >
- <style>#___plusone_0 {float:right !important;}</style>
- <div class="g-plusone" data-size="medium"></div>
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" style="width:940px">
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="/license.html">Content
- License</a>.
- </div>
-
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-
-
-
-
- <script src="https://developer.android.com/ytblogger_lists_unified.js" type="text/javascript"></script>
- <script src="/jd_lists_unified.js" type="text/javascript"></script>
- <script src="/jd_extras.js" type="text/javascript"></script>
- <script src="/jd_collections.js" type="text/javascript"></script>
- <script src="/jd_tag_helpers.js" type="text/javascript"></script>
-
-</body>
-</html>
diff --git a/docs/html/preview/index.jd b/docs/html/preview/index.jd
index a2d0b18..c6c2068 100644
--- a/docs/html/preview/index.jd
+++ b/docs/html/preview/index.jd
@@ -17,44 +17,36 @@
<div class="col-1of2 col-pull-1of2">
<h1 class="dac-hero-title">M Developer Preview</h1>
<p class="dac-hero-description">
- Get ready for the next official release of the platform. Test your apps
- and give us feedback!
+ Get ready for the next official release of the platform. The preview program gives
+ you an advance look at new APIs, features, and behaviors coming to Android.
+ Test your apps and give us feedback!
</p>
- <a class="dac-hero-cta" href="{@docRoot}preview/setup-sdk.html">
+
+ <a class="dac-hero-cta" href="{@docRoot}preview/overview.html">
<span class="dac-sprite dac-auto-chevron"></span>
- Set up the Preview SDK
+ Preview Program Overview
</a><br>
<a class="dac-hero-cta" href="{@docRoot}preview/api-overview.html">
<span class="dac-sprite dac-auto-chevron"></span>
Review the API changes
</a><br>
+ <a class="dac-hero-cta" href="{@docRoot}preview/setup-sdk.html">
+ <span class="dac-sprite dac-auto-chevron"></span>
+ Set up the Preview SDK
+ </a><br>
<a class="dac-hero-cta" href="https://code.google.com/p/android-developer-preview/">
<span class="dac-sprite dac-auto-chevron"></span>
Report issues
</a><br>
+
</div>
</div>
+
+ <div class="dac-section dac-small">
+ <div class="resource-widget resource-flow-layout col-16"
+ data-query="collection:preview/landing/resources"
+ data-cardSizes="6x2"
+ data-maxResults="6"></div>
+ </div>
</div>
-</section>
-
-<section class="dac-section dac-gray dac-small dac-invert"><div class="wrap">
- <h2 class="norule">Latest</h2>
- <div class="resource-widget resource-flow-layout col-16"
- data-query="collection:develop/landing/latest"
- data-cardSizes="6x6"
- data-maxResults="3"></div>
-</div></section>
-
-
-<section class="dac-section"><div class="wrap">
- <h1 class="dac-section-title">Resources</h1>
- <div class="dac-section-subtitle">
- Check out these resources to help you get started with the M Developer Preview.
- </div>
- <div class="resource-widget resource-flow-layout col-16"
- data-query="collection:preview/landing/resources"
- data-cardSizes="6x6"
- data-maxResults="6"></div>
-</div></section>
-
-
+</section>
\ No newline at end of file
diff --git a/docs/html/preview/license.html b/docs/html/preview/license.html
deleted file mode 100644
index deb16aa..0000000
--- a/docs/html/preview/license.html
+++ /dev/null
@@ -1,274 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-
-
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta name="viewport" content="width=970" />
-
-<meta name="Description" content="To get started with the Android SDK Preview, you must agree to the following terms and conditions. As described below, please note that this is a preview version of the Android SDK, subject to change, that you use at your own risk.">
-<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
-<title>License Agreement | Android Developers</title>
-
-<!-- STYLESHEETS -->
-<link rel="stylesheet"
-href="//fonts.googleapis.com/css?family=Roboto+Condensed">
-<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold"
- title="roboto">
-<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
-
-
-
-<!-- JAVASCRIPT -->
-<script src="//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 = [];
- var devsite = false;
-</script>
-<script src="/assets/js/docs.js" type="text/javascript"></script>
-
-<script>
- (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
- (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
- m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
- })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
-
- ga('create', 'UA-5831155-1', 'android.com');
- ga('create', 'UA-49880327-2', 'android.com', {'name': 'universal'}); // New tracker);
- ga('send', 'pageview');
- ga('universal.send', 'pageview'); // Send page view for new tracker.
-</script>
-
-</head>
-
-
-<body class="gc-documentation" itemscope="" itemtype="http://schema.org/Article">
-
-
-<a name="top"></a>
-<div id="body-content">
-<div class="fullpage">
-<div id="jd-content">
- <div class="jd-descr" itemprop="articleBody">
-<style>
-body,html, #qv {background-color:#e9e9e9}
-
-#qv * { font-weight:bold;}
-
-.fullpage>#footer,
-#jd-content>.content-footer.wrap {
- display:none;
-}
-
-.content-footer {
- display: none;
-}
-</style>
-
- <div style="border-bottom: 1px solid #a5c43a; position: absolute; left: 0; right: 0; top: 0;">
- <div class="wrap" style="position: relative; height: 45px; padding: 0 20px;">
- <a href="/index.html" style="position:absolute;top:8px">
- <img src="/assets/images/dac_logo.png" srcset="/assets/images/dac_logo@2x.png 2x" width="123" height="25" alt="Android Developers home page">
- </a>
- </div>
- </div>
-
- <div class="landing-rest-of-page">
- <div class="landing-section" style="padding:55px 10px 0">
-
-<div class="wrap">
-
-<div class="col-16" id="doc-col" >
-
- <h1 itemprop="name" >L Developer Preview License Agreement</h1>
-
-<div class="jd-descr" itemprop="articleBody">
- <p>
-If you are using the Android SDK
-Preview, you must agree to the following terms
-and conditions. As described below, please note that the preview version of the
-Android SDK is subject to change, and that you use it at your own risk. The
-Android SDK Preview is not a stable release, and may contain errors and defects
-that can result in serious damage to your computer systems, devices and data.
-</p>
-
-<p>
-This is the Android SDK Preview License Agreement (the “License Agreement”).
-</p>
-
-<div class="sdk-terms" style="height:auto;border:0;padding:0;width:940px">
-1. Introduction
-
-1.1 The Android SDK Preview (referred to in the License Agreement as the “Preview” and specifically including the Android system files, packaged APIs, and Preview library files, if and when they are made available) is licensed to you subject to the terms of the License Agreement. The License Agreement forms a legally binding contract between you and Google in relation to your use of the Preview.
-
-1.2 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
-
-1.3 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
-
-2. Accepting the License Agreement
-
-2.1 In order to use the Preview, you must first agree to the License Agreement. You may not use the Preview if you do not accept the License Agreement.
-
-2.2 By clicking to accept and/or using the Preview, you hereby agree to the terms of the License Agreement.
-
-2.3 You may not use the Preview and may not accept the License Agreement if you are a person barred from receiving the Preview under the laws of the United States or other countries including the country in which you are resident or from which you use the Preview.
-
-2.4 If you will use the Preview internally within your company or organization you agree to be bound by the License Agreement on behalf of your employer or other entity, and you represent and warrant that you have full legal authority to bind your employer or such entity to the License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the Preview on behalf of your employer or other entity.
-
-3. Preview License from Google
-
-3.1 Subject to the terms of the License Agreement, Google grants you a royalty-free, non-assignable, non-exclusive, non-sublicensable, limited, revocable license to use the Preview, personally or internally within your company or organization, solely to develop applications to run on the Android platform.
-
-3.2 You agree that Google or third parties owns all legal right, title and interest in and to the Preview, including any Intellectual Property Rights that subsist in the Preview. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
-
-3.3 You may not use the Preview for any purpose not expressly permitted by the License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the Preview or any part of the Preview; or (b) load any part of the Preview onto a mobile handset or any other hardware device except a personal computer, combine any part of the Preview with other software, or distribute any software or device incorporating a part of the Preview.
-
-3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the Preview.
-
-3.5 Use, reproduction and distribution of components of the Preview licensed under an open source software license are governed solely by the terms of that open source software license and not the License Agreement. You agree to remain a licensee in good standing in regard to such open source software licenses under all the rights granted and to refrain from any actions that may terminate, suspend, or breach such rights.
-
-3.6 You agree that the form and nature of the Preview that Google provides may change without prior notice to you and that future versions of the Preview may be incompatible with applications developed on previous versions of the Preview. You agree that Google may stop (permanently or temporarily) providing the Preview (or any features within the Preview) to you or to users generally at Google's sole discretion, without prior notice to you.
-
-3.7 Nothing in the License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
-
-3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the Preview.
-
-4. Use of the Preview by You
-
-4.1 Google agrees that nothing in the License Agreement gives Google any right, title or interest from you (or your licensors) under the License Agreement in or to any software applications that you develop using the Preview, including any intellectual property rights that subsist in those applications.
-
-4.2 You agree to use the Preview and write applications only for purposes that are permitted by (a) the License Agreement, and (b) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).
-
-4.3 You agree that if you use the Preview to develop applications, you will protect the privacy and legal rights of users. If users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If users provide you with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, each user has given you permission to do so.
-
-4.4 You agree that you will not engage in any activity with the Preview, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of Google or any third party.
-
-4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android and/or applications for Android, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
-
-4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under the License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
-
-4.7 The Preview is in development, and your testing and feedback are an important part of the development process. By using the Preview, you acknowledge that implementation of some features are still under development and that you should not rely on the Preview having the full functionality of a stable release. You agree not to publicly distribute or ship any application using this Preview as this Preview will no longer be supported after the official Android SDK is released.
-
-5. Your Developer Credentials
-
-5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
-
-6. Privacy and Information
-
-6.1 In order to continually innovate and improve the Preview, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the Preview are being used and how they are being used. Before any of this information is collected, the Preview will notify you and seek your consent. If you withhold consent, the information will not be collected.
-
-6.2 The data collected is examined in the aggregate to improve the Preview and is maintained in accordance with Google's Privacy Policy located at http://www.google.com/policies/privacy/.
-
-7. Third Party Applications
-
-7.1 If you use the Preview to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
-
-7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
-
-7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party.
-
-8. Using Google APIs
-
-8.1 Google APIs
-
-8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
-
-8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
-
-9. Terminating the License Agreement
-
-9.1 the License Agreement will continue to apply until terminated by either you or Google as set out below.
-
-9.2 If you want to terminate the License Agreement, you may do so by ceasing your use of the Preview and any relevant developer credentials.
-
-9.3 Google may at any time, terminate the License Agreement, with or without cause, upon notice to you.
-
-9.4 The License Agreement will automatically terminate without notice or other action upon the earlier of:
-(A) when Google ceases to provide the Preview or certain parts of the Preview to users in the country in which you are resident or from which you use the service; and
-(B) Google issues a final release version of the Android SDK.
-
-9.5 When the License Agreement is terminated, the license granted to you in the License Agreement will terminate, you will immediately cease all use of the Preview, and the provisions of paragraphs 10, 11, 12 and 14 shall survive indefinitely.
-
-10. DISCLAIMERS
-
-10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE PREVIEW IS AT YOUR SOLE RISK AND THAT THE PREVIEW IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
-
-10.2 YOUR USE OF THE PREVIEW AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE PREVIEW IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE. WITHOUT LIMITING THE FOREGOING, YOU UNDERSTAND THAT THE PREVIEW IS NOT A STABLE RELEASE AND MAY CONTAIN ERRORS, DEFECTS AND SECURITY VULNERABILITIES THAT CAN RESULT IN SIGNIFICANT DAMAGE, INCLUDING THE COMPLETE, IRRECOVERABLE LOSS OF USE OF YOUR COMPUTER SYSTEM OR OTHER DEVICE.
-
-10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
-
-11. LIMITATION OF LIABILITY
-
-11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
-
-12. Indemnification
-
-12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys’ fees) arising out of or accruing from (a) your use of the Preview, (b) any application you develop on the Preview that infringes any Intellectual Property Rights of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you of the License Agreement.
-
-13. Changes to the License Agreement
-
-13.1 Google may make changes to the License Agreement as it distributes new versions of the Preview. When these changes are made, Google will make a new version of the License Agreement available on the website where the Preview is made available.
-
-14. General Legal Terms
-
-14.1 the License Agreement constitutes the whole legal agreement between you and Google and governs your use of the Preview (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the Preview.
-
-14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in the License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
-
-14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of the License Agreement is invalid, then that provision will be removed from the License Agreement without affecting the rest of the License Agreement. The remaining provisions of the License Agreement will continue to be valid and enforceable.
-
-14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to the License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of the License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to the License Agreement.
-
-14.5 EXPORT RESTRICTIONS. THE PREVIEW IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE PREVIEW. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
-
-14.6 The License Agreement may not be assigned or transferred by you without the prior written approval of Google, and any attempted assignment without such approval will be void. You shall not delegate your responsibilities or obligations under the License Agreement without the prior written approval of Google.
-
-14.7 The License Agreement, and your relationship with Google under the License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from the License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
-
-
-</div>
- </div>
- </div>
-
-</div>
- </div> <!-- end landing-body-content -->
-
- </div>
-
- <div class="content-footer wrap" itemscope=""
- itemtype="http://schema.org/SiteNavigationElement">
-
- <div class="paging-links layout-content-col col-10">
-
- </div>
-
- </div>
-
-
-
-
- </div> <!-- end jd-content -->
-
-<div id="footer" class="wrap" style="width:940px">
-
-
- <div id="copyright">
-
- Except as noted, this content is
- licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
- Creative Commons Attribution 2.5</a>. For details and
- restrictions, see the <a href="https://developer.android.com/license.html">Content
- License</a>.
- </div>
-
-
-</div> <!-- end footer -->
-</div><!-- end doc-content -->
-
-</div> <!-- end body-content -->
-
-</body>
-</html>
diff --git a/docs/html/preview/overview.jd b/docs/html/preview/overview.jd
index 00f1cfe..0c8931d 100644
--- a/docs/html/preview/overview.jd
+++ b/docs/html/preview/overview.jd
@@ -3,5 +3,54 @@
@jd:body
<p>
- This is an overview of the program. Bacon.
-</p>
\ No newline at end of file
+ The M Developer Preview program is an opportunity for you to test the compatibility of your apps
+ with the next platform release, try out early versions of new API features, and provide feedback
+ to the Android team. The program includes update releases during course of the program to allow
+ you to follow the progress of feature development and fixes, leading up to the official release
+ of the platform, as shown in Figure 1.
+</p>
+
+<img src="{@docRoot}preview/images/m-preview-timeline.png"
+ alt="Preview program timeline" id="figure1" style="margin-top: 15px;">
+<p class="img-caption">
+ <b>Figure 1.</b> Timeline for the M Developer Preview program.
+</p>
+
+<p>
+ We strongly encourage you to provide feedback for the M Preview releases through our <a href=
+ "https://code.google.com/p/android-developer-preview/">issue tracker</a>. Issues reported early
+ in the program have a better chance of being addressed before the official release, so reports
+ provided by June 30, 2015 receive priority processing by the Android team.
+</p>
+
+<p>
+ To get started testing your app:
+</p>
+
+<ul>
+ <li>Review the <a href="{@docRoot}preview/api-overview.html">
+ API Overview</a> and <a href=
+ "{@docRoot}preview/api-changes.html">Behavior Changes</a> to
+ get an idea of what's new and how it affects your app.
+ </li>
+
+ <li>Setup for testing and development by following the instructions for <a href=
+ "{@docRoot}preview/setup-sdk.html">Setting up the Preview
+ SDK</a> and configuring test devices.
+ </li>
+
+ <li>Review the <a href="{@docRoot}preview/reference.html">M
+ Preview API Reference</a> and <a href=
+ "{@docRoot}preview/samples.html">M Preview samples</a> to
+ gain more insight into new API features and how to use them in your app.
+ </li>
+
+ <li>Join the <a href="https://plus.google.com/communities/101985907812750684586">M Preview
+ Google+ developer community</a> to get the latest developer updates and connect with other
+ developers working with the preview.
+ </li>
+</ul>
+
+<p>
+ Thanks in advance for your participation in the developer preview program!
+</p>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index a352f65..8da052e 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -55,7 +55,6 @@
<style type="text/css">
.offline {display:none;}
- a.download-bundle-button {display:block;}
h2.feature {
padding-top:30px;
margin-top:0;
@@ -66,19 +65,6 @@
padding-top:40px;
}
- .landing-button.green {
- font-size:16px;
- background-color:#90c653;
- padding:8px 10px 10px;
- margin:0;
- width:206px;
- text-align:center;
- }
-
- .landing-button.green:hover {
- background-color:#85b84f;
- }
-
.landing-button .small {
font-size: 12px;
font-weight: normal;
@@ -284,7 +270,7 @@
<img src="{@docRoot}images/tools/studio-hero.png"
srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x"
-width="760" height="400" alt="" style="margin-bottom:100px" />
+width="760" height="400" alt="" />
<div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px">
@@ -300,7 +286,7 @@
<li>Android 5.0 emulator system image with Google APIs</li>
</ul>
-<a class="online landing-button green download-bundle-button" style="margin-top:30px;"
+<a class="online landing-button green download-bundle-button"
href="#Other" >Download Android Studio</a>
<!-- this appears when viewing the offline docs -->
@@ -308,8 +294,9 @@
To get Android Studio or stand-alone SDK tools, visit <a
href="http://developer.android.com/sdk/index.html">developer.android.com/sdk/</a>
</p>
+</div>
-<ul style="margin-top:50px;color:#444">
+<ul>
<li><a href="#Requirements">System Requirements</a></li>
<li><a href="#Other">Other Download Options</a></li>
<li><a href="{@docRoot}sdk/installing/migrate.html">Migrating to Android Studio</a></li>
@@ -317,7 +304,6 @@
target="_blank">Take a Survey</a></li>
</ul>
-</div>
@@ -403,8 +389,7 @@
<p>Build APKs from Android Studio or the command line.</p>
</div>
-
-
+</div>
<h2 class="feature norule">More about Android Studio</h2>
<div style="background:#424242;padding:30px; color:#fff;margin:0 0 15px;">
diff --git a/docs/html/tools/sdk/ndk/index.jd b/docs/html/tools/sdk/ndk/index.jd
index 520fe67..ae15bc1 100644
--- a/docs/html/tools/sdk/ndk/index.jd
+++ b/docs/html/tools/sdk/ndk/index.jd
@@ -2,29 +2,25 @@
page.template=sdk
-ndk.mac64_download=android-ndk-r10d-darwin-x86_64.bin
-ndk.mac64_bytes=442691567
-ndk.mac64_checksum=cb101e1e62d56ea75b215f6bc6c27fae
+ndk.mac64_download=android-ndk-r10e-darwin-x86_64.bin
+ndk.mac64_bytes=388937326
+ndk.mac64_checksum=2cb8893a5701603519d38a7e04c50e81
-ndk.mac32_download=android-ndk-r10d-darwin-x86.bin
-ndk.mac32_bytes=441545213
-ndk.mac32_checksum=0aeb3dc062dc457a4cd01e72eadb2379
+ndk.linux64_download=android-ndk-r10e-linux-x86_64.bin
+ndk.linux64_bytes=401522849
+ndk.linux64_checksum=19af543b068bdb7f27787c2bc69aba7f
-ndk.linux64_download=android-ndk-r10d-linux-x86_64.bin
-ndk.linux64_bytes=459151600
-ndk.linux64_checksum=263b83071e6bca15f67898548d8d236e
+ndk.linux32_download=android-ndk-r10e-linux-x86.bin
+ndk.linux32_bytes=394281908
+ndk.linux32_checksum=c3edd3273029da1cbd2f62c48249e978
-ndk.linux32_download=android-ndk-r10d-linux-x86.bin
-ndk.linux32_bytes=449997190
-ndk.linux32_checksum=70ed6d8c34e7e620c145b791e8eeef89
+ndk.win64_download=android-ndk-r10e-windows-x86_64.exe
+ndk.win64_bytes=419616132
+ndk.win64_checksum=8412bb4991a95e08fda50b5a44d95df7
-ndk.win64_download=android-ndk-r10d-windows-x86_64.exe
-ndk.win64_bytes=472613732
-ndk.win64_checksum=9a33f96da58a7e0b70e47d27b4a880b4
-
-ndk.win32_download=android-ndk-r10d-windows-x86.exe
-ndk.win32_bytes=455427281
-ndk.win32_checksum=c0930abfae0c990c4d191cc4ebd46b68
+ndk.win32_download=android-ndk-r10e-windows-x86.exe
+ndk.win32_bytes=396563176
+ndk.win32_checksum=1a82445baaf62aec3a46386ab1e5772c
@@ -382,11 +378,174 @@
<p>The following sections provide information about releases of the NDK.</p>
-
<div class="toggle-content opened">
<p>
<a href="#" onclick="return toggleContent(this)"> <img
src="/assets/images/triangle-opened.png" class="toggle-content-img" alt=""
+ >Android NDK, Revision 10e</a> <em>(May 2015)</em>
+ </p>
+ <div class="toggle-content-toggleme">
+ <dl>
+ <dt>Important changes:</dt>
+ <dd>
+ <ul>
+ <li>Integrated the workaround for Cortex-A53 Erratum 843419 into the
+ {@code aarch64-linux-android-4.9} linker. For more information on this workaround, see
+ <a href="https://sourceware.org/ml/binutils/2015-03/msg00446.html">Workaround for cortex-a53
+ erratum 843419.</a></li>
+
+ <li>Added Clang 3.6; {@code NDK_TOOLCHAIN_VERSION=clang} now picks that version
+ of Clang by default.</li>
+
+ <li>Removed Clang 3.4.</li>
+
+ <li>Removed GCC 4.6.</li>
+
+ <li>Implemented multithreading support in {@code ld.gold} for all architectures. It can
+ now link with or without support for multithreading; the default is to do it without.
+ <ul>
+ <li>To compile with multithreading, use the {@code --threads} option.</li>
+ <li>To compile without multithreading, use the {@code --no-threads} option.</li>
+ </ul>
+ </li>
+
+ <li>Upgraded GDB/gdbserver to 7.7 for all architectures.</li>
+
+ <li>Removed the NDK package for 32-bit Darwin.</li>
+ </ul>
+ </dd>
+ <dl>
+
+
+ <dt>Important bug fixes:</dt>
+ <dd>
+ <ul>
+ <li>Fixed a crash that occurred when there were OpenMP loops outside of the main thread.</li>
+
+ <li>Fixed a GCC 4.9 internal compiler error (<i>ICE</i>) that occured when the user declared
+ {@code #pragma GCC optimize ("O0")}, but had a different level of optimization specified
+ on the command line. The {@code pragma} takes precedence.</li>
+
+ <li>Fixed an error that used to produce a crash with the following error message:
+<pre>
+in add_stores, at var-tracking.c:6000
+</pre>
+ </li>
+
+ <li>Implemented a workaround for a Clang 3.5 issue in which LLVM auto-vectorization
+ generates {@code llvm.cttz.v2i64()}, an instruction with no counterpart in the ARM
+ instruction set.</li>
+ </ul>
+ </dd>
+
+ <dt>Other bug fixes:</dt>
+ <dd>
+ <ul>
+ <li>Made the following header and library fixes:</li>
+ <ul>
+ <li>Fixed {@code PROPERTY_*} in {@code media/NdkMediaDrm.h}.</li>
+ <li>Fixed {@code sys/ucontext.h} for {@code mips64}.</li>
+ <li>Dropped the Clang version check for {@code __builtin_isnan} and
+ {@code __builtin_isinf}.</li>
+ <li>Added {@code android-21/arch-mips/usr/include/asm/reg.h}
+ and {@code android-21/arch-mips64/usr/include/asm/reg.h}.</li>
+ </ul>
+ </li>
+
+ <li>Fixed a spurious array-bounds warning that GCC 4.9 produced for x86, and reenabled the
+ array bounds warning that GCC 4.9 had produced for ARM. The warning for ARM had
+ previously been unconditionally disabled.</li>
+
+ <li>Fixed Clang 3.5 for {@code mips} and {@code mips64} to create a writable
+ {@code .gcc_except_table} section, thus matching GCC behavior. This change allows you
+ to avoid the following linker warning:
+
+<pre>
+.../ld: warning: creating a DT_TEXTREL in a shared object
+</pre>
+ </li>
+
+ <li>Backported a fix for {@code compiler-rt} issues that were causing crashes when Clang
+ compiled for {@code mips64}. For more information, see LLVM Issue
+ <a href="http://llvm.org/bugs/show_bug.cgi?id=20098">20098</a>.</li>
+
+ <li>Fixed Clang 3.5 crashes that occurred on non-ASCII comments. (Issue
+ <a href="https://code.google.com/p/android/issues/detail?id=81440">81440</a>)</li>
+
+ <li>Fixed {@code stlport collate::compare} to return {@code -1} and {@code 1}. Previously,
+ it had returned arbitrary signed numbers.</li>
+
+ <li>Fixed {@code ndk-gdb} for 64-bit ABIs. (Issue
+ <a href="https://code.google.com/p/android/issues/detail?id=118300">118300</a>)</li>
+
+ <li>Fixed the crash that the HelloComputeNDK sample for RenderScript was producing on
+ Android 4.4 (Android API level 19). For more information, see
+ <a href="http://stackoverflow.com/questions/28057049/targeting-pre-lollipop-devices-using-renderscript-from-ndk-c">this page</a>.</li>
+
+ <li>Fixed {@code libc++ __wrap_iter} for GCC. For more information, see LLVM Issue
+ <a href="http://llvm.org/bugs/show_bug.cgi?id=22355">22355</a>.</li>
+
+ <li>Fixed {@code .asm} support for ABI {@code x86_64}.</li>
+
+ <li>Implemented a workaround for the GCC 4.8 {@code stlport} issue. (Issue
+ <a href="https://android-review.googlesource.com/#/c/127773">127773</a>)</li>
+
+ <li>Removed the trailing directory separator {@code \\} from the project path in Windows.
+ (Issue <a href="https://code.google.com/p/android/issues/detail?id=160584">160584</a>)
+ </li>
+
+ <li>Fixed a {@code no rule to make target} error that occurred when compiling a single
+ {@code .c} file by executing the {@code ndk-build.cmd} command from {@code gradle}. (Issue
+ <a href="https://code.google.com/p/android/issues/detail?id=66937">66937</a>)</li>
+
+ <li>Added the {@code libatomic.a} and {@code libgomp.a} libraries that had been missing from
+ the following host toolchains:
+ <ul>
+ <li>{@code aarch64-linux-android-4.9}</li>
+ <li>{@code mips64el-linux-android-4.9}</li>
+ <li>{@code mipsel-linux-android-4.9}</li>
+ <li>{@code x86_64-4.9}</li>
+ </ul>
+ </ul>
+ </dd>
+
+ <dt>Other changes:</dt>
+ <dd>
+ <ul>
+ <li>Added {@code ld.gold} for {@code aarch64}. The default linker remains {@code ld.bfd}.
+ To explicitly enable {@code ld.gold}, add {@code -fuse-ld=gold} to the
+ {@code LOCAL_LDFLAGS} or {@code APP_LDFLAGS} variable.</li>
+
+ <li>Built the MIPS and MIPS64 toolchains with {@code binutils-2.25}, which provides improved
+ R6 support.</li>
+
+ <li>Made {@code -fstandalone-debug} (full debug info) a default option for Clang.</li>
+
+ <li>Replaced {@code -fstack-protector} with {@code -fstack-protector-strong} for
+ the ARM, AArch64, X86, and X86_64 toolchains for GCC 4.9, Clang 3.5, and
+ Clang 3.6.</li>
+
+ <li>Added the {@code --package} command-line switch to {@code ndk-gdb} to allow the build
+ system to override the package name. (Issue
+ <a href="https://code.google.com/p/android/issues/detail?id=56189">56189</a>)</li>
+
+ <li> Deprecated {@code -mno-ldc1-stc1} for MIPS. This option may not work with the new
+ {@code -fpxx} and {@code -mno-odd-spreg} options, or with the FPXX ABI.</li>
+
+ <li>Added MIPS MSA and R6 detection to {@code cpu-features}.</li>
+
+ </ul>
+ </dd>
+
+ </dl>
+ </div>
+</div>
+
+
+<div class="toggle-content closed">
+ <p>
+ <a href="#" onclick="return toggleContent(this)"> <img
+ src="/assets/images/triangle-closed.png" class="toggle-content-img" alt=""
>Android NDK, Revision 10d</a> <em>(December 2014)</em>
</p>
<div class="toggle-content-toggleme">
diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd
index ee1ed72..573baad 100644
--- a/docs/html/tools/support-library/features.jd
+++ b/docs/html/tools/support-library/features.jd
@@ -373,9 +373,8 @@
developer guide.</p>
<p class="note">
- <strong>Note:</strong> Use of RenderScript with the support library is supported with the Android
- Eclipse plugin and Ant build tools. It is <em>not currently</em> supported with Android Studio or
- Gradle-based builds.
+ <strong>Note:</strong> Use of RenderScript with the support library is supported with Android
+ Studio and Gradle-based builds, as well as the Eclipse plugin and Ant build tools.
</p>
diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd
index fea3b2c..4005a05 100644
--- a/docs/html/training/articles/keystore.jd
+++ b/docs/html/training/articles/keystore.jd
@@ -88,7 +88,7 @@
<h3 id="GeneratingANewSecretKey">Generating a New Secret Key</h3>
<p>To generate the key, use a {@link javax.crypto.KeyGenerator} with
- {@link android.security.KeyGeneratorSpec}.
+ {@link android.security.keystore.KeyGenParameterSpec}.
<h3 id="WorkingWithKeyStoreEntries">Working with Keystore Entries</h3>
diff --git a/docs/html/training/location/location-testing.jd b/docs/html/training/location/location-testing.jd
index 5021fc0..8f73d51 100644
--- a/docs/html/training/location/location-testing.jd
+++ b/docs/html/training/location/location-testing.jd
@@ -79,7 +79,7 @@
<h2 id="TurnOnMockMode">Turn On Mock Mode</h2>
<p>
To send mock locations to Location Services in mock mode, a test app must request the permission
- {@link android.Manifest.permission#ACCESS_MOCK_LOCATION}. In addition, you must enable mock
+ android.Manifest.permission#ACCESS_MOCK_LOCATION. In addition, you must enable mock
locations on the test device using the option <b>Enable mock locations</b>. To learn how to
enable mock locations on the device, see
<a href="{@docRoot}tools/device.html#setting-up">Setting up a Device for Development</a>.
diff --git a/docs/image_sources/preview/m-preview-timeline.svg b/docs/image_sources/preview/m-preview-timeline.svg
new file mode 100644
index 0000000..b05dc98
--- /dev/null
+++ b/docs/image_sources/preview/m-preview-timeline.svg
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1052.3622"
+ height="744.09448"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="m-preview-timeline.svg"
+ inkscape:export-filename="/usr/local/google/home/joefernandez/projects/2015-05-006-m-preview-landing-page/m-preview-timeline.png"
+ inkscape:export-xdpi="119.84538"
+ inkscape:export-ydpi="119.84538">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.1315767"
+ inkscape:cx="526.18109"
+ inkscape:cy="372.04724"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1491"
+ inkscape:window-height="1008"
+ inkscape:window-x="313"
+ inkscape:window-y="118"
+ inkscape:window-maximized="0"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="196.21345,346.92813"
+ id="guide3936" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="201.9008,562.0994"
+ id="guide4068" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="418.01996,410.43683"
+ id="guide4088" />
+ <sodipodi:guide
+ orientation="0,1"
+ position="194.31767,462.57084"
+ id="guide4108" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-308.2677)">
+ <rect
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect4170"
+ width="880.83386"
+ height="5"
+ x="25.750326"
+ y="649.00873" />
+ <rect
+ style="color:#000000;fill:#99cc00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect2987"
+ width="673.49542"
+ height="8.5310192"
+ x="117.70681"
+ y="647.24158" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#99cc00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path3757"
+ sodipodi:cx="104.26801"
+ sodipodi:cy="404.74948"
+ sodipodi:rx="14.218366"
+ sodipodi:ry="14.218366"
+ d="m 118.48638,404.74948 c 0,7.85259 -6.36578,14.21837 -14.21837,14.21837 -7.852584,0 -14.218363,-6.36578 -14.218363,-14.21837 0,-7.85259 6.365779,-14.21836 14.218363,-14.21836 7.85259,0 14.21837,6.36577 14.21837,14.21836 z"
+ transform="translate(53.377673,246.4966)" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(-9.180856,193.63686)"><flowRegion
+ id="flowRegion3761"><rect
+ id="rect3763"
+ width="155.34293"
+ height="135.3176"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766">Preview </flowPara><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3046">Release</flowPara><flowPara
+ style="font-size:24px;text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3967">(Google I/O)</flowPara></flowRoot> <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#99cc00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path3757-1"
+ sodipodi:cx="104.26801"
+ sodipodi:cy="404.74948"
+ sodipodi:rx="14.218366"
+ sodipodi:ry="14.218366"
+ d="m 118.48638,404.74948 c 0,7.85259 -6.36578,14.21837 -14.21837,14.21837 -7.852584,0 -14.218363,-6.36578 -14.218363,-14.21837 0,-7.85259 6.365779,-14.21836 14.218363,-14.21836 7.85259,0 14.21837,6.36577 14.21837,14.21836 z"
+ transform="translate(279.50908,246.65479)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#99cc00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path3757-1-8"
+ sodipodi:cx="104.26801"
+ sodipodi:cy="404.74948"
+ sodipodi:rx="14.218366"
+ sodipodi:ry="14.218366"
+ d="m 118.48638,404.74948 c 0,7.85259 -6.36578,14.21837 -14.21837,14.21837 -7.852584,0 -14.218363,-6.36578 -14.218363,-14.21837 0,-7.85259 6.365779,-14.21836 14.218363,-14.21836 7.85259,0 14.21837,6.36577 14.21837,14.21836 z"
+ transform="translate(505.64051,247.60268)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="path3757-1-84"
+ sodipodi:cx="104.26801"
+ sodipodi:cy="404.74948"
+ sodipodi:rx="14.218366"
+ sodipodi:ry="14.218366"
+ d="m 118.48638,404.74948 c 0,7.85259 -6.36578,14.21837 -14.21837,14.21837 -7.852584,0 -14.218363,-6.36578 -14.218363,-14.21837 0,-7.85259 6.365779,-14.21836 14.218363,-14.21836 7.85259,0 14.21837,6.36577 14.21837,14.21836 z"
+ transform="translate(731.7719,245.70689)" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-2"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(-1.0121143,408.40861)"><flowRegion
+ id="flowRegion3761-9"><rect
+ id="rect3763-3"
+ width="80.11277"
+ height="51.644661"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-9">May</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-2-1"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(177.38621,408.98166)"><flowRegion
+ id="flowRegion3761-9-4"><rect
+ id="rect3763-3-3"
+ width="80.11277"
+ height="51.644661"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-9-1">June</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-2-1-2"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(406.04158,409.3565)"><flowRegion
+ id="flowRegion3761-9-4-5"><rect
+ id="rect3763-3-3-1"
+ width="80.11277"
+ height="51.644661"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-9-1-3">July</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-2-1-2-6"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(608.0263,409.3565)"><flowRegion
+ id="flowRegion3761-9-4-5-0"><rect
+ id="rect3763-3-3-1-1"
+ width="127.50733"
+ height="51.644653"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-9-1-3-0">August</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-8"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(149.48728,293.44548)"><flowRegion
+ id="flowRegion3761-2"><rect
+ id="rect3763-4"
+ width="194.80757"
+ height="45.009438"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="font-size:36px;text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3967-7">Update 1</flowPara></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-8-3"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(295.61638,193.80278)"><flowRegion
+ id="flowRegion3761-2-2"><rect
+ id="rect3763-4-5"
+ width="162.57927"
+ height="43.113655"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-1-4">Update 2</flowPara><flowPara
+ style="font-size:24px;text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3967-7-8" /></flowRoot> <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-8-9"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(434.6735,292.06086)"><flowRegion
+ id="flowRegion3761-2-3"><rect
+ id="rect3763-4-1"
+ width="169.21451"
+ height="45.957329"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="font-size:36px;text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3967-7-4">Update 3</flowPara></flowRoot> <path
+ style="fill:none;stroke:#000000;stroke-width:1.49251163px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 119.43972,584.77048 c 0,55.54049 0,55.54049 0,55.54049"
+ id="path4048"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.76536787px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 424.475,506.61135 c 0,134.1317 0,134.1317 0,134.1317"
+ id="path4048-8"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.43408465px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 288.17078,601.45265 c 0,40.18609 0,40.18609 0,40.18609"
+ id="path4048-8-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.52709746px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 570.63062,598.15011 c 0,42.05171 0,42.05171 0,42.05171"
+ id="path4048-8-9-7"
+ inkscape:connector-curvature="0" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot3759-8-3-0"
+ style="font-size:36px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;color:#000000;fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Roboto;-inkscape-font-specification:Roboto Light"
+ transform="translate(635.68275,194.45687)"><flowRegion
+ id="flowRegion3761-2-2-4"><rect
+ id="rect3763-4-5-9"
+ width="203.33855"
+ height="86.562088"
+ x="50.939774"
+ y="260.83688"
+ style="text-align:center;text-anchor:middle;fill:#666666" /></flowRegion><flowPara
+ style="text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3766-1-4-3">Official SDK Release </flowPara><flowPara
+ style="font-size:24px;text-align:center;text-anchor:middle;fill:#666666"
+ id="flowPara3967-7-8-2" /></flowRoot> <path
+ style="fill:none;stroke:#000000;stroke-width:1.62254512px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 790.21294,546.10533 c 0,95.71447 0,95.71447 0,95.71447"
+ id="path4048-8-1"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 20cd9b1..c5d68bd 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -184,12 +184,8 @@
/** @hide bit mask for the flag enabling vertical rendering for text */
public static final int VERTICAL_TEXT_FLAG = 0x1000;
-
- /** @hide default flags, even if unspecified */
- public static final int HIDDEN_DEFAULT_PAINT_FLAGS =
- DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
- /** @hide default flags for no-param constructor */
- public static final int DEFAULT_PAINT_FLAGS = ANTI_ALIAS_FLAG;
+ // These flags are always set on a new/reset paint, even if flags 0 is passed.
+ static final int HIDDEN_DEFAULT_PAINT_FLAGS = DEV_KERN_TEXT_FLAG | EMBEDDED_BITMAP_TEXT_FLAG;
/**
* Font hinter option that disables font hinting.
@@ -419,11 +415,9 @@
/**
* Create a new paint with default settings.
- *
- * As of {@link android.os.Build.VERSION_CODES#MNC}, sets {@link #ANTI_ALIAS_FLAG}.
*/
public Paint() {
- this(DEFAULT_PAINT_FLAGS);
+ this(0);
}
/**
@@ -458,7 +452,7 @@
/** Restores the paint to its default settings. */
public void reset() {
native_reset(mNativePaint);
- setFlags(DEFAULT_PAINT_FLAGS | HIDDEN_DEFAULT_PAINT_FLAGS);
+ setFlags(HIDDEN_DEFAULT_PAINT_FLAGS);
// TODO: Turning off hinting has undesirable side effects, we need to
// revisit hinting once we add support for subpixel positioning
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index f52c661..5c54324 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -347,6 +347,14 @@
nativeRelease();
}
+ /**
+ * Returns true if the SurfaceTexture was released
+ * @hide
+ */
+ public boolean isReleased() {
+ return nativeIsReleased();
+ }
+
@Override
protected void finalize() throws Throwable {
try {
@@ -383,6 +391,7 @@
private native int nativeAttachToGLContext(int texName);
private native int nativeGetQueuedCount();
private native void nativeRelease();
+ private native boolean nativeIsReleased();
/*
* We use a class initializer to allow the native code to cache some
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index 24e0d6a..4fc5ede 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -127,7 +127,9 @@
throws XmlPullParserException, IOException {
final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.AnimatedRotateDrawable);
super.inflateWithAttributes(r, parser, a, R.styleable.AnimatedRotateDrawable_visible);
+
updateStateFromTypedArray(a);
+ inflateChildDrawable(r, parser, attrs, theme);
verifyRequiredAttributes(a);
a.recycle();
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 5ccb165..e1975c9 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -87,8 +87,8 @@
public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
private AnimationState mAnimationState;
- /** The current frame, may be -1 when not animating. */
- private int mCurFrame = -1;
+ /** The current frame, ranging from 0 to {@link #mAnimationState#getChildCount() - 1} */
+ private int mCurFrame = 0;
/** Whether the drawable has an animation callback posted. */
private boolean mRunning;
@@ -120,7 +120,7 @@
final boolean changed = super.setVisible(visible, restart);
if (visible) {
if (restart || changed) {
- boolean startFromZero = restart || mCurFrame < 0 ||
+ boolean startFromZero = restart || !mRunning ||
mCurFrame >= mAnimationState.getChildCount();
setFrame(startFromZero ? 0 : mCurFrame, true, mAnimating);
}
@@ -151,7 +151,9 @@
mAnimating = true;
if (!isRunning()) {
- run();
+ // Start from 0th frame.
+ setFrame(0, false, mAnimationState.getChildCount() > 1
+ || !mAnimationState.mOneShot);
}
}
@@ -194,7 +196,7 @@
@Override
public void unscheduleSelf(Runnable what) {
- mCurFrame = -1;
+ mCurFrame = 0;
mRunning = false;
super.unscheduleSelf(what);
}
@@ -245,7 +247,7 @@
*/
public void addFrame(@NonNull Drawable frame, int duration) {
mAnimationState.addFrame(frame, duration);
- if (mCurFrame < 0) {
+ if (!mRunning) {
setFrame(0, true, false);
}
}
@@ -272,7 +274,6 @@
selectDrawable(frame);
if (unschedule || animate) {
unscheduleSelf(this);
- mRunning = false;
}
if (animate) {
// Unscheduling may have clobbered these values; restore them
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 8e91621..5ad31f7 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -43,7 +43,7 @@
* @attr ref android.R.styleable#ColorDrawable_color
*/
public class ColorDrawable extends Drawable {
- private final Paint mPaint = new Paint();
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
private ColorState mColorState;
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 0da4275..bd8eae0 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -432,7 +432,8 @@
@Override
public int getChangingConfigurations() {
- return mChangingConfigurations | mDrawableState.getChangingConfigurations();
+ return mChangingConfigurations
+ | (mDrawableState != null ? mDrawableState.getChangingConfigurations() : 0);
}
public boolean canConstantState() {
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index dc9aa67..4c2817c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -133,7 +133,7 @@
private GradientState mGradientState;
- private final Paint mFillPaint = new Paint();
+ private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Rect mPadding;
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
@@ -323,7 +323,7 @@
private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
if (mStrokePaint == null) {
- mStrokePaint = new Paint();
+ mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
mStrokePaint.setStrokeWidth(width);
@@ -1802,7 +1802,7 @@
mPadding = state.mPadding;
if (state.mStrokeWidth >= 0) {
- mStrokePaint = new Paint();
+ mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mStrokePaint.setStyle(Paint.Style.STROKE);
mStrokePaint.setStrokeWidth(state.mStrokeWidth);
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 47a1f77..7b4329a 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -18,9 +18,9 @@
import android.annotation.DrawableRes;
import android.content.ContentResolver;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
-import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
@@ -31,13 +31,14 @@
import android.os.Parcelable;
import android.util.Log;
-import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.InputStream;
-import java.lang.IllegalArgumentException;
-import java.lang.Override;
+import java.io.OutputStream;
/**
* An umbrella container for several serializable graphics representations, including Bitmaps,
@@ -52,10 +53,16 @@
public final class Icon implements Parcelable {
private static final String TAG = "Icon";
- private static final int TYPE_BITMAP = 1;
- private static final int TYPE_RESOURCE = 2;
- private static final int TYPE_DATA = 3;
- private static final int TYPE_URI = 4;
+ /** @hide */
+ public static final int TYPE_BITMAP = 1;
+ /** @hide */
+ public static final int TYPE_RESOURCE = 2;
+ /** @hide */
+ public static final int TYPE_DATA = 3;
+ /** @hide */
+ public static final int TYPE_URI = 4;
+
+ private static final int VERSION_STREAM_SERIALIZER = 1;
private final int mType;
@@ -78,15 +85,34 @@
// TYPE_DATA: data offset
private int mInt2;
- // Internal accessors for different mType variants
- private Bitmap getBitmap() {
+ /**
+ * @return The type of image data held in this Icon. One of
+ * {@link #TYPE_BITMAP},
+ * {@link #TYPE_RESOURCE},
+ * {@link #TYPE_DATA}, or
+ * {@link #TYPE_URI}.
+ * @hide
+ */
+ public int getType() {
+ return mType;
+ }
+
+ /**
+ * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
+ * @hide
+ */
+ public Bitmap getBitmap() {
if (mType != TYPE_BITMAP) {
throw new IllegalStateException("called getBitmap() on " + this);
}
return (Bitmap) mObj1;
}
- private int getDataLength() {
+ /**
+ * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon.
+ * @hide
+ */
+ public int getDataLength() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataLength() on " + this);
}
@@ -95,7 +121,12 @@
}
}
- private int getDataOffset() {
+ /**
+ * @return The offset into the byte array held by this {@link #TYPE_DATA} Icon at which
+ * valid compressed bitmap data is found.
+ * @hide
+ */
+ public int getDataOffset() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataOffset() on " + this);
}
@@ -104,7 +135,12 @@
}
}
- private byte[] getDataBytes() {
+ /**
+ * @return The byte array held by this {@link #TYPE_DATA} Icon ctonaining compressed
+ * bitmap data.
+ * @hide
+ */
+ public byte[] getDataBytes() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataBytes() on " + this);
}
@@ -113,39 +149,58 @@
}
}
- private Resources getResources() {
+ /**
+ * @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon.
+ * @hide
+ */
+ public Resources getResources() {
if (mType != TYPE_RESOURCE) {
throw new IllegalStateException("called getResources() on " + this);
}
return (Resources) mObj1;
}
- private String getResPackage() {
+ /**
+ * @return The package containing resources for this {@link #TYPE_RESOURCE} Icon.
+ * @hide
+ */
+ public String getResPackage() {
if (mType != TYPE_RESOURCE) {
throw new IllegalStateException("called getResPackage() on " + this);
}
return mString1;
}
- private int getResId() {
+ /**
+ * @return The resource ID for this {@link #TYPE_RESOURCE} Icon.
+ * @hide
+ */
+ public int getResId() {
if (mType != TYPE_RESOURCE) {
throw new IllegalStateException("called getResId() on " + this);
}
return mInt1;
}
- private String getUriString() {
+ /**
+ * @return The URI (as a String) for this {@link #TYPE_URI} Icon.
+ * @hide
+ */
+ public String getUriString() {
if (mType != TYPE_URI) {
throw new IllegalStateException("called getUriString() on " + this);
}
return mString1;
}
- private Uri getUri() {
+ /**
+ * @return The {@link android.net.Uri} for this {@link #TYPE_URI} Icon.
+ * @hide
+ */
+ public Uri getUri() {
return Uri.parse(getUriString());
}
- // Convert a int32 into a four-char string
private static final String typeToString(int x) {
switch (x) {
case TYPE_BITMAP: return "BITMAP";
@@ -177,14 +232,13 @@
* Invokes {@link #loadDrawable(Context)} on a background thread
* and then runs <code>andThen</code> on the UI thread when finished.
*
- * @param context {@link android.content.Context Context} in which to load the drawable; see
+ * @param context {@link Context Context} in which to load the drawable; see
* {@link #loadDrawable(Context)}
- * @param handler {@link android.os.Handler} on which to run <code>andThen</code>.
* @param listener a callback to run on the provided
- * Handler once the drawable is available.
+ * @param handler {@link Handler} on which to run <code>andThen</code>.
*/
- public void loadDrawableAsync(Context context, Handler handler,
- final OnDrawableLoadedListener listener) {
+ public void loadDrawableAsync(Context context, final OnDrawableLoadedListener listener,
+ Handler handler) {
new LoadDrawableTask(context, handler, listener).runAsync();
}
@@ -211,14 +265,22 @@
try {
mObj1 = pm.getResourcesForApplication(getResPackage());
} catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG,
- String.format("Unable to find package '%s'", getResPackage()),
+ Log.e(TAG, String.format("Unable to find pkg=%s",
+ getResPackage()),
e);
break;
}
}
}
- return getResources().getDrawable(getResId(), context.getTheme());
+ try {
+ return getResources().getDrawable(getResId(), context.getTheme());
+ } catch (RuntimeException e) {
+ Log.e(TAG, String.format("Unable to load resource 0x%08x from pkg=%s",
+ getResId(),
+ getResPackage()),
+ e);
+ }
+ break;
case TYPE_DATA:
return new BitmapDrawable(context.getResources(),
BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength())
@@ -250,35 +312,154 @@
return null;
}
+ /**
+ * Load the requested resources under the given userId, if the system allows it,
+ * before actually loading the drawable.
+ *
+ * @hide
+ */
+ public Drawable loadDrawableAsUser(Context context, int userId) {
+ if (mType == TYPE_RESOURCE) {
+ if (getResources() == null
+ && getResPackage() != null
+ && !(getResPackage().equals("android"))) {
+ final PackageManager pm = context.getPackageManager();
+ try {
+ mObj1 = pm.getResourcesForApplicationAsUser(getResPackage(), userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, String.format("Unable to find pkg=%s user=%d",
+ getResPackage(),
+ userId),
+ e);
+ }
+ }
+ }
+ return loadDrawable(context);
+ }
+
+ /**
+ * Writes a serialized version of an Icon to the specified stream.
+ *
+ * @param stream The stream on which to serialize the Icon.
+ * @hide
+ */
+ public void writeToStream(OutputStream stream) throws IOException {
+ DataOutputStream dataStream = new DataOutputStream(stream);
+
+ dataStream.writeInt(VERSION_STREAM_SERIALIZER);
+ dataStream.writeByte(mType);
+
+ switch (mType) {
+ case TYPE_BITMAP:
+ getBitmap().compress(Bitmap.CompressFormat.PNG, 100, dataStream);
+ break;
+ case TYPE_DATA:
+ dataStream.writeInt(getDataLength());
+ dataStream.write(getDataBytes(), getDataOffset(), getDataLength());
+ break;
+ case TYPE_RESOURCE:
+ dataStream.writeUTF(getResPackage());
+ dataStream.writeInt(getResId());
+ break;
+ case TYPE_URI:
+ dataStream.writeUTF(getUriString());
+ break;
+ }
+ }
+
private Icon(int mType) {
this.mType = mType;
}
/**
- * Create a Icon pointing to a drawable resource.
- * @param res Resources for a package containing the resource in question
- * @param resid ID of the drawable resource
+ * Create an Icon from the specified stream.
+ *
+ * @param stream The input stream from which to reconstruct the Icon.
+ * @hide
*/
- public static Icon createWithResource(Resources res, @DrawableRes int resid) {
+ public static Icon createFromStream(InputStream stream) throws IOException {
+ DataInputStream inputStream = new DataInputStream(stream);
+
+ final int version = inputStream.readInt();
+ if (version >= VERSION_STREAM_SERIALIZER) {
+ final int type = inputStream.readByte();
+ switch (type) {
+ case TYPE_BITMAP:
+ return createWithBitmap(BitmapFactory.decodeStream(inputStream));
+ case TYPE_DATA:
+ final int length = inputStream.readInt();
+ final byte[] data = new byte[length];
+ inputStream.read(data, 0 /* offset */, length);
+ return createWithData(data, 0 /* offset */, length);
+ case TYPE_RESOURCE:
+ final String packageName = inputStream.readUTF();
+ final int resId = inputStream.readInt();
+ return createWithResource(packageName, resId);
+ case TYPE_URI:
+ final String uriOrPath = inputStream.readUTF();
+ return createWithContentUri(uriOrPath);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Create an Icon pointing to a drawable resource.
+ * @param context The context for the application whose resources should be used to resolve the
+ * given resource ID.
+ * @param resId ID of the drawable resource
+ */
+ public static Icon createWithResource(Context context, @DrawableRes int resId) {
final Icon rep = new Icon(TYPE_RESOURCE);
- rep.mObj1 = res;
- rep.mInt1 = resid;
- rep.mString1 = res.getResourcePackageName(resid);
+ rep.mInt1 = resId;
+ rep.mString1 = context.getPackageName();
return rep;
}
/**
- * Create a Icon pointing to a bitmap in memory.
+ * Version of createWithResource that takes Resources. Do not use.
+ * @hide
+ */
+ public static Icon createWithResource(Resources res, @DrawableRes int resId) {
+ if (res == null) {
+ throw new IllegalArgumentException("Resource must not be null.");
+ }
+ final Icon rep = new Icon(TYPE_RESOURCE);
+ rep.mInt1 = resId;
+ rep.mString1 = res.getResourcePackageName(resId);
+ return rep;
+ }
+
+ /**
+ * Create an Icon pointing to a drawable resource.
+ * @param resPackage Name of the package containing the resource in question
+ * @param resId ID of the drawable resource
+ */
+ public static Icon createWithResource(String resPackage, @DrawableRes int resId) {
+ if (resPackage == null) {
+ throw new IllegalArgumentException("Resource package name must not be null.");
+ }
+ final Icon rep = new Icon(TYPE_RESOURCE);
+ rep.mInt1 = resId;
+ rep.mString1 = resPackage;
+ return rep;
+ }
+
+ /**
+ * Create an Icon pointing to a bitmap in memory.
* @param bits A valid {@link android.graphics.Bitmap} object
*/
public static Icon createWithBitmap(Bitmap bits) {
+ if (bits == null) {
+ throw new IllegalArgumentException("Bitmap must not be null.");
+ }
final Icon rep = new Icon(TYPE_BITMAP);
rep.mObj1 = bits;
return rep;
}
/**
- * Create a Icon pointing to a compressed bitmap stored in a byte array.
+ * Create an Icon pointing to a compressed bitmap stored in a byte array.
* @param data Byte array storing compressed bitmap data of a type that
* {@link android.graphics.BitmapFactory}
* can decode (see {@link android.graphics.Bitmap.CompressFormat}).
@@ -286,6 +467,9 @@
* @param length Length of the bitmap data
*/
public static Icon createWithData(byte[] data, int offset, int length) {
+ if (data == null) {
+ throw new IllegalArgumentException("Data must not be null.");
+ }
final Icon rep = new Icon(TYPE_DATA);
rep.mObj1 = data;
rep.mInt1 = length;
@@ -294,34 +478,43 @@
}
/**
- * Create a Icon pointing to a content specified by URI.
+ * Create an Icon pointing to an image file specified by URI.
*
* @param uri A uri referring to local content:// or file:// image data.
*/
public static Icon createWithContentUri(String uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("Uri must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = uri;
return rep;
}
/**
- * Create a Icon pointing to a content specified by URI.
+ * Create an Icon pointing to an image file specified by URI.
*
* @param uri A uri referring to local content:// or file:// image data.
*/
public static Icon createWithContentUri(Uri uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("Uri must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = uri.toString();
return rep;
}
/**
- * Create a Icon pointing to
+ * Create an Icon pointing to an image file specified by path.
*
* @param path A path to a file that contains compressed bitmap data of
* a type that {@link android.graphics.BitmapFactory} can decode.
*/
public static Icon createWithFilePath(String path) {
+ if (path == null) {
+ throw new IllegalArgumentException("Path must not be null.");
+ }
final Icon rep = new Icon(TYPE_URI);
rep.mString1 = path;
return rep;
@@ -341,7 +534,7 @@
sb.append(" pkg=")
.append(getResPackage())
.append(" id=")
- .append(String.format("%08x", getResId()));
+ .append(String.format("0x%08x", getResId()));
break;
case TYPE_DATA:
sb.append(" len=").append(getDataLength());
@@ -437,8 +630,8 @@
};
/**
- * Implement this interface to receive notification when
- * {@link #loadDrawableAsync(Context, Handler, OnDrawableLoadedListener) loadDrawableAsync}
+ * Implement this interface to receive a callback when
+ * {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
* is finished and your Drawable is ready.
*/
public interface OnDrawableLoadedListener {
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index caa0787..334b3bd 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -501,7 +501,7 @@
if (mShapeState.mPaint != null) {
mShapeState.mPaint = new Paint(mShapeState.mPaint);
} else {
- mShapeState.mPaint = new Paint();
+ mShapeState.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
if (mShapeState.mPadding != null) {
mShapeState.mPadding = new Rect(mShapeState.mPadding);
@@ -555,7 +555,7 @@
mAlpha = orig.mAlpha;
mShaderFactory = orig.mShaderFactory;
} else {
- mPaint = new Paint();
+ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
index 2b9bf50..a214b9e 100644
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
@@ -27,15 +27,11 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.Override;
import java.util.Arrays;
import java.util.ArrayList;
-import junit.framework.TestCase;
-
import com.android.frameworks.graphicstests.R;
public class IconTest extends AndroidTestCase {
@@ -116,8 +112,7 @@
final Bitmap res1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
.getBitmap();
- final Icon im1 = Icon.createWithResource(getContext().getResources(),
- R.drawable.landscape);
+ final Icon im1 = Icon.createWithResource(getContext(), R.drawable.landscape);
final Drawable draw1 = im1.loadDrawable(mContext);
final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
@@ -173,7 +168,7 @@
thd.start();
final Handler h = new Handler(thd.getLooper());
L(TAG, "asyncTest: dispatching load to thread: " + thd);
- im1.loadDrawableAsync(mContext, h, new Icon.OnDrawableLoadedListener() {
+ im1.loadDrawableAsync(mContext, new Icon.OnDrawableLoadedListener() {
@Override
public void onDrawableLoaded(Drawable draw1) {
L(TAG, "asyncTest: thread: loading drawable");
@@ -195,7 +190,7 @@
fail("testAsync: file1 differs, check " + dir);
}
}
- });
+ }, h);
L(TAG, "asyncTest: awaiting result");
Thread.sleep(500); // ;_;
assertTrue("async-test.png does not exist!", new File(dir, "async-test.png").exists());
@@ -227,7 +222,7 @@
imgs.add(bit1);
final Icon data1 = Icon.createWithData(pngdata, 0, pngdata.length);
imgs.add(data1);
- final Icon res1 = Icon.createWithResource(getContext().getResources(), R.drawable.landscape);
+ final Icon res1 = Icon.createWithResource(getContext(), R.drawable.landscape);
imgs.add(res1);
ArrayList<Icon> test = new ArrayList<>();
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 6283e02..5d777b0 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -216,7 +216,7 @@
* particular {@code alias}. All three can exist for any given alias.
* Returns {@code true} if there was at least one of those types.
*/
- static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) {
+ public static boolean deleteAllTypesForAlias(KeyStore keystore, String alias) {
/*
* Make sure every type is deleted. There can be all three types, so
* don't use a conditional here.
@@ -231,7 +231,7 @@
* particular {@code alias}. All three can exist for any given alias.
* Returns {@code true} if there was at least one of those types.
*/
- static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) {
+ public static boolean deleteCertificateTypesForAlias(KeyStore keystore, String alias) {
/*
* Make sure every certificate type is deleted. There can be two types,
* so don't use a conditional here.
@@ -252,7 +252,7 @@
* Delete secret key for a particular {@code alias}.
* Returns {@code true} if an entry was was deleted.
*/
- static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) {
+ public static boolean deleteSecretKeyTypeForAlias(KeyStore keystore, String alias) {
return keystore.delete(Credentials.USER_SECRET_KEY + alias);
}
}
diff --git a/keystore/java/android/security/EcIesParameterSpec.java b/keystore/java/android/security/EcIesParameterSpec.java
index af93519..1cd8784 100644
--- a/keystore/java/android/security/EcIesParameterSpec.java
+++ b/keystore/java/android/security/EcIesParameterSpec.java
@@ -51,49 +51,44 @@
*/
public class EcIesParameterSpec implements AlgorithmParameterSpec {
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef({
- PointFormat.UNSPECIFIED,
- PointFormat.UNCOMPRESSED,
- PointFormat.COMPRESSED,
+ POINT_FORMAT_UNSPECIFIED,
+ POINT_FORMAT_UNCOMPRESSED,
+ POINT_FORMAT_COMPRESSED,
})
public @interface PointFormatEnum {}
+ /** Unspecified EC point format. */
+ public static final int POINT_FORMAT_UNSPECIFIED = -1;
+
/**
- * Wire format of the EC point.
+ * Uncompressed EC point format: both coordinates are stored separately.
+ *
+ * <p>The wire format is byte {@code 0x04} followed by binary representation of the {@code x}
+ * coordinate followed by binary representation of the {@code y} coordinate. See
+ * {@code ISO 18033-2} section {@code 5.4.3}.
*/
- public static abstract class PointFormat {
+ public static final int POINT_FORMAT_UNCOMPRESSED = 0;
- private PointFormat() {}
-
- /** Unspecified point format. */
- public static final int UNSPECIFIED = -1;
-
- /**
- * Uncompressed point format: both coordinates are stored separately.
- *
- * <p>The wire format is byte {@code 0x04} followed by binary representation of the
- * {@code x} coordinate followed by binary representation of the {@code y} coordinate. See
- * {@code ISO 18033-2} section {@code 5.4.3}.
- */
- public static final int UNCOMPRESSED = 0;
-
- /**
- * Compressed point format: only one coordinate is stored.
- *
- * <p>The wire format is byte {@code 0x02} or {@code 0x03} (depending on the value of the
- * stored coordinate) followed by the binary representation of the {@code x} coordinate.
- * See {@code ISO 18033-2} section {@code 5.4.3}.
- */
- public static final int COMPRESSED = 1;
- }
+ /**
+ * Compressed EC point format: only one coordinate is stored.
+ *
+ * <p>The wire format is byte {@code 0x02} or {@code 0x03} (depending on the value of the stored
+ * coordinate) followed by the binary representation of the {@code x} coordinate. See
+ * {@code ISO 18033-2} section {@code 5.4.3}.
+ */
+ public static final int POINT_FORMAT_COMPRESSED = 1;
/**
* Default parameter spec: compressed point format, {@code HKDFwithSHA256}, DEM uses 128-bit AES
* GCM.
*/
public static final EcIesParameterSpec DEFAULT = new EcIesParameterSpec(
- PointFormat.COMPRESSED,
+ POINT_FORMAT_COMPRESSED,
"HKDFwithSHA256",
"AES/GCM/NoPadding",
128,
@@ -123,7 +118,7 @@
}
/**
- * Returns KEM EC point wire format or {@link PointFormat#UNSPECIFIED} if not specified.
+ * Returns KEM EC point wire format or {@link #POINT_FORMAT_UNSPECIFIED} if not specified.
*/
public @PointFormatEnum int getKemPointFormat() {
return mKemPointFormat;
@@ -184,7 +179,7 @@
* Builder of {@link EcIesParameterSpec}.
*/
public static class Builder {
- private @PointFormatEnum int mKemPointFormat = PointFormat.UNSPECIFIED;
+ private @PointFormatEnum int mKemPointFormat = POINT_FORMAT_UNSPECIFIED;
private String mKemKdfAlgorithm;
private String mDemCipherTransformation;
private int mDemCipherKeySize = 128;
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index 5617836..c1df28c 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package android.security;
import android.os.RemoteException;
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index d3dbebf..817b7c9 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -23,11 +23,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.net.Uri;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.security.keystore.KeyProperties;
+
import java.io.ByteArrayInputStream;
import java.io.Closeable;
import java.security.InvalidKeyException;
@@ -117,19 +120,7 @@
* Extra for use with {@link #ACTION_CHOOSER}
* @hide Also used by KeyChainActivity implementation
*/
- public static final String EXTRA_HOST = "host";
-
- /**
- * Extra for use with {@link #ACTION_CHOOSER}
- * @hide Also used by KeyChainActivity implementation
- */
- public static final String EXTRA_PORT = "port";
-
- /**
- * Extra for use with {@link #ACTION_CHOOSER}
- * @hide Also used by KeyChainActivity implementation
- */
- public static final String EXTRA_URL = "url";
+ public static final String EXTRA_URI = "uri";
/**
* Extra for use with {@link #ACTION_CHOOSER}
@@ -266,9 +257,15 @@
*/
public static void choosePrivateKeyAlias(@NonNull Activity activity,
@NonNull KeyChainAliasCallback response,
- @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
+ @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers,
@Nullable String host, int port, @Nullable String alias) {
- choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias);
+ Uri uri = null;
+ if (host != null) {
+ uri = new Uri.Builder()
+ .authority(host + (port != -1 ? ":" + port : ""))
+ .build();
+ }
+ choosePrivateKeyAlias(activity, response, keyTypes, issuers, uri, alias);
}
/**
@@ -301,19 +298,15 @@
* "EC" or "RSA", or a null array.
* @param issuers The acceptable certificate issuers for the
* certificate matching the private key, or null.
- * @param host The host name of the server requesting the
- * certificate, or null if unavailable.
- * @param port The port number of the server requesting the
- * certificate, or -1 if unavailable.
- * @param url The full url the server is requesting the certificate
+ * @param uri The full URI the server is requesting the certificate
* for, or null if unavailable.
* @param alias The alias to preselect if available, or null if
* unavailable.
*/
public static void choosePrivateKeyAlias(@NonNull Activity activity,
@NonNull KeyChainAliasCallback response,
- @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
- @Nullable String host, int port, @Nullable String url, @Nullable String alias) {
+ @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers,
+ @Nullable Uri uri, @Nullable String alias) {
/*
* TODO currently keyTypes, issuers are unused. They are meant
* to follow the semantics and purpose of X509KeyManager
@@ -339,9 +332,7 @@
Intent intent = new Intent(ACTION_CHOOSER);
intent.setPackage(KEYCHAIN_PACKAGE);
intent.putExtra(EXTRA_RESPONSE, new AliasResponse(response));
- intent.putExtra(EXTRA_HOST, host);
- intent.putExtra(EXTRA_PORT, port);
- intent.putExtra(EXTRA_URL, url);
+ intent.putExtra(EXTRA_URI, uri);
intent.putExtra(EXTRA_ALIAS, alias);
// the PendingIntent is used to get calling package name
intent.putExtra(EXTRA_SENDER, PendingIntent.getActivity(activity, 0, new Intent(), 0));
@@ -439,10 +430,10 @@
* "RSA").
*/
public static boolean isKeyAlgorithmSupported(
- @NonNull @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) {
final String algUpper = algorithm.toUpperCase(Locale.US);
- return KeyStoreKeyProperties.Algorithm.EC.equals(algUpper)
- || KeyStoreKeyProperties.Algorithm.RSA.equals(algUpper);
+ return KeyProperties.KEY_ALGORITHM_EC.equals(algUpper)
+ || KeyProperties.KEY_ALGORITHM_RSA.equals(algUpper);
}
/**
@@ -453,7 +444,7 @@
* that makes it non-exportable.
*/
public static boolean isBoundKeyAlgorithm(
- @NonNull @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) {
if (!isKeyAlgorithmSupported(algorithm)) {
return false;
}
diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java
deleted file mode 100644
index 404f939..0000000
--- a/keystore/java/android/security/KeyGeneratorSpec.java
+++ /dev/null
@@ -1,524 +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 android.security;
-
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.KeyguardManager;
-import android.content.Context;
-import android.text.TextUtils;
-
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.Date;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-
-/**
- * {@link AlgorithmParameterSpec} for initializing a {@link KeyGenerator} of the
- * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
- * specifies whether user authentication is required for using the key, what uses the key is
- * authorized for (e.g., only in {@code CBC} mode), whether the key should be encrypted at rest, the
- * key's and validity start and end dates.
- *
- * <p>To generate a key, create an instance of this class using the {@link Builder}, initialize a
- * {@code KeyGenerator} of the desired key type (e.g., {@code AES} or {@code HmacSHA256}) from the
- * {@code AndroidKeyStore} provider with the {@code KeyGeneratorSpec} instance, and then generate a
- * key using {@link KeyGenerator#generateKey()}.
- *
- * <p>The generated key will be returned by the {@code KeyGenerator} and also stored in the Android
- * KeyStore under the alias specified in this {@code KeyGeneratorSpec}. To obtain the key from the
- * Android KeyStore use
- * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
- * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- *
- * <p>NOTE: The key material of the keys generating using the {@code KeyGeneratorSpec} is not
- * accessible.
- *
- * <p><h3>Example</h3>
- * The following example illustrates how to generate an HMAC key in the Android KeyStore under alias
- * {@code key1} authorized to be used only for HMAC with SHA-256 digest and only if the user has
- * been authenticated within the last five minutes.
- * <pre> {@code
- * KeyGenerator keyGenerator = KeyGenerator.getInstance(
- * KeyStoreKeyProperties.Algorithm.HMAC_SHA256,
- * "AndroidKeyStore");
- * keyGenerator.initialize(
- * new KeyGeneratorSpec.Builder(context)
- * .setAlias("key1")
- * .setPurposes(KeyStoreKeyProperties.Purpose.SIGN
- * | KeyStoreKeyProperties.Purpose.VERIFY)
- * // Only permit this key to be used if the user authenticated
- * // within the last five minutes.
- * .setUserAuthenticationRequired(true)
- * .setUserAuthenticationValidityDurationSeconds(5 * 60)
- * .build());
- * SecretKey key = keyGenerator.generateKey();
- *
- * // The key can also be obtained from the Android KeyStore any time as follows:
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * SecretKey key = (SecretKey) keyStore.getKey("key1", null);
- * }</pre>
- */
-public class KeyGeneratorSpec implements AlgorithmParameterSpec {
-
- private final Context mContext;
- private final String mKeystoreAlias;
- private final int mFlags;
- private final int mKeySize;
- private final Date mKeyValidityStart;
- private final Date mKeyValidityForOriginationEnd;
- private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
- private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
- private final boolean mRandomizedEncryptionRequired;
- private final boolean mUserAuthenticationRequired;
- private final int mUserAuthenticationValidityDurationSeconds;
-
- private KeyGeneratorSpec(
- Context context,
- String keyStoreAlias,
- int flags,
- int keySize,
- Date keyValidityStart,
- Date keyValidityForOriginationEnd,
- Date keyValidityForConsumptionEnd,
- @KeyStoreKeyProperties.PurposeEnum int purposes,
- @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
- @KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
- boolean randomizedEncryptionRequired,
- boolean userAuthenticationRequired,
- int userAuthenticationValidityDurationSeconds) {
- if (context == null) {
- throw new IllegalArgumentException("context == null");
- } else if (TextUtils.isEmpty(keyStoreAlias)) {
- throw new IllegalArgumentException("keyStoreAlias must not be empty");
- } else if ((userAuthenticationValidityDurationSeconds < 0)
- && (userAuthenticationValidityDurationSeconds != -1)) {
- throw new IllegalArgumentException(
- "userAuthenticationValidityDurationSeconds must not be negative");
- }
-
- mContext = context;
- mKeystoreAlias = keyStoreAlias;
- mFlags = flags;
- mKeySize = keySize;
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
- mPurposes = purposes;
- mEncryptionPaddings =
- ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
- mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
- mRandomizedEncryptionRequired = randomizedEncryptionRequired;
- mUserAuthenticationRequired = userAuthenticationRequired;
- mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
- }
-
- /**
- * Gets the Android context used for operations with this instance.
- */
- public Context getContext() {
- return mContext;
- }
-
- /**
- * Returns the alias that will be used in the {@code java.security.KeyStore} in conjunction with
- * the {@code AndroidKeyStore}.
- */
- public String getKeystoreAlias() {
- return mKeystoreAlias;
- }
-
- /**
- * @hide
- */
- public int getFlags() {
- return mFlags;
- }
-
- /**
- * Returns the requested key size or {@code -1} if default size should be used.
- */
- public int getKeySize() {
- return mKeySize;
- }
-
- /**
- * Gets the time instant before which the key is not yet valid.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityStart() {
- return mKeyValidityStart;
- }
-
- /**
- * Gets the time instant after which the key is no longer valid for decryption and verification.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
- }
-
- /**
- * Gets the time instant after which the key is no longer valid for encryption and signing.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
- }
-
- /**
- * Gets the set of purposes for which the key can be used.
- */
- public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
- return mPurposes;
- }
-
- /**
- * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
- */
- @NonNull
- public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
- return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
- }
-
- /**
- * Gets the set of block modes with which the key can be used.
- */
- @NonNull
- public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
- return ArrayUtils.cloneIfNotEmpty(mBlockModes);
- }
-
- /**
- * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic property
- * being required is <em>indistinguishability under chosen-plaintext attack ({@code
- * IND-CPA})</em>. This property is important because it mitigates several classes of
- * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
- * given plaintext always produces the same ciphertext, an attacker may see the repeated
- * ciphertexts and be able to deduce something about the plaintext.
- */
- public boolean isRandomizedEncryptionRequired() {
- return mRandomizedEncryptionRequired;
- }
-
- /**
- * Returns {@code true} if user authentication is required for this key to be used.
- *
- * @see #getUserAuthenticationValidityDurationSeconds()
- */
- public boolean isUserAuthenticationRequired() {
- return mUserAuthenticationRequired;
- }
-
- /**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * @return duration in seconds or {@code -1} if authentication is required for every use of the
- * key.
- *
- * @see #isUserAuthenticationRequired()
- */
- public int getUserAuthenticationValidityDurationSeconds() {
- return mUserAuthenticationValidityDurationSeconds;
- }
-
- /**
- * Returns {@code true} if the key must be encrypted at rest. This will protect the key with the
- * secure lock screen credential (e.g., password, PIN, or pattern).
- */
- public boolean isEncryptionRequired() {
- return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
- }
-
- public static class Builder {
- private final Context mContext;
- private String mKeystoreAlias;
- private int mFlags;
- private int mKeySize = -1;
- private Date mKeyValidityStart;
- private Date mKeyValidityForOriginationEnd;
- private Date mKeyValidityForConsumptionEnd;
- private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
- private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
- private boolean mRandomizedEncryptionRequired = true;
- private boolean mUserAuthenticationRequired;
- private int mUserAuthenticationValidityDurationSeconds = -1;
-
- /**
- * Creates a new instance of the {@code Builder} with the given {@code context}. The
- * {@code context} passed in may be used to pop up some UI to ask the user to unlock or
- * initialize the Android KeyStore facility.
- */
- public Builder(@NonNull Context context) {
- if (context == null) {
- throw new NullPointerException("context == null");
- }
- mContext = context;
- }
-
- /**
- * Sets the alias to be used to retrieve the key later from a {@link java.security.KeyStore}
- * instance using the {@code AndroidKeyStore} provider.
- *
- * <p>The alias must be provided. There is no default.
- */
- @NonNull
- public Builder setAlias(@NonNull String alias) {
- if (alias == null) {
- throw new NullPointerException("alias == null");
- }
- mKeystoreAlias = alias;
- return this;
- }
-
- /**
- * Sets the size (in bits) of the key to be generated.
- *
- * <p>By default, the key size will be determines based on the key algorithm. For example,
- * for {@code HmacSHA256}, the key size will default to {@code 256}.
- */
- @NonNull
- public Builder setKeySize(int keySize) {
- mKeySize = keySize;
- return this;
- }
-
- /**
- * Indicates that this key must be encrypted at rest. This will protect the key with the
- * secure lock screen credential (e.g., password, PIN, or pattern).
- *
- * <p>Note that this feature requires that the secure lock screen (e.g., password, PIN,
- * pattern) is set up, otherwise key generation will fail. Moreover, this key will be
- * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
- * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
- * screen after boot.
- *
- * @see KeyguardManager#isDeviceSecure()
- */
- @NonNull
- public Builder setEncryptionRequired() {
- mFlags |= KeyStore.FLAG_ENCRYPTED;
- return this;
- }
-
- /**
- * Sets the time instant before which the key is not yet valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * @see #setKeyValidityEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityStart(Date startDate) {
- mKeyValidityStart = startDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * @see #setKeyValidityStart(Date)
- * @see #setKeyValidityForConsumptionEnd(Date)
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityEnd(Date endDate) {
- setKeyValidityForOriginationEnd(endDate);
- setKeyValidityForConsumptionEnd(endDate);
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for encryption and signing.
- *
- * <p>By default, the key is valid at any instant.
- *
- * @see #setKeyValidityForConsumptionEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForOriginationEnd(Date endDate) {
- mKeyValidityForOriginationEnd = endDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for decryption and
- * verification.
- *
- * <p>By default, the key is valid at any instant.
- *
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForConsumptionEnd(Date endDate) {
- mKeyValidityForConsumptionEnd = endDate;
- return this;
- }
-
- /**
- * Sets the set of purposes for which the key can be used.
- *
- * <p>This must be specified for all keys. There is no default.
- */
- @NonNull
- public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
- mPurposes = purposes;
- return this;
- }
-
- /**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
- *
- * <p>This must be specified for keys which are used for encryption/decryption.
- */
- @NonNull
- public Builder setEncryptionPaddings(
- @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
- mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
- return this;
- }
-
- /**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
- *
- * <p>This must be specified for encryption/decryption keys.
- */
- @NonNull
- public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
- mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
- return this;
- }
-
- /**
- * Sets whether encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic
- * property being required is <em>indistinguishability under chosen-plaintext attack
- * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
- * of weaknesses due to which ciphertext may leak information about plaintext. For example,
- * if a given plaintext always produces the same ciphertext, an attacker may see the
- * repeated ciphertexts and be able to deduce something about the plaintext.
- *
- * <p>By default, {@code IND-CPA} is required.
- *
- * <p>When {@code IND-CPA} is required:
- * <ul>
- * <li>block modes which do not offer {@code IND-CPA}, such as {@code ECB}, are prohibited;
- * </li>
- * <li>in block modes which use an IV, such as {@code CBC}, {@code CTR}, and {@code GCM},
- * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are
- * used.</li>
- *
- * <p>Before disabling this requirement, consider the following approaches instead:
- * <ul>
- * <li>If you are generating a random IV for encryption and then initializing a {@code}
- * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
- * instead. This will occur if the {@code Cipher} is initialized for encryption without an
- * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
- * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
- * random, such as the name of the file being encrypted, or transaction ID, or password,
- * or a device identifier), consider changing your design to use a random IV which will then
- * be provided in addition to the ciphertext to the entities which need to decrypt the
- * ciphertext.</li>
- * </ul>
- */
- @NonNull
- public Builder setRandomizedEncryptionRequired(boolean required) {
- mRandomizedEncryptionRequired = required;
- return this;
- }
-
- /**
- * Sets whether user authentication is required to use this key.
- *
- * <p>By default, the key can be used without user authentication.
- *
- * <p>When user authentication is required, the user authorizes the use of the key by
- * authenticating to this Android device using a subset of their secure lock screen
- * credentials. Different authentication methods are used depending on whether the every
- * use of the key must be authenticated (as specified by
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
- * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
- * information</a>.
- *
- * @see #setUserAuthenticationValidityDurationSeconds(int)
- */
- @NonNull
- public Builder setUserAuthenticationRequired(boolean required) {
- mUserAuthenticationRequired = required;
- return this;
- }
-
- /**
- * Sets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * <p>By default, the user needs to authenticate for every use of the key.
- *
- * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
- * every use of the key.
- *
- * @see #setUserAuthenticationRequired(boolean)
- */
- @NonNull
- public Builder setUserAuthenticationValidityDurationSeconds(
- @IntRange(from = -1) int seconds) {
- mUserAuthenticationValidityDurationSeconds = seconds;
- return this;
- }
-
- /**
- * Builds a new instance instance of {@code KeyGeneratorSpec}.
- *
- * @throws IllegalArgumentException if a required field is missing or violates a constraint.
- */
- @NonNull
- public KeyGeneratorSpec build() {
- return new KeyGeneratorSpec(mContext,
- mKeystoreAlias,
- mFlags,
- mKeySize,
- mKeyValidityStart,
- mKeyValidityForOriginationEnd,
- mKeyValidityForConsumptionEnd,
- mPurposes,
- mEncryptionPaddings,
- mBlockModes,
- mRandomizedEncryptionRequired,
- mUserAuthenticationRequired,
- mUserAuthenticationValidityDurationSeconds);
- }
- }
-}
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 2086ccb..efbce41 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -17,14 +17,14 @@
package android.security;
import android.app.KeyguardManager;
-import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
import android.text.TextUtils;
import java.math.BigInteger;
-import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
@@ -34,72 +34,32 @@
import javax.security.auth.x500.X500Principal;
/**
- * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} of the
- * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
- * specifies whether user authentication is required for using the private key, what uses the
- * private key is authorized for (e.g., only for signing -- decryption not permitted), whether the
- * private key should be encrypted at rest, the private key's and validity start and end dates.
+ * This provides the required parameters needed for initializing the
+ * {@code KeyPairGenerator} that works with
+ * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
+ * facility</a>. The Android KeyStore facility is accessed through a
+ * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore}
+ * provider. The {@code context} passed in may be used to pop up some UI to ask
+ * the user to unlock or initialize the Android KeyStore facility.
+ * <p>
+ * After generation, the {@code keyStoreAlias} is used with the
+ * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
+ * interface to retrieve the {@link PrivateKey} and its associated
+ * {@link Certificate} chain.
+ * <p>
+ * The KeyPair generator will create a self-signed certificate with the subject
+ * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
+ * Distinguished Name along with the other parameters specified with the
+ * {@link Builder}.
+ * <p>
+ * The self-signed X.509 certificate may be replaced at a later time by a
+ * certificate signed by a real Certificate Authority.
*
- * <p>To generate a key pair, create an instance of this class using the {@link Builder}, initialize
- * a {@code KeyPairGenerator} of the desired key type (e.g., {@code EC} or {@code RSA}) from the
- * {@code AndroidKeyStore} provider with the {@code KeyPairGeneratorSpec} instance, and then
- * generate a key pair using {@link KeyPairGenerator#generateKeyPair()}.
- *
- * <p>The generated key pair will be returned by the {@code KeyPairGenerator} and also stored in the
- * Android KeyStore under the alias specified in this {@code KeyPairGeneratorSpec}. To obtain the
- * private key from the Android KeyStore use
- * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
- * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- * To obtain the public key from the Android KeyStore use
- * {@link java.security.KeyStore#getCertificate(String)} and then
- * {@link Certificate#getPublicKey()}.
- *
- * <p>A self-signed X.509 certificate will be also generated and stored in the Android KeyStore.
- * This is because the {@link java.security.KeyStore} abstraction does not support storing key pairs
- * without a certificate. The subject, serial number, and validity dates of the certificate can be
- * specified in this {@code KeyPairGeneratorSpec}. The self-signed certificate may be replaced at a
- * later time by a certificate signed by a Certificate Authority (CA).
- *
- * <p>NOTE: The key material of the private keys generating using the {@code KeyPairGeneratorSpec}
- * is not accessible. The key material of the public keys is accessible.
- *
- * <p><h3>Example</h3>
- * The following example illustrates how to generate an EC key pair in the Android KeyStore under
- * alias {@code key2} authorized to be used only for signing using SHA-256, SHA-384, or SHA-512
- * digest and only if the user has been authenticated within the last five minutes.
- * <pre> {@code
- * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
- * KeyStoreKeyProperties.Algorithm.EC,
- * "AndroidKeyStore");
- * keyPairGenerator.initialize(
- * new KeyGeneratorSpec.Builder(context)
- * .setAlias("key2")
- * .setPurposes(KeyStoreKeyProperties.Purpose.SIGN
- * | KeyStoreKeyProperties.Purpose.VERIFY)
- * .setDigests(KeyStoreKeyProperties.Digest.SHA256
- * | KeyStoreKeyProperties.Digest.SHA384
- * | KeyStoreKeyProperties.Digest.SHA512)
- * // Only permit this key to be used if the user authenticated
- * // within the last five minutes.
- * .setUserAuthenticationRequired(true)
- * .setUserAuthenticationValidityDurationSeconds(5 * 60)
- * .build());
- * KeyPair keyPair = keyPairGenerator.generateKey();
- *
- * // The key pair can also be obtained from the Android KeyStore any time as follows:
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key2", null);
- * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * }</pre>
+ * @deprecated Use {@link KeyGenParameterSpec} instead.
*/
+@Deprecated
public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
- private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
- private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
- private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
- private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
-
private final Context mContext;
private final String mKeystoreAlias;
@@ -120,28 +80,6 @@
private final int mFlags;
- private final Date mKeyValidityStart;
-
- private final Date mKeyValidityForOriginationEnd;
-
- private final Date mKeyValidityForConsumptionEnd;
-
- private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
-
- private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
-
- private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
-
- private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
-
- private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
-
- private final boolean mRandomizedEncryptionRequired;
-
- private final boolean mUserAuthenticationRequired;
-
- private final int mUserAuthenticationValidityDurationSeconds;
-
/**
* Parameter specification for the "{@code AndroidKeyPairGenerator}"
* instance of the {@link java.security.KeyPairGenerator} API. The
@@ -162,7 +100,7 @@
* @param context Android context for the activity
* @param keyStoreAlias name to use for the generated key in the Android
* keystore
- * @param keyType key algorithm to use (EC, RSA)
+ * @param keyType key algorithm to use (RSA, DSA, EC)
* @param keySize size of key to generate
* @param spec the underlying key type parameters
* @param subjectDN X.509 v3 Subject Distinguished Name
@@ -176,39 +114,21 @@
*/
public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
- Date startDate, Date endDate, int flags,
- Date keyValidityStart,
- Date keyValidityForOriginationEnd,
- Date keyValidityForConsumptionEnd,
- @KeyStoreKeyProperties.PurposeEnum int purposes,
- @KeyStoreKeyProperties.DigestEnum String[] digests,
- @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
- @KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
- @KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
- boolean randomizedEncryptionRequired,
- boolean userAuthenticationRequired,
- int userAuthenticationValidityDurationSeconds) {
+ Date startDate, Date endDate, int flags) {
if (context == null) {
throw new IllegalArgumentException("context == null");
} else if (TextUtils.isEmpty(keyStoreAlias)) {
throw new IllegalArgumentException("keyStoreAlias must not be empty");
- } else if ((userAuthenticationValidityDurationSeconds < 0)
- && (userAuthenticationValidityDurationSeconds != -1)) {
- throw new IllegalArgumentException(
- "userAuthenticationValidityDurationSeconds must not be negative");
- }
-
- if (subjectDN == null) {
- subjectDN = DEFAULT_CERT_SUBJECT;
- }
- if (startDate == null) {
- startDate = DEFAULT_CERT_NOT_BEFORE;
- }
- if (endDate == null) {
- endDate = DEFAULT_CERT_NOT_AFTER;
- }
- if (serialNumber == null) {
- serialNumber = DEFAULT_CERT_SERIAL_NUMBER;
+ } else if (subjectDN == null) {
+ throw new IllegalArgumentException("subjectDN == null");
+ } else if (serialNumber == null) {
+ throw new IllegalArgumentException("serialNumber == null");
+ } else if (startDate == null) {
+ throw new IllegalArgumentException("startDate == null");
+ } else if (endDate == null) {
+ throw new IllegalArgumentException("endDate == null");
+ } else if (endDate.before(startDate)) {
+ throw new IllegalArgumentException("endDate < startDate");
}
if (endDate.before(startDate)) {
@@ -225,50 +145,6 @@
mStartDate = startDate;
mEndDate = endDate;
mFlags = flags;
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
- mPurposes = purposes;
- mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests));
- mEncryptionPaddings =
- ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
- mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
- mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
- mRandomizedEncryptionRequired = randomizedEncryptionRequired;
- mUserAuthenticationRequired = userAuthenticationRequired;
- mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
- }
-
- /**
- * TODO: Remove this constructor once tests are switched over to the new one above.
- * @hide
- */
- public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize,
- AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber,
- Date startDate, Date endDate, int flags) {
-
- this(context,
- keyStoreAlias,
- keyType,
- keySize,
- spec,
- subjectDN,
- serialNumber,
- startDate,
- endDate,
- flags,
- startDate,
- endDate,
- endDate,
- 0, // purposes
- null, // digests
- null, // encryption paddings
- null, // signature paddings
- null, // block modes
- false, // randomized encryption required
- false, // user authentication required
- -1 // user authentication validity duration (seconds)
- );
}
/**
@@ -287,10 +163,11 @@
}
/**
- * Returns the key type (e.g., "EC", "RSA") specified by this parameter.
+ * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
+ * {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
*/
@Nullable
- public @KeyStoreKeyProperties.AlgorithmEnum String getKeyType() {
+ public @KeyProperties.KeyAlgorithmEnum String getKeyType() {
return mKeyType;
}
@@ -351,130 +228,27 @@
/**
* @hide
*/
- int getFlags() {
+ public int getFlags() {
return mFlags;
}
/**
* Returns {@code true} if the key must be encrypted at rest. This will protect the key pair
* with the secure lock screen credential (e.g., password, PIN, or pattern).
+ *
+ * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password,
+ * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be
+ * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
+ * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
+ * screen after boot.
+ *
+ * @see KeyguardManager#isDeviceSecure()
*/
public boolean isEncryptionRequired() {
return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
}
/**
- * Gets the time instant before which the key pair is not yet valid.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityStart() {
- return mKeyValidityStart;
- }
-
- /**
- * Gets the time instant after which the key pair is no longer valid for decryption and
- * verification.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
- }
-
- /**
- * Gets the time instant after which the key pair is no longer valid for encryption and signing.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
- }
-
- /**
- * Gets the set of purposes for which the key can be used.
- */
- public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
- return mPurposes;
- }
-
- /**
- * Gets the set of digest algorithms with which the key can be used.
- */
- @NonNull
- public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
- return ArrayUtils.cloneIfNotEmpty(mDigests);
- }
-
- /**
- * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
- */
- @NonNull
- public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
- return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
- }
-
- /**
- * Gets the set of padding schemes with which the key can be used when signing/verifying.
- */
- @NonNull
- public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
- return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
- }
-
- /**
- * Gets the set of block modes with which the key can be used.
- */
- @NonNull
- public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
- return ArrayUtils.cloneIfNotEmpty(mBlockModes);
- }
-
- /**
- * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic property
- * being required is <em>indistinguishability under chosen-plaintext attack ({@code
- * IND-CPA})</em>. This property is important because it mitigates several classes of
- * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
- * given plaintext always produces the same ciphertext, an attacker may see the repeated
- * ciphertexts and be able to deduce something about the plaintext.
- */
- public boolean isRandomizedEncryptionRequired() {
- return mRandomizedEncryptionRequired;
- }
-
- /**
- * Returns {@code true} if user authentication is required for this key to be used.
- *
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
- *
- * @see #getUserAuthenticationValidityDurationSeconds()
- */
- public boolean isUserAuthenticationRequired() {
- return mUserAuthenticationRequired;
- }
-
- /**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
- *
- * @return duration in seconds or {@code -1} if authentication is required for every use of the
- * key.
- *
- * @see #isUserAuthenticationRequired()
- */
- public int getUserAuthenticationValidityDurationSeconds() {
- return mUserAuthenticationValidityDurationSeconds;
- }
-
- /**
* Builder class for {@link KeyPairGeneratorSpec} objects.
* <p>
* This will build a parameter spec for use with the <a href="{@docRoot}
@@ -494,7 +268,10 @@
* .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337))
* .setStartDate(start.getTime()).setEndDate(end.getTime()).build();
* </pre>
+ *
+ * @deprecated Use {@link KeyGenParameterSpec.Builder} instead.
*/
+ @Deprecated
public final static class Builder {
private final Context mContext;
@@ -516,28 +293,6 @@
private int mFlags;
- private Date mKeyValidityStart;
-
- private Date mKeyValidityForOriginationEnd;
-
- private Date mKeyValidityForConsumptionEnd;
-
- private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
-
- private @KeyStoreKeyProperties.DigestEnum String[] mDigests;
-
- private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
-
- private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
-
- private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
-
- private boolean mRandomizedEncryptionRequired = true;
-
- private boolean mUserAuthenticationRequired;
-
- private int mUserAuthenticationValidityDurationSeconds = -1;
-
/**
* Creates a new instance of the {@code Builder} with the given
* {@code context}. The {@code context} passed in may be used to pop up
@@ -566,10 +321,12 @@
}
/**
- * Sets the key type (e.g., EC, RSA) of the keypair to be created.
+ * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be
+ * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants.
+ *
*/
@NonNull
- public Builder setKeyType(@NonNull @KeyStoreKeyProperties.AlgorithmEnum String keyType)
+ public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType)
throws NoSuchAlgorithmException {
if (keyType == null) {
throw new NullPointerException("keyType == null");
@@ -611,10 +368,6 @@
/**
* Sets the subject used for the self-signed certificate of the
* generated key pair.
- *
- * <p>The subject must be specified on API Level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
- * newer platforms the subject defaults to {@code CN=fake} if not specified.
*/
@NonNull
public Builder setSubject(@NonNull X500Principal subject) {
@@ -628,10 +381,6 @@
/**
* Sets the serial number used for the self-signed certificate of the
* generated key pair.
- *
- * <p>The serial number must be specified on API Level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
- * newer platforms the serial number defaults to {@code 1} if not specified.
*/
@NonNull
public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
@@ -645,10 +394,6 @@
/**
* Sets the start of the validity period for the self-signed certificate
* of the generated key pair.
- *
- * <p>The date must be specified on API Level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
- * newer platforms the date defaults to {@code Jan 1 1970} if not specified.
*/
@NonNull
public Builder setStartDate(@NonNull Date startDate) {
@@ -662,10 +407,6 @@
/**
* Sets the end of the validity period for the self-signed certificate
* of the generated key pair.
- *
- * <p>The date must be specified on API Level
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On
- * newer platforms the date defaults to {@code Jan 1 2048} if not specified.
*/
@NonNull
public Builder setEndDate(@NonNull Date endDate) {
@@ -695,226 +436,6 @@
}
/**
- * Sets the time instant before which the key is not yet valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @see #setKeyValidityEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityStart(Date startDate) {
- mKeyValidityStart = startDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @see #setKeyValidityStart(Date)
- * @see #setKeyValidityForConsumptionEnd(Date)
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityEnd(Date endDate) {
- setKeyValidityForOriginationEnd(endDate);
- setKeyValidityForConsumptionEnd(endDate);
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for encryption and signing.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @see #setKeyValidityForConsumptionEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForOriginationEnd(Date endDate) {
- mKeyValidityForOriginationEnd = endDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for decryption and
- * verification.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForConsumptionEnd(Date endDate) {
- mKeyValidityForConsumptionEnd = endDate;
- return this;
- }
-
- /**
- * Sets the set of purposes for which the key can be used.
- *
- * <p>This must be specified for all keys. There is no default.
- *
- * <p>If the set of purposes for which the key can be used does not contain
- * {@link KeyStoreKeyProperties.Purpose#SIGN}, the self-signed certificate generated by
- * {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an invalid
- * signature. This is OK if the certificate is only used for obtaining the public key from
- * Android KeyStore.
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
- mPurposes = purposes;
- return this;
- }
-
- /**
- * Sets the set of digests with which the key can be used when signing/verifying. Attempts
- * to use the key with any other digest will be rejected.
- *
- * <p>This must be specified for keys which are used for signing/verification.
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
- mDigests = ArrayUtils.cloneIfNotEmpty(digests);
- return this;
- }
-
- /**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
- *
- * <p>This must be specified for keys which are used for encryption/decryption.
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setEncryptionPaddings(
- @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
- mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
- return this;
- }
-
- /**
- * Sets the set of padding schemes with which the key can be used when
- * signing/verifying. Attempts to use the key with any other padding scheme will be
- * rejected.
- *
- * <p>This must be specified for RSA keys which are used for signing/verification.
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setSignaturePaddings(
- @KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
- mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
- return this;
- }
-
- /**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
- *
- * <p>This must be specified for encryption/decryption keys.
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
- mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
- return this;
- }
-
- /**
- * Sets whether encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic
- * property being required is <em>indistinguishability under chosen-plaintext attack
- * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
- * of weaknesses due to which ciphertext may leak information about plaintext. For example,
- * if a given plaintext always produces the same ciphertext, an attacker may see the
- * repeated ciphertexts and be able to deduce something about the plaintext.
- *
- * <p>By default, {@code IND-CPA} is required.
- *
- * <p>When {@code IND-CPA} is required, encryption/decryption transformations which do not
- * offer {@code IND-CPA}, such as RSA without padding, are prohibited.
- *
- * <p>Before disabling this requirement, consider the following approaches instead:
- * <ul>
- * <li>If you are using RSA encryption without padding, consider switching to padding
- * schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
- * </ul>
- *
- * <p><b>NOTE: This has currently no effect.
- */
- @NonNull
- public Builder setRandomizedEncryptionRequired(boolean required) {
- mRandomizedEncryptionRequired = required;
- return this;
- }
-
- /**
- * Sets whether user authentication is required to use this key.
- *
- * <p>By default, the key can be used without user authentication.
- *
- * <p>When user authentication is required, the user authorizes the use of the key by
- * authenticating to this Android device using a subset of their secure lock screen
- * credentials. Different authentication methods are used depending on whether the every
- * use of the key must be authenticated (as specified by
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
- * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
- * information</a>.
- *
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @see #setUserAuthenticationValidityDurationSeconds(int)
- */
- @NonNull
- public Builder setUserAuthenticationRequired(boolean required) {
- mUserAuthenticationRequired = required;
- return this;
- }
-
- /**
- * Sets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * <p>By default, the user needs to authenticate for every use of the key.
- *
- * <p>This restriction applies only to private key operations. Public key operations are not
- * restricted.
- *
- * <p><b>NOTE: This has currently no effect.
- *
- * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
- * every use of the key.
- *
- * @see #setUserAuthenticationRequired(boolean)
- */
- @NonNull
- public Builder setUserAuthenticationValidityDurationSeconds(
- @IntRange(from = -1) int seconds) {
- mUserAuthenticationValidityDurationSeconds = seconds;
- return this;
- }
-
- /**
* Builds the instance of the {@code KeyPairGeneratorSpec}.
*
* @throws IllegalArgumentException if a required field is missing
@@ -931,18 +452,7 @@
mSerialNumber,
mStartDate,
mEndDate,
- mFlags,
- mKeyValidityStart,
- mKeyValidityForOriginationEnd,
- mKeyValidityForConsumptionEnd,
- mPurposes,
- mDigests,
- mEncryptionPaddings,
- mSignaturePaddings,
- mBlockModes,
- mRandomizedEncryptionRequired,
- mUserAuthenticationRequired,
- mUserAuthenticationValidityDurationSeconds);
+ mFlags);
}
}
}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 3ed8899..06f5b06 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -35,6 +35,11 @@
import android.security.keymaster.KeymasterBlob;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
+import android.security.keystore.KeyExpiredException;
+import android.security.keystore.KeyNotYetValidException;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.UserNotAuthenticatedException;
import android.util.Log;
import java.security.InvalidKeyException;
@@ -101,10 +106,10 @@
private KeyStore(IKeystoreService binder) {
mBinder = binder;
- mContext = getContext();
+ mContext = getApplicationContext();
}
- private static Context getContext() {
+ public static Context getApplicationContext() {
ActivityThread activityThread = ActivityThread.currentActivityThread();
if (activityThread == null) {
throw new IllegalStateException(
@@ -131,10 +136,10 @@
return mToken;
}
- static int getKeyTypeForAlgorithm(@KeyStoreKeyProperties.AlgorithmEnum String keyType) {
- if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(keyType)) {
+ public static int getKeyTypeForAlgorithm(@KeyProperties.KeyAlgorithmEnum String keyType) {
+ if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) {
return NativeConstants.EVP_PKEY_RSA;
- } else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(keyType)) {
+ } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyType)) {
return NativeConstants.EVP_PKEY_EC;
} else {
return -1;
@@ -581,6 +586,44 @@
}
}
+ /**
+ * Notify keystore that a user was added.
+ *
+ * @param userId the new user.
+ * @param parentId the parent of the new user, or -1 if the user has no parent. If parentId is
+ * specified then the new user's keystore will be intialized with the same secure lockscreen
+ * password as the parent.
+ */
+ public void onUserAdded(int userId, int parentId) {
+ try {
+ mBinder.onUserAdded(userId, parentId);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ }
+ }
+
+ /**
+ * Notify keystore that a user was added.
+ *
+ * @param userId the new user.
+ */
+ public void onUserAdded(int userId) {
+ onUserAdded(userId, -1);
+ }
+
+ /**
+ * Notify keystore that a user was removed.
+ *
+ * @param userId the removed user.
+ */
+ public void onUserRemoved(int userId) {
+ try {
+ mBinder.onUserRemoved(userId);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ }
+ }
+
public boolean onUserPasswordChanged(String newPassword) {
return onUserPasswordChanged(UserHandle.getUserId(Process.myUid()), newPassword);
}
@@ -589,7 +632,7 @@
* Returns a {@link KeyStoreException} corresponding to the provided keystore/keymaster error
* code.
*/
- static KeyStoreException getKeyStoreException(int errorCode) {
+ public static KeyStoreException getKeyStoreException(int errorCode) {
if (errorCode > 0) {
// KeyStore layer error
switch (errorCode) {
@@ -631,7 +674,8 @@
* Returns an {@link InvalidKeyException} corresponding to the provided
* {@link KeyStoreException}.
*/
- InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, KeyStoreException e) {
+ public InvalidKeyException getInvalidKeyException(
+ String keystoreKeyAlias, KeyStoreException e) {
switch (e.getErrorCode()) {
case LOCKED:
return new UserNotAuthenticatedException();
@@ -702,7 +746,7 @@
* Returns an {@link InvalidKeyException} corresponding to the provided keystore/keymaster error
* code.
*/
- InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) {
+ public InvalidKeyException getInvalidKeyException(String keystoreKeyAlias, int errorCode) {
return getInvalidKeyException(keystoreKeyAlias, getKeyStoreException(errorCode));
}
}
diff --git a/keystore/java/android/security/KeyStoreKeyProperties.java b/keystore/java/android/security/KeyStoreKeyProperties.java
deleted file mode 100644
index d1b0e5b..0000000
--- a/keystore/java/android/security/KeyStoreKeyProperties.java
+++ /dev/null
@@ -1,725 +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 android.security;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.StringDef;
-import android.security.keymaster.KeymasterDefs;
-
-import libcore.util.EmptyArray;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.util.Collection;
-import java.util.Locale;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKeyFactory;
-
-/**
- * Properties of {@code AndroidKeyStore} keys.
- */
-public abstract class KeyStoreKeyProperties {
- private KeyStoreKeyProperties() {}
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true,
- value = {Purpose.ENCRYPT, Purpose.DECRYPT, Purpose.SIGN, Purpose.VERIFY})
- public @interface PurposeEnum {}
-
- /**
- * Purposes of key.
- */
- public static abstract class Purpose {
- private Purpose() {}
-
- /**
- * Purpose: encryption.
- */
- public static final int ENCRYPT = 1 << 0;
-
- /**
- * Purpose: decryption.
- */
- public static final int DECRYPT = 1 << 1;
-
- /**
- * Purpose: signing.
- */
- public static final int SIGN = 1 << 2;
-
- /**
- * Purpose: signature verification.
- */
- public static final int VERIFY = 1 << 3;
-
- /**
- * @hide
- */
- public static int toKeymaster(@PurposeEnum int purpose) {
- switch (purpose) {
- case ENCRYPT:
- return KeymasterDefs.KM_PURPOSE_ENCRYPT;
- case DECRYPT:
- return KeymasterDefs.KM_PURPOSE_DECRYPT;
- case SIGN:
- return KeymasterDefs.KM_PURPOSE_SIGN;
- case VERIFY:
- return KeymasterDefs.KM_PURPOSE_VERIFY;
- default:
- throw new IllegalArgumentException("Unknown purpose: " + purpose);
- }
- }
-
- /**
- * @hide
- */
- public static @PurposeEnum int fromKeymaster(int purpose) {
- switch (purpose) {
- case KeymasterDefs.KM_PURPOSE_ENCRYPT:
- return ENCRYPT;
- case KeymasterDefs.KM_PURPOSE_DECRYPT:
- return DECRYPT;
- case KeymasterDefs.KM_PURPOSE_SIGN:
- return SIGN;
- case KeymasterDefs.KM_PURPOSE_VERIFY:
- return VERIFY;
- default:
- throw new IllegalArgumentException("Unknown purpose: " + purpose);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- public static int[] allToKeymaster(@PurposeEnum int purposes) {
- int[] result = getSetFlags(purposes);
- for (int i = 0; i < result.length; i++) {
- result[i] = toKeymaster(result[i]);
- }
- return result;
- }
-
- /**
- * @hide
- */
- public static @PurposeEnum int allFromKeymaster(@NonNull Collection<Integer> purposes) {
- @PurposeEnum int result = 0;
- for (int keymasterPurpose : purposes) {
- result |= fromKeymaster(keymasterPurpose);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @StringDef({
- Algorithm.RSA,
- Algorithm.EC,
- Algorithm.AES,
- Algorithm.HMAC_SHA1,
- Algorithm.HMAC_SHA224,
- Algorithm.HMAC_SHA256,
- Algorithm.HMAC_SHA384,
- Algorithm.HMAC_SHA512,
- })
- public @interface AlgorithmEnum {}
-
- /**
- * Key algorithms.
- *
- * <p>These are standard names which can be used to obtain instances of {@link KeyGenerator},
- * {@link KeyPairGenerator}, {@link Cipher} (as part of the transformation string), {@link Mac},
- * {@link KeyFactory}, {@link SecretKeyFactory}. These are also the names used by
- * {@link Key#getAlgorithm()}.
- */
- public static abstract class Algorithm {
- private Algorithm() {}
-
- /** Rivest Shamir Adleman (RSA) key. */
- public static final String RSA = "RSA";
-
- /** Elliptic Curve (EC) key. */
- public static final String EC = "EC";
-
- /** Advanced Encryption Standard (AES) key. */
- public static final String AES = "AES";
-
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */
- public static final String HMAC_SHA1 = "HmacSHA1";
-
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */
- public static final String HMAC_SHA224 = "HmacSHA224";
-
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */
- public static final String HMAC_SHA256 = "HmacSHA256";
-
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */
- public static final String HMAC_SHA384 = "HmacSHA384";
-
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */
- public static final String HMAC_SHA512 = "HmacSHA512";
-
- /**
- * @hide
- */
- static int toKeymasterSecretKeyAlgorithm(@NonNull @AlgorithmEnum String algorithm) {
- if (AES.equalsIgnoreCase(algorithm)) {
- return KeymasterDefs.KM_ALGORITHM_AES;
- } else if (algorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
- return KeymasterDefs.KM_ALGORITHM_HMAC;
- } else {
- throw new IllegalArgumentException(
- "Unsupported secret key algorithm: " + algorithm);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @AlgorithmEnum String fromKeymasterSecretKeyAlgorithm(
- int keymasterAlgorithm, int keymasterDigest) {
- switch (keymasterAlgorithm) {
- case KeymasterDefs.KM_ALGORITHM_AES:
- if (keymasterDigest != -1) {
- throw new IllegalArgumentException("Digest not supported for AES key: "
- + Digest.fromKeymaster(keymasterDigest));
- }
- return AES;
- case KeymasterDefs.KM_ALGORITHM_HMAC:
- switch (keymasterDigest) {
- case KeymasterDefs.KM_DIGEST_SHA1:
- return HMAC_SHA1;
- case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return HMAC_SHA224;
- case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return HMAC_SHA256;
- case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return HMAC_SHA384;
- case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return HMAC_SHA512;
- default:
- throw new IllegalArgumentException("Unsupported HMAC digest: "
- + Digest.fromKeymaster(keymasterDigest));
- }
- default:
- throw new IllegalArgumentException(
- "Unsupported algorithm: " + keymasterAlgorithm);
- }
- }
-
- /**
- * @hide
- *
- * @return keymaster digest or {@code -1} if the algorithm does not involve a digest.
- */
- static int toKeymasterDigest(@NonNull @AlgorithmEnum String algorithm) {
- String algorithmUpper = algorithm.toUpperCase(Locale.US);
- if (algorithmUpper.startsWith("HMAC")) {
- String digestUpper = algorithmUpper.substring("HMAC".length());
- switch (digestUpper) {
- case "SHA1":
- return KeymasterDefs.KM_DIGEST_SHA1;
- case "SHA224":
- return KeymasterDefs.KM_DIGEST_SHA_2_224;
- case "SHA256":
- return KeymasterDefs.KM_DIGEST_SHA_2_256;
- case "SHA384":
- return KeymasterDefs.KM_DIGEST_SHA_2_384;
- case "SHA512":
- return KeymasterDefs.KM_DIGEST_SHA_2_512;
- default:
- throw new IllegalArgumentException(
- "Unsupported HMAC digest: " + digestUpper);
- }
- } else {
- return -1;
- }
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @StringDef({
- BlockMode.ECB,
- BlockMode.CBC,
- BlockMode.CTR,
- BlockMode.GCM,
- })
- public @interface BlockModeEnum {}
-
- /**
- * Block modes that can be used when encrypting/decrypting using a key.
- */
- public static abstract class BlockMode {
- private BlockMode() {}
-
- /** Electronic Codebook (ECB) block mode. */
- public static final String ECB = "ECB";
-
- /** Cipher Block Chaining (CBC) block mode. */
- public static final String CBC = "CBC";
-
- /** Counter (CTR) block mode. */
- public static final String CTR = "CTR";
-
- /** Galois/Counter Mode (GCM) block mode. */
- public static final String GCM = "GCM";
-
- /**
- * @hide
- */
- static int toKeymaster(@NonNull @BlockModeEnum String blockMode) {
- if (ECB.equalsIgnoreCase(blockMode)) {
- return KeymasterDefs.KM_MODE_ECB;
- } else if (CBC.equalsIgnoreCase(blockMode)) {
- return KeymasterDefs.KM_MODE_CBC;
- } else if (CTR.equalsIgnoreCase(blockMode)) {
- return KeymasterDefs.KM_MODE_CTR;
- } else if (GCM.equalsIgnoreCase(blockMode)) {
- return KeymasterDefs.KM_MODE_GCM;
- } else {
- throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @BlockModeEnum String fromKeymaster(int blockMode) {
- switch (blockMode) {
- case KeymasterDefs.KM_MODE_ECB:
- return ECB;
- case KeymasterDefs.KM_MODE_CBC:
- return CBC;
- case KeymasterDefs.KM_MODE_CTR:
- return CTR;
- case KeymasterDefs.KM_MODE_GCM:
- return GCM;
- default:
- throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @BlockModeEnum String[] allFromKeymaster(@NonNull Collection<Integer> blockModes) {
- if ((blockModes == null) || (blockModes.isEmpty())) {
- return EmptyArray.STRING;
- }
- @BlockModeEnum String[] result = new String[blockModes.size()];
- int offset = 0;
- for (int blockMode : blockModes) {
- result[offset] = fromKeymaster(blockMode);
- offset++;
- }
- return result;
- }
-
- /**
- * @hide
- */
- static int[] allToKeymaster(@Nullable @BlockModeEnum String[] blockModes) {
- if ((blockModes == null) || (blockModes.length == 0)) {
- return EmptyArray.INT;
- }
- int[] result = new int[blockModes.length];
- for (int i = 0; i < blockModes.length; i++) {
- result[i] = toKeymaster(blockModes[i]);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @StringDef({
- EncryptionPadding.NONE,
- EncryptionPadding.PKCS7,
- EncryptionPadding.RSA_PKCS1,
- EncryptionPadding.RSA_OAEP,
- })
- public @interface EncryptionPaddingEnum {}
-
- /**
- * Padding schemes for encryption/decryption.
- */
- public static abstract class EncryptionPadding {
- private EncryptionPadding() {}
-
- /**
- * No padding.
- */
- public static final String NONE = "NoPadding";
-
- /**
- * PKCS#7 padding.
- */
- public static final String PKCS7 = "PKCS7Padding";
-
- /**
- * RSA PKCS#1 v1.5 padding for encryption/decryption.
- */
- public static final String RSA_PKCS1 = "PKCS1Padding";
-
- /**
- * RSA Optimal Asymmetric Encryption Padding (OAEP).
- */
- public static final String RSA_OAEP = "OAEPPadding";
-
- /**
- * @hide
- */
- static int toKeymaster(@NonNull @EncryptionPaddingEnum String padding) {
- if (NONE.equalsIgnoreCase(padding)) {
- return KeymasterDefs.KM_PAD_NONE;
- } else if (PKCS7.equalsIgnoreCase(padding)) {
- return KeymasterDefs.KM_PAD_PKCS7;
- } else if (RSA_PKCS1.equalsIgnoreCase(padding)) {
- return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
- } else if (RSA_OAEP.equalsIgnoreCase(padding)) {
- return KeymasterDefs.KM_PAD_RSA_OAEP;
- } else {
- throw new IllegalArgumentException(
- "Unsupported encryption padding scheme: " + padding);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @EncryptionPaddingEnum String fromKeymaster(int padding) {
- switch (padding) {
- case KeymasterDefs.KM_PAD_NONE:
- return NONE;
- case KeymasterDefs.KM_PAD_PKCS7:
- return PKCS7;
- case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
- return RSA_PKCS1;
- case KeymasterDefs.KM_PAD_RSA_OAEP:
- return RSA_OAEP;
- default:
- throw new IllegalArgumentException(
- "Unsupported encryption padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static int[] allToKeymaster(@Nullable @EncryptionPaddingEnum String[] paddings) {
- if ((paddings == null) || (paddings.length == 0)) {
- return EmptyArray.INT;
- }
- int[] result = new int[paddings.length];
- for (int i = 0; i < paddings.length; i++) {
- result[i] = toKeymaster(paddings[i]);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @StringDef({
- SignaturePadding.RSA_PKCS1,
- SignaturePadding.RSA_PSS,
- })
- public @interface SignaturePaddingEnum {}
-
- /**
- * Padding schemes for signing/verification.
- */
- public static abstract class SignaturePadding {
- private SignaturePadding() {}
-
- /**
- * RSA PKCS#1 v1.5 padding for signatures.
- */
- public static final String RSA_PKCS1 = "PKCS1";
-
- /**
- * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
- */
- public static final String RSA_PSS = "PSS";
-
- /**
- * @hide
- */
- static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) {
- switch (padding.toUpperCase(Locale.US)) {
- case RSA_PKCS1:
- return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
- case RSA_PSS:
- return KeymasterDefs.KM_PAD_RSA_PSS;
- default:
- throw new IllegalArgumentException(
- "Unsupported signature padding scheme: " + padding);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @SignaturePaddingEnum String fromKeymaster(int padding) {
- switch (padding) {
- case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
- return RSA_PKCS1;
- case KeymasterDefs.KM_PAD_RSA_PSS:
- return RSA_PSS;
- default:
- throw new IllegalArgumentException("Unsupported signature padding: " + padding);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) {
- if ((paddings == null) || (paddings.length == 0)) {
- return EmptyArray.INT;
- }
- int[] result = new int[paddings.length];
- for (int i = 0; i < paddings.length; i++) {
- result[i] = toKeymaster(paddings[i]);
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @StringDef({
- Digest.NONE,
- Digest.MD5,
- Digest.SHA1,
- Digest.SHA224,
- Digest.SHA256,
- Digest.SHA384,
- Digest.SHA512,
- })
- public @interface DigestEnum {}
-
- /**
- * Digests that can be used with a key when signing or generating Message Authentication
- * Codes (MACs).
- */
- public static abstract class Digest {
- private Digest() {}
-
- /**
- * No digest: sign/authenticate the raw message.
- */
- public static final String NONE = "NONE";
-
- /**
- * MD5 digest.
- */
- public static final String MD5 = "MD5";
-
- /**
- * SHA-1 digest.
- */
- public static final String SHA1 = "SHA-1";
-
- /**
- * SHA-2 224 (aka SHA-224) digest.
- */
- public static final String SHA224 = "SHA-224";
-
- /**
- * SHA-2 256 (aka SHA-256) digest.
- */
- public static final String SHA256 = "SHA-256";
-
- /**
- * SHA-2 384 (aka SHA-384) digest.
- */
- public static final String SHA384 = "SHA-384";
-
- /**
- * SHA-2 512 (aka SHA-512) digest.
- */
- public static final String SHA512 = "SHA-512";
-
- /**
- * @hide
- */
- static int toKeymaster(@NonNull @DigestEnum String digest) {
- switch (digest.toUpperCase(Locale.US)) {
- case SHA1:
- return KeymasterDefs.KM_DIGEST_SHA1;
- case SHA224:
- return KeymasterDefs.KM_DIGEST_SHA_2_224;
- case SHA256:
- return KeymasterDefs.KM_DIGEST_SHA_2_256;
- case SHA384:
- return KeymasterDefs.KM_DIGEST_SHA_2_384;
- case SHA512:
- return KeymasterDefs.KM_DIGEST_SHA_2_512;
- case NONE:
- return KeymasterDefs.KM_DIGEST_NONE;
- case MD5:
- return KeymasterDefs.KM_DIGEST_MD5;
- default:
- throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @DigestEnum String fromKeymaster(int digest) {
- switch (digest) {
- case KeymasterDefs.KM_DIGEST_NONE:
- return NONE;
- case KeymasterDefs.KM_DIGEST_MD5:
- return MD5;
- case KeymasterDefs.KM_DIGEST_SHA1:
- return SHA1;
- case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return SHA224;
- case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return SHA256;
- case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return SHA384;
- case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return SHA512;
- default:
- throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
- }
- }
-
- /**
- * @hide
- */
- @NonNull
- static @DigestEnum String[] allFromKeymaster(@NonNull Collection<Integer> digests) {
- if (digests.isEmpty()) {
- return EmptyArray.STRING;
- }
- String[] result = new String[digests.size()];
- int offset = 0;
- for (int digest : digests) {
- result[offset] = fromKeymaster(digest);
- offset++;
- }
- return result;
- }
-
- /**
- * @hide
- */
- @NonNull
- static int[] allToKeymaster(@Nullable @DigestEnum String[] digests) {
- if ((digests == null) || (digests.length == 0)) {
- return EmptyArray.INT;
- }
- int[] result = new int[digests.length];
- int offset = 0;
- for (@DigestEnum String digest : digests) {
- result[offset] = toKeymaster(digest);
- offset++;
- }
- return result;
- }
- }
-
- @Retention(RetentionPolicy.SOURCE)
- @IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
- public @interface OriginEnum {}
-
- /**
- * Origin of the key.
- */
- public static abstract class Origin {
- private Origin() {}
-
- /** Key was generated inside AndroidKeyStore. */
- public static final int GENERATED = 1 << 0;
-
- /** Key was imported into AndroidKeyStore. */
- public static final int IMPORTED = 1 << 1;
-
- /**
- * Origin of the key is unknown. This can occur only for keys backed by an old TEE-backed
- * implementation which does not record origin information.
- */
- public static final int UNKNOWN = 1 << 2;
-
- /**
- * @hide
- */
- public static @OriginEnum int fromKeymaster(int origin) {
- switch (origin) {
- case KeymasterDefs.KM_ORIGIN_GENERATED:
- return GENERATED;
- case KeymasterDefs.KM_ORIGIN_IMPORTED:
- return IMPORTED;
- case KeymasterDefs.KM_ORIGIN_UNKNOWN:
- return UNKNOWN;
- default:
- throw new IllegalArgumentException("Unknown origin: " + origin);
- }
- }
- }
-
- private static int[] getSetFlags(int flags) {
- if (flags == 0) {
- return EmptyArray.INT;
- }
- int result[] = new int[getSetBitCount(flags)];
- int resultOffset = 0;
- int flag = 1;
- while (flags != 0) {
- if ((flags & 1) != 0) {
- result[resultOffset] = flag;
- resultOffset++;
- }
- flags >>>= 1;
- flag <<= 1;
- }
- return result;
- }
-
- private static int getSetBitCount(int value) {
- if (value == 0) {
- return 0;
- }
- int result = 0;
- while (value != 0) {
- if ((value & 1) != 0) {
- result++;
- }
- value >>>= 1;
- }
- return result;
- }
-}
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 4a736c3..174e03f 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -16,145 +16,51 @@
package android.security;
-import android.annotation.IntRange;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProtection;
-import java.security.Key;
+import java.security.KeyPairGenerator;
import java.security.KeyStore.ProtectionParameter;
-import java.security.cert.Certificate;
-import java.util.Date;
-
-import javax.crypto.Cipher;
/**
- * Parameters specifying how to secure and restrict the use of a key or key pair being imported into
- * the <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
- * specifies whether user authentication is required for using the key, what uses the key is
- * authorized for (e.g., only in {@code CTR} mode, or only for signing -- decryption not permitted),
- * whether the key should be encrypted at rest, the key's and validity start and end dates.
+ * This provides the optional parameters that can be specified for
+ * {@code KeyStore} entries that work with
+ * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore
+ * facility</a>. The Android KeyStore facility is accessed through a
+ * {@link java.security.KeyStore} API using the {@code AndroidKeyStore}
+ * provider. The {@code context} passed in may be used to pop up some UI to ask
+ * the user to unlock or initialize the Android KeyStore facility.
+ * <p>
+ * Any entries placed in the {@code KeyStore} may be retrieved later. Note that
+ * there is only one logical instance of the {@code KeyStore} per application
+ * UID so apps using the {@code sharedUid} facility will also share a
+ * {@code KeyStore}.
+ * <p>
+ * Keys may be generated using the {@link KeyPairGenerator} facility with a
+ * {@link KeyPairGeneratorSpec} to specify the entry's {@code alias}. A
+ * self-signed X.509 certificate will be attached to generated entries, but that
+ * may be replaced at a later time by a certificate signed by a real Certificate
+ * Authority.
*
- * <p>To import a key or key pair into the Android KeyStore, create an instance of this class using
- * the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry}
- * with the key or key pair being imported.
- *
- * <p>To obtain the secret/symmetric or private key from the Android KeyStore use
- * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
- * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
- * To obtain the public key from the Android KeyStore use
- * {@link java.security.KeyStore#getCertificate(String)} and then
- * {@link Certificate#getPublicKey()}.
- *
- * <p>NOTE: The key material of keys stored in the Android KeyStore is not accessible.
- *
- * <p><h3>Example: Symmetric Key</h3>
- * The following example illustrates how to import an AES key into the Android KeyStore under alias
- * {@code key1} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
- * padding. The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
- * <pre> {@code
- * SecretKey key = ...; // AES key
- *
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * keyStore.setEntry(
- * "key1",
- * new KeyStore.SecretKeyEntry(key),
- * new KeyStoreParameter.Builder(context)
- * .setPurposes(KeyStoreKeyProperties.Purpose.ENCRYPT
- * | KeyStoreKeyProperties.Purpose.DECRYPT)
- * .setBlockMode(KeyStoreKeyProperties.BlockMode.CBC)
- * .setEncryptionPaddings(
- * KeyStoreKeyProperties.EncryptionPaddings.PKCS7)
- * .build());
- * // Key imported, obtain a reference to it.
- * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
- * // The original key can now be thrown away.
- * }</pre>
- *
- * <p><h3>Example: Asymmetric Key Pair</h3>
- * The following example illustrates how to import an EC key pair into the Android KeyStore under
- * alias {@code key2} authorized to be used only for signing with SHA-256 digest and only if
- * the user has been authenticated within the last ten minutes. Both the private and the public key
- * must export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509}
- * format respectively.
- * <pre> {@code
- * PrivateKey privateKey = ...; // EC private key
- * Certificate[] certChain = ...; // Certificate chain with the first certificate
- * // containing the corresponding EC public key.
- *
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * keyStore.setEntry(
- * "key2",
- * new KeyStore.PrivateKeyEntry(privateKey, certChain),
- * new KeyStoreParameter.Builder(context)
- * .setPurposes(KeyStoreKeyProperties.Purpose.SIGN)
- * .setDigests(KeyStoreKeyProperties.Digest.SHA256)
- * // Only permit this key to be used if the user
- * // authenticated within the last ten minutes.
- * .setUserAuthenticationRequired(true)
- * .setUserAuthenticationValidityDurationSeconds(10 * 60)
- * .build());
- * // Key pair imported, obtain a reference to it.
- * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
- * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * // The original private key can now be thrown away.
- * }</pre>
+ * @deprecated Use {@link KeyProtection} instead.
*/
+@Deprecated
public final class KeyStoreParameter implements ProtectionParameter {
private final Context mContext;
private final int mFlags;
- private final Date mKeyValidityStart;
- private final Date mKeyValidityForOriginationEnd;
- private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
- private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
- private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
- private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
- private final boolean mRandomizedEncryptionRequired;
- private final boolean mUserAuthenticationRequired;
- private final int mUserAuthenticationValidityDurationSeconds;
private KeyStoreParameter(
Context context,
- int flags,
- Date keyValidityStart,
- Date keyValidityForOriginationEnd,
- Date keyValidityForConsumptionEnd,
- @KeyStoreKeyProperties.PurposeEnum int purposes,
- @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
- @KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
- @KeyStoreKeyProperties.DigestEnum String[] digests,
- @KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
- boolean randomizedEncryptionRequired,
- boolean userAuthenticationRequired,
- int userAuthenticationValidityDurationSeconds) {
+ int flags) {
if (context == null) {
throw new IllegalArgumentException("context == null");
- } else if ((userAuthenticationValidityDurationSeconds < 0)
- && (userAuthenticationValidityDurationSeconds != -1)) {
- throw new IllegalArgumentException(
- "userAuthenticationValidityDurationSeconds must not be negative");
}
mContext = context;
mFlags = flags;
- mKeyValidityStart = keyValidityStart;
- mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
- mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
- mPurposes = purposes;
- mEncryptionPaddings =
- ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
- mSignaturePaddings =
- ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
- mDigests = ArrayUtils.cloneIfNotEmpty(digests);
- mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
- mRandomizedEncryptionRequired = randomizedEncryptionRequired;
- mUserAuthenticationRequired = userAuthenticationRequired;
- mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
}
/**
@@ -175,135 +81,20 @@
* Returns {@code true} if the {@link java.security.KeyStore} entry must be encrypted at rest.
* This will protect the entry with the secure lock screen credential (e.g., password, PIN, or
* pattern).
+ *
+ * <p>Note that encrypting the key at rest requires that the secure lock screen (e.g., password,
+ * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be
+ * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device
+ * Administrator). Finally, this key cannot be used until the user unlocks the secure lock
+ * screen after boot.
+ *
+ * @see KeyguardManager#isDeviceSecure()
*/
public boolean isEncryptionRequired() {
return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0;
}
/**
- * Gets the time instant before which the key is not yet valid.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityStart() {
- return mKeyValidityStart;
- }
-
- /**
- * Gets the time instant after which the key is no long valid for decryption and verification.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForConsumptionEnd() {
- return mKeyValidityForConsumptionEnd;
- }
-
- /**
- * Gets the time instant after which the key is no long valid for encryption and signing.
- *
- * @return instant or {@code null} if not restricted.
- */
- @Nullable
- public Date getKeyValidityForOriginationEnd() {
- return mKeyValidityForOriginationEnd;
- }
-
- /**
- * Gets the set of purposes for which the key can be used.
- */
- public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
- return mPurposes;
- }
-
- /**
- * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
- */
- @NonNull
- public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
- return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
- }
-
- /**
- * Gets the set of padding schemes with which the key can be used when signing or verifying
- * signatures.
- */
- @NonNull
- public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
- return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
- }
-
- /**
- * Gets the set of digest algorithms with which the key can be used.
- *
- * @throws IllegalStateException if this set has not been specified.
- *
- * @see #isDigestsSpecified()
- */
- @NonNull
- public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
- if (mDigests == null) {
- throw new IllegalStateException("Digests not specified");
- }
- return ArrayUtils.cloneIfNotEmpty(mDigests);
- }
-
- /**
- * Returns {@code true} if the set of digest algorithms with which the key can be used has been
- * specified.
- *
- * @see #getDigests()
- */
- @NonNull
- public boolean isDigestsSpecified() {
- return mDigests != null;
- }
-
- /**
- * Gets the set of block modes with which the key can be used.
- */
- @NonNull
- public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
- return ArrayUtils.cloneIfNotEmpty(mBlockModes);
- }
-
- /**
- * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic property
- * being required is <em>indistinguishability under chosen-plaintext attack ({@code
- * IND-CPA})</em>. This property is important because it mitigates several classes of
- * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
- * given plaintext always produces the same ciphertext, an attacker may see the repeated
- * ciphertexts and be able to deduce something about the plaintext.
- */
- public boolean isRandomizedEncryptionRequired() {
- return mRandomizedEncryptionRequired;
- }
-
- /**
- * Returns {@code true} if user authentication is required for this key to be used.
- *
- * @see #getUserAuthenticationValidityDurationSeconds()
- */
- public boolean isUserAuthenticationRequired() {
- return mUserAuthenticationRequired;
- }
-
- /**
- * Gets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * @return duration in seconds or {@code -1} if authentication is required for every use of the
- * key.
- *
- * @see #isUserAuthenticationRequired()
- */
- public int getUserAuthenticationValidityDurationSeconds() {
- return mUserAuthenticationValidityDurationSeconds;
- }
-
- /**
* Builder class for {@link KeyStoreParameter} objects.
* <p>
* This will build protection parameters for use with the
@@ -316,24 +107,16 @@
*
* <pre class="prettyprint">
* KeyStoreParameter params = new KeyStoreParameter.Builder(mContext)
- * .setEncryptionRequired(true)
+ * .setEncryptionRequired()
* .build();
* </pre>
+ *
+ * @deprecated Use {@link KeyProtection.Builder} instead.
*/
+ @Deprecated
public final static class Builder {
private final Context mContext;
private int mFlags;
- private Date mKeyValidityStart;
- private Date mKeyValidityForOriginationEnd;
- private Date mKeyValidityForConsumptionEnd;
- private @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
- private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
- private @KeyStoreKeyProperties.DigestEnum String[] mDigests;
- private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
- private boolean mRandomizedEncryptionRequired = true;
- private boolean mUserAuthenticationRequired;
- private int mUserAuthenticationValidityDurationSeconds = -1;
/**
* Creates a new instance of the {@code Builder} with the given
@@ -372,230 +155,6 @@
}
/**
- * Sets the time instant before which the key is not yet valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @see #setKeyValidityEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityStart(Date startDate) {
- mKeyValidityStart = startDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @see #setKeyValidityStart(Date)
- * @see #setKeyValidityForConsumptionEnd(Date)
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityEnd(Date endDate) {
- setKeyValidityForOriginationEnd(endDate);
- setKeyValidityForConsumptionEnd(endDate);
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for encryption and signing.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @see #setKeyValidityForConsumptionEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForOriginationEnd(Date endDate) {
- mKeyValidityForOriginationEnd = endDate;
- return this;
- }
-
- /**
- * Sets the time instant after which the key is no longer valid for decryption and
- * verification.
- *
- * <p>By default, the key is valid at any instant.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @see #setKeyValidityForOriginationEnd(Date)
- */
- @NonNull
- public Builder setKeyValidityForConsumptionEnd(Date endDate) {
- mKeyValidityForConsumptionEnd = endDate;
- return this;
- }
-
- /**
- * Sets the set of purposes for which the key can be used.
- *
- * <p>This must be specified for all keys. There is no default.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
- mPurposes = purposes;
- return this;
- }
-
- /**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
- *
- * <p>This must be specified for keys which are used for encryption/decryption.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setEncryptionPaddings(
- @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
- mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
- return this;
- }
-
- /**
- * Sets the set of padding schemes with which the key can be used when
- * signing/verifying. Attempts to use the key with any other padding scheme will be
- * rejected.
- *
- * <p>This must be specified for RSA keys which are used for signing/verification.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setSignaturePaddings(
- @KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
- mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
- return this;
- }
-
-
- /**
- * Sets the set of digests with which the key can be used when signing/verifying or
- * generating MACs. Attempts to use the key with any other digest will be rejected.
- *
- * <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For
- * asymmetric signing keys this constraint must be specified.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
- mDigests = ArrayUtils.cloneIfNotEmpty(digests);
- return this;
- }
-
- /**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
- *
- * <p>This must be specified for encryption/decryption keys.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
- mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
- return this;
- }
-
- /**
- * Sets whether encryption using this key must be sufficiently randomized to produce
- * different ciphertexts for the same plaintext every time. The formal cryptographic
- * property being required is <em>indistinguishability under chosen-plaintext attack
- * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
- * of weaknesses due to which ciphertext may leak information about plaintext. For example,
- * if a given plaintext always produces the same ciphertext, an attacker may see the
- * repeated ciphertexts and be able to deduce something about the plaintext.
- *
- * <p>By default, {@code IND-CPA} is required.
- *
- * <p>When {@code IND-CPA} is required:
- * <ul>
- * <li>transformation which do not offer {@code IND-CPA}, such as symmetric ciphers using
- * {@code ECB} mode or RSA encryption without padding, are prohibited;</li>
- * <li>in transformations which use an IV, such as symmetric ciphers in {@code CBC},
- * {@code CTR}, and {@code GCM} block modes, caller-provided IVs are rejected when
- * encrypting, to ensure that only random IVs are used.</li>
- *
- * <p>Before disabling this requirement, consider the following approaches instead:
- * <ul>
- * <li>If you are generating a random IV for encryption and then initializing a {@code}
- * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
- * instead. This will occur if the {@code Cipher} is initialized for encryption without an
- * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
- * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
- * random, such as the name of the file being encrypted, or transaction ID, or password,
- * or a device identifier), consider changing your design to use a random IV which will then
- * be provided in addition to the ciphertext to the entities which need to decrypt the
- * ciphertext.</li>
- * <li>If you are using RSA encryption without padding, consider switching to padding
- * schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
- * </ul>
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- */
- @NonNull
- public Builder setRandomizedEncryptionRequired(boolean required) {
- mRandomizedEncryptionRequired = required;
- return this;
- }
-
- /**
- * Sets whether user authentication is required to use this key.
- *
- * <p>By default, the key can be used without user authentication.
- *
- * <p>When user authentication is required, the user authorizes the use of the key by
- * authenticating to this Android device using a subset of their secure lock screen
- * credentials. Different authentication methods are used depending on whether the every
- * use of the key must be authenticated (as specified by
- * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
- * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
- * information</a>.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @see #setUserAuthenticationValidityDurationSeconds(int)
- */
- @NonNull
- public Builder setUserAuthenticationRequired(boolean required) {
- mUserAuthenticationRequired = required;
- return this;
- }
-
- /**
- * Sets the duration of time (seconds) for which this key can be used after the user is
- * successfully authenticated. This has effect only if user authentication is required.
- *
- * <p>By default, the user needs to authenticate for every use of the key.
- *
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
- *
- * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
- * every use of the key.
- *
- * @see #setUserAuthenticationRequired(boolean)
- */
- @NonNull
- public Builder setUserAuthenticationValidityDurationSeconds(
- @IntRange(from = -1) int seconds) {
- mUserAuthenticationValidityDurationSeconds = seconds;
- return this;
- }
-
- /**
* Builds the instance of the {@code KeyStoreParameter}.
*
* @throws IllegalArgumentException if a required field is missing
@@ -605,18 +164,7 @@
public KeyStoreParameter build() {
return new KeyStoreParameter(
mContext,
- mFlags,
- mKeyValidityStart,
- mKeyValidityForOriginationEnd,
- mKeyValidityForConsumptionEnd,
- mPurposes,
- mEncryptionPaddings,
- mSignaturePaddings,
- mDigests,
- mBlockModes,
- mRandomizedEncryptionRequired,
- mUserAuthenticationRequired,
- mUserAuthenticationValidityDurationSeconds);
+ mFlags);
}
}
}
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/keystore/AndroidKeyPairGeneratorSpi.java
similarity index 61%
rename from keystore/java/android/security/AndroidKeyPairGenerator.java
rename to keystore/java/android/security/keystore/AndroidKeyPairGeneratorSpi.java
index 3f29c6a..2c393fd 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/keystore/AndroidKeyPairGeneratorSpi.java
@@ -14,7 +14,12 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+
+import android.annotation.NonNull;
+import android.security.Credentials;
+import android.security.KeyPairGeneratorSpec;
+import android.security.KeyStore;
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
import com.android.org.conscrypt.NativeConstants;
@@ -36,6 +41,7 @@
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAKeyGenParameterSpec;
import java.security.spec.X509EncodedKeySpec;
+import java.util.Locale;
/**
* Provides a way to create instances of a KeyPair which will be placed in the
@@ -50,17 +56,17 @@
*
* {@hide}
*/
-public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
+public abstract class AndroidKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
- public static class RSA extends AndroidKeyPairGenerator {
+ public static class RSA extends AndroidKeyPairGeneratorSpi {
public RSA() {
- super(KeyStoreKeyProperties.Algorithm.RSA);
+ super(KeyProperties.KEY_ALGORITHM_RSA);
}
}
- public static class EC extends AndroidKeyPairGenerator {
+ public static class EC extends AndroidKeyPairGeneratorSpi {
public EC() {
- super(KeyStoreKeyProperties.Algorithm.EC);
+ super(KeyProperties.KEY_ALGORITHM_EC);
}
}
@@ -80,18 +86,19 @@
private final String mAlgorithm;
- private android.security.KeyStore mKeyStore;
+ private KeyStore mKeyStore;
- private KeyPairGeneratorSpec mSpec;
- private @KeyStoreKeyProperties.AlgorithmEnum String mKeyAlgorithm;
+ private KeyGenParameterSpec mSpec;
+ private boolean mEncryptionAtRestRequired;
+ private @KeyProperties.KeyAlgorithmEnum String mKeyAlgorithm;
private int mKeyType;
private int mKeySize;
- protected AndroidKeyPairGenerator(@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ protected AndroidKeyPairGeneratorSpi(@KeyProperties.KeyAlgorithmEnum String algorithm) {
mAlgorithm = algorithm;
}
- public @KeyStoreKeyProperties.AlgorithmEnum String getAlgorithm() {
+ @KeyProperties.KeyAlgorithmEnum String getAlgorithm() {
return mAlgorithm;
}
@@ -113,15 +120,16 @@
@Override
public KeyPair generateKeyPair() {
if (mKeyStore == null || mSpec == null) {
- throw new IllegalStateException(
- "Must call initialize with an android.security.KeyPairGeneratorSpec first");
+ throw new IllegalStateException("Not initialized");
+
}
- if (((mSpec.getFlags() & KeyStore.FLAG_ENCRYPTED) != 0)
+ final int flags = (mEncryptionAtRestRequired) ? KeyStore.FLAG_ENCRYPTED : 0;
+ if (((flags & KeyStore.FLAG_ENCRYPTED) != 0)
&& (mKeyStore.state() != KeyStore.State.UNLOCKED)) {
throw new IllegalStateException(
- "Android keystore must be in initialized and unlocked state "
- + "if encryption is required");
+ "Encryption at rest using secure lock screen credential requested for key pair"
+ + ", but the user has not yet entered the credential");
}
final String alias = mSpec.getKeystoreAlias();
@@ -131,8 +139,9 @@
byte[][] args = getArgsForKeyType(mKeyType, mSpec.getAlgorithmParameterSpec());
final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias;
+
if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mKeyType, mKeySize,
- mSpec.getFlags(), args)) {
+ flags, args)) {
throw new IllegalStateException("could not generate key in keystore");
}
@@ -175,7 +184,7 @@
}
if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, certBytes, KeyStore.UID_SELF,
- mSpec.getFlags())) {
+ flags)) {
Credentials.deleteAllTypesForAlias(mKeyStore, alias);
throw new IllegalStateException("Can't store certificate in AndroidKeyStore");
}
@@ -188,16 +197,17 @@
throws Exception {
final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setPublicKey(publicKey);
- certGen.setSerialNumber(mSpec.getSerialNumber());
- certGen.setSubjectDN(mSpec.getSubjectDN());
- certGen.setIssuerDN(mSpec.getSubjectDN());
- certGen.setNotBefore(mSpec.getStartDate());
- certGen.setNotAfter(mSpec.getEndDate());
+ certGen.setSerialNumber(mSpec.getCertificateSerialNumber());
+ certGen.setSubjectDN(mSpec.getCertificateSubject());
+ certGen.setIssuerDN(mSpec.getCertificateSubject());
+ certGen.setNotBefore(mSpec.getCertificateNotBefore());
+ certGen.setNotAfter(mSpec.getCertificateNotAfter());
certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyAlgorithm(mKeyAlgorithm));
return certGen.generate(privateKey);
}
- private @KeyStoreKeyProperties.AlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
+ @NonNull
+ private @KeyProperties.KeyAlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
String result = spec.getKeyType();
if (result != null) {
return result;
@@ -249,10 +259,10 @@
}
private static String getDefaultSignatureAlgorithmForKeyAlgorithm(
- @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
- if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(algorithm)) {
+ @KeyProperties.KeyAlgorithmEnum String algorithm) {
+ if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) {
return "sha256WithRSA";
- } else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(algorithm)) {
+ } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) {
return "sha256WithECDSA";
} else {
throw new IllegalArgumentException("Unsupported key type " + algorithm);
@@ -281,14 +291,87 @@
throws InvalidAlgorithmParameterException {
if (params == null) {
throw new InvalidAlgorithmParameterException(
- "must supply params of type android.security.KeyPairGeneratorSpec");
- } else if (!(params instanceof KeyPairGeneratorSpec)) {
- throw new InvalidAlgorithmParameterException(
- "params must be of type android.security.KeyPairGeneratorSpec");
+ "Must supply params of type " + KeyGenParameterSpec.class.getName()
+ + " or " + KeyPairGeneratorSpec.class.getName());
}
- KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
- @KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithm = getKeyAlgorithm(spec);
+ String keyAlgorithm;
+ KeyGenParameterSpec spec;
+ boolean encryptionAtRestRequired = false;
+ if (params instanceof KeyPairGeneratorSpec) {
+ KeyPairGeneratorSpec legacySpec = (KeyPairGeneratorSpec) params;
+ try {
+ KeyGenParameterSpec.Builder specBuilder;
+ keyAlgorithm = getKeyAlgorithm(legacySpec).toUpperCase(Locale.US);
+ if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+ specBuilder = new KeyGenParameterSpec.Builder(
+ legacySpec.getKeystoreAlias(),
+ KeyProperties.PURPOSE_SIGN
+ | KeyProperties.PURPOSE_VERIFY);
+ specBuilder.setDigests(
+ KeyProperties.DIGEST_NONE,
+ KeyProperties.DIGEST_MD5,
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA224,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA384,
+ KeyProperties.DIGEST_SHA512);
+ } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+ specBuilder = new KeyGenParameterSpec.Builder(
+ legacySpec.getKeystoreAlias(),
+ KeyProperties.PURPOSE_ENCRYPT
+ | KeyProperties.PURPOSE_DECRYPT
+ | KeyProperties.PURPOSE_SIGN
+ | KeyProperties.PURPOSE_VERIFY);
+ specBuilder.setDigests(
+ KeyProperties.DIGEST_NONE,
+ KeyProperties.DIGEST_MD5,
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA224,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA384,
+ KeyProperties.DIGEST_SHA512);
+ specBuilder.setSignaturePaddings(
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+ specBuilder.setBlockModes(KeyProperties.BLOCK_MODE_ECB);
+ specBuilder.setEncryptionPaddings(
+ KeyProperties.ENCRYPTION_PADDING_NONE,
+ KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
+ // Disable randomized encryption requirement to support encryption padding NONE
+ // above.
+ specBuilder.setRandomizedEncryptionRequired(false);
+ } else {
+ throw new InvalidAlgorithmParameterException(
+ "Unsupported key algorithm: " + keyAlgorithm);
+ }
+
+ if (legacySpec.getKeySize() != -1) {
+ specBuilder.setKeySize(legacySpec.getKeySize());
+ }
+ if (legacySpec.getAlgorithmParameterSpec() != null) {
+ specBuilder.setAlgorithmParameterSpec(legacySpec.getAlgorithmParameterSpec());
+ }
+ specBuilder.setCertificateSubject(legacySpec.getSubjectDN());
+ specBuilder.setCertificateSerialNumber(legacySpec.getSerialNumber());
+ specBuilder.setCertificateNotBefore(legacySpec.getStartDate());
+ specBuilder.setCertificateNotAfter(legacySpec.getEndDate());
+ encryptionAtRestRequired = legacySpec.isEncryptionRequired();
+ specBuilder.setUserAuthenticationRequired(false);
+
+ spec = specBuilder.build();
+ } catch (NullPointerException | IllegalArgumentException e) {
+ throw new InvalidAlgorithmParameterException(e);
+ }
+ } else if (params instanceof KeyGenParameterSpec) {
+ spec = (KeyGenParameterSpec) params;
+ keyAlgorithm = getAlgorithm();
+ } else {
+ throw new InvalidAlgorithmParameterException(
+ "Unsupported params class: " + params.getClass().getName()
+ + ". Supported: " + KeyGenParameterSpec.class.getName()
+ + ", " + KeyPairGeneratorSpec.class);
+ }
+
int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm);
if (keyType == -1) {
throw new InvalidAlgorithmParameterException(
@@ -299,7 +382,7 @@
keySize = getDefaultKeySize(keyType);
if (keySize == -1) {
throw new InvalidAlgorithmParameterException(
- "Unsupported key algorithm: " + keyAlgorithm);
+ "Unsupported key algorithm: " + keyAlgorithm);
}
}
checkCorrectParametersSpec(keyType, keySize, spec.getAlgorithmParameterSpec());
@@ -309,6 +392,7 @@
mKeyType = keyType;
mKeySize = keySize;
mSpec = spec;
- mKeyStore = android.security.KeyStore.getInstance();
+ mEncryptionAtRestRequired = encryptionAtRestRequired;
+ mKeyStore = KeyStore.getInstance();
}
}
diff --git a/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
similarity index 75%
rename from keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
index 45329cf..3774e36 100644
--- a/keystore/java/android/security/AndroidKeyStoreBCWorkaroundProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.Provider;
@@ -40,9 +40,9 @@
// classes when this provider is instantiated and installed early on during each app's
// initialization process.
- private static final String PACKAGE_NAME = "android.security";
+ private static final String PACKAGE_NAME = "android.security.keystore";
private static final String KEYSTORE_SECRET_KEY_CLASS_NAME =
- PACKAGE_NAME + ".KeyStoreSecretKey";
+ PACKAGE_NAME + ".AndroidKeyStoreSecretKey";
AndroidKeyStoreBCWorkaroundProvider() {
super("AndroidKeyStoreBCWorkaround",
@@ -50,25 +50,25 @@
"Android KeyStore security provider to work around Bouncy Castle");
// javax.crypto.Mac
- putMacImpl("HmacSHA1", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA1");
- putMacImpl("HmacSHA224", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA224");
- putMacImpl("HmacSHA256", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA256");
- putMacImpl("HmacSHA384", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA384");
- putMacImpl("HmacSHA512", PACKAGE_NAME + ".KeyStoreHmacSpi$HmacSHA512");
+ putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1");
+ putMacImpl("HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA224");
+ putMacImpl("HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA256");
+ putMacImpl("HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA384");
+ putMacImpl("HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA512");
// javax.crypto.Cipher
putSymmetricCipherImpl("AES/ECB/NoPadding",
- PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$NoPadding");
+ PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$ECB$NoPadding");
putSymmetricCipherImpl("AES/ECB/PKCS7Padding",
- PACKAGE_NAME + ".KeyStoreCipherSpi$AES$ECB$PKCS7Padding");
+ PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$ECB$PKCS7Padding");
putSymmetricCipherImpl("AES/CBC/NoPadding",
- PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$NoPadding");
+ PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CBC$NoPadding");
putSymmetricCipherImpl("AES/CBC/PKCS7Padding",
- PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CBC$PKCS7Padding");
+ PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CBC$PKCS7Padding");
putSymmetricCipherImpl("AES/CTR/NoPadding",
- PACKAGE_NAME + ".KeyStoreCipherSpi$AES$CTR$NoPadding");
+ PACKAGE_NAME + ".AndroidKeyStoreCipherSpi$AES$CTR$NoPadding");
}
private void putMacImpl(String algorithm, String implClass) {
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpi.java
similarity index 97%
rename from keystore/java/android/security/KeyStoreCipherSpi.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreCipherSpi.java
index bd601bc..27df5e7 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpi.java
@@ -14,12 +14,15 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import android.os.IBinder;
+import android.security.KeyStore;
+import android.security.KeyStoreException;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
+import android.security.keystore.KeyProperties;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
@@ -47,9 +50,10 @@
*
* @hide
*/
-public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCryptoOperation {
+public abstract class AndroidKeyStoreCipherSpi extends CipherSpi
+ implements KeyStoreCryptoOperation {
- public abstract static class AES extends KeyStoreCipherSpi {
+ public abstract static class AES extends AndroidKeyStoreCipherSpi {
protected AES(int keymasterBlockMode, int keymasterPadding, boolean ivUsed) {
super(KeymasterDefs.KM_ALGORITHM_AES,
keymasterBlockMode,
@@ -119,7 +123,7 @@
// Fields below are populated by Cipher.init and KeyStore.begin and should be preserved after
// doFinal finishes.
protected boolean mEncrypting;
- private KeyStoreSecretKey mKey;
+ private AndroidKeyStoreSecretKey mKey;
private SecureRandom mRng;
private boolean mFirstOperationInitiated;
private byte[] mIv;
@@ -146,7 +150,7 @@
*/
private Exception mCachedException;
- protected KeyStoreCipherSpi(
+ protected AndroidKeyStoreCipherSpi(
int keymasterAlgorithm,
int keymasterBlockMode,
int keymasterPadding,
@@ -218,11 +222,11 @@
}
private void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
- if (!(key instanceof KeyStoreSecretKey)) {
+ if (!(key instanceof AndroidKeyStoreSecretKey)) {
throw new InvalidKeyException(
"Unsupported key: " + ((key != null) ? key.getClass().getName() : "null"));
}
- mKey = (KeyStoreSecretKey) key;
+ mKey = (AndroidKeyStoreSecretKey) key;
mRng = random;
mIv = null;
mFirstOperationInitiated = false;
@@ -496,7 +500,7 @@
if ((mIv != null) && (mIv.length > 0)) {
try {
AlgorithmParameters params =
- AlgorithmParameters.getInstance(KeyStoreKeyProperties.Algorithm.AES);
+ AlgorithmParameters.getInstance(KeyProperties.KEY_ALGORITHM_AES);
params.init(new IvParameterSpec(mIv));
return params;
} catch (NoSuchAlgorithmException e) {
diff --git a/keystore/java/android/security/KeyStoreHmacSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
similarity index 90%
rename from keystore/java/android/security/KeyStoreHmacSpi.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
index 5089a25..b82a7f5 100644
--- a/keystore/java/android/security/KeyStoreHmacSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreHmacSpi.java
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import android.os.IBinder;
+import android.security.KeyStore;
+import android.security.KeyStoreException;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
import android.security.keymaster.OperationResult;
@@ -34,33 +36,33 @@
*
* @hide
*/
-public abstract class KeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation {
+public abstract class AndroidKeyStoreHmacSpi extends MacSpi implements KeyStoreCryptoOperation {
- public static class HmacSHA1 extends KeyStoreHmacSpi {
+ public static class HmacSHA1 extends AndroidKeyStoreHmacSpi {
public HmacSHA1() {
super(KeymasterDefs.KM_DIGEST_SHA1);
}
}
- public static class HmacSHA224 extends KeyStoreHmacSpi {
+ public static class HmacSHA224 extends AndroidKeyStoreHmacSpi {
public HmacSHA224() {
super(KeymasterDefs.KM_DIGEST_SHA_2_224);
}
}
- public static class HmacSHA256 extends KeyStoreHmacSpi {
+ public static class HmacSHA256 extends AndroidKeyStoreHmacSpi {
public HmacSHA256() {
super(KeymasterDefs.KM_DIGEST_SHA_2_256);
}
}
- public static class HmacSHA384 extends KeyStoreHmacSpi {
+ public static class HmacSHA384 extends AndroidKeyStoreHmacSpi {
public HmacSHA384() {
super(KeymasterDefs.KM_DIGEST_SHA_2_384);
}
}
- public static class HmacSHA512 extends KeyStoreHmacSpi {
+ public static class HmacSHA512 extends AndroidKeyStoreHmacSpi {
public HmacSHA512() {
super(KeymasterDefs.KM_DIGEST_SHA_2_512);
}
@@ -71,14 +73,14 @@
private final int mMacSizeBits;
// Fields below are populated by engineInit and should be preserved after engineDoFinal.
- private KeyStoreSecretKey mKey;
+ private AndroidKeyStoreSecretKey mKey;
// Fields below are reset when engineDoFinal succeeds.
private KeyStoreCryptoOperationChunkedStreamer mChunkedStreamer;
private IBinder mOperationToken;
private long mOperationHandle;
- protected KeyStoreHmacSpi(int keymasterDigest) {
+ protected AndroidKeyStoreHmacSpi(int keymasterDigest) {
mKeymasterDigest = keymasterDigest;
mMacSizeBits = KeymasterUtils.getDigestOutputSizeBits(keymasterDigest);
}
@@ -109,11 +111,11 @@
InvalidAlgorithmParameterException {
if (key == null) {
throw new InvalidKeyException("key == null");
- } else if (!(key instanceof KeyStoreSecretKey)) {
+ } else if (!(key instanceof AndroidKeyStoreSecretKey)) {
throw new InvalidKeyException(
"Only Android KeyStore secret keys supported. Key: " + key);
}
- mKey = (KeyStoreSecretKey) key;
+ mKey = (AndroidKeyStoreSecretKey) key;
if (params != null) {
throw new InvalidAlgorithmParameterException(
diff --git a/keystore/java/android/security/KeyStoreKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java
similarity index 88%
rename from keystore/java/android/security/KeyStoreKey.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreKey.java
index 7a34829..6098e5c 100644
--- a/keystore/java/android/security/KeyStoreKey.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.Key;
@@ -23,11 +23,11 @@
*
* @hide
*/
-public class KeyStoreKey implements Key {
+public class AndroidKeyStoreKey implements Key {
private final String mAlias;
private final String mAlgorithm;
- public KeyStoreKey(String alias, String algorithm) {
+ public AndroidKeyStoreKey(String alias, String algorithm) {
mAlias = alias;
mAlgorithm = algorithm;
}
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
similarity index 65%
rename from keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 4b914c2..dc4c8a3 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -14,16 +14,23 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+import android.security.Credentials;
+import android.security.KeyStore;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+
+import libcore.util.EmptyArray;
import java.security.InvalidAlgorithmParameterException;
import java.security.ProviderException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
+import java.util.Arrays;
import java.util.Date;
import javax.crypto.KeyGeneratorSpi;
@@ -34,9 +41,9 @@
*
* @hide
*/
-public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
+public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
- public static class AES extends KeyStoreKeyGeneratorSpi {
+ public static class AES extends AndroidKeyStoreKeyGeneratorSpi {
public AES() {
super(KeymasterDefs.KM_ALGORITHM_AES, 128);
}
@@ -53,7 +60,7 @@
}
}
- protected static abstract class HmacBase extends KeyStoreKeyGeneratorSpi {
+ protected static abstract class HmacBase extends AndroidKeyStoreKeyGeneratorSpi {
protected HmacBase(int keymasterDigest) {
super(KeymasterDefs.KM_ALGORITHM_HMAC,
keymasterDigest,
@@ -96,21 +103,22 @@
private final int mKeymasterDigest;
private final int mDefaultKeySizeBits;
- private KeyGeneratorSpec mSpec;
+ private KeyGenParameterSpec mSpec;
private SecureRandom mRng;
protected int mKeySizeBits;
private int[] mKeymasterPurposes;
private int[] mKeymasterBlockModes;
private int[] mKeymasterPaddings;
+ private int[] mKeymasterDigests;
- protected KeyStoreKeyGeneratorSpi(
+ protected AndroidKeyStoreKeyGeneratorSpi(
int keymasterAlgorithm,
int defaultKeySizeBits) {
this(keymasterAlgorithm, -1, defaultKeySizeBits);
}
- protected KeyStoreKeyGeneratorSpi(
+ protected AndroidKeyStoreKeyGeneratorSpi(
int keymasterAlgorithm,
int keymasterDigest,
int defaultKeySizeBits) {
@@ -129,14 +137,14 @@
@Override
protected void engineInit(SecureRandom random) {
- throw new UnsupportedOperationException("Cannot initialize without an "
- + KeyGeneratorSpec.class.getName() + " parameter");
+ throw new UnsupportedOperationException("Cannot initialize without a "
+ + KeyGenParameterSpec.class.getName() + " parameter");
}
@Override
protected void engineInit(int keySize, SecureRandom random) {
throw new UnsupportedOperationException("Cannot initialize without a "
- + KeyGeneratorSpec.class.getName() + " parameter");
+ + KeyGenParameterSpec.class.getName() + " parameter");
}
@Override
@@ -146,11 +154,11 @@
boolean success = false;
try {
- if ((params == null) || (!(params instanceof KeyGeneratorSpec))) {
- throw new InvalidAlgorithmParameterException("Cannot initialize without an "
- + KeyGeneratorSpec.class.getName() + " parameter");
+ if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
+ throw new InvalidAlgorithmParameterException("Cannot initialize without a "
+ + KeyGenParameterSpec.class.getName() + " parameter");
}
- KeyGeneratorSpec spec = (KeyGeneratorSpec) params;
+ KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
if (spec.getKeystoreAlias() == null) {
throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
}
@@ -168,13 +176,11 @@
}
try {
- mKeymasterPurposes =
- KeyStoreKeyProperties.Purpose.allToKeymaster(spec.getPurposes());
- mKeymasterPaddings = KeyStoreKeyProperties.EncryptionPadding.allToKeymaster(
+ mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
+ mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
spec.getEncryptionPaddings());
- mKeymasterBlockModes =
- KeyStoreKeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
- if (((spec.getPurposes() & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
+ if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (spec.isRandomizedEncryptionRequired())) {
for (int keymasterBlockMode : mKeymasterBlockModes) {
if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(
@@ -182,14 +188,55 @@
throw new InvalidAlgorithmParameterException(
"Randomized encryption (IND-CPA) required but may be violated"
+ " by block mode: "
- + KeyStoreKeyProperties.BlockMode.fromKeymaster(
- keymasterBlockMode)
- + ". See " + KeyGeneratorSpec.class.getName()
+ + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
+ + ". See " + KeyGenParameterSpec.class.getName()
+ " documentation.");
}
}
}
- } catch (IllegalArgumentException e) {
+ if (spec.isDigestsSpecified()) {
+ // Digest(s) explicitly specified in the spec
+ mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
+ if (mKeymasterDigest != -1) {
+ // Key algorithm implies a digest -- ensure it's specified in the spec as
+ // first digest.
+ if (!com.android.internal.util.ArrayUtils.contains(
+ mKeymasterDigests, mKeymasterDigest)) {
+ throw new InvalidAlgorithmParameterException(
+ "Digests specified in algorithm parameters ("
+ + Arrays.asList(spec.getDigests()) + ") must include "
+ + " the digest "
+ + KeyProperties.Digest.fromKeymaster(mKeymasterDigest)
+ + " implied by key algorithm");
+ }
+ if (mKeymasterDigests[0] != mKeymasterDigest) {
+ // The first digest is not the one implied by the key algorithm.
+ // Swap the implied digest with the first one.
+ for (int i = 0; i < mKeymasterDigests.length; i++) {
+ if (mKeymasterDigests[i] == mKeymasterDigest) {
+ mKeymasterDigests[i] = mKeymasterDigests[0];
+ mKeymasterDigests[0] = mKeymasterDigest;
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ // No digest specified in the spec
+ if (mKeymasterDigest != -1) {
+ // Key algorithm implies a digest -- use that digest
+ mKeymasterDigests = new int[] {mKeymasterDigest};
+ } else {
+ mKeymasterDigests = EmptyArray.INT;
+ }
+ }
+ if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
+ if (mKeymasterDigests.length == 0) {
+ throw new InvalidAlgorithmParameterException(
+ "At least one digest algorithm must be specified");
+ }
+ }
+ } catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -212,29 +259,19 @@
@Override
protected SecretKey engineGenerateKey() {
- KeyGeneratorSpec spec = mSpec;
+ KeyGenParameterSpec spec = mSpec;
if (spec == null) {
throw new IllegalStateException("Not initialized");
}
- if ((spec.isEncryptionRequired())
- && (mKeyStore.state() != KeyStore.State.UNLOCKED)) {
- throw new IllegalStateException(
- "Android KeyStore must be in initialized and unlocked state if encryption is"
- + " required");
- }
-
KeymasterArguments args = new KeymasterArguments();
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits);
args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm);
- if (mKeymasterDigest != -1) {
- args.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest);
- }
args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes);
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
+ args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
KeymasterUtils.addUserAuthArgs(args,
- spec.getContext(),
spec.isUserAuthenticationRequired(),
spec.getUserAuthenticationValidityDurationSeconds());
args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
@@ -247,7 +284,7 @@
(spec.getKeyValidityForConsumptionEnd() != null)
? spec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE));
- if (((spec.getPurposes() & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!spec.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
@@ -256,7 +293,7 @@
byte[] additionalEntropy =
KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
mRng, (mKeySizeBits + 7) / 8);
- int flags = spec.getFlags();
+ int flags = 0;
String keyAliasInKeystore = Credentials.USER_SECRET_KEY + spec.getKeystoreAlias();
KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
int errorCode = mKeyStore.generateKey(
@@ -265,13 +302,13 @@
throw new ProviderException(
"Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
}
- String keyAlgorithmJCA;
+ @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA;
try {
- keyAlgorithmJCA = KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
+ keyAlgorithmJCA = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
mKeymasterAlgorithm, mKeymasterDigest);
} catch (IllegalArgumentException e) {
throw new ProviderException("Failed to obtain JCA secret key algorithm name", e);
}
- return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA);
+ return new AndroidKeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmJCA);
}
}
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
similarity index 84%
rename from keystore/java/android/security/AndroidKeyStoreProvider.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
index 257ab54..b20a122 100644
--- a/keystore/java/android/security/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreProvider.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+
+import android.security.KeyStore;
import java.security.Provider;
import java.security.Security;
@@ -38,25 +40,25 @@
// Instead, they need to be offered by AndroidKeyStoreBCWorkaroundProvider. See its Javadoc
// for details.
- private static final String PACKAGE_NAME = "android.security";
+ private static final String PACKAGE_NAME = "android.security.keystore";
public AndroidKeyStoreProvider() {
super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
// java.security.KeyStore
- put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStore");
+ put("KeyStore.AndroidKeyStore", PACKAGE_NAME + ".AndroidKeyStoreSpi");
// java.security.KeyPairGenerator
- put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyPairGenerator$EC");
- put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyPairGenerator$RSA");
+ put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyPairGeneratorSpi$EC");
+ put("KeyPairGenerator.RSA", PACKAGE_NAME + ".AndroidKeyPairGeneratorSpi$RSA");
// javax.crypto.KeyGenerator
- put("KeyGenerator.AES", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$AES");
- put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA1");
- put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA224");
- put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA256");
- put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA384");
- put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".KeyStoreKeyGeneratorSpi$HmacSHA512");
+ put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES");
+ put("KeyGenerator.HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA1");
+ put("KeyGenerator.HmacSHA224", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA224");
+ put("KeyGenerator.HmacSHA256", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA256");
+ put("KeyGenerator.HmacSHA384", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA384");
+ put("KeyGenerator.HmacSHA512", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$HmacSHA512");
// java.security.SecretKeyFactory
putSecretKeyFactoryImpl("AES");
@@ -95,7 +97,7 @@
}
private void putSecretKeyFactoryImpl(String algorithm) {
- put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".KeyStoreSecretKeyFactorySpi");
+ put("SecretKeyFactory." + algorithm, PACKAGE_NAME + ".AndroidKeyStoreSecretKeyFactorySpi");
}
/**
diff --git a/keystore/java/android/security/KeyStoreSecretKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java
similarity index 79%
rename from keystore/java/android/security/KeyStoreSecretKey.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java
index ee25465..f75516b 100644
--- a/keystore/java/android/security/KeyStoreSecretKey.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import javax.crypto.SecretKey;
@@ -23,9 +23,9 @@
*
* @hide
*/
-public class KeyStoreSecretKey extends KeyStoreKey implements SecretKey {
+public class AndroidKeyStoreSecretKey extends AndroidKeyStoreKey implements SecretKey {
- public KeyStoreSecretKey(String alias, String algorithm) {
+ public AndroidKeyStoreSecretKey(String alias, String algorithm) {
super(alias, algorithm);
}
}
diff --git a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
similarity index 86%
rename from keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
index 548296b..455f170 100644
--- a/keystore/java/android/security/KeyStoreSecretKeyFactorySpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKeyFactorySpi.java
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+import android.security.Credentials;
+import android.security.KeyStore;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterDefs;
@@ -37,7 +39,7 @@
*
* @hide
*/
-public class KeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
+public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
private final KeyStore mKeyStore = KeyStore.getInstance();
@@ -47,7 +49,7 @@
if (keySpecClass == null) {
throw new InvalidKeySpecException("keySpecClass == null");
}
- if (!(key instanceof KeyStoreSecretKey)) {
+ if (!(key instanceof AndroidKeyStoreSecretKey)) {
throw new InvalidKeySpecException("Only Android KeyStore secret keys supported: " +
((key != null) ? key.getClass().getName() : "null"));
}
@@ -55,10 +57,10 @@
throw new InvalidKeySpecException(
"Key material export of Android KeyStore keys is not supported");
}
- if (!KeyStoreKeySpec.class.equals(keySpecClass)) {
+ if (!KeyInfo.class.equals(keySpecClass)) {
throw new InvalidKeySpecException("Unsupported key spec: " + keySpecClass.getName());
}
- String keyAliasInKeystore = ((KeyStoreSecretKey) key).getAlias();
+ String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias();
String entryAlias;
if (keyAliasInKeystore.startsWith(Credentials.USER_SECRET_KEY)) {
entryAlias = keyAliasInKeystore.substring(Credentials.USER_SECRET_KEY.length());
@@ -75,22 +77,22 @@
}
boolean insideSecureHardware;
- @KeyStoreKeyProperties.OriginEnum int origin;
+ @KeyProperties.OriginEnum int origin;
int keySize;
- @KeyStoreKeyProperties.PurposeEnum int purposes;
+ @KeyProperties.PurposeEnum int purposes;
String[] encryptionPaddings;
- @KeyStoreKeyProperties.DigestEnum String[] digests;
- @KeyStoreKeyProperties.BlockModeEnum String[] blockModes;
+ @KeyProperties.DigestEnum String[] digests;
+ @KeyProperties.BlockModeEnum String[] blockModes;
int keymasterSwEnforcedUserAuthenticators;
int keymasterHwEnforcedUserAuthenticators;
try {
if (keyCharacteristics.hwEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = true;
- origin = KeyStoreKeyProperties.Origin.fromKeymaster(
+ origin = KeyProperties.Origin.fromKeymaster(
keyCharacteristics.hwEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else if (keyCharacteristics.swEnforced.containsTag(KeymasterDefs.KM_TAG_ORIGIN)) {
insideSecureHardware = false;
- origin = KeyStoreKeyProperties.Origin.fromKeymaster(
+ origin = KeyProperties.Origin.fromKeymaster(
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_ORIGIN, -1));
} else {
throw new InvalidKeySpecException("Key origin not available");
@@ -100,15 +102,14 @@
throw new InvalidKeySpecException("Key size not available");
}
keySize = keySizeInteger;
- purposes = KeyStoreKeyProperties.Purpose.allFromKeymaster(
+ purposes = KeyProperties.Purpose.allFromKeymaster(
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PURPOSE));
List<String> encryptionPaddingsList = new ArrayList<String>();
for (int keymasterPadding : keyCharacteristics.getInts(KeymasterDefs.KM_TAG_PADDING)) {
- @KeyStoreKeyProperties.EncryptionPaddingEnum String jcaPadding;
+ @KeyProperties.EncryptionPaddingEnum String jcaPadding;
try {
- jcaPadding =
- KeyStoreKeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
+ jcaPadding = KeyProperties.EncryptionPadding.fromKeymaster(keymasterPadding);
} catch (IllegalArgumentException e) {
throw new InvalidKeySpecException(
"Unsupported encryption padding: " + keymasterPadding);
@@ -118,9 +119,9 @@
encryptionPaddings =
encryptionPaddingsList.toArray(new String[encryptionPaddingsList.size()]);
- digests = KeyStoreKeyProperties.Digest.allFromKeymaster(
+ digests = KeyProperties.Digest.allFromKeymaster(
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_DIGEST));
- blockModes = KeyStoreKeyProperties.BlockMode.allFromKeymaster(
+ blockModes = KeyProperties.BlockMode.allFromKeymaster(
keyCharacteristics.getInts(KeymasterDefs.KM_TAG_BLOCK_MODE));
keymasterSwEnforcedUserAuthenticators =
keyCharacteristics.swEnforced.getInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, 0);
@@ -154,7 +155,7 @@
&& (keymasterHwEnforcedUserAuthenticators != 0)
&& (keymasterSwEnforcedUserAuthenticators == 0);
- return new KeyStoreKeySpec(entryAlias,
+ return new KeyInfo(entryAlias,
insideSecureHardware,
origin,
keySize,
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
similarity index 81%
rename from keystore/java/android/security/AndroidKeyStore.java
rename to keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 69d80e6..f159c30 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -14,16 +14,20 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import com.android.org.conscrypt.OpenSSLEngine;
import com.android.org.conscrypt.OpenSSLKeyHolder;
import libcore.util.EmptyArray;
+import android.security.Credentials;
+import android.security.KeyStoreParameter;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
import android.util.Log;
import java.io.ByteArrayInputStream;
@@ -79,7 +83,7 @@
*
* @hide
*/
-public class AndroidKeyStore extends KeyStoreSpi {
+public class AndroidKeyStoreSpi extends KeyStoreSpi {
public static final String NAME = "AndroidKeyStore";
private android.security.KeyStore mKeyStore;
@@ -129,17 +133,16 @@
keymasterDigest = keymasterDigests.get(0);
}
- @KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithmString;
+ @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
try {
- keyAlgorithmString =
- KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
- keymasterAlgorithm, keymasterDigest);
+ keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
+ keymasterAlgorithm, keymasterDigest);
} catch (IllegalArgumentException e) {
throw (UnrecoverableKeyException)
new UnrecoverableKeyException("Unsupported secret key type").initCause(e);
}
- return new KeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmString);
+ return new AndroidKeyStoreSecretKey(keyAliasInKeystore, keyAlgorithmString);
}
return null;
@@ -270,7 +273,73 @@
}
private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain,
- KeyStoreParameter params) throws KeyStoreException {
+ java.security.KeyStore.ProtectionParameter param) throws KeyStoreException {
+ int flags = 0;
+ KeyProtection spec;
+ if (param instanceof KeyStoreParameter) {
+ KeyStoreParameter legacySpec = (KeyStoreParameter) param;
+ try {
+ String keyAlgorithm = key.getAlgorithm();
+ KeyProtection.Builder specBuilder;
+ if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+ specBuilder =
+ new KeyProtection.Builder(
+ KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY);
+ specBuilder.setDigests(
+ KeyProperties.DIGEST_NONE,
+ KeyProperties.DIGEST_MD5,
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA224,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA384,
+ KeyProperties.DIGEST_SHA512);
+ } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+ specBuilder =
+ new KeyProtection.Builder(
+ KeyProperties.PURPOSE_ENCRYPT
+ | KeyProperties.PURPOSE_DECRYPT
+ | KeyProperties.PURPOSE_SIGN
+ | KeyProperties.PURPOSE_VERIFY);
+ specBuilder.setDigests(
+ KeyProperties.DIGEST_NONE,
+ KeyProperties.DIGEST_MD5,
+ KeyProperties.DIGEST_SHA1,
+ KeyProperties.DIGEST_SHA224,
+ KeyProperties.DIGEST_SHA256,
+ KeyProperties.DIGEST_SHA384,
+ KeyProperties.DIGEST_SHA512);
+ specBuilder.setSignaturePaddings(
+ KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+ specBuilder.setBlockModes(KeyProperties.BLOCK_MODE_ECB);
+ specBuilder.setEncryptionPaddings(
+ KeyProperties.ENCRYPTION_PADDING_NONE,
+ KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
+ // Disable randomized encryption requirement to support encryption padding NONE
+ // above.
+ specBuilder.setRandomizedEncryptionRequired(false);
+ } else {
+ throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm);
+ }
+ if (legacySpec.isEncryptionRequired()) {
+ flags = android.security.KeyStore.FLAG_ENCRYPTED;
+ }
+ specBuilder.setUserAuthenticationRequired(false);
+
+ spec = specBuilder.build();
+ } catch (NullPointerException | IllegalArgumentException e) {
+ throw new KeyStoreException("Unsupported protection parameter", e);
+ }
+ } else if (param instanceof KeyProtection) {
+ spec = (KeyProtection) param;
+ } else if (param != null) {
+ throw new KeyStoreException(
+ "Unsupported protection parameter class:" + param.getClass().getName()
+ + ". Supported: " + KeyStoreParameter.class.getName() + ", "
+ + KeyProtection.class.getName());
+ } else {
+ spec = null;
+ }
+
byte[] keyBytes = null;
final String pkeyAlias;
@@ -383,8 +452,6 @@
Credentials.deleteSecretKeyTypeForAlias(mKeyStore, alias);
}
- final int flags = (params == null) ? 0 : params.getFlags();
-
if (shouldReplacePrivateKey
&& !mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes,
android.security.KeyStore.UID_SELF, flags)) {
@@ -402,12 +469,20 @@
}
}
- private void setSecretKeyEntry(String entryAlias, SecretKey key, KeyStoreParameter params)
+ private void setSecretKeyEntry(String entryAlias, SecretKey key,
+ java.security.KeyStore.ProtectionParameter param)
throws KeyStoreException {
- if (key instanceof KeyStoreSecretKey) {
+ if ((param != null) && (!(param instanceof KeyProtection))) {
+ throw new KeyStoreException(
+ "Unsupported protection parameter class: " + param.getClass().getName()
+ + ". Supported: " + KeyProtection.class.getName());
+ }
+ KeyProtection params = (KeyProtection) param;
+
+ if (key instanceof AndroidKeyStoreSecretKey) {
// KeyStore-backed secret key. It cannot be duplicated into another entry and cannot
// overwrite its own entry.
- String keyAliasInKeystore = ((KeyStoreSecretKey) key).getAlias();
+ String keyAliasInKeystore = ((AndroidKeyStoreSecretKey) key).getAlias();
if (keyAliasInKeystore == null) {
throw new KeyStoreException("KeyStore-backed secret key does not have an alias");
}
@@ -453,10 +528,9 @@
int keymasterAlgorithm;
int keymasterDigest;
try {
- keymasterAlgorithm = KeyStoreKeyProperties.Algorithm.toKeymasterSecretKeyAlgorithm(
- keyAlgorithmString);
- keymasterDigest =
- KeyStoreKeyProperties.Algorithm.toKeymasterDigest(keyAlgorithmString);
+ keymasterAlgorithm =
+ KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(keyAlgorithmString);
+ keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString);
} catch (IllegalArgumentException e) {
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
}
@@ -467,7 +541,7 @@
int[] keymasterDigests;
if (params.isDigestsSpecified()) {
// Digest(s) specified in parameters
- keymasterDigests = KeyStoreKeyProperties.Digest.allToKeymaster(params.getDigests());
+ keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests());
if (keymasterDigest != -1) {
// Digest also specified in the JCA key algorithm name.
if (!com.android.internal.util.ArrayUtils.contains(
@@ -476,6 +550,21 @@
+ ". Key: " + keyAlgorithmString
+ ", parameter spec: " + Arrays.asList(params.getDigests()));
}
+ // When the key is read back from keystore we reconstruct the JCA key algorithm
+ // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to
+ // ensure that the digest reflected in the JCA key algorithm name is the first
+ // KM_TAG_DIGEST tag.
+ if (keymasterDigests[0] != keymasterDigest) {
+ // The first digest is not the one implied by the JCA key algorithm name.
+ // Swap the implied digest with the first one.
+ for (int i = 0; i < keymasterDigests.length; i++) {
+ if (keymasterDigests[i] == keymasterDigest) {
+ keymasterDigests[i] = keymasterDigests[0];
+ keymasterDigests[0] = keymasterDigest;
+ break;
+ }
+ }
+ }
}
} else {
// No digest specified in parameters
@@ -494,33 +583,32 @@
}
}
- @KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes();
+ @KeyProperties.PurposeEnum int purposes = params.getPurposes();
int[] keymasterBlockModes =
- KeyStoreKeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
- if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ KeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
+ if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (params.isRandomizedEncryptionRequired())) {
for (int keymasterBlockMode : keymasterBlockModes) {
if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) {
throw new KeyStoreException(
"Randomized encryption (IND-CPA) required but may be violated by block"
+ " mode: "
- + KeyStoreKeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
- + ". See KeyStoreParameter documentation.");
+ + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
+ + ". See KeyProtection documentation.");
}
}
}
- for (int keymasterPurpose : KeyStoreKeyProperties.Purpose.allToKeymaster(purposes)) {
+ for (int keymasterPurpose : KeyProperties.Purpose.allToKeymaster(purposes)) {
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
}
args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes);
if (params.getSignaturePaddings().length > 0) {
throw new KeyStoreException("Signature paddings not supported for symmetric keys");
}
- int[] keymasterPaddings = KeyStoreKeyProperties.EncryptionPadding.allToKeymaster(
+ int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
params.getEncryptionPaddings());
args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
KeymasterUtils.addUserAuthArgs(args,
- params.getContext(),
params.isUserAuthenticationRequired(),
params.getUserAuthenticationValidityDurationSeconds());
args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
@@ -536,7 +624,7 @@
// TODO: Remove this once keymaster does not require us to specify the size of imported key.
args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keyMaterial.length * 8);
- if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!params.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
@@ -549,7 +637,7 @@
args,
KeymasterDefs.KM_KEY_FORMAT_RAW,
keyMaterial,
- params.getFlags(),
+ 0, // flags
new KeyCharacteristics());
if (errorCode != android.security.KeyStore.NO_ERROR) {
throw new KeyStoreException("Failed to import secret key. Keystore error code: "
@@ -774,19 +862,12 @@
return;
}
- if (param != null && !(param instanceof KeyStoreParameter)) {
- throw new KeyStoreException(
- "protParam should be android.security.KeyStoreParameter; was: "
- + param.getClass().getName());
- }
-
if (entry instanceof PrivateKeyEntry) {
PrivateKeyEntry prE = (PrivateKeyEntry) entry;
- setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(),
- (KeyStoreParameter) param);
+ setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(), param);
} else if (entry instanceof SecretKeyEntry) {
SecretKeyEntry secE = (SecretKeyEntry) entry;
- setSecretKeyEntry(alias, secE.getSecretKey(), (KeyStoreParameter) param);
+ setSecretKeyEntry(alias, secE.getSecretKey(), param);
} else {
throw new KeyStoreException(
"Entry must be a PrivateKeyEntry, SecretKeyEntry or TrustedCertificateEntry"
diff --git a/keystore/java/android/security/ArrayUtils.java b/keystore/java/android/security/keystore/ArrayUtils.java
similarity index 73%
rename from keystore/java/android/security/ArrayUtils.java
rename to keystore/java/android/security/keystore/ArrayUtils.java
index 2047d3f..81be3848 100644
--- a/keystore/java/android/security/ArrayUtils.java
+++ b/keystore/java/android/security/keystore/ArrayUtils.java
@@ -1,11 +1,27 @@
-package android.security;
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
import libcore.util.EmptyArray;
/**
* @hide
*/
-abstract class ArrayUtils {
+public abstract class ArrayUtils {
private ArrayUtils() {}
public static String[] nullToEmpty(String[] array) {
diff --git a/keystore/java/android/security/KeyExpiredException.java b/keystore/java/android/security/keystore/KeyExpiredException.java
similarity index 97%
rename from keystore/java/android/security/KeyExpiredException.java
rename to keystore/java/android/security/keystore/KeyExpiredException.java
index f58e48a..15b8d67 100644
--- a/keystore/java/android/security/KeyExpiredException.java
+++ b/keystore/java/android/security/keystore/KeyExpiredException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.InvalidKeyException;
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
new file mode 100644
index 0000000..1d4c188
--- /dev/null
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -0,0 +1,804 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.text.TextUtils;
+
+import java.math.BigInteger;
+import java.security.KeyPairGenerator;
+import java.security.cert.Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.Date;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.security.auth.x500.X500Principal;
+
+/**
+ * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} or a
+ * {@link KeyGenerator} of the <a href="{@docRoot}training/articles/keystore.html">Android Keystore
+ * system</a>. The spec determines whether user authentication is required for using the key, what
+ * uses the key is authorized for (e.g., only for signing -- decryption not permitted), the key's
+ * validity start and end dates.
+ *
+ * <p>To generate an asymmetric key pair or a symmetric key, create an instance of this class using
+ * the {@link Builder}, initialize a {@code KeyPairGenerator} or a {@code KeyGenerator} of the
+ * desired key type (e.g., {@code EC} or {@code AES} -- see
+ * {@link KeyProperties}.{@code KEY_ALGORITHM} constants) from the {@code AndroidKeyStore} provider
+ * with the {@code KeyPairGeneratorSpec} instance, and then generate a key or key pair using
+ * {@link KeyPairGenerator#generateKeyPair()}.
+ *
+ * <p>The generated key pair or key will be returned by the generator and also stored in the Android
+ * Keystore system under the alias specified in this spec. To obtain the secret or private key from
+ * the Android KeyStore use {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)}
+ * or {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
+ * To obtain the public key from the Android Keystore system use
+ * {@link java.security.KeyStore#getCertificate(String)} and then
+ * {@link Certificate#getPublicKey()}.
+ *
+ * <p>For asymmetric key pairs, a self-signed X.509 certificate will be also generated and stored in
+ * the Android KeyStore. This is because the {@link java.security.KeyStore} abstraction does not
+ * support storing key pairs without a certificate. The subject, serial number, and validity dates
+ * of the certificate can be customized in this spec. The self-signed certificate may be replaced at
+ * a later time by a certificate signed by a Certificate Authority (CA).
+ *
+ * <p>NOTE: The key material of the generated symmetric and private keys is not accessible. The key
+ * material of the public keys is accessible.
+ *
+ * <p><h3>Example: Asymmetric key pair</h3>
+ * The following example illustrates how to generate an EC key pair in the Android KeyStore system
+ * under alias {@code key1} authorized to be used only for signing using SHA-256, SHA-384,
+ * or SHA-512 digest and only if the user has been authenticated within the last five minutes.
+ * <pre> {@code
+ * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
+ * KeyProperties.KEY_ALGORITHM_EC,
+ * "AndroidKeyStore");
+ * keyPairGenerator.initialize(
+ * new KeyGenParameterSpec.Builder("key1",
+ * KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+ * .setDigests(KeyProperties.DIGEST_SHA256
+ * | KeyProperties.DIGEST_SHA384
+ * | KeyProperties.DIGEST_SHA512)
+ * // Only permit this key to be used if the user authenticated
+ * // within the last five minutes.
+ * .setUserAuthenticationRequired(true)
+ * .setUserAuthenticationValidityDurationSeconds(5 * 60)
+ * .build());
+ * KeyPair keyPair = keyPairGenerator.generateKeyPair();
+ *
+ * // The key pair can also be obtained from the Android Keystore any time as follows:
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key1", null);
+ * PublicKey publicKey = keyStore.getCertificate("key1").getPublicKey();
+ * }</pre>
+ *
+ * <p><h3>Example: Symmetric key</h3>
+ * The following example illustrates how to generate an AES key in the Android KeyStore system under
+ * alias {@code key2} authorized to be used only for encryption/decryption in CTR mode.
+ * <pre> {@code
+ * KeyGenerator keyGenerator = KeyGenerator.getInstance(
+ * KeyProperties.KEY_ALGORITHM_HMAC_SHA256,
+ * "AndroidKeyStore");
+ * keyGenerator.initialize(
+ * new KeyGenParameterSpec.Builder("key2",
+ * KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+ * .setBlockModes(KeyProperties.BLOCK_MODE_CTR)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ * .build());
+ * SecretKey key = keyGenerator.generateKey();
+ *
+ * // The key can also be obtained from the Android Keystore any time as follows:
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * key = (SecretKey) keyStore.getKey("key2", null);
+ * }</pre>
+ */
+public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
+
+ private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+ private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+ private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+ private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
+ private final String mKeystoreAlias;
+ private final int mKeySize;
+ private final AlgorithmParameterSpec mSpec;
+ private final X500Principal mCertificateSubject;
+ private final BigInteger mCertificateSerialNumber;
+ private final Date mCertificateNotBefore;
+ private final Date mCertificateNotAfter;
+ private final Date mKeyValidityStart;
+ private final Date mKeyValidityForOriginationEnd;
+ private final Date mKeyValidityForConsumptionEnd;
+ private final @KeyProperties.PurposeEnum int mPurposes;
+ private final @KeyProperties.DigestEnum String[] mDigests;
+ private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
+ private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
+ private final @KeyProperties.BlockModeEnum String[] mBlockModes;
+ private final boolean mRandomizedEncryptionRequired;
+ private final boolean mUserAuthenticationRequired;
+ private final int mUserAuthenticationValidityDurationSeconds;
+
+ /**
+ * @hide should be built with Builder
+ */
+ public KeyGenParameterSpec(
+ String keyStoreAlias,
+ int keySize,
+ AlgorithmParameterSpec spec,
+ X500Principal certificateSubject,
+ BigInteger certificateSerialNumber,
+ Date certificateNotBefore,
+ Date certificateNotAfter,
+ Date keyValidityStart,
+ Date keyValidityForOriginationEnd,
+ Date keyValidityForConsumptionEnd,
+ @KeyProperties.PurposeEnum int purposes,
+ @KeyProperties.DigestEnum String[] digests,
+ @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
+ @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
+ @KeyProperties.BlockModeEnum String[] blockModes,
+ boolean randomizedEncryptionRequired,
+ boolean userAuthenticationRequired,
+ int userAuthenticationValidityDurationSeconds) {
+ if (TextUtils.isEmpty(keyStoreAlias)) {
+ throw new IllegalArgumentException("keyStoreAlias must not be empty");
+ } else if ((userAuthenticationValidityDurationSeconds < 0)
+ && (userAuthenticationValidityDurationSeconds != -1)) {
+ throw new IllegalArgumentException(
+ "userAuthenticationValidityDurationSeconds must not be negative");
+ }
+
+ if (certificateSubject == null) {
+ certificateSubject = DEFAULT_CERT_SUBJECT;
+ }
+ if (certificateNotBefore == null) {
+ certificateNotBefore = DEFAULT_CERT_NOT_BEFORE;
+ }
+ if (certificateNotAfter == null) {
+ certificateNotAfter = DEFAULT_CERT_NOT_AFTER;
+ }
+ if (certificateSerialNumber == null) {
+ certificateSerialNumber = DEFAULT_CERT_SERIAL_NUMBER;
+ }
+
+ if (certificateNotAfter.before(certificateNotBefore)) {
+ throw new IllegalArgumentException("certificateNotAfter < certificateNotBefore");
+ }
+
+ mKeystoreAlias = keyStoreAlias;
+ mKeySize = keySize;
+ mSpec = spec;
+ mCertificateSubject = certificateSubject;
+ mCertificateSerialNumber = certificateSerialNumber;
+ mCertificateNotBefore = certificateNotBefore;
+ mCertificateNotAfter = certificateNotAfter;
+ mKeyValidityStart = keyValidityStart;
+ mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
+ mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
+ mPurposes = purposes;
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
+ mRandomizedEncryptionRequired = randomizedEncryptionRequired;
+ mUserAuthenticationRequired = userAuthenticationRequired;
+ mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ }
+
+ /**
+ * Returns the alias that will be used in the {@code java.security.KeyStore}
+ * in conjunction with the {@code AndroidKeyStore}.
+ */
+ public String getKeystoreAlias() {
+ return mKeystoreAlias;
+ }
+
+ /**
+ * Returns the requested key size or {@code -1} if default size should be used.
+ */
+ public int getKeySize() {
+ return mKeySize;
+ }
+
+ /**
+ * Returns the {@link AlgorithmParameterSpec} that will be used for creation
+ * of the key pair.
+ */
+ @NonNull
+ public AlgorithmParameterSpec getAlgorithmParameterSpec() {
+ return mSpec;
+ }
+
+ /**
+ * Returns the subject distinguished name to be used on the X.509 certificate that will be put
+ * in the {@link java.security.KeyStore}.
+ */
+ @NonNull
+ public X500Principal getCertificateSubject() {
+ return mCertificateSubject;
+ }
+
+ /**
+ * Returns the serial number to be used on the X.509 certificate that will be put in the
+ * {@link java.security.KeyStore}.
+ */
+ @NonNull
+ public BigInteger getCertificateSerialNumber() {
+ return mCertificateSerialNumber;
+ }
+
+ /**
+ * Returns the start date to be used on the X.509 certificate that will be put in the
+ * {@link java.security.KeyStore}.
+ */
+ @NonNull
+ public Date getCertificateNotBefore() {
+ return mCertificateNotBefore;
+ }
+
+ /**
+ * Returns the end date to be used on the X.509 certificate that will be put in the
+ * {@link java.security.KeyStore}.
+ */
+ @NonNull
+ public Date getCertificateNotAfter() {
+ return mCertificateNotAfter;
+ }
+
+ /**
+ * Returns the time instant before which the key is not yet valid or {@code null} if not
+ * restricted.
+ */
+ @Nullable
+ public Date getKeyValidityStart() {
+ return mKeyValidityStart;
+ }
+
+ /**
+ * Returns the time instant after which the key is no longer valid for decryption and
+ * verification or {@code null} if not restricted.
+ */
+ @Nullable
+ public Date getKeyValidityForConsumptionEnd() {
+ return mKeyValidityForConsumptionEnd;
+ }
+
+ /**
+ * Returns the time instant after which the key is no longer valid for encryption and signing
+ * or {@code null} if not restricted.
+ */
+ @Nullable
+ public Date getKeyValidityForOriginationEnd() {
+ return mKeyValidityForOriginationEnd;
+ }
+
+ /**
+ * Returns the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
+ * Attempts to use the key for any other purpose will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
+ */
+ public @KeyProperties.PurposeEnum int getPurposes() {
+ return mPurposes;
+ }
+
+ /**
+ * Returns the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the
+ * key can be used or {@code null} if not specified.
+ *
+ * <p>See {@link KeyProperties}.{@code DIGEST} constants.
+ *
+ * @throws IllegalStateException if this set has not been specified.
+ *
+ * @see #isDigestsSpecified()
+ */
+ @NonNull
+ public @KeyProperties.DigestEnum String[] getDigests() {
+ if (mDigests == null) {
+ throw new IllegalStateException("Digests not specified");
+ }
+ return ArrayUtils.cloneIfNotEmpty(mDigests);
+ }
+
+ /**
+ * Returns {@code true} if the set of digest algorithms with which the key can be used has been
+ * specified.
+ *
+ * @see #getDigests()
+ */
+ @NonNull
+ public boolean isDigestsSpecified() {
+ return mDigests != null;
+ }
+
+ /**
+ * Returns the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OEAPPadding},
+ * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
+ * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
+ * rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
+ */
+ @NonNull
+ public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
+ }
+
+ /**
+ * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
+ * can be used when signing/verifying. Attempts to use the key with any other padding scheme
+ * will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
+ */
+ @NonNull
+ public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
+ }
+
+ /**
+ * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * when encrypting/decrypting. Attempts to use the key with any other block modes will be
+ * rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
+ */
+ @NonNull
+ public @KeyProperties.BlockModeEnum String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
+ }
+
+ /**
+ * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
+ * different ciphertexts for the same plaintext every time. The formal cryptographic property
+ * being required is <em>indistinguishability under chosen-plaintext attack ({@code
+ * IND-CPA})</em>. This property is important because it mitigates several classes of
+ * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
+ * given plaintext always produces the same ciphertext, an attacker may see the repeated
+ * ciphertexts and be able to deduce something about the plaintext.
+ */
+ public boolean isRandomizedEncryptionRequired() {
+ return mRandomizedEncryptionRequired;
+ }
+
+ /**
+ * Returns {@code true} if user authentication is required for this key to be used.
+ *
+ * <p>This restriction applies only to private key operations. Public key operations are not
+ * restricted.
+ *
+ * @see #getUserAuthenticationValidityDurationSeconds()
+ */
+ public boolean isUserAuthenticationRequired() {
+ return mUserAuthenticationRequired;
+ }
+
+ /**
+ * Gets the duration of time (seconds) for which this key can be used after the user is
+ * successfully authenticated. This has effect only if user authentication is required.
+ *
+ * <p>This restriction applies only to private key operations. Public key operations are not
+ * restricted.
+ *
+ * @return duration in seconds or {@code -1} if authentication is required for every use of the
+ * key.
+ *
+ * @see #isUserAuthenticationRequired()
+ */
+ public int getUserAuthenticationValidityDurationSeconds() {
+ return mUserAuthenticationValidityDurationSeconds;
+ }
+
+ /**
+ * Builder of {@link KeyGenParameterSpec} instances.
+ */
+ public final static class Builder {
+ private final String mKeystoreAlias;
+ private @KeyProperties.PurposeEnum int mPurposes;
+
+ private int mKeySize = -1;
+ private AlgorithmParameterSpec mSpec;
+ private X500Principal mCertificateSubject;
+ private BigInteger mCertificateSerialNumber;
+ private Date mCertificateNotBefore;
+ private Date mCertificateNotAfter;
+ private Date mKeyValidityStart;
+ private Date mKeyValidityForOriginationEnd;
+ private Date mKeyValidityForConsumptionEnd;
+ private @KeyProperties.DigestEnum String[] mDigests;
+ private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
+ private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
+ private @KeyProperties.BlockModeEnum String[] mBlockModes;
+ private boolean mRandomizedEncryptionRequired = true;
+ private boolean mUserAuthenticationRequired;
+ private int mUserAuthenticationValidityDurationSeconds = -1;
+
+ /**
+ * Creates a new instance of the {@code Builder}.
+ *
+ * @param keystoreAlias alias of the entry in which the generated key will appear in
+ * Android KeyStore.
+ * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
+ * used. Attempts to use the key for any other purpose will be rejected.
+ *
+ * <p>If the set of purposes for which the key can be used does not contain
+ * {@link KeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by
+ * {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an
+ * invalid signature. This is OK if the certificate is only used for obtaining the
+ * public key from Android KeyStore.
+ *
+ * <p><b>NOTE: The {@code purposes} parameter has currently no effect on asymmetric
+ * key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
+ */
+ public Builder(@NonNull String keystoreAlias, @KeyProperties.PurposeEnum int purposes) {
+ if (keystoreAlias == null) {
+ throw new NullPointerException("keystoreAlias == null");
+ }
+ mKeystoreAlias = keystoreAlias;
+ mPurposes = purposes;
+ }
+
+ /**
+ * Sets the size (in bits) of the key to be generated. For instance, for RSA keys this sets
+ * the modulus size, for EC keys this selects a curve with a matching field size, and for
+ * symmetric keys this sets the size of the bitstring which is their key material.
+ *
+ * <p>The default key size is specific to each key algorithm.
+ */
+ @NonNull
+ public Builder setKeySize(int keySize) {
+ if (keySize < 0) {
+ throw new IllegalArgumentException("keySize < 0");
+ }
+ mKeySize = keySize;
+ return this;
+ }
+
+ /**
+ * Sets the algorithm-specific key generation parameters. For example, for RSA keys this may
+ * be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
+ */
+ public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
+ if (spec == null) {
+ throw new NullPointerException("spec == null");
+ }
+ mSpec = spec;
+ return this;
+ }
+
+ /**
+ * Sets the subject used for the self-signed certificate of the generated key pair.
+ *
+ * <p>By default, the subject is {@code CN=fake}.
+ */
+ @NonNull
+ public Builder setCertificateSubject(@NonNull X500Principal subject) {
+ if (subject == null) {
+ throw new NullPointerException("subject == null");
+ }
+ mCertificateSubject = subject;
+ return this;
+ }
+
+ /**
+ * Sets the serial number used for the self-signed certificate of the generated key pair.
+ *
+ * <p>By default, the serial number is {@code 1}.
+ */
+ @NonNull
+ public Builder setCertificateSerialNumber(@NonNull BigInteger serialNumber) {
+ if (serialNumber == null) {
+ throw new NullPointerException("serialNumber == null");
+ }
+ mCertificateSerialNumber = serialNumber;
+ return this;
+ }
+
+ /**
+ * Sets the start of the validity period for the self-signed certificate of the generated
+ * key pair.
+ *
+ * <p>By default, this date is {@code Jan 1 1970}.
+ */
+ @NonNull
+ public Builder setCertificateNotBefore(@NonNull Date date) {
+ if (date == null) {
+ throw new NullPointerException("date == null");
+ }
+ mCertificateNotBefore = date;
+ return this;
+ }
+
+ /**
+ * Sets the end of the validity period for the self-signed certificate of the generated key
+ * pair.
+ *
+ * <p>By default, this date is {@code Jan 1 2048}.
+ */
+ @NonNull
+ public Builder setCertificateNotAfter(@NonNull Date date) {
+ if (date == null) {
+ throw new NullPointerException("date == null");
+ }
+ mCertificateNotAfter = date;
+ return this;
+ }
+
+ /**
+ * Sets the time instant before which the key is not yet valid.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityStart(Date startDate) {
+ mKeyValidityStart = startDate;
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityStart(Date)
+ * @see #setKeyValidityForConsumptionEnd(Date)
+ * @see #setKeyValidityForOriginationEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityEnd(Date endDate) {
+ setKeyValidityForOriginationEnd(endDate);
+ setKeyValidityForConsumptionEnd(endDate);
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid for encryption and signing.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityForConsumptionEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityForOriginationEnd(Date endDate) {
+ mKeyValidityForOriginationEnd = endDate;
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid for decryption and
+ * verification.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityForOriginationEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityForConsumptionEnd(Date endDate) {
+ mKeyValidityForConsumptionEnd = endDate;
+ return this;
+ }
+
+ /**
+ * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which
+ * the key can be used when signing/verifying. Attempts to use the key with any other digest
+ * algorithm will be rejected.
+ *
+ * <p>This must be specified for keys which are used for signing/verification. For HMAC
+ * keys, the set of digests defaults to the digest associated with the key algorithm (e.g.,
+ * {@code SHA-256} for key algorithm {@code HmacSHA256}
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see KeyProperties.Digest
+ */
+ @NonNull
+ public Builder setDigests(@KeyProperties.DigestEnum String... digests) {
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ return this;
+ }
+
+ /**
+ * Sets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code OAEPPadding},
+ * {@code PKCS1Padding}, {@code NoPadding}) with which the key can be used when
+ * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
+ * rejected.
+ *
+ * <p>This must be specified for keys which are used for encryption/decryption.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
+ */
+ @NonNull
+ public Builder setEncryptionPaddings(
+ @KeyProperties.EncryptionPaddingEnum String... paddings) {
+ mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
+ return this;
+ }
+
+ /**
+ * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
+ * can be used when signing/verifying. Attempts to use the key with any other padding scheme
+ * will be rejected.
+ *
+ * <p>This must be specified for RSA keys which are used for signing/verification.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
+ */
+ @NonNull
+ public Builder setSignaturePaddings(
+ @KeyProperties.SignaturePaddingEnum String... paddings) {
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
+ return this;
+ }
+
+ /**
+ * Sets the set of block modes (e.g., {@code CBC}, {@code CTR}, {@code ECB}) with which the
+ * key can be used when encrypting/decrypting. Attempts to use the key with any other block
+ * modes will be rejected.
+ *
+ * <p>This must be specified for encryption/decryption keys.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
+ */
+ @NonNull
+ public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) {
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
+ return this;
+ }
+
+ /**
+ * Sets whether encryption using this key must be sufficiently randomized to produce
+ * different ciphertexts for the same plaintext every time. The formal cryptographic
+ * property being required is <em>indistinguishability under chosen-plaintext attack
+ * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
+ * of weaknesses due to which ciphertext may leak information about plaintext. For example,
+ * if a given plaintext always produces the same ciphertext, an attacker may see the
+ * repeated ciphertexts and be able to deduce something about the plaintext.
+ *
+ * <p>By default, {@code IND-CPA} is required.
+ *
+ * <p>When {@code IND-CPA} is required:
+ * <ul>
+ * <li>encryption/decryption transformation which do not offer {@code IND-CPA}, such as
+ * {@code ECB} with a symmetric encryption algorithm, or RSA encryption/decryption without
+ * padding, are prohibited;</li>
+ * <li>in block modes which use an IV, such as {@code CBC}, {@code CTR}, and {@code GCM},
+ * caller-provided IVs are rejected when encrypting, to ensure that only random IVs are
+ * used.</li>
+ * </ul>
+ *
+ * <p>Before disabling this requirement, consider the following approaches instead:
+ * <ul>
+ * <li>If you are generating a random IV for encryption and then initializing a {@code}
+ * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
+ * instead. This will occur if the {@code Cipher} is initialized for encryption without an
+ * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
+ * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
+ * random, such as the name of the file being encrypted, or transaction ID, or password,
+ * or a device identifier), consider changing your design to use a random IV which will then
+ * be provided in addition to the ciphertext to the entities which need to decrypt the
+ * ciphertext.</li>
+ * <li>If you are using RSA encryption without padding, consider switching to encryption
+ * padding schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
+ * </ul>
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ */
+ @NonNull
+ public Builder setRandomizedEncryptionRequired(boolean required) {
+ mRandomizedEncryptionRequired = required;
+ return this;
+ }
+
+ /**
+ * Sets whether user authentication is required to use this key.
+ *
+ * <p>By default, the key can be used without user authentication.
+ *
+ * <p>When user authentication is required, the user authorizes the use of the key by
+ * authenticating to this Android device using a subset of their secure lock screen
+ * credentials. Different authentication methods are used depending on whether the every
+ * use of the key must be authenticated (as specified by
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+ * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
+ * information</a>.
+ *
+ * <p>This restriction applies only to private key operations. Public key operations are not
+ * restricted.
+ *
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * @see #setUserAuthenticationValidityDurationSeconds(int)
+ */
+ @NonNull
+ public Builder setUserAuthenticationRequired(boolean required) {
+ mUserAuthenticationRequired = required;
+ return this;
+ }
+
+ /**
+ * Sets the duration of time (seconds) for which this key can be used after the user is
+ * successfully authenticated. This has effect only if user authentication is required.
+ *
+ * <p>By default, the user needs to authenticate for every use of the key.
+ *
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
+ * every use of the key.
+ *
+ * @see #setUserAuthenticationRequired(boolean)
+ */
+ @NonNull
+ public Builder setUserAuthenticationValidityDurationSeconds(
+ @IntRange(from = -1) int seconds) {
+ mUserAuthenticationValidityDurationSeconds = seconds;
+ return this;
+ }
+
+ /**
+ * Builds an instance of {@code KeyGenParameterSpec}.
+ *
+ * @throws IllegalArgumentException if a required field is missing
+ */
+ @NonNull
+ public KeyGenParameterSpec build() {
+ return new KeyGenParameterSpec(
+ mKeystoreAlias,
+ mKeySize,
+ mSpec,
+ mCertificateSubject,
+ mCertificateSerialNumber,
+ mCertificateNotBefore,
+ mCertificateNotAfter,
+ mKeyValidityStart,
+ mKeyValidityForOriginationEnd,
+ mKeyValidityForConsumptionEnd,
+ mPurposes,
+ mDigests,
+ mEncryptionPaddings,
+ mSignaturePaddings,
+ mBlockModes,
+ mRandomizedEncryptionRequired,
+ mUserAuthenticationRequired,
+ mUserAuthenticationValidityDurationSeconds);
+ }
+ }
+}
diff --git a/keystore/java/android/security/KeyStoreKeySpec.java b/keystore/java/android/security/keystore/KeyInfo.java
similarity index 68%
rename from keystore/java/android/security/KeyStoreKeySpec.java
rename to keystore/java/android/security/keystore/KeyInfo.java
index 81a19bb..e4f921e 100644
--- a/keystore/java/android/security/KeyStoreKeySpec.java
+++ b/keystore/java/android/security/keystore/KeyInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -27,55 +27,55 @@
/**
* Information about a key from the <a href="{@docRoot}training/articles/keystore.html">Android
- * KeyStore</a>. This class describes whether the key material is available in
+ * Keystore system</a>. This class describes whether the key material is available in
* plaintext outside of secure hardware, whether user authentication is required for using the key
* and whether this requirement is enforced by secure hardware, the key's origin, what uses the key
* is authorized for (e.g., only in {@code CBC} mode, or signing only), whether the key should be
* encrypted at rest, the key's and validity start and end dates.
*
* <p><h3>Example: Symmetric Key</h3>
- * The following example illustrates how to obtain a {@link KeyStoreKeySpec} describing the provided
- * Android KeyStore {@link SecretKey}.
+ * The following example illustrates how to obtain a {@code KeyInfo} describing the provided Android
+ * Keystore {@link SecretKey}.
* <pre> {@code
- * SecretKey key = ...; // Android KeyStore key
+ * SecretKey key = ...; // Android Keystore key
*
* SecretKeyFactory factory = SecretKeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
- * KeyStoreKeySpec spec;
+ * KeyInfo keyInfo;
* try {
- * spec = (KeyStoreKeySpec) factory.getKeySpec(key, KeyStoreKeySpec.class);
+ * keyInfo = (KeyInfo) factory.getKeySpec(key, KeyInfo.class);
* } catch (InvalidKeySpecException e) {
* // Not an Android KeyStore key.
* }
* }</pre>
*
* <p><h3>Example: Private Key</h3>
- * The following example illustrates how to obtain a {@link KeyStoreKeySpec} describing the provided
+ * The following example illustrates how to obtain a {@code KeyInfo} describing the provided
* Android KeyStore {@link PrivateKey}.
* <pre> {@code
* PrivateKey key = ...; // Android KeyStore key
*
* KeyFactory factory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
- * KeyStoreKeySpec spec;
+ * KeyInfo keyInfo;
* try {
- * spec = factory.getKeySpec(key, KeyStoreKeySpec.class);
+ * keyInfo = factory.getKeySpec(key, KeyInfo.class);
* } catch (InvalidKeySpecException e) {
* // Not an Android KeyStore key.
* }
* }</pre>
*/
-public class KeyStoreKeySpec implements KeySpec {
+public class KeyInfo implements KeySpec {
private final String mKeystoreAlias;
private final int mKeySize;
private final boolean mInsideSecureHardware;
- private final @KeyStoreKeyProperties.OriginEnum int mOrigin;
+ private final @KeyProperties.OriginEnum int mOrigin;
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
- private final @KeyStoreKeyProperties.PurposeEnum int mPurposes;
- private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
- private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
- private final @KeyStoreKeyProperties.DigestEnum String[] mDigests;
- private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes;
+ private final @KeyProperties.PurposeEnum int mPurposes;
+ private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
+ private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
+ private final @KeyProperties.DigestEnum String[] mDigests;
+ private final @KeyProperties.BlockModeEnum String[] mBlockModes;
private final boolean mUserAuthenticationRequired;
private final int mUserAuthenticationValidityDurationSeconds;
private final boolean mUserAuthenticationRequirementEnforcedBySecureHardware;
@@ -83,18 +83,18 @@
/**
* @hide
*/
- KeyStoreKeySpec(String keystoreKeyAlias,
+ public KeyInfo(String keystoreKeyAlias,
boolean insideSecureHardware,
- @KeyStoreKeyProperties.OriginEnum int origin,
+ @KeyProperties.OriginEnum int origin,
int keySize,
Date keyValidityStart,
Date keyValidityForOriginationEnd,
Date keyValidityForConsumptionEnd,
- @KeyStoreKeyProperties.PurposeEnum int purposes,
- @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
- @KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings,
- @KeyStoreKeyProperties.DigestEnum String[] digests,
- @KeyStoreKeyProperties.BlockModeEnum String[] blockModes,
+ @KeyProperties.PurposeEnum int purposes,
+ @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
+ @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
+ @KeyProperties.DigestEnum String[] digests,
+ @KeyProperties.BlockModeEnum String[] blockModes,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
boolean userAuthenticationRequirementEnforcedBySecureHardware) {
@@ -135,9 +135,9 @@
}
/**
- * Gets the origin of the key.
+ * Gets the origin of the key. See {@link KeyProperties}.{@code ORIGIN} constants.
*/
- public @KeyStoreKeyProperties.OriginEnum int getOrigin() {
+ public @KeyProperties.OriginEnum int getOrigin() {
return mOrigin;
}
@@ -179,41 +179,59 @@
}
/**
- * Gets the set of purposes for which the key can be used.
+ * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
+ * Attempts to use the key for any other purpose will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
*/
- public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
+ public @KeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of block modes with which the key can be used.
+ * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * when encrypting/decrypting. Attempts to use the key with any other block modes will be
+ * rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
*/
@NonNull
- public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
+ public @KeyProperties.BlockModeEnum String[] getBlockModes() {
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
- * Gets the set of padding modes with which the key can be used when encrypting/decrypting.
+ * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding},
+ * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use
+ * the key with any other padding scheme will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
@NonNull
- public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
+ public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of padding modes with which the key can be used when signing/verifying.
+ * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
+ * can be used when signing/verifying. Attempts to use the key with any other padding scheme
+ * will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
@NonNull
- public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
+ public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
- * Gets the set of digest algorithms with which the key can be used.
+ * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key
+ * can be used.
+ *
+ * <p>See {@link KeyProperties}.{@code DIGEST} constants.
*/
@NonNull
- public @KeyStoreKeyProperties.DigestEnum String[] getDigests() {
+ public @KeyProperties.DigestEnum String[] getDigests() {
return ArrayUtils.cloneIfNotEmpty(mDigests);
}
diff --git a/keystore/java/android/security/KeyNotYetValidException.java b/keystore/java/android/security/keystore/KeyNotYetValidException.java
similarity index 97%
rename from keystore/java/android/security/KeyNotYetValidException.java
rename to keystore/java/android/security/keystore/KeyNotYetValidException.java
index 4ea27ef..2cec77d 100644
--- a/keystore/java/android/security/KeyNotYetValidException.java
+++ b/keystore/java/android/security/keystore/KeyNotYetValidException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.InvalidKeyException;
diff --git a/keystore/java/android/security/KeyPermanentlyInvalidatedException.java b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
similarity index 98%
rename from keystore/java/android/security/KeyPermanentlyInvalidatedException.java
rename to keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
index 229eab0..e320c9c 100644
--- a/keystore/java/android/security/KeyPermanentlyInvalidatedException.java
+++ b/keystore/java/android/security/keystore/KeyPermanentlyInvalidatedException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.InvalidKeyException;
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
new file mode 100644
index 0000000..e3c2d1d
--- /dev/null
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -0,0 +1,677 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.security.keymaster.KeymasterDefs;
+
+import libcore.util.EmptyArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
+import java.util.Locale;
+
+/**
+ * Properties of <a href="{@docRoot}training/articles/keystore.html">Android Keystore</a> keys.
+ */
+public abstract class KeyProperties {
+ private KeyProperties() {}
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true,
+ value = {
+ PURPOSE_ENCRYPT,
+ PURPOSE_DECRYPT,
+ PURPOSE_SIGN,
+ PURPOSE_VERIFY,
+ })
+ public @interface PurposeEnum {}
+
+ /**
+ * Purpose of key: encryption.
+ */
+ public static final int PURPOSE_ENCRYPT = 1 << 0;
+
+ /**
+ * Purpose of key: decryption.
+ */
+ public static final int PURPOSE_DECRYPT = 1 << 1;
+
+ /**
+ * Purpose of key: signing or generating a Message Authentication Code (MAC).
+ */
+ public static final int PURPOSE_SIGN = 1 << 2;
+
+ /**
+ * Purpose of key: signature or Message Authentication Code (MAC) verification.
+ */
+ public static final int PURPOSE_VERIFY = 1 << 3;
+
+ /**
+ * @hide
+ */
+ public static abstract class Purpose {
+ private Purpose() {}
+
+ public static int toKeymaster(@PurposeEnum int purpose) {
+ switch (purpose) {
+ case PURPOSE_ENCRYPT:
+ return KeymasterDefs.KM_PURPOSE_ENCRYPT;
+ case PURPOSE_DECRYPT:
+ return KeymasterDefs.KM_PURPOSE_DECRYPT;
+ case PURPOSE_SIGN:
+ return KeymasterDefs.KM_PURPOSE_SIGN;
+ case PURPOSE_VERIFY:
+ return KeymasterDefs.KM_PURPOSE_VERIFY;
+ default:
+ throw new IllegalArgumentException("Unknown purpose: " + purpose);
+ }
+ }
+
+ public static @PurposeEnum int fromKeymaster(int purpose) {
+ switch (purpose) {
+ case KeymasterDefs.KM_PURPOSE_ENCRYPT:
+ return PURPOSE_ENCRYPT;
+ case KeymasterDefs.KM_PURPOSE_DECRYPT:
+ return PURPOSE_DECRYPT;
+ case KeymasterDefs.KM_PURPOSE_SIGN:
+ return PURPOSE_SIGN;
+ case KeymasterDefs.KM_PURPOSE_VERIFY:
+ return PURPOSE_VERIFY;
+ default:
+ throw new IllegalArgumentException("Unknown purpose: " + purpose);
+ }
+ }
+
+ @NonNull
+ public static int[] allToKeymaster(@PurposeEnum int purposes) {
+ int[] result = getSetFlags(purposes);
+ for (int i = 0; i < result.length; i++) {
+ result[i] = toKeymaster(result[i]);
+ }
+ return result;
+ }
+
+ public static @PurposeEnum int allFromKeymaster(@NonNull Collection<Integer> purposes) {
+ @PurposeEnum int result = 0;
+ for (int keymasterPurpose : purposes) {
+ result |= fromKeymaster(keymasterPurpose);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({
+ KEY_ALGORITHM_RSA,
+ KEY_ALGORITHM_EC,
+ KEY_ALGORITHM_AES,
+ KEY_ALGORITHM_HMAC_SHA1,
+ KEY_ALGORITHM_HMAC_SHA224,
+ KEY_ALGORITHM_HMAC_SHA256,
+ KEY_ALGORITHM_HMAC_SHA384,
+ KEY_ALGORITHM_HMAC_SHA512,
+ })
+ public @interface KeyAlgorithmEnum {}
+
+ /** Rivest Shamir Adleman (RSA) key. */
+ public static final String KEY_ALGORITHM_RSA = "RSA";
+
+ /** Elliptic Curve (EC) Cryptography key. */
+ public static final String KEY_ALGORITHM_EC = "EC";
+
+ /** Advanced Encryption Standard (AES) key. */
+ public static final String KEY_ALGORITHM_AES = "AES";
+
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA1 = "HmacSHA1";
+
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA224 = "HmacSHA224";
+
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA256 = "HmacSHA256";
+
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA384 = "HmacSHA384";
+
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA512 = "HmacSHA512";
+
+ /**
+ * @hide
+ */
+ public static abstract class KeyAlgorithm {
+ private KeyAlgorithm() {}
+
+ public static int toKeymasterSecretKeyAlgorithm(
+ @NonNull @KeyAlgorithmEnum String algorithm) {
+ if (KEY_ALGORITHM_AES.equalsIgnoreCase(algorithm)) {
+ return KeymasterDefs.KM_ALGORITHM_AES;
+ } else if (algorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
+ return KeymasterDefs.KM_ALGORITHM_HMAC;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported secret key algorithm: " + algorithm);
+ }
+ }
+
+ @NonNull
+ public static @KeyAlgorithmEnum String fromKeymasterSecretKeyAlgorithm(
+ int keymasterAlgorithm, int keymasterDigest) {
+ switch (keymasterAlgorithm) {
+ case KeymasterDefs.KM_ALGORITHM_AES:
+ if (keymasterDigest != -1) {
+ throw new IllegalArgumentException("Digest not supported for AES key: "
+ + Digest.fromKeymaster(keymasterDigest));
+ }
+ return KEY_ALGORITHM_AES;
+ case KeymasterDefs.KM_ALGORITHM_HMAC:
+ switch (keymasterDigest) {
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return KEY_ALGORITHM_HMAC_SHA1;
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return KEY_ALGORITHM_HMAC_SHA224;
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return KEY_ALGORITHM_HMAC_SHA256;
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return KEY_ALGORITHM_HMAC_SHA384;
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return KEY_ALGORITHM_HMAC_SHA512;
+ default:
+ throw new IllegalArgumentException("Unsupported HMAC digest: "
+ + Digest.fromKeymaster(keymasterDigest));
+ }
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported key algorithm: " + keymasterAlgorithm);
+ }
+ }
+
+ /**
+ * @hide
+ *
+ * @return keymaster digest or {@code -1} if the algorithm does not involve a digest.
+ */
+ public static int toKeymasterDigest(@NonNull @KeyAlgorithmEnum String algorithm) {
+ String algorithmUpper = algorithm.toUpperCase(Locale.US);
+ if (algorithmUpper.startsWith("HMAC")) {
+ String digestUpper = algorithmUpper.substring("HMAC".length());
+ switch (digestUpper) {
+ case "SHA1":
+ return KeymasterDefs.KM_DIGEST_SHA1;
+ case "SHA224":
+ return KeymasterDefs.KM_DIGEST_SHA_2_224;
+ case "SHA256":
+ return KeymasterDefs.KM_DIGEST_SHA_2_256;
+ case "SHA384":
+ return KeymasterDefs.KM_DIGEST_SHA_2_384;
+ case "SHA512":
+ return KeymasterDefs.KM_DIGEST_SHA_2_512;
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported HMAC digest: " + digestUpper);
+ }
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({
+ BLOCK_MODE_ECB,
+ BLOCK_MODE_CBC,
+ BLOCK_MODE_CTR,
+ BLOCK_MODE_GCM,
+ })
+ public @interface BlockModeEnum {}
+
+ /** Electronic Codebook (ECB) block mode. */
+ public static final String BLOCK_MODE_ECB = "ECB";
+
+ /** Cipher Block Chaining (CBC) block mode. */
+ public static final String BLOCK_MODE_CBC = "CBC";
+
+ /** Counter (CTR) block mode. */
+ public static final String BLOCK_MODE_CTR = "CTR";
+
+ /** Galois/Counter Mode (GCM) block mode. */
+ public static final String BLOCK_MODE_GCM = "GCM";
+
+ /**
+ * @hide
+ */
+ public static abstract class BlockMode {
+ private BlockMode() {}
+
+ public static int toKeymaster(@NonNull @BlockModeEnum String blockMode) {
+ if (BLOCK_MODE_ECB.equalsIgnoreCase(blockMode)) {
+ return KeymasterDefs.KM_MODE_ECB;
+ } else if (BLOCK_MODE_CBC.equalsIgnoreCase(blockMode)) {
+ return KeymasterDefs.KM_MODE_CBC;
+ } else if (BLOCK_MODE_CTR.equalsIgnoreCase(blockMode)) {
+ return KeymasterDefs.KM_MODE_CTR;
+ } else if (BLOCK_MODE_GCM.equalsIgnoreCase(blockMode)) {
+ return KeymasterDefs.KM_MODE_GCM;
+ } else {
+ throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
+ }
+ }
+
+ @NonNull
+ public static @BlockModeEnum String fromKeymaster(int blockMode) {
+ switch (blockMode) {
+ case KeymasterDefs.KM_MODE_ECB:
+ return BLOCK_MODE_ECB;
+ case KeymasterDefs.KM_MODE_CBC:
+ return BLOCK_MODE_CBC;
+ case KeymasterDefs.KM_MODE_CTR:
+ return BLOCK_MODE_CTR;
+ case KeymasterDefs.KM_MODE_GCM:
+ return BLOCK_MODE_GCM;
+ default:
+ throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
+ }
+ }
+
+ @NonNull
+ public static @BlockModeEnum String[] allFromKeymaster(
+ @NonNull Collection<Integer> blockModes) {
+ if ((blockModes == null) || (blockModes.isEmpty())) {
+ return EmptyArray.STRING;
+ }
+ @BlockModeEnum String[] result = new String[blockModes.size()];
+ int offset = 0;
+ for (int blockMode : blockModes) {
+ result[offset] = fromKeymaster(blockMode);
+ offset++;
+ }
+ return result;
+ }
+
+ public static int[] allToKeymaster(@Nullable @BlockModeEnum String[] blockModes) {
+ if ((blockModes == null) || (blockModes.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[blockModes.length];
+ for (int i = 0; i < blockModes.length; i++) {
+ result[i] = toKeymaster(blockModes[i]);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({
+ ENCRYPTION_PADDING_NONE,
+ ENCRYPTION_PADDING_PKCS7,
+ ENCRYPTION_PADDING_RSA_PKCS1,
+ ENCRYPTION_PADDING_RSA_OAEP,
+ })
+ public @interface EncryptionPaddingEnum {}
+
+ /**
+ * No encryption padding.
+ */
+ public static final String ENCRYPTION_PADDING_NONE = "NoPadding";
+
+ /**
+ * PKCS#7 encryption padding scheme.
+ */
+ public static final String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
+
+ /**
+ * RSA PKCS#1 v1.5 padding scheme for encryption.
+ */
+ public static final String ENCRYPTION_PADDING_RSA_PKCS1 = "PKCS1Padding";
+
+ /**
+ * RSA Optimal Asymmetric Encryption Padding (OAEP) scheme.
+ */
+ public static final String ENCRYPTION_PADDING_RSA_OAEP = "OAEPPadding";
+
+ /**
+ * @hide
+ */
+ public static abstract class EncryptionPadding {
+ private EncryptionPadding() {}
+
+ public static int toKeymaster(@NonNull @EncryptionPaddingEnum String padding) {
+ if (ENCRYPTION_PADDING_NONE.equalsIgnoreCase(padding)) {
+ return KeymasterDefs.KM_PAD_NONE;
+ } else if (ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(padding)) {
+ return KeymasterDefs.KM_PAD_PKCS7;
+ } else if (ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(padding)) {
+ return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
+ } else if (ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(padding)) {
+ return KeymasterDefs.KM_PAD_RSA_OAEP;
+ } else {
+ throw new IllegalArgumentException(
+ "Unsupported encryption padding scheme: " + padding);
+ }
+ }
+
+ @NonNull
+ public static @EncryptionPaddingEnum String fromKeymaster(int padding) {
+ switch (padding) {
+ case KeymasterDefs.KM_PAD_NONE:
+ return ENCRYPTION_PADDING_NONE;
+ case KeymasterDefs.KM_PAD_PKCS7:
+ return ENCRYPTION_PADDING_PKCS7;
+ case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
+ return ENCRYPTION_PADDING_RSA_PKCS1;
+ case KeymasterDefs.KM_PAD_RSA_OAEP:
+ return ENCRYPTION_PADDING_RSA_OAEP;
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported encryption padding: " + padding);
+ }
+ }
+
+ @NonNull
+ public static int[] allToKeymaster(@Nullable @EncryptionPaddingEnum String[] paddings) {
+ if ((paddings == null) || (paddings.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[paddings.length];
+ for (int i = 0; i < paddings.length; i++) {
+ result[i] = toKeymaster(paddings[i]);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({
+ SIGNATURE_PADDING_RSA_PKCS1,
+ SIGNATURE_PADDING_RSA_PSS,
+ })
+ public @interface SignaturePaddingEnum {}
+
+ /**
+ * RSA PKCS#1 v1.5 padding for signatures.
+ */
+ public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
+
+ /**
+ * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
+ */
+ public static final String SIGNATURE_PADDING_RSA_PSS = "PSS";
+
+ static abstract class SignaturePadding {
+ private SignaturePadding() {}
+
+ static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) {
+ switch (padding.toUpperCase(Locale.US)) {
+ case SIGNATURE_PADDING_RSA_PKCS1:
+ return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
+ case SIGNATURE_PADDING_RSA_PSS:
+ return KeymasterDefs.KM_PAD_RSA_PSS;
+ default:
+ throw new IllegalArgumentException(
+ "Unsupported signature padding scheme: " + padding);
+ }
+ }
+
+ @NonNull
+ static @SignaturePaddingEnum String fromKeymaster(int padding) {
+ switch (padding) {
+ case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
+ return SIGNATURE_PADDING_RSA_PKCS1;
+ case KeymasterDefs.KM_PAD_RSA_PSS:
+ return SIGNATURE_PADDING_RSA_PSS;
+ default:
+ throw new IllegalArgumentException("Unsupported signature padding: " + padding);
+ }
+ }
+
+ @NonNull
+ static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) {
+ if ((paddings == null) || (paddings.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[paddings.length];
+ for (int i = 0; i < paddings.length; i++) {
+ result[i] = toKeymaster(paddings[i]);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({
+ DIGEST_NONE,
+ DIGEST_MD5,
+ DIGEST_SHA1,
+ DIGEST_SHA224,
+ DIGEST_SHA256,
+ DIGEST_SHA384,
+ DIGEST_SHA512,
+ })
+ public @interface DigestEnum {}
+
+ /**
+ * No digest: sign/authenticate the raw message.
+ */
+ public static final String DIGEST_NONE = "NONE";
+
+ /**
+ * MD5 digest.
+ */
+ public static final String DIGEST_MD5 = "MD5";
+
+ /**
+ * SHA-1 digest.
+ */
+ public static final String DIGEST_SHA1 = "SHA-1";
+
+ /**
+ * SHA-2 224 (aka SHA-224) digest.
+ */
+ public static final String DIGEST_SHA224 = "SHA-224";
+
+ /**
+ * SHA-2 256 (aka SHA-256) digest.
+ */
+ public static final String DIGEST_SHA256 = "SHA-256";
+
+ /**
+ * SHA-2 384 (aka SHA-384) digest.
+ */
+ public static final String DIGEST_SHA384 = "SHA-384";
+
+ /**
+ * SHA-2 512 (aka SHA-512) digest.
+ */
+ public static final String DIGEST_SHA512 = "SHA-512";
+
+ /**
+ * @hide
+ */
+ public static abstract class Digest {
+ private Digest() {}
+
+ public static int toKeymaster(@NonNull @DigestEnum String digest) {
+ switch (digest.toUpperCase(Locale.US)) {
+ case DIGEST_SHA1:
+ return KeymasterDefs.KM_DIGEST_SHA1;
+ case DIGEST_SHA224:
+ return KeymasterDefs.KM_DIGEST_SHA_2_224;
+ case DIGEST_SHA256:
+ return KeymasterDefs.KM_DIGEST_SHA_2_256;
+ case DIGEST_SHA384:
+ return KeymasterDefs.KM_DIGEST_SHA_2_384;
+ case DIGEST_SHA512:
+ return KeymasterDefs.KM_DIGEST_SHA_2_512;
+ case DIGEST_NONE:
+ return KeymasterDefs.KM_DIGEST_NONE;
+ case DIGEST_MD5:
+ return KeymasterDefs.KM_DIGEST_MD5;
+ default:
+ throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
+ }
+ }
+
+ @NonNull
+ public static @DigestEnum String fromKeymaster(int digest) {
+ switch (digest) {
+ case KeymasterDefs.KM_DIGEST_NONE:
+ return DIGEST_NONE;
+ case KeymasterDefs.KM_DIGEST_MD5:
+ return DIGEST_MD5;
+ case KeymasterDefs.KM_DIGEST_SHA1:
+ return DIGEST_SHA1;
+ case KeymasterDefs.KM_DIGEST_SHA_2_224:
+ return DIGEST_SHA224;
+ case KeymasterDefs.KM_DIGEST_SHA_2_256:
+ return DIGEST_SHA256;
+ case KeymasterDefs.KM_DIGEST_SHA_2_384:
+ return DIGEST_SHA384;
+ case KeymasterDefs.KM_DIGEST_SHA_2_512:
+ return DIGEST_SHA512;
+ default:
+ throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
+ }
+ }
+
+ @NonNull
+ public static @DigestEnum String[] allFromKeymaster(@NonNull Collection<Integer> digests) {
+ if (digests.isEmpty()) {
+ return EmptyArray.STRING;
+ }
+ String[] result = new String[digests.size()];
+ int offset = 0;
+ for (int digest : digests) {
+ result[offset] = fromKeymaster(digest);
+ offset++;
+ }
+ return result;
+ }
+
+ @NonNull
+ public static int[] allToKeymaster(@Nullable @DigestEnum String[] digests) {
+ if ((digests == null) || (digests.length == 0)) {
+ return EmptyArray.INT;
+ }
+ int[] result = new int[digests.length];
+ int offset = 0;
+ for (@DigestEnum String digest : digests) {
+ result[offset] = toKeymaster(digest);
+ offset++;
+ }
+ return result;
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ ORIGIN_GENERATED,
+ ORIGIN_IMPORTED,
+ ORIGIN_UNKNOWN,
+ })
+ public @interface OriginEnum {}
+
+ /** Key was generated inside AndroidKeyStore. */
+ public static final int ORIGIN_GENERATED = 1 << 0;
+
+ /** Key was imported into AndroidKeyStore. */
+ public static final int ORIGIN_IMPORTED = 1 << 1;
+
+ /**
+ * Origin of the key is unknown. This can occur only for keys backed by an old TEE-backed
+ * implementation which does not record origin information.
+ */
+ public static final int ORIGIN_UNKNOWN = 1 << 2;
+
+ /**
+ * @hide
+ */
+ public static abstract class Origin {
+ private Origin() {}
+
+ public static @OriginEnum int fromKeymaster(int origin) {
+ switch (origin) {
+ case KeymasterDefs.KM_ORIGIN_GENERATED:
+ return ORIGIN_GENERATED;
+ case KeymasterDefs.KM_ORIGIN_IMPORTED:
+ return ORIGIN_IMPORTED;
+ case KeymasterDefs.KM_ORIGIN_UNKNOWN:
+ return ORIGIN_UNKNOWN;
+ default:
+ throw new IllegalArgumentException("Unknown origin: " + origin);
+ }
+ }
+ }
+
+ private static int[] getSetFlags(int flags) {
+ if (flags == 0) {
+ return EmptyArray.INT;
+ }
+ int result[] = new int[getSetBitCount(flags)];
+ int resultOffset = 0;
+ int flag = 1;
+ while (flags != 0) {
+ if ((flags & 1) != 0) {
+ result[resultOffset] = flag;
+ resultOffset++;
+ }
+ flags >>>= 1;
+ flag <<= 1;
+ }
+ return result;
+ }
+
+ private static int getSetBitCount(int value) {
+ if (value == 0) {
+ return 0;
+ }
+ int result = 0;
+ while (value != 0) {
+ if ((value & 1) != 0) {
+ result++;
+ }
+ value >>>= 1;
+ }
+ return result;
+ }
+}
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
new file mode 100644
index 0000000..f52a193
--- /dev/null
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.keystore;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.security.Key;
+import java.security.KeyStore.ProtectionParameter;
+import java.security.cert.Certificate;
+import java.util.Date;
+
+import javax.crypto.Cipher;
+
+/**
+ * Specification of how a key or key pair is secured when imported into the
+ * <a href="{@docRoot}training/articles/keystore.html">Android KeyStore facility</a>. This class
+ * specifies parameters such as whether user authentication is required for using the key, what uses
+ * the key is authorized for (e.g., only in {@code CTR} mode, or only for signing -- decryption not
+ * permitted), the key's and validity start and end dates.
+ *
+ * <p>To import a key or key pair into the Android KeyStore, create an instance of this class using
+ * the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry}
+ * with the key or key pair being imported.
+ *
+ * <p>To obtain the secret/symmetric or private key from the Android KeyStore use
+ * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or
+ * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}.
+ * To obtain the public key from the Android KeyStore use
+ * {@link java.security.KeyStore#getCertificate(String)} and then
+ * {@link Certificate#getPublicKey()}.
+ *
+ * <p>NOTE: The key material of keys stored in the Android KeyStore is not accessible.
+ *
+ * <p><h3>Example: Symmetric Key</h3>
+ * The following example illustrates how to import an AES key into the Android KeyStore under alias
+ * {@code key1} authorized to be used only for encryption/decryption in CBC mode with PKCS#7
+ * padding. The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format.
+ * <pre> {@code
+ * SecretKey key = ...; // AES key
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ * "key1",
+ * new KeyStore.SecretKeyEntry(key),
+ * new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+ * .setBlockMode(KeyProperties.BLOCK_MODE_CBC)
+ * .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+ * .build());
+ * // Key imported, obtain a reference to it.
+ * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
+ * // The original key can now be thrown away.
+ * }</pre>
+ *
+ * <p><h3>Example: Asymmetric Key Pair</h3>
+ * The following example illustrates how to import an EC key pair into the Android KeyStore under
+ * alias {@code key2} authorized to be used only for signing with SHA-256 digest and only if
+ * the user has been authenticated within the last ten minutes. Both the private and the public key
+ * must export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509}
+ * format respectively.
+ * <pre> {@code
+ * PrivateKey privateKey = ...; // EC private key
+ * Certificate[] certChain = ...; // Certificate chain with the first certificate
+ * // containing the corresponding EC public key.
+ *
+ * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+ * keyStore.load(null);
+ * keyStore.setEntry(
+ * "key2",
+ * new KeyStore.PrivateKeyEntry(privateKey, certChain),
+ * new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
+ * .setDigests(KeyProperties.DIGEST_SHA256)
+ * // Only permit this key to be used if the user
+ * // authenticated within the last ten minutes.
+ * .setUserAuthenticationRequired(true)
+ * .setUserAuthenticationValidityDurationSeconds(10 * 60)
+ * .build());
+ * // Key pair imported, obtain a reference to it.
+ * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
+ * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
+ * // The original private key can now be thrown away.
+ * }</pre>
+ */
+public final class KeyProtection implements ProtectionParameter {
+ private final Date mKeyValidityStart;
+ private final Date mKeyValidityForOriginationEnd;
+ private final Date mKeyValidityForConsumptionEnd;
+ private final @KeyProperties.PurposeEnum int mPurposes;
+ private final @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
+ private final @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
+ private final @KeyProperties.DigestEnum String[] mDigests;
+ private final @KeyProperties.BlockModeEnum String[] mBlockModes;
+ private final boolean mRandomizedEncryptionRequired;
+ private final boolean mUserAuthenticationRequired;
+ private final int mUserAuthenticationValidityDurationSeconds;
+
+ private KeyProtection(
+ Date keyValidityStart,
+ Date keyValidityForOriginationEnd,
+ Date keyValidityForConsumptionEnd,
+ @KeyProperties.PurposeEnum int purposes,
+ @KeyProperties.EncryptionPaddingEnum String[] encryptionPaddings,
+ @KeyProperties.SignaturePaddingEnum String[] signaturePaddings,
+ @KeyProperties.DigestEnum String[] digests,
+ @KeyProperties.BlockModeEnum String[] blockModes,
+ boolean randomizedEncryptionRequired,
+ boolean userAuthenticationRequired,
+ int userAuthenticationValidityDurationSeconds) {
+ if ((userAuthenticationValidityDurationSeconds < 0)
+ && (userAuthenticationValidityDurationSeconds != -1)) {
+ throw new IllegalArgumentException(
+ "userAuthenticationValidityDurationSeconds must not be negative");
+ }
+
+ mKeyValidityStart = keyValidityStart;
+ mKeyValidityForOriginationEnd = keyValidityForOriginationEnd;
+ mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd;
+ mPurposes = purposes;
+ mEncryptionPaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings));
+ mSignaturePaddings =
+ ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings));
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes));
+ mRandomizedEncryptionRequired = randomizedEncryptionRequired;
+ mUserAuthenticationRequired = userAuthenticationRequired;
+ mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ }
+
+ /**
+ * Gets the time instant before which the key is not yet valid.
+ *
+ * @return instant or {@code null} if not restricted.
+ */
+ @Nullable
+ public Date getKeyValidityStart() {
+ return mKeyValidityStart;
+ }
+
+ /**
+ * Gets the time instant after which the key is no long valid for decryption and verification.
+ *
+ * @return instant or {@code null} if not restricted.
+ */
+ @Nullable
+ public Date getKeyValidityForConsumptionEnd() {
+ return mKeyValidityForConsumptionEnd;
+ }
+
+ /**
+ * Gets the time instant after which the key is no long valid for encryption and signing.
+ *
+ * @return instant or {@code null} if not restricted.
+ */
+ @Nullable
+ public Date getKeyValidityForOriginationEnd() {
+ return mKeyValidityForOriginationEnd;
+ }
+
+ /**
+ * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used.
+ * Attempts to use the key for any other purpose will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
+ */
+ public @KeyProperties.PurposeEnum int getPurposes() {
+ return mPurposes;
+ }
+
+ /**
+ * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding},
+ * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use
+ * the key with any other padding scheme will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
+ */
+ @NonNull
+ public @KeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
+ }
+
+ /**
+ * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
+ * can be used when signing/verifying. Attempts to use the key with any other padding scheme
+ * will be rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
+ */
+ @NonNull
+ public @KeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
+ return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
+ }
+
+ /**
+ * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key
+ * can be used.
+ *
+ * <p>See {@link KeyProperties}.{@code DIGEST} constants.
+ *
+ * @throws IllegalStateException if this set has not been specified.
+ *
+ * @see #isDigestsSpecified()
+ */
+ @NonNull
+ public @KeyProperties.DigestEnum String[] getDigests() {
+ if (mDigests == null) {
+ throw new IllegalStateException("Digests not specified");
+ }
+ return ArrayUtils.cloneIfNotEmpty(mDigests);
+ }
+
+ /**
+ * Returns {@code true} if the set of digest algorithms with which the key can be used has been
+ * specified.
+ *
+ * @see #getDigests()
+ */
+ public boolean isDigestsSpecified() {
+ return mDigests != null;
+ }
+
+ /**
+ * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used
+ * when encrypting/decrypting. Attempts to use the key with any other block modes will be
+ * rejected.
+ *
+ * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
+ */
+ @NonNull
+ public @KeyProperties.BlockModeEnum String[] getBlockModes() {
+ return ArrayUtils.cloneIfNotEmpty(mBlockModes);
+ }
+
+ /**
+ * Returns {@code true} if encryption using this key must be sufficiently randomized to produce
+ * different ciphertexts for the same plaintext every time. The formal cryptographic property
+ * being required is <em>indistinguishability under chosen-plaintext attack ({@code
+ * IND-CPA})</em>. This property is important because it mitigates several classes of
+ * weaknesses due to which ciphertext may leak information about plaintext. For example, if a
+ * given plaintext always produces the same ciphertext, an attacker may see the repeated
+ * ciphertexts and be able to deduce something about the plaintext.
+ */
+ public boolean isRandomizedEncryptionRequired() {
+ return mRandomizedEncryptionRequired;
+ }
+
+ /**
+ * Returns {@code true} if user authentication is required for this key to be used.
+ *
+ * @see #getUserAuthenticationValidityDurationSeconds()
+ */
+ public boolean isUserAuthenticationRequired() {
+ return mUserAuthenticationRequired;
+ }
+
+ /**
+ * Gets the duration of time (seconds) for which this key can be used after the user is
+ * successfully authenticated. This has effect only if user authentication is required.
+ *
+ * @return duration in seconds or {@code -1} if authentication is required for every use of the
+ * key.
+ *
+ * @see #isUserAuthenticationRequired()
+ */
+ public int getUserAuthenticationValidityDurationSeconds() {
+ return mUserAuthenticationValidityDurationSeconds;
+ }
+
+ /**
+ * Builder of {@link KeyProtection} instances.
+ */
+ public final static class Builder {
+ private @KeyProperties.PurposeEnum int mPurposes;
+
+ private Date mKeyValidityStart;
+ private Date mKeyValidityForOriginationEnd;
+ private Date mKeyValidityForConsumptionEnd;
+ private @KeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings;
+ private @KeyProperties.SignaturePaddingEnum String[] mSignaturePaddings;
+ private @KeyProperties.DigestEnum String[] mDigests;
+ private @KeyProperties.BlockModeEnum String[] mBlockModes;
+ private boolean mRandomizedEncryptionRequired = true;
+ private boolean mUserAuthenticationRequired;
+ private int mUserAuthenticationValidityDurationSeconds = -1;
+
+ /**
+ * Creates a new instance of the {@code Builder}.
+ *
+ * @param purposes set of purposes (e.g., encrypt, decrypt, sign) for which the key can be
+ * used. Attempts to use the key for any other purpose will be rejected.
+ *
+ * <p><b>NOTE: The {@code purposes} parameter has currently no effect on asymmetric
+ * key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code PURPOSE} flags.
+ */
+ public Builder(@KeyProperties.PurposeEnum int purposes) {
+ mPurposes = purposes;
+ }
+
+ /**
+ * Sets the time instant before which the key is not yet valid.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityStart(Date startDate) {
+ mKeyValidityStart = startDate;
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityStart(Date)
+ * @see #setKeyValidityForConsumptionEnd(Date)
+ * @see #setKeyValidityForOriginationEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityEnd(Date endDate) {
+ setKeyValidityForOriginationEnd(endDate);
+ setKeyValidityForConsumptionEnd(endDate);
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid for encryption and signing.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityForConsumptionEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityForOriginationEnd(Date endDate) {
+ mKeyValidityForOriginationEnd = endDate;
+ return this;
+ }
+
+ /**
+ * Sets the time instant after which the key is no longer valid for decryption and
+ * verification.
+ *
+ * <p>By default, the key is valid at any instant.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setKeyValidityForOriginationEnd(Date)
+ */
+ @NonNull
+ public Builder setKeyValidityForConsumptionEnd(Date endDate) {
+ mKeyValidityForConsumptionEnd = endDate;
+ return this;
+ }
+
+ /**
+ * Sets the set of padding schemes (e.g., {@code OAEPPadding}, {@code PKCS7Padding},
+ * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to
+ * use the key with any other padding scheme will be rejected.
+ *
+ * <p>This must be specified for keys which are used for encryption/decryption.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code ENCRYPTION_PADDING} constants.
+ */
+ @NonNull
+ public Builder setEncryptionPaddings(
+ @KeyProperties.EncryptionPaddingEnum String... paddings) {
+ mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
+ return this;
+ }
+
+ /**
+ * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key
+ * can be used when signing/verifying. Attempts to use the key with any other padding scheme
+ * will be rejected.
+ *
+ * <p>This must be specified for RSA keys which are used for signing/verification.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code SIGNATURE_PADDING} constants.
+ */
+ @NonNull
+ public Builder setSignaturePaddings(
+ @KeyProperties.SignaturePaddingEnum String... paddings) {
+ mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
+ return this;
+ }
+
+ /**
+ * Sets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the
+ * key can be used when signing/verifying or generating MACs. Attempts to use the key with
+ * any other digest algorithm will be rejected.
+ *
+ * <p>For HMAC keys, the default is the digest algorithm specified in
+ * {@link Key#getAlgorithm()}. For asymmetric signing keys the set of digest algorithms
+ * must be specified.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code DIGEST} constants.
+ */
+ @NonNull
+ public Builder setDigests(@KeyProperties.DigestEnum String... digests) {
+ mDigests = ArrayUtils.cloneIfNotEmpty(digests);
+ return this;
+ }
+
+ /**
+ * Sets the set of block modes (e.g., {@code CBC}, {@code CTR}, {@code ECB}) with which the
+ * key can be used when encrypting/decrypting. Attempts to use the key with any other block
+ * modes will be rejected.
+ *
+ * <p>This must be specified for encryption/decryption keys.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyProperties}.{@code BLOCK_MODE} constants.
+ */
+ @NonNull
+ public Builder setBlockModes(@KeyProperties.BlockModeEnum String... blockModes) {
+ mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
+ return this;
+ }
+
+ /**
+ * Sets whether encryption using this key must be sufficiently randomized to produce
+ * different ciphertexts for the same plaintext every time. The formal cryptographic
+ * property being required is <em>indistinguishability under chosen-plaintext attack
+ * ({@code IND-CPA})</em>. This property is important because it mitigates several classes
+ * of weaknesses due to which ciphertext may leak information about plaintext. For example,
+ * if a given plaintext always produces the same ciphertext, an attacker may see the
+ * repeated ciphertexts and be able to deduce something about the plaintext.
+ *
+ * <p>By default, {@code IND-CPA} is required.
+ *
+ * <p>When {@code IND-CPA} is required:
+ * <ul>
+ * <li>transformation which do not offer {@code IND-CPA}, such as symmetric ciphers using
+ * {@code ECB} mode or RSA encryption without padding, are prohibited;</li>
+ * <li>in transformations which use an IV, such as symmetric ciphers in {@code CBC},
+ * {@code CTR}, and {@code GCM} block modes, caller-provided IVs are rejected when
+ * encrypting, to ensure that only random IVs are used.</li>
+ *
+ * <p>Before disabling this requirement, consider the following approaches instead:
+ * <ul>
+ * <li>If you are generating a random IV for encryption and then initializing a {@code}
+ * Cipher using the IV, the solution is to let the {@code Cipher} generate a random IV
+ * instead. This will occur if the {@code Cipher} is initialized for encryption without an
+ * IV. The IV can then be queried via {@link Cipher#getIV()}.</li>
+ * <li>If you are generating a non-random IV (e.g., an IV derived from something not fully
+ * random, such as the name of the file being encrypted, or transaction ID, or password,
+ * or a device identifier), consider changing your design to use a random IV which will then
+ * be provided in addition to the ciphertext to the entities which need to decrypt the
+ * ciphertext.</li>
+ * <li>If you are using RSA encryption without padding, consider switching to padding
+ * schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
+ * </ul>
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ */
+ @NonNull
+ public Builder setRandomizedEncryptionRequired(boolean required) {
+ mRandomizedEncryptionRequired = required;
+ return this;
+ }
+
+ /**
+ * Sets whether user authentication is required to use this key.
+ *
+ * <p>By default, the key can be used without user authentication.
+ *
+ * <p>When user authentication is required, the user authorizes the use of the key by
+ * authenticating to this Android device using a subset of their secure lock screen
+ * credentials. Different authentication methods are used depending on whether the every
+ * use of the key must be authenticated (as specified by
+ * {@link #setUserAuthenticationValidityDurationSeconds(int)}).
+ * <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
+ * information</a>.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see #setUserAuthenticationValidityDurationSeconds(int)
+ */
+ @NonNull
+ public Builder setUserAuthenticationRequired(boolean required) {
+ mUserAuthenticationRequired = required;
+ return this;
+ }
+
+ /**
+ * Sets the duration of time (seconds) for which this key can be used after the user is
+ * successfully authenticated. This has effect only if user authentication is required.
+ *
+ * <p>By default, the user needs to authenticate for every use of the key.
+ *
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
+ * every use of the key.
+ *
+ * @see #setUserAuthenticationRequired(boolean)
+ */
+ @NonNull
+ public Builder setUserAuthenticationValidityDurationSeconds(
+ @IntRange(from = -1) int seconds) {
+ mUserAuthenticationValidityDurationSeconds = seconds;
+ return this;
+ }
+
+ /**
+ * Builds an instance of {@link KeyProtection}.
+ *
+ * @throws IllegalArgumentException if a required field is missing
+ */
+ @NonNull
+ public KeyProtection build() {
+ return new KeyProtection(
+ mKeyValidityStart,
+ mKeyValidityForOriginationEnd,
+ mKeyValidityForConsumptionEnd,
+ mPurposes,
+ mEncryptionPaddings,
+ mSignaturePaddings,
+ mDigests,
+ mBlockModes,
+ mRandomizedEncryptionRequired,
+ mUserAuthenticationRequired,
+ mUserAuthenticationValidityDurationSeconds);
+ }
+ }
+}
diff --git a/keystore/java/android/security/KeyStoreConnectException.java b/keystore/java/android/security/keystore/KeyStoreConnectException.java
similarity index 96%
rename from keystore/java/android/security/KeyStoreConnectException.java
rename to keystore/java/android/security/keystore/KeyStoreConnectException.java
index 885f1f7..e008976 100644
--- a/keystore/java/android/security/KeyStoreConnectException.java
+++ b/keystore/java/android/security/keystore/KeyStoreConnectException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.ProviderException;
diff --git a/keystore/java/android/security/KeyStoreCryptoOperation.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperation.java
similarity index 92%
rename from keystore/java/android/security/KeyStoreCryptoOperation.java
rename to keystore/java/android/security/keystore/KeyStoreCryptoOperation.java
index c5cf211..2c709ae 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperation.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperation.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+
+import android.security.KeyStore;
/**
* Cryptographic operation backed by {@link KeyStore}.
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
similarity index 98%
rename from keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
rename to keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index 0619199..7d57e5f 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -14,9 +14,11 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import android.os.IBinder;
+import android.security.KeyStore;
+import android.security.KeyStoreException;
import android.security.keymaster.OperationResult;
import libcore.util.EmptyArray;
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java
similarity index 92%
rename from keystore/java/android/security/KeyStoreCryptoOperationUtils.java
rename to keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java
index 311278b..6ae76f1 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationUtils.java
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+import android.security.KeyStore;
import android.security.keymaster.KeymasterDefs;
import java.security.GeneralSecurityException;
@@ -40,7 +41,7 @@
* the {@code init} method should succeed.
*/
static InvalidKeyException getInvalidKeyExceptionForInit(
- KeyStore keyStore, KeyStoreKey key, int beginOpResultCode) {
+ KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) {
if (beginOpResultCode == KeyStore.NO_ERROR) {
return null;
}
@@ -68,8 +69,8 @@
* in response to {@code KeyStore.begin} operation or {@code null} if the {@code init} method
* should succeed.
*/
- static GeneralSecurityException getExceptionForCipherInit(
- KeyStore keyStore, KeyStoreKey key, int beginOpResultCode) {
+ public static GeneralSecurityException getExceptionForCipherInit(
+ KeyStore keyStore, AndroidKeyStoreKey key, int beginOpResultCode) {
if (beginOpResultCode == KeyStore.NO_ERROR) {
return null;
}
diff --git a/keystore/java/android/security/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
similarity index 95%
rename from keystore/java/android/security/KeymasterUtils.java
rename to keystore/java/android/security/keystore/KeymasterUtils.java
index df67ae7..e7529e1 100644
--- a/keystore/java/android/security/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
-import android.content.Context;
import android.hardware.fingerprint.FingerprintManager;
+import android.security.GateKeeper;
+import android.security.KeyStore;
import android.security.keymaster.KeymasterArguments;
import android.security.keymaster.KeymasterDefs;
@@ -73,7 +74,6 @@
* use of the key needs authorization.
*/
public static void addUserAuthArgs(KeymasterArguments args,
- Context context,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds) {
if (!userAuthenticationRequired) {
@@ -85,7 +85,7 @@
// Every use of this key needs to be authorized by the user. This currently means
// fingerprint-only auth.
FingerprintManager fingerprintManager =
- context.getSystemService(FingerprintManager.class);
+ KeyStore.getApplicationContext().getSystemService(FingerprintManager.class);
if ((fingerprintManager == null) || (!fingerprintManager.isHardwareDetected())) {
throw new IllegalStateException(
"This device does not support keys which require authentication for every"
diff --git a/keystore/java/android/security/UserNotAuthenticatedException.java b/keystore/java/android/security/keystore/UserNotAuthenticatedException.java
similarity index 97%
rename from keystore/java/android/security/UserNotAuthenticatedException.java
rename to keystore/java/android/security/keystore/UserNotAuthenticatedException.java
index 2954fa7..21f861c 100644
--- a/keystore/java/android/security/UserNotAuthenticatedException.java
+++ b/keystore/java/android/security/keystore/UserNotAuthenticatedException.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import java.security.InvalidKeyException;
diff --git a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
index 681a9ff..bc8dd13 100644
--- a/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
+++ b/keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java
@@ -24,11 +24,6 @@
import javax.security.auth.x500.X500Principal;
public class KeyPairGeneratorSpecTest extends AndroidTestCase {
- private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
- private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
- private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1980
- private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
-
private static final String TEST_ALIAS_1 = "test1";
private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
@@ -110,37 +105,46 @@
}
}
- public void testConstructor_NullSubjectDN_Success() throws Exception {
- KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
- getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
- NOW_PLUS_10_YEARS, 0);
- assertEquals(DEFAULT_CERT_SUBJECT, spec.getSubjectDN());
+ public void testConstructor_NullSubjectDN_Failure() throws Exception {
+ try {
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
+ NOW_PLUS_10_YEARS, 0);
+ fail("Should throw IllegalArgumentException when subjectDN is null");
+ } catch (IllegalArgumentException success) {
+ }
}
- public void testConstructor_NullSerial_Success() throws Exception {
- KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
- getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
- NOW_PLUS_10_YEARS, 0);
- assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getSerialNumber());
+ public void testConstructor_NullSerial_Failure() throws Exception {
+ try {
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
+ NOW_PLUS_10_YEARS, 0);
+ fail("Should throw IllegalArgumentException when startDate is null");
+ } catch (IllegalArgumentException success) {
+ }
}
- public void testConstructor_NullStartDate_Success() throws Exception {
- KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
- getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, null,
- NOW_PLUS_10_YEARS, 0);
- assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getStartDate());
+ public void testConstructor_NullStartDate_Failure() throws Exception {
+ try {
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
+ null, NOW_PLUS_10_YEARS, 0);
+ fail("Should throw IllegalArgumentException when startDate is null");
+ } catch (IllegalArgumentException success) {
+ }
}
- public void testConstructor_NullEndDate_Success() throws Exception {
- KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
- getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW, null, 0);
- assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getEndDate());
+ public void testConstructor_NullEndDate_Failure() throws Exception {
+ try {
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
+ NOW, null, 0);
+ fail("Should throw IllegalArgumentException when keystoreAlias is null");
+ } catch (IllegalArgumentException success) {
+ }
}
public void testConstructor_EndBeforeStart_Failure() throws Exception {
try {
- new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1,
- SERIAL_1, NOW_PLUS_10_YEARS, NOW, 0);
+ new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
+ NOW_PLUS_10_YEARS, NOW, 0);
fail("Should throw IllegalArgumentException when end is before start");
} catch (IllegalArgumentException success) {
}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index d138c24..c68b42b 100644
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -21,7 +21,6 @@
import android.os.IBinder;
import android.os.Process;
import android.os.ServiceManager;
-import android.security.KeyStore;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
@@ -954,7 +953,8 @@
assertEquals("Generate should succeed", KeyStore.NO_ERROR, rc);
OperationResult result = mKeyStore.begin(name, KeymasterDefs.KM_PURPOSE_ENCRYPT,
true, args, null, out);
- assertEquals("Begin should succeed", KeyStore.NO_ERROR, result.resultCode);
+ assertEquals("Begin should expect authorization", KeyStore.OP_AUTH_NEEDED,
+ result.resultCode);
IBinder token = result.token;
result = mKeyStore.update(token, null, new byte[] {0x01, 0x02, 0x03, 0x04});
assertEquals("Update should require authorization",
diff --git a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java
similarity index 98%
rename from keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
rename to keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java
index 9c2f358..cad4e54 100644
--- a/keystore/tests/src/android/security/AndroidKeyPairGeneratorTest.java
+++ b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
+import android.security.Credentials;
+import android.security.KeyPairGeneratorSpec;
import android.test.AndroidTestCase;
import java.io.ByteArrayInputStream;
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java
similarity index 99%
rename from keystore/tests/src/android/security/AndroidKeyStoreTest.java
rename to keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java
index 4b2b9b5..2d4e4a0 100644
--- a/keystore/tests/src/android/security/AndroidKeyStoreTest.java
+++ b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-package android.security;
+package android.security.keystore;
import com.android.org.bouncycastle.x509.X509V3CertificateGenerator;
import com.android.org.conscrypt.NativeConstants;
import com.android.org.conscrypt.OpenSSLEngine;
+import android.security.Credentials;
+import android.security.KeyStore;
+import android.security.KeyStoreParameter;
import android.test.AndroidTestCase;
import java.io.ByteArrayInputStream;
@@ -1319,9 +1322,9 @@
}
public void testKeyStore_GetType_Encrypted_Success() throws Exception {
- assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
+ assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType());
setupPassword();
- assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
+ assertEquals(AndroidKeyStoreSpi.NAME, mKeyStore.getType());
}
public void testKeyStore_IsCertificateEntry_CA_Encrypted_Success() throws Exception {
diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk
index 8a4e609..3e76656 100644
--- a/libs/hwui/Android.common.mk
+++ b/libs/hwui/Android.common.mk
@@ -40,11 +40,11 @@
DisplayList.cpp \
DisplayListCanvas.cpp \
Dither.cpp \
- DrawProfiler.cpp \
Extensions.cpp \
FboCache.cpp \
FontRenderer.cpp \
FrameInfo.cpp \
+ FrameInfoVisualizer.cpp \
GammaFontRenderer.cpp \
GlopBuilder.cpp \
GradientCache.cpp \
diff --git a/libs/hwui/DrawProfiler.h b/libs/hwui/DrawProfiler.h
deleted file mode 100644
index ef6101c..0000000
--- a/libs/hwui/DrawProfiler.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef DRAWPROFILER_H
-#define DRAWPROFILER_H
-
-#include "Properties.h"
-#include "Rect.h"
-
-#include <utils/Timers.h>
-
-namespace android {
-namespace uirenderer {
-
-class OpenGLRenderer;
-
-class DrawProfiler {
-public:
- DrawProfiler();
- ~DrawProfiler();
-
- bool consumeProperties();
- void setDensity(float density);
-
- void startFrame(nsecs_t recordDurationNanos = 0);
- void markPlaybackStart();
- void markPlaybackEnd();
- void finishFrame();
-
- void unionDirty(SkRect* dirty);
- void draw(OpenGLRenderer* canvas);
-
- void dumpData(int fd);
-
-private:
- typedef struct {
- float record;
- float prepare;
- float playback;
- float swapBuffers;
- } FrameTimingData;
-
- void createData();
- void destroyData();
-
- void addRect(Rect& r, float data, float* shapeOutput);
- void prepareShapes(const int baseline);
- void drawGraph(OpenGLRenderer* canvas);
- void drawCurrentFrame(OpenGLRenderer* canvas);
- void drawThreshold(OpenGLRenderer* canvas);
-
- ProfileType mType = ProfileType::None;
- float mDensity = 0;
-
- FrameTimingData* mData = nullptr;
- int mDataSize = 0;
-
- int mCurrentFrame = -1;
- nsecs_t mPreviousTime = 0;
-
- int mVerticalUnit = 0;
- int mHorizontalUnit = 0;
- int mThresholdStroke = 0;
-
- /*
- * mRects represents an array of rect shapes, divided into NUM_ELEMENTS
- * groups such that each group is drawn with the same paint.
- * For example mRects[0] is the array of rect floats suitable for
- * OpenGLRenderer:drawRects() that makes up all the FrameTimingData:record
- * information.
- */
- float** mRects = nullptr;
-
- bool mShowDirtyRegions = false;
- SkRect mDirtyRegion;
- bool mFlashToggle = false;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif /* DRAWPROFILER_H */
diff --git a/libs/hwui/DrawProfiler.cpp b/libs/hwui/FrameInfoVisualizer.cpp
similarity index 60%
rename from libs/hwui/DrawProfiler.cpp
rename to libs/hwui/FrameInfoVisualizer.cpp
index 7addef9..0411742 100644
--- a/libs/hwui/DrawProfiler.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -13,19 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#include "DrawProfiler.h"
-
-#include <cutils/compiler.h>
+#include "FrameInfoVisualizer.h"
#include "OpenGLRenderer.h"
-#define DEFAULT_MAX_FRAMES 128
+#include <cutils/compiler.h>
#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == ProfileType::None)) return
#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == ProfileType::None && !mShowDirtyRegions)) return
-#define NANOS_TO_MILLIS_FLOAT(nanos) ((nanos) * 0.000001f)
-
#define PROFILE_DRAW_WIDTH 3
#define PROFILE_DRAW_THRESHOLD_STROKE_WIDTH 2
#define PROFILE_DRAW_DP_PER_MS 7
@@ -55,15 +51,16 @@
return (int) (dp * density + 0.5f);
}
-DrawProfiler::DrawProfiler() {
+FrameInfoVisualizer::FrameInfoVisualizer(FrameInfoSource& source)
+ : mFrameSource(source) {
setDensity(1);
}
-DrawProfiler::~DrawProfiler() {
+FrameInfoVisualizer::~FrameInfoVisualizer() {
destroyData();
}
-void DrawProfiler::setDensity(float density) {
+void FrameInfoVisualizer::setDensity(float density) {
if (CC_UNLIKELY(mDensity != density)) {
mDensity = density;
mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
@@ -72,35 +69,7 @@
}
}
-void DrawProfiler::startFrame(nsecs_t recordDurationNanos) {
- RETURN_IF_PROFILING_DISABLED();
- mData[mCurrentFrame].record = NANOS_TO_MILLIS_FLOAT(recordDurationNanos);
- mPreviousTime = systemTime(CLOCK_MONOTONIC);
-}
-
-void DrawProfiler::markPlaybackStart() {
- RETURN_IF_PROFILING_DISABLED();
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
- mData[mCurrentFrame].prepare = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
- mPreviousTime = now;
-}
-
-void DrawProfiler::markPlaybackEnd() {
- RETURN_IF_PROFILING_DISABLED();
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
- mData[mCurrentFrame].playback = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
- mPreviousTime = now;
-}
-
-void DrawProfiler::finishFrame() {
- RETURN_IF_PROFILING_DISABLED();
- nsecs_t now = systemTime(CLOCK_MONOTONIC);
- mData[mCurrentFrame].swapBuffers = NANOS_TO_MILLIS_FLOAT(now - mPreviousTime);
- mPreviousTime = now;
- mCurrentFrame = (mCurrentFrame + 1) % mDataSize;
-}
-
-void DrawProfiler::unionDirty(SkRect* dirty) {
+void FrameInfoVisualizer::unionDirty(SkRect* dirty) {
RETURN_IF_DISABLED();
// Not worth worrying about minimizing the dirty region for debugging, so just
// dirty the entire viewport.
@@ -110,7 +79,7 @@
}
}
-void DrawProfiler::draw(OpenGLRenderer* canvas) {
+void FrameInfoVisualizer::draw(OpenGLRenderer* canvas) {
RETURN_IF_DISABLED();
if (mShowDirtyRegions) {
@@ -131,27 +100,21 @@
}
}
-void DrawProfiler::createData() {
- if (mData) return;
+void FrameInfoVisualizer::createData() {
+ if (mRects.get()) return;
- mDataSize = property_get_int32(PROPERTY_PROFILE_MAXFRAMES, DEFAULT_MAX_FRAMES);
- if (mDataSize <= 0) mDataSize = 1;
- if (mDataSize > 4096) mDataSize = 4096; // Reasonable maximum
- mData = (FrameTimingData*) calloc(mDataSize, sizeof(FrameTimingData));
- mRects = new float*[NUM_ELEMENTS];
+ mRects.reset(new float*[mFrameSource.capacity()]);
for (int i = 0; i < NUM_ELEMENTS; i++) {
// 4 floats per rect
- mRects[i] = (float*) calloc(mDataSize, 4 * sizeof(float));
+ mRects.get()[i] = (float*) calloc(mFrameSource.capacity(), 4 * sizeof(float));
}
- mCurrentFrame = 0;
}
-void DrawProfiler::destroyData() {
- delete mData;
- mData = nullptr;
+void FrameInfoVisualizer::destroyData() {
+ mRects.reset(nullptr);
}
-void DrawProfiler::addRect(Rect& r, float data, float* shapeOutput) {
+void FrameInfoVisualizer::addRect(Rect& r, float data, float* shapeOutput) {
r.top = r.bottom - (data * mVerticalUnit);
shapeOutput[0] = r.left;
shapeOutput[1] = r.top;
@@ -160,40 +123,40 @@
r.bottom = r.top;
}
-void DrawProfiler::prepareShapes(const int baseline) {
+void FrameInfoVisualizer::prepareShapes(const int baseline) {
Rect r;
r.right = mHorizontalUnit;
- for (int i = 0; i < mDataSize; i++) {
+ for (size_t i = 0; i < mFrameSource.size(); i++) {
const int shapeIndex = i * 4;
r.bottom = baseline;
- addRect(r, mData[i].record, mRects[RECORD_INDEX] + shapeIndex);
- addRect(r, mData[i].prepare, mRects[PREPARE_INDEX] + shapeIndex);
- addRect(r, mData[i].playback, mRects[PLAYBACK_INDEX] + shapeIndex);
- addRect(r, mData[i].swapBuffers, mRects[SWAPBUFFERS_INDEX] + shapeIndex);
+ addRect(r, recordDuration(i), mRects.get()[RECORD_INDEX] + shapeIndex);
+ addRect(r, prepareDuration(i), mRects.get()[PREPARE_INDEX] + shapeIndex);
+ addRect(r, issueDrawDuration(i), mRects.get()[PLAYBACK_INDEX] + shapeIndex);
+ addRect(r, swapBuffersDuration(i), mRects.get()[SWAPBUFFERS_INDEX] + shapeIndex);
r.translate(mHorizontalUnit, 0);
}
}
-void DrawProfiler::drawGraph(OpenGLRenderer* canvas) {
+void FrameInfoVisualizer::drawGraph(OpenGLRenderer* canvas) {
SkPaint paint;
for (int i = 0; i < NUM_ELEMENTS; i++) {
paint.setColor(ELEMENT_COLORS[i]);
- canvas->drawRects(mRects[i], mDataSize * 4, &paint);
+ canvas->drawRects(mRects.get()[i], mFrameSource.capacity() * 4, &paint);
}
}
-void DrawProfiler::drawCurrentFrame(OpenGLRenderer* canvas) {
+void FrameInfoVisualizer::drawCurrentFrame(OpenGLRenderer* canvas) {
// This draws a solid rect over the entirety of the current frame's shape
// To do so we use the bottom of mRects[0] and the top of mRects[NUM_ELEMENTS-1]
// which will therefore fully overlap the previously drawn rects
SkPaint paint;
paint.setColor(CURRENT_FRAME_COLOR);
- const int i = mCurrentFrame * 4;
- canvas->drawRect(mRects[0][i], mRects[NUM_ELEMENTS-1][i+1], mRects[0][i+2],
- mRects[0][i+3], &paint);
+ const int i = (mFrameSource.size() - 1) * 4;
+ canvas->drawRect(mRects.get()[0][i], mRects.get()[NUM_ELEMENTS-1][i+1],
+ mRects.get()[0][i+2], mRects.get()[0][i+3], &paint);
}
-void DrawProfiler::drawThreshold(OpenGLRenderer* canvas) {
+void FrameInfoVisualizer::drawThreshold(OpenGLRenderer* canvas) {
SkPaint paint;
paint.setColor(THRESHOLD_COLOR);
paint.setStrokeWidth(mThresholdStroke);
@@ -205,7 +168,7 @@
canvas->drawLines(pts, 4, &paint);
}
-bool DrawProfiler::consumeProperties() {
+bool FrameInfoVisualizer::consumeProperties() {
bool changed = false;
ProfileType newType = Properties::getProfileType();
if (newType != mType) {
@@ -226,29 +189,25 @@
return changed;
}
-void DrawProfiler::dumpData(int fd) {
+void FrameInfoVisualizer::dumpData(int fd) {
RETURN_IF_PROFILING_DISABLED();
// This method logs the last N frames (where N is <= mDataSize) since the
// last call to dumpData(). In other words if there's a dumpData(), draw frame,
// dumpData(), the last dumpData() should only log 1 frame.
- const FrameTimingData emptyData = {0, 0, 0, 0};
-
FILE *file = fdopen(fd, "a");
fprintf(file, "\n\tDraw\tPrepare\tProcess\tExecute\n");
- for (int frameOffset = 1; frameOffset <= mDataSize; frameOffset++) {
- int i = (mCurrentFrame + frameOffset) % mDataSize;
- if (!memcmp(mData + i, &emptyData, sizeof(FrameTimingData))) {
+ for (size_t i = 0; i < mFrameSource.size(); i++) {
+ if (mFrameSource[i][FrameInfoIndex::kIntendedVsync] <= mLastFrameLogged) {
continue;
}
+ mLastFrameLogged = mFrameSource[i][FrameInfoIndex::kIntendedVsync];
fprintf(file, "\t%3.2f\t%3.2f\t%3.2f\t%3.2f\n",
- mData[i].record, mData[i].prepare, mData[i].playback, mData[i].swapBuffers);
+ recordDuration(i), prepareDuration(i),
+ issueDrawDuration(i), swapBuffersDuration(i));
}
- // reset the buffer
- memset(mData, 0, sizeof(FrameTimingData) * mDataSize);
- mCurrentFrame = 0;
fflush(file);
}
diff --git a/libs/hwui/FrameInfoVisualizer.h b/libs/hwui/FrameInfoVisualizer.h
new file mode 100644
index 0000000..f62e34d
--- /dev/null
+++ b/libs/hwui/FrameInfoVisualizer.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef DRAWPROFILER_H
+#define DRAWPROFILER_H
+
+#include "FrameInfo.h"
+#include "Properties.h"
+#include "Rect.h"
+#include "utils/RingBuffer.h"
+
+#include <utils/Timers.h>
+
+#include <memory>
+
+namespace android {
+namespace uirenderer {
+
+class OpenGLRenderer;
+
+// TODO: This is a bit awkward as it needs to match the thing in CanvasContext
+// A better abstraction here would be nice but iterators are painful
+// and RingBuffer having the size baked into the template is also painful
+// But making DrawProfiler also be templated is ALSO painful
+// At least this is a compile failure if this doesn't match, so there's that.
+typedef RingBuffer<FrameInfo, 120> FrameInfoSource;
+
+class FrameInfoVisualizer {
+public:
+ FrameInfoVisualizer(FrameInfoSource& source);
+ ~FrameInfoVisualizer();
+
+ bool consumeProperties();
+ void setDensity(float density);
+
+ void unionDirty(SkRect* dirty);
+ void draw(OpenGLRenderer* canvas);
+
+ void dumpData(int fd);
+
+private:
+ void createData();
+ void destroyData();
+
+ void addRect(Rect& r, float data, float* shapeOutput);
+ void prepareShapes(const int baseline);
+ void drawGraph(OpenGLRenderer* canvas);
+ void drawCurrentFrame(OpenGLRenderer* canvas);
+ void drawThreshold(OpenGLRenderer* canvas);
+
+ static inline float duration(nsecs_t start, nsecs_t end) {
+ float duration = ((end - start) * 0.000001f);
+ return duration > 0.0f ? duration : 0.0f;
+ }
+
+ inline float recordDuration(size_t index) {
+ return duration(
+ mFrameSource[index][FrameInfoIndex::kIntendedVsync],
+ mFrameSource[index][FrameInfoIndex::kSyncStart]);
+ }
+
+ inline float prepareDuration(size_t index) {
+ return duration(
+ mFrameSource[index][FrameInfoIndex::kSyncStart],
+ mFrameSource[index][FrameInfoIndex::kIssueDrawCommandsStart]);
+ }
+
+ inline float issueDrawDuration(size_t index) {
+ return duration(
+ mFrameSource[index][FrameInfoIndex::kIssueDrawCommandsStart],
+ mFrameSource[index][FrameInfoIndex::kSwapBuffers]);
+ }
+
+ inline float swapBuffersDuration(size_t index) {
+ return duration(
+ mFrameSource[index][FrameInfoIndex::kSwapBuffers],
+ mFrameSource[index][FrameInfoIndex::kFrameCompleted]);
+ }
+
+ ProfileType mType = ProfileType::None;
+ float mDensity = 0;
+
+ FrameInfoSource& mFrameSource;
+
+ int mVerticalUnit = 0;
+ int mHorizontalUnit = 0;
+ int mThresholdStroke = 0;
+
+ /*
+ * mRects represents an array of rect shapes, divided into NUM_ELEMENTS
+ * groups such that each group is drawn with the same paint.
+ * For example mRects[0] is the array of rect floats suitable for
+ * OpenGLRenderer:drawRects() that makes up all the FrameTimingData:record
+ * information.
+ */
+ std::unique_ptr<float*> mRects;
+
+ bool mShowDirtyRegions = false;
+ SkRect mDirtyRegion;
+ bool mFlashToggle = false;
+ nsecs_t mLastFrameLogged = 0;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DRAWPROFILER_H */
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 458f35b..e16865e 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -90,8 +90,10 @@
// re-init renderer's light position, based upon last cached location in window
Vector3 lightPos = rootRenderer.getLightCenter();
cachedInvTransformInWindow.mapPoint3d(lightPos);
- renderer->initLight(lightPos, rootRenderer.getLightRadius(),
- rootRenderer.getAmbientShadowAlpha(), rootRenderer.getSpotShadowAlpha());
+ renderer->initLight(rootRenderer.getLightRadius(),
+ rootRenderer.getAmbientShadowAlpha(),
+ rootRenderer.getSpotShadowAlpha());
+ renderer->setLightCenter(lightPos);
rendererLightPosDirty = false;
}
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 09674f7..54bcd7e 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -94,14 +94,17 @@
}
}
-void OpenGLRenderer::initLight(const Vector3& lightCenter, float lightRadius,
- uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
- mLightCenter = lightCenter;
+void OpenGLRenderer::initLight(float lightRadius, uint8_t ambientShadowAlpha,
+ uint8_t spotShadowAlpha) {
mLightRadius = lightRadius;
mAmbientShadowAlpha = ambientShadowAlpha;
mSpotShadowAlpha = spotShadowAlpha;
}
+void OpenGLRenderer::setLightCenter(const Vector3& lightCenter) {
+ mLightCenter = lightCenter;
+}
+
///////////////////////////////////////////////////////////////////////////////
// Setup
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index c34eb2c..218818d 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -127,8 +127,9 @@
void setViewport(int width, int height) { mState.setViewport(width, height); }
void initProperties();
- void initLight(const Vector3& lightCenter, float lightRadius,
- uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
+ void initLight(float lightRadius, uint8_t ambientShadowAlpha,
+ uint8_t spotShadowAlpha);
+ void setLightCenter(const Vector3& lightCenter);
/*
* Prepares the renderer to draw a frame. This method must be invoked
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 8f5fea3..e466604 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -280,6 +280,7 @@
}
void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
+ ATRACE_NAME("Upload Path Texture");
SkAutoLockPixels alp(bitmap);
if (!bitmap.readyToDraw()) {
ALOGE("Cannot generate texture from bitmap");
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index cb5560f..26d8bf7 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -109,20 +109,6 @@
#define PROPERTY_PROFILE_VISUALIZE_BARS "visual_bars"
/**
- * System property used to specify the number of frames to be used
- * when doing hardware rendering profiling.
- * The default value of this property is #PROFILE_MAX_FRAMES.
- *
- * When profiling is enabled, the adb shell dumpsys gfxinfo command will
- * output extra information about the time taken to execute by the last
- * frames.
- *
- * Possible values:
- * "60", to set the limit of frames to 60
- */
-#define PROPERTY_PROFILE_MAXFRAMES "debug.hwui.profile.maxframes"
-
-/**
* Used to enable/disable non-rectangular clipping debugging.
*
* The accepted values are:
@@ -250,7 +236,7 @@
#define DEFAULT_TEXTURE_CACHE_SIZE 24.0f
#define DEFAULT_LAYER_CACHE_SIZE 16.0f
#define DEFAULT_RENDER_BUFFER_CACHE_SIZE 2.0f
-#define DEFAULT_PATH_CACHE_SIZE 10.0f
+#define DEFAULT_PATH_CACHE_SIZE 4.0f
#define DEFAULT_VERTEX_CACHE_SIZE 1.0f
#define DEFAULT_PATCH_CACHE_SIZE 128 // in kB
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 8f95e0d..9146b68 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -392,6 +392,13 @@
}
LOG_ALWAYS_FATAL_IF(!isLayer && properties().getHasOverlappingRendering());
renderer.scaleAlpha(properties().getAlpha());
+
+ if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) {
+ // pretend to cause savelayer to warn about performance problem affecting old versions
+ ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(),
+ static_cast<int>(getWidth()),
+ static_cast<int>(getHeight()));
+ }
}
if (clipFlags) {
Rect clipRect;
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index a43566d..98029a8 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -576,15 +576,15 @@
&& getOutline().getAlpha() != 0.0f;
}
- LayerType effectiveLayerType() const {
- LayerType type = mLayerProperties.mType;
- if (type == LayerType::None
+ bool promotedToLayer() const {
+ return mLayerProperties.mType == LayerType::None
&& !MathUtils::isZero(mPrimitiveFields.mAlpha)
&& mPrimitiveFields.mAlpha < 1
- && mPrimitiveFields.mHasOverlappingRendering) {
- return LayerType::RenderLayer;
- }
- return type;
+ && mPrimitiveFields.mHasOverlappingRendering;
+ }
+
+ LayerType effectiveLayerType() const {
+ return promotedToLayer() ? LayerType::RenderLayer : mLayerProperties.mType;
}
private:
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 733e5e0..8329cd4 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -46,7 +46,8 @@
, mOpaque(!translucent)
, mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
, mRootRenderNode(rootRenderNode)
- , mJankTracker(thread.timeLord().frameIntervalNanos()) {
+ , mJankTracker(thread.timeLord().frameIntervalNanos())
+ , mProfiler(mFrames) {
mRenderThread.renderState().registerCanvasContext(this);
mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
}
@@ -126,10 +127,15 @@
}
// TODO: don't pass viewport size, it's automatic via EGL
-void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
+void CanvasContext::setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
if (!mCanvas) return;
- mCanvas->initLight(lightCenter, lightRadius, ambientShadowAlpha, spotShadowAlpha);
+ mCanvas->initLight(lightRadius, ambientShadowAlpha, spotShadowAlpha);
+}
+
+void CanvasContext::setLightCenter(const Vector3& lightCenter) {
+ if (!mCanvas) return;
+ mCanvas->setLightCenter(lightCenter);
}
void CanvasContext::setOpaque(bool opaque) {
@@ -218,7 +224,6 @@
return;
}
- profiler().markPlaybackStart();
mCurrentFrameInfo->markIssueDrawCommandsStart();
EGLint width, height;
@@ -251,8 +256,6 @@
bool drew = mCanvas->finish();
- profiler().markPlaybackEnd();
-
// Even if we decided to cancel the frame, from the perspective of jank
// metrics the frame was swapped at this point
mCurrentFrameInfo->markSwapBuffers();
@@ -267,7 +270,6 @@
mCurrentFrameInfo->markFrameCompleted();
mJankTracker.addFrame(*mCurrentFrameInfo);
mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
- profiler().finishFrame();
}
// Called by choreographer to do an RT-driven animation
@@ -278,7 +280,6 @@
ATRACE_CALL();
- profiler().startFrame();
int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
UiFrameInfoBuilder(frameInfo)
.addFlag(FrameInfoFlags::kRTAnimation)
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 8163b0f..17917af 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -18,9 +18,9 @@
#define CANVASCONTEXT_H_
#include "DamageAccumulator.h"
-#include "DrawProfiler.h"
#include "IContextFactory.h"
#include "FrameInfo.h"
+#include "FrameInfoVisualizer.h"
#include "RenderNode.h"
#include "utils/RingBuffer.h"
#include "renderthread/RenderTask.h"
@@ -72,8 +72,9 @@
bool pauseSurface(ANativeWindow* window);
bool hasSurface() { return mNativeWindow.get(); }
- void setup(int width, int height, const Vector3& lightCenter, float lightRadius,
+ void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
+ void setLightCenter(const Vector3& lightCenter);
void setOpaque(bool opaque);
void makeCurrent();
void processLayerUpdate(DeferredLayerUpdater* layerUpdater);
@@ -103,7 +104,7 @@
void stopDrawing();
void notifyFramePending();
- DrawProfiler& profiler() { return mProfiler; }
+ FrameInfoVisualizer& profiler() { return mProfiler; }
void dumpFrames(int fd);
void resetFrameStats();
@@ -140,12 +141,12 @@
const sp<RenderNode> mRootRenderNode;
- DrawProfiler mProfiler;
FrameInfo* mCurrentFrameInfo = nullptr;
- // Ring buffer large enough for 1 second worth of frames
- RingBuffer<FrameInfo, 60> mFrames;
+ // Ring buffer large enough for 2 seconds worth of frames
+ RingBuffer<FrameInfo, 120> mFrames;
std::string mName;
JankTracker mJankTracker;
+ FrameInfoVisualizer mProfiler;
std::set<RenderNode*> mPrefetechedLayers;
};
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 35391b2..83af4ae 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -83,8 +83,6 @@
void DrawFrameTask::run() {
ATRACE_NAME("DrawFrame");
- mContext->profiler().startFrame();
-
bool canUnblockUiThread;
bool canDrawThisFrame;
{
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 17e47b9..d8a9921 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -172,27 +172,37 @@
return (bool) postAndWait(task);
}
-CREATE_BRIDGE7(setup, CanvasContext* context, int width, int height,
- Vector3 lightCenter, float lightRadius,
- uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
- args->context->setup(args->width, args->height, args->lightCenter, args->lightRadius,
+CREATE_BRIDGE6(setup, CanvasContext* context, int width, int height,
+ float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
+ args->context->setup(args->width, args->height, args->lightRadius,
args->ambientShadowAlpha, args->spotShadowAlpha);
return nullptr;
}
-void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
+void RenderProxy::setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
SETUP_TASK(setup);
args->context = mContext;
args->width = width;
args->height = height;
- args->lightCenter = lightCenter;
args->lightRadius = lightRadius;
args->ambientShadowAlpha = ambientShadowAlpha;
args->spotShadowAlpha = spotShadowAlpha;
post(task);
}
+CREATE_BRIDGE2(setLightCenter, CanvasContext* context, Vector3 lightCenter) {
+ args->context->setLightCenter(args->lightCenter);
+ return nullptr;
+}
+
+void RenderProxy::setLightCenter(const Vector3& lightCenter) {
+ SETUP_TASK(setLightCenter);
+ args->context = mContext;
+ args->lightCenter = lightCenter;
+ post(task);
+}
+
CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) {
args->context->setOpaque(args->opaque);
return nullptr;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 31456cd..5febbe0 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -70,8 +70,9 @@
ANDROID_API bool initialize(const sp<ANativeWindow>& window);
ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
ANDROID_API bool pauseSurface(const sp<ANativeWindow>& window);
- ANDROID_API void setup(int width, int height, const Vector3& lightCenter, float lightRadius,
+ ANDROID_API void setup(int width, int height, float lightRadius,
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
+ ANDROID_API void setLightCenter(const Vector3& lightCenter);
ANDROID_API void setOpaque(bool opaque);
ANDROID_API int64_t* frameInfo();
ANDROID_API int syncAndDrawFrame();
diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp
index 2f79c58..ceee953 100644
--- a/libs/hwui/tests/main.cpp
+++ b/libs/hwui/tests/main.cpp
@@ -92,8 +92,8 @@
proxy->loadSystemProperties();
proxy->initialize(surface);
float lightX = width / 2.0;
- proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)},
- dp(800.0f), 255 * 0.075, 255 * 0.15);
+ proxy->setup(width, height, dp(800.0f), 255 * 0.075, 255 * 0.15);
+ proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
android::uirenderer::Rect DUMMY;
diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h
index fc9aec0..6d0a06b 100644
--- a/libs/hwui/utils/RingBuffer.h
+++ b/libs/hwui/utils/RingBuffer.h
@@ -31,7 +31,7 @@
RingBuffer() {}
~RingBuffer() {}
- size_t capacity() { return SIZE; }
+ constexpr size_t capacity() { return SIZE; }
size_t size() { return mCount; }
T& next() {
diff --git a/libs/hwui/utils/TraceUtils.h b/libs/hwui/utils/TraceUtils.h
index ff8ccb8..ddc272c 100644
--- a/libs/hwui/utils/TraceUtils.h
+++ b/libs/hwui/utils/TraceUtils.h
@@ -35,7 +35,7 @@
};
static void atraceFormatBegin(const char* fmt, ...) {
- if (CC_UNLIKELY(!ATRACE_ENABLED())) return;
+ if (CC_LIKELY(!ATRACE_ENABLED())) return;
const int BUFFER_SIZE = 256;
va_list ap;
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index af76175..a3ea896 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -77,14 +77,15 @@
ProviderProperties getProviderProperties(String provider);
boolean isProviderEnabled(String provider);
- void addTestProvider(String name, in ProviderProperties properties);
- void removeTestProvider(String provider);
- void setTestProviderLocation(String provider, in Location loc);
- void clearTestProviderLocation(String provider);
- void setTestProviderEnabled(String provider, boolean enabled);
- void clearTestProviderEnabled(String provider);
- void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime);
- void clearTestProviderStatus(String provider);
+ void addTestProvider(String name, in ProviderProperties properties, String opPackageName);
+ void removeTestProvider(String provider, String opPackageName);
+ void setTestProviderLocation(String provider, in Location loc, String opPackageName);
+ void clearTestProviderLocation(String provider, String opPackageName);
+ void setTestProviderEnabled(String provider, boolean enabled, String opPackageName);
+ void clearTestProviderEnabled(String provider, String opPackageName);
+ void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime,
+ String opPackageName);
+ void clearTestProviderStatus(String provider, String opPackageName);
boolean sendExtraCommand(String provider, String command, inout Bundle extras);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index a3d04d9..b09f216 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -37,7 +37,6 @@
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
-import static android.Manifest.permission.ACCESS_MOCK_LOCATION;
/**
* This class provides access to the system location services. These
@@ -1218,12 +1217,11 @@
*
* @param name the provider name
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if a provider with the given name already exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
@@ -1235,7 +1233,7 @@
}
try {
- mService.addTestProvider(name, properties);
+ mService.addTestProvider(name, properties, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1246,15 +1244,14 @@
*
* @param provider the provider name
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void removeTestProvider(String provider) {
try {
- mService.removeTestProvider(provider);
+ mService.removeTestProvider(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1270,13 +1267,12 @@
* @param provider the provider name
* @param loc the mock location
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
* @throws IllegalArgumentException if the location is incomplete
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void setTestProviderLocation(String provider, Location loc) {
if (!loc.isComplete()) {
IllegalArgumentException e = new IllegalArgumentException(
@@ -1292,7 +1288,7 @@
}
try {
- mService.setTestProviderLocation(provider, loc);
+ mService.setTestProviderLocation(provider, loc, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1303,15 +1299,14 @@
*
* @param provider the provider name
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void clearTestProviderLocation(String provider) {
try {
- mService.clearTestProviderLocation(provider);
+ mService.clearTestProviderLocation(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1324,15 +1319,14 @@
* @param provider the provider name
* @param enabled the mock enabled value
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void setTestProviderEnabled(String provider, boolean enabled) {
try {
- mService.setTestProviderEnabled(provider, enabled);
+ mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1343,15 +1337,14 @@
*
* @param provider the provider name
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void clearTestProviderEnabled(String provider) {
try {
- mService.clearTestProviderEnabled(provider);
+ mService.clearTestProviderEnabled(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1366,15 +1359,15 @@
* @param extras a Bundle containing mock extras
* @param updateTime the mock update time
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
try {
- mService.setTestProviderStatus(provider, status, extras, updateTime);
+ mService.setTestProviderStatus(provider, status, extras, updateTime,
+ mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
@@ -1385,15 +1378,14 @@
*
* @param provider the provider name
*
- * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present
- * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION
- * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled
+ * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION
+ * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED
+ * allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- @RequiresPermission(value = ACCESS_MOCK_LOCATION, conditional = true)
public void clearTestProviderStatus(String provider) {
try {
- mService.clearTestProviderStatus(provider);
+ mService.clearTestProviderStatus(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
}
diff --git a/media/java/android/media/OnAudioDeviceConnectionListener.java b/media/java/android/media/AudioDeviceCallback.java
similarity index 84%
rename from media/java/android/media/OnAudioDeviceConnectionListener.java
rename to media/java/android/media/AudioDeviceCallback.java
index 57e9e17..d7fa492 100644
--- a/media/java/android/media/OnAudioDeviceConnectionListener.java
+++ b/media/java/android/media/AudioDeviceCallback.java
@@ -20,12 +20,13 @@
* OnAudioDeviceConnectionListener defines the interface for notification listeners in the
* {@link AudioManager}
*/
-public interface OnAudioDeviceConnectionListener {
+public abstract class AudioDeviceCallback {
/**
* Called by the {@link AudioManager} to indicate that an audio device has been
* connected or disconnected. A listener will probably call the
* {@link AudioManager#getDevices} method to retrieve the current list of audio
* devices.
*/
- public void onAudioDeviceConnection();
+ public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {}
+ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {}
}
diff --git a/media/java/android/media/AudioDeviceInfo.java b/media/java/android/media/AudioDeviceInfo.java
index 566f8dc..2099bd0 100644
--- a/media/java/android/media/AudioDeviceInfo.java
+++ b/media/java/android/media/AudioDeviceInfo.java
@@ -16,6 +16,7 @@
package android.media;
+import android.annotation.NonNull;
import android.util.SparseIntArray;
/**
@@ -121,8 +122,9 @@
/**
* @return The human-readable name of the audio device.
*/
- public CharSequence getName() {
- return mPort.name();
+ public CharSequence getProductName() {
+ String portName = mPort.name();
+ return portName.length() != 0 ? portName : android.os.Build.MODEL;
}
/**
@@ -151,27 +153,38 @@
/**
* @return An array of sample rates supported by the audio device.
*/
- public int[] getSampleRates() {
+ public @NonNull int[] getSampleRates() {
return mPort.samplingRates();
}
/**
- * @return An array of channel masks ({@link AudioFormat#CHANNEL_IN_STEREO},
- * {@link AudioFormat#CHANNEL_OUT_7POINT1) for which this audio device can be configured.
+ * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO},
+ * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
*
* @see AudioFormat
*/
- public int[] getChannelMasks() {
+ public @NonNull int[] getChannelMasks() {
return mPort.channelMasks();
}
/**
- * @return An array of channel counts (1, 2, 4....) for which this audio device
+ * @return An array of channel index masks for which this audio device can be configured.
+ *
+ * @see AudioFormat
+ */
+ public @NonNull int[] getChannelIndexMasks() {
+ // TODO: implement
+ return new int[0];
+ }
+
+ /**
+ * @return An array of channel counts (1, 2, 4, ...) for which this audio device
* can be configured.
*/
- public int[] getChannelCounts() {
+ public @NonNull int[] getChannelCounts() {
int[] masks = getChannelMasks();
int[] counts = new int[masks.length];
+ // TODO: consider channel index masks
for (int mask_index = 0; mask_index < masks.length; mask_index++) {
counts[mask_index] = isSink()
? AudioFormat.channelCountFromOutChannelMask(masks[mask_index])
@@ -181,12 +194,16 @@
}
/**
- * @return An array of audio format IDs (@link AudioFormat#ENCODING_PCM_16BIT,
- * {@link AudioFormat#ENCODING_PCM_FLOAT}...) supported by the audio device.
+ * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT},
+ * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device.
+ * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more
+ * than 16 bits of integer precision. Specifying <code>ENCODING_PCM_FLOAT</code>
+ * with {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of
+ * integer precision to that device.
*
* @see AudioFormat
*/
- public int[] getFormats() {
+ public @NonNull int[] getEncodings() {
return mPort.formats();
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index cba83f9..e7013a5 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3710,11 +3710,12 @@
* The message sent to apps when the contents of the device list changes if they provide
* a {#link Handler} object to addOnAudioDeviceConnectionListener().
*/
- private final static int MSG_DEVICES_LIST_CHANGE = 0;
+ private final static int MSG_DEVICES_DEVICES_ADDED = 0;
+ private final static int MSG_DEVICES_DEVICES_REMOVED = 1;
- private ArrayMap<OnAudioDeviceConnectionListener, NativeEventHandlerDelegate>
- mDeviceConnectionListeners =
- new ArrayMap<OnAudioDeviceConnectionListener, NativeEventHandlerDelegate>();
+ private ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>
+ mDeviceCallbacks =
+ new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>();
/**
* Specifies to the {@link AudioManager#getDevices(int)} method to include
@@ -3757,22 +3758,8 @@
return getDevicesStatic(flags);
}
- /**
- * Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently
- * connected to the system and meeting the criteria specified in the <code>flags</code>
- * parameter.
- * @param flags A set of bitflags specifying the criteria to test.
- * @see {@link GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}.
- * @return A (possibly zero-length) array of AudioDeviceInfo objects.
- * @hide
- */
- public static AudioDeviceInfo[] getDevicesStatic(int flags) {
- ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>();
- int status = AudioManager.listAudioDevicePorts(ports);
- if (status != AudioManager.SUCCESS) {
- // fail and bail!
- return new AudioDeviceInfo[0];
- }
+ private static AudioDeviceInfo[]
+ infoListFromPortList(ArrayList<AudioDevicePort> ports, int flags) {
// figure out how many AudioDeviceInfo we need space for
int numRecs = 0;
@@ -3794,28 +3781,74 @@
return deviceList;
}
+ /*
+ * Calculate the list of ports that are in ports_B, but not in ports_A
+ */
+ private static AudioDeviceInfo[] calcListDeltas(
+ ArrayList<AudioDevicePort> ports_A, ArrayList<AudioDevicePort> ports_B, int flags) {
+
+ ArrayList<AudioDevicePort> delta_ports = new ArrayList<AudioDevicePort>();
+
+ AudioDevicePort cur_port = null;
+ for (int cur_index = 0; cur_index < ports_B.size(); cur_index++) {
+ boolean cur_port_found = false;
+ cur_port = ports_B.get(cur_index);
+ for (int prev_index = 0;
+ prev_index < ports_A.size() && !cur_port_found;
+ prev_index++) {
+ cur_port_found = (cur_port.id() == ports_A.get(prev_index).id());
+ }
+
+ if (!cur_port_found) {
+ delta_ports.add(cur_port);
+ }
+ }
+
+ return infoListFromPortList(delta_ports, flags);
+ }
+
/**
- * Adds an {@link OnAudioDeviceConnectionListener} to receive notifications of changes
+ * Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently
+ * connected to the system and meeting the criteria specified in the <code>flags</code>
+ * parameter.
+ * @param flags A set of bitflags specifying the criteria to test.
+ * @see {@link GET_DEVICES_OUTPUTS}, {@link GET_DEVICES_INPUTS} and {@link GET_DEVICES_ALL}.
+ * @return A (possibly zero-length) array of AudioDeviceInfo objects.
+ * @hide
+ */
+ public static AudioDeviceInfo[] getDevicesStatic(int flags) {
+ ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>();
+ int status = AudioManager.listAudioDevicePorts(ports);
+ if (status != AudioManager.SUCCESS) {
+ // fail and bail!
+ return new AudioDeviceInfo[0];
+ }
+
+ return infoListFromPortList(ports, flags);
+ }
+
+ /**
+ * Adds an {@link AudioDeviceCallback} to receive notifications of changes
* to the set of connected audio devices.
*/
- public void addOnAudioDeviceConnectionListener(OnAudioDeviceConnectionListener listener,
+ public void registerAudioDeviceCallback(AudioDeviceCallback callback,
android.os.Handler handler) {
- if (listener != null && !mDeviceConnectionListeners.containsKey(listener)) {
- synchronized (mDeviceConnectionListeners) {
- mDeviceConnectionListeners.put(
- listener, new NativeEventHandlerDelegate(listener, handler));
+ if (callback != null && !mDeviceCallbacks.containsKey(callback)) {
+ synchronized (mDeviceCallbacks) {
+ mDeviceCallbacks.put(
+ callback, new NativeEventHandlerDelegate(callback, handler));
}
}
}
/**
- * Removes an {@link OnAudioDeviceConnectionListener} which has been previously registered
+ * Removes an {@link AudioDeviceCallback} which has been previously registered
* to receive notifications of changes to the set of connected audio devices.
*/
- public void removeOnAudioDeviceConnectionListener(OnAudioDeviceConnectionListener listener) {
- synchronized (mDeviceConnectionListeners) {
- if (mDeviceConnectionListeners.containsKey(listener)) {
- mDeviceConnectionListeners.remove(listener);
+ public void unregisterAudioDeviceCallback(AudioDeviceCallback callback) {
+ synchronized (mDeviceCallbacks) {
+ if (mDeviceCallbacks.containsKey(callback)) {
+ mDeviceCallbacks.remove(callback);
}
}
}
@@ -3824,14 +3857,42 @@
* Sends device list change notification to all listeners.
*/
private void broadcastDeviceListChange() {
- Collection<NativeEventHandlerDelegate> values;
- synchronized (mDeviceConnectionListeners) {
- values = mDeviceConnectionListeners.values();
+ int status;
+
+ ArrayList<AudioDevicePort> previous_ports = new ArrayList<AudioDevicePort>();
+ status = AudioManager.listPreviousAudioDevicePorts(previous_ports);
+ if (status != AudioManager.SUCCESS) {
+ return;
}
- for (NativeEventHandlerDelegate delegate : values) {
- Handler handler = delegate.getHandler();
- if (handler != null) {
- handler.sendEmptyMessage(MSG_DEVICES_LIST_CHANGE);
+
+ ArrayList<AudioDevicePort> current_ports = new ArrayList<AudioDevicePort>();
+ status = AudioManager.listAudioDevicePorts(current_ports);
+ if (status != AudioManager.SUCCESS) {
+ return;
+ }
+
+ AudioDeviceInfo[] added_devices =
+ calcListDeltas(previous_ports, current_ports, GET_DEVICES_ALL);
+ AudioDeviceInfo[] removed_devices =
+ calcListDeltas(current_ports, previous_ports, GET_DEVICES_ALL);
+
+ if (added_devices.length != 0 || removed_devices.length != 0) {
+ Collection<NativeEventHandlerDelegate> values;
+ synchronized (mDeviceCallbacks) {
+ values = mDeviceCallbacks.values();
+ }
+ for (NativeEventHandlerDelegate delegate : values) {
+ Handler handler = delegate.getHandler();
+ if (handler != null) {
+ if (added_devices.length != 0) {
+ handler.sendMessage(
+ Message.obtain(handler,MSG_DEVICES_DEVICES_ADDED, added_devices));
+ }
+ if (removed_devices.length != 0) {
+ handler.sendMessage(
+ Message.obtain(handler,MSG_DEVICES_DEVICES_REMOVED, removed_devices));
+ }
+ }
}
}
}
@@ -3869,7 +3930,7 @@
private class NativeEventHandlerDelegate {
private final Handler mHandler;
- NativeEventHandlerDelegate(final OnAudioDeviceConnectionListener listener,
+ NativeEventHandlerDelegate(final AudioDeviceCallback callback,
Handler handler) {
// find the looper for our new event handler
Looper looper;
@@ -3887,12 +3948,19 @@
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
- case MSG_DEVICES_LIST_CHANGE:
+ case MSG_DEVICES_DEVICES_ADDED:
// call the OnAudioDeviceConnectionListener
- if (listener != null) {
- listener.onAudioDeviceConnection();
+ if (callback != null) {
+ callback.onAudioDevicesAdded((AudioDeviceInfo[])msg.obj);
}
break;
+
+ case MSG_DEVICES_DEVICES_REMOVED:
+ if (callback != null) {
+ callback.onAudioDevicesRemoved((AudioDeviceInfo[])msg.obj);
+ }
+ break;
+
default:
Log.e(TAG, "Unknown native event type: " + msg.what);
break;
@@ -3908,5 +3976,4 @@
return mHandler;
}
}
-
}
diff --git a/media/java/android/media/AudioManagerInternal.java b/media/java/android/media/AudioManagerInternal.java
index a721923..ac59ace 100644
--- a/media/java/android/media/AudioManagerInternal.java
+++ b/media/java/android/media/AudioManagerInternal.java
@@ -43,6 +43,8 @@
public abstract int getVolumeControllerUid();
+ public abstract void updateRingerModeAffectedStreamsInternal();
+
public interface RingerModeDelegate {
/** Called when external ringer mode is evaluated, returns the new internal ringer mode */
int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
@@ -53,5 +55,7 @@
int ringerModeExternal, VolumePolicy policy);
boolean canVolumeDownEnterSilent();
+
+ int getRingerModeAffectedStreams(int streams);
}
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index eda14a7..f893fdd 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -242,7 +242,7 @@
/**
* The audio channel mask used for calling native AudioTrack
*/
- private int mChannels = AudioFormat.CHANNEL_OUT_MONO;
+ private int mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
/**
* The type of the audio stream to play. See
@@ -485,7 +485,7 @@
session[0] = sessionId;
// native initialization
int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
- mSampleRate, mChannels, mChannelIndexMask, mAudioFormat,
+ mSampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
mNativeBufferSizeInBytes, mDataLoadMode, session);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing AudioTrack.");
@@ -699,7 +699,7 @@
// This is where constructor IllegalArgumentException-s are thrown
// postconditions:
// mChannelCount is valid
- // mChannels is valid
+ // mChannelMask is valid
// mAudioFormat is valid
// mSampleRate is valid
// mDataLoadMode is valid
@@ -722,12 +722,12 @@
case AudioFormat.CHANNEL_OUT_MONO:
case AudioFormat.CHANNEL_CONFIGURATION_MONO:
mChannelCount = 1;
- mChannels = AudioFormat.CHANNEL_OUT_MONO;
+ mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
break;
case AudioFormat.CHANNEL_OUT_STEREO:
case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
mChannelCount = 2;
- mChannels = AudioFormat.CHANNEL_OUT_STEREO;
+ mChannelMask = AudioFormat.CHANNEL_OUT_STEREO;
break;
default:
if (channelConfig == AudioFormat.CHANNEL_INVALID && channelIndexMask != 0) {
@@ -738,7 +738,7 @@
// input channel configuration features unsupported channels
throw new IllegalArgumentException("Unsupported channel configuration.");
}
- mChannels = channelConfig;
+ mChannelMask = channelConfig;
mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
}
// check the channel index configuration (if present)
@@ -908,8 +908,8 @@
}
/**
- * Returns the current playback params.
- * See {@link #setPlaybackParams(PlaybackParams)} to set playback params
+ * Returns the current playback parameters.
+ * See {@link #setPlaybackParams(PlaybackParams)} to set playback parameters
* @return current {@link PlaybackParams}.
* @throws IllegalStateException if track is not initialized.
*/
@@ -1311,8 +1311,8 @@
/**
- * Sets the playback params.
- * This method returns failure if it cannot apply the playback params.
+ * Sets the playback parameters.
+ * This method returns failure if it cannot apply the playback parameters.
* One possible cause is that the parameters for speed or pitch are out of range.
* Another possible cause is that the <code>AudioTrack</code> is streaming
* (see {@link #MODE_STREAM}) and the
@@ -1321,7 +1321,7 @@
* {@link #getMinBufferSize(int, int, int)}) to allow proper playback.
* @param params see {@link PlaybackParams}. In particular,
* speed, pitch, and audio mode should be set.
- * @throws IllegalArgumentException if the params are invalid or not accepted.
+ * @throws IllegalArgumentException if the parameters are invalid or not accepted.
* @throws IllegalStateException if track is not initialized.
*/
public void setPlaybackParams(@NonNull PlaybackParams params) {
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 195c987..e18e9a3 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -163,10 +163,12 @@
* Get the timestamp associated with this frame.
* <p>
* The timestamp is measured in nanoseconds, and is normally monotonically
- * increasing. However, the behavior of the timestamp depends on the source
- * of this image. See {@link android.hardware.Camera Camera},
- * {@link android.hardware.camera2.CameraDevice CameraDevice}, {@link MediaPlayer} and
- * {@link MediaCodec} for more details.
+ * increasing. The timestamps for the images from different sources may have
+ * different timebases therefore may not be comparable. The specific meaning and
+ * timebase of the timestamp depend on the source providing images. See
+ * {@link android.hardware.Camera Camera},
+ * {@link android.hardware.camera2.CameraDevice CameraDevice},
+ * {@link MediaPlayer} and {@link MediaCodec} for more details.
* </p>
*/
public abstract long getTimestamp();
@@ -175,9 +177,11 @@
* Set the timestamp associated with this frame.
* <p>
* The timestamp is measured in nanoseconds, and is normally monotonically
- * increasing. However, the behavior of the timestamp depends on
- * the destination of this image. See {@link android.hardware.Camera Camera}
- * , {@link android.hardware.camera2.CameraDevice CameraDevice},
+ * increasing. The timestamps for the images from different sources may have
+ * different timebases therefore may not be comparable. The specific meaning and
+ * timebase of the timestamp depend on the source providing images. See
+ * {@link android.hardware.Camera Camera},
+ * {@link android.hardware.camera2.CameraDevice CameraDevice},
* {@link MediaPlayer} and {@link MediaCodec} for more details.
* </p>
* <p>
@@ -195,18 +199,6 @@
return;
}
- /**
- * <p>Check if the image is opaque.</p>
- *
- * <p>The pixel data of opaque images are not accessible to the application,
- * and therefore {@link #getPlanes} will return an empty array for an opaque image.
- * </p>
- */
- public boolean isOpaque() {
- throwISEIfImageIsInvalid();
- return false;
- }
-
private Rect mCropRect;
/**
@@ -243,10 +235,11 @@
/**
* Get the array of pixel planes for this Image. The number of planes is
- * determined by the format of the Image. The application will get an
- * empty array if the image is opaque because the opaque image pixel data
- * is not directly accessible. The application can check if an image is
- * opaque by calling {@link Image#isOpaque}.
+ * determined by the format of the Image. The application will get an empty
+ * array if the image format is {@link android.graphics.ImageFormat#PRIVATE
+ * PRIVATE}, because the image pixel data is not directly accessible. The
+ * application can check the image format by calling
+ * {@link Image#getFormat()}.
*/
public abstract Plane[] getPlanes();
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 6d30208..9bd721a 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -68,76 +68,45 @@
private static final int ACQUIRE_MAX_IMAGES = 2;
/**
- * <p>Create a new reader for images of the desired size and format.</p>
- *
- * <p>The {@code maxImages} parameter determines the maximum number of {@link Image}
- * objects that can be be acquired from the {@code ImageReader}
- * simultaneously. Requesting more buffers will use up more memory, so it is
- * important to use only the minimum number necessary for the use case.</p>
- *
- * <p>The valid sizes and formats depend on the source of the image
- * data.</p>
- *
- * @param width
- * The default width in pixels of the Images that this reader will produce.
- * @param height
- * The default height in pixels of the Images that this reader will produce.
- * @param format
- * The format of the Image that this reader will produce. This
- * must be one of the {@link android.graphics.ImageFormat} or
- * {@link android.graphics.PixelFormat} constants. Note that
- * not all formats is supported, like ImageFormat.NV21.
- * @param maxImages
- * The maximum number of images the user will want to
- * access simultaneously. This should be as small as possible to limit
- * memory use. Once maxImages Images are obtained by the user, one of them
- * has to be released before a new Image will become available for access
- * through {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
- * Must be greater than 0.
- *
- * @see Image
- */
- public static ImageReader newInstance(int width, int height, int format, int maxImages) {
- if (format == ImageFormat.PRIVATE) {
- throw new IllegalArgumentException("To obtain an opaque ImageReader, please use"
- + " newOpaqueInstance rather than newInstance");
- }
- return new ImageReader(width, height, format, maxImages);
- }
-
- /**
* <p>
- * Create a new opaque reader for images of the desired size.
- * </p>
- * <p>
- * An opaque {@link ImageReader} produces images that are not directly
- * accessible by the application. The application can still acquire images
- * from an opaque image reader, and send them to the
- * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via
- * {@link ImageWriter} interface. However, the {@link Image#getPlanes()
- * getPlanes()} will return an empty array for opaque images. The
- * application can check if an existing reader is an opaque reader by
- * calling {@link #isOpaque()}.
+ * Create a new reader for images of the desired size and format.
* </p>
* <p>
* The {@code maxImages} parameter determines the maximum number of
* {@link Image} objects that can be be acquired from the
* {@code ImageReader} simultaneously. Requesting more buffers will use up
- * more memory, so it is important to use only the minimum number necessary.
+ * more memory, so it is important to use only the minimum number necessary
+ * for the use case.
* </p>
* <p>
* The valid sizes and formats depend on the source of the image data.
* </p>
* <p>
- * Opaque ImageReaders are more efficient to use when application access to
- * image data is not necessary, compared to ImageReaders using a non-opaque
- * format such as {@link ImageFormat#YUV_420_888 YUV_420_888}.
+ * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created
+ * {@link ImageReader} will produce images that are not directly accessible
+ * by the application. The application can still acquire images from this
+ * {@link ImageReader}, and send them to the
+ * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via
+ * {@link ImageWriter} interface. However, the {@link Image#getPlanes()
+ * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE
+ * PRIVATE} format images. The application can check if an existing reader's
+ * format by calling {@link #getImageFormat()}.
+ * </p>
+ * <p>
+ * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader
+ * ImageReaders} are more efficient to use when application access to image
+ * data is not necessary, compared to ImageReaders using other format such
+ * as {@link ImageFormat#YUV_420_888 YUV_420_888}.
* </p>
*
* @param width The default width in pixels of the Images that this reader
* will produce.
* @param height The default height in pixels of the Images that this reader
* will produce.
+ * @param format The format of the Image that this reader will produce. This
+ * must be one of the {@link android.graphics.ImageFormat} or
+ * {@link android.graphics.PixelFormat} constants. Note that not
+ * all formats are supported, like ImageFormat.NV21.
* @param maxImages The maximum number of images the user will want to
* access simultaneously. This should be as small as possible to
* limit memory use. Once maxImages Images are obtained by the
@@ -147,8 +116,8 @@
* Must be greater than 0.
* @see Image
*/
- public static ImageReader newOpaqueInstance(int width, int height, int maxImages) {
- return new ImageReader(width, height, ImageFormat.PRIVATE, maxImages);
+ public static ImageReader newInstance(int width, int height, int format, int maxImages) {
+ return new ImageReader(width, height, format, maxImages);
}
/**
@@ -248,23 +217,6 @@
}
/**
- * <p>
- * Check if the {@link ImageReader} is an opaque reader.
- * </p>
- * <p>
- * An opaque image reader produces opaque images, see {@link Image#isOpaque}
- * for more details.
- * </p>
- *
- * @return true if the ImageReader is opaque.
- * @see Image#isOpaque
- * @see ImageReader#newOpaqueInstance
- */
- public boolean isOpaque() {
- return mFormat == ImageFormat.PRIVATE;
- }
-
- /**
* <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
* {@code ImageReader}.</p>
*
@@ -540,11 +492,11 @@
* </p>
* <p>
* This method can be used to achieve zero buffer copy for use cases like
- * {@link android.hardware.camera2.CameraDevice Camera2 API} OPAQUE and YUV
+ * {@link android.hardware.camera2.CameraDevice Camera2 API} PRIVATE and YUV
* reprocessing, where the application can select an output image from
* {@link ImageReader} and transfer this image directly to
* {@link ImageWriter}, where this image can be consumed by camera directly.
- * For OPAQUE reprocessing, this is the only way to send input buffers to
+ * For PRIVATE reprocessing, this is the only way to send input buffers to
* the {@link android.hardware.camera2.CameraDevice camera} for
* reprocessing.
* </p>
@@ -703,26 +655,26 @@
@Override
public int getFormat() {
throwISEIfImageIsInvalid();
+ int readerFormat = ImageReader.this.getImageFormat();
+ // Assume opaque reader always produce opaque images.
+ mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat :
+ nativeGetFormat(readerFormat);
return mFormat;
}
@Override
public int getWidth() {
throwISEIfImageIsInvalid();
- if (mWidth == -1) {
- mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() :
- nativeGetWidth(mFormat);
- }
+ mWidth = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getWidth() :
+ nativeGetWidth(mFormat);
return mWidth;
}
@Override
public int getHeight() {
throwISEIfImageIsInvalid();
- if (mHeight == -1) {
- mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() :
- nativeGetHeight(mFormat);
- }
+ mHeight = (getFormat() == ImageFormat.JPEG) ? ImageReader.this.getHeight() :
+ nativeGetHeight(mFormat);
return mHeight;
}
@@ -746,12 +698,6 @@
}
@Override
- public boolean isOpaque() {
- throwISEIfImageIsInvalid();
- return mFormat == ImageFormat.PRIVATE;
- }
-
- @Override
protected final void finalize() throws Throwable {
try {
close();
@@ -876,6 +822,7 @@
private synchronized native SurfacePlane nativeCreatePlane(int idx, int readerFormat);
private synchronized native int nativeGetWidth(int format);
private synchronized native int nativeGetHeight(int format);
+ private synchronized native int nativeGetFormat(int readerFormat);
}
private synchronized native void nativeInit(Object weakSelf, int w, int h,
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index 89313bf3..c312525 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -57,7 +57,7 @@
case ImageFormat.RAW_SENSOR:
case ImageFormat.RAW10:
return 1;
- case PixelFormat.OPAQUE:
+ case ImageFormat.PRIVATE:
return 0;
default:
throw new UnsupportedOperationException(
@@ -70,10 +70,11 @@
* Copy source image data to destination Image.
* </p>
* <p>
- * Only support the copy between two non-opaque images with same properties
- * (format, size, etc.). The data from the source image will be copied to
- * the byteBuffers from the destination Image starting from position zero,
- * and the destination image will be rewound to zero after copy is done.
+ * Only support the copy between two non-{@link ImageFormat#PRIVATE PRIVATE} format
+ * images with same properties (format, size, etc.). The data from the
+ * source image will be copied to the byteBuffers from the destination Image
+ * starting from position zero, and the destination image will be rewound to
+ * zero after copy is done.
* </p>
*
* @param src The source image to be copied from.
@@ -88,8 +89,9 @@
if (src.getFormat() != dst.getFormat()) {
throw new IllegalArgumentException("Src and dst images should have the same format");
}
- if (src.isOpaque() || dst.isOpaque()) {
- throw new IllegalArgumentException("Opaque image is not copyable");
+ if (src.getFormat() == ImageFormat.PRIVATE ||
+ dst.getFormat() == ImageFormat.PRIVATE) {
+ throw new IllegalArgumentException("PRIVATE format images are not copyable");
}
if (!(dst.getOwner() instanceof ImageWriter)) {
throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index f805339..2ef2519 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -33,8 +33,8 @@
/**
* <p>
* The ImageWriter class allows an application to produce Image data into a
- * {@link android.view.Surface}, and have it be consumed by another component like
- * {@link android.hardware.camera2.CameraDevice CameraDevice}.
+ * {@link android.view.Surface}, and have it be consumed by another component
+ * like {@link android.hardware.camera2.CameraDevice CameraDevice}.
* </p>
* <p>
* Several Android API classes can provide input {@link android.view.Surface
@@ -54,21 +54,21 @@
* <p>
* If the application already has an Image from {@link ImageReader}, the
* application can directly queue this Image into ImageWriter (via
- * {@link #queueInputImage}), potentially with zero buffer copies. For the opaque
- * Images produced by an opaque ImageReader (created by
- * {@link ImageReader#newOpaqueInstance}), this is the only way to send Image
- * data to ImageWriter, as the Image data aren't accessible by the application.
+ * {@link #queueInputImage}), potentially with zero buffer copies. For the
+ * {@link ImageFormat#PRIVATE PRIVATE} format Images produced by
+ * {@link ImageReader}, this is the only way to send Image data to ImageWriter,
+ * as the Image data aren't accessible by the application.
* </p>
- * Once new input Images are queued into an ImageWriter, it's up to the downstream
- * components (e.g. {@link ImageReader} or
+ * Once new input Images are queued into an ImageWriter, it's up to the
+ * downstream components (e.g. {@link ImageReader} or
* {@link android.hardware.camera2.CameraDevice}) to consume the Images. If the
* downstream components cannot consume the Images at least as fast as the
- * ImageWriter production rate, the {@link #dequeueInputImage} call will eventually
- * block and the application will have to drop input frames. </p>
+ * ImageWriter production rate, the {@link #dequeueInputImage} call will
+ * eventually block and the application will have to drop input frames. </p>
*/
public class ImageWriter implements AutoCloseable {
private final Object mListenerLock = new Object();
- private ImageListener mListener;
+ private OnImageReleasedListener mListener;
private ListenerHandler mListenerHandler;
private long mNativeContext;
@@ -168,32 +168,34 @@
* This call will block if all available input images have been queued by
* the application and the downstream consumer has not yet consumed any.
* When an Image is consumed by the downstream consumer and released, an
- * {@link ImageListener#onInputImageReleased} callback will be fired, which
- * indicates that there is one input Image available. For non-opaque formats
- * (({@link ImageWriter#getFormat()} != {@link ImageFormat#PRIVATE})), it is
+ * {@link OnImageReleasedListener#onImageReleased} callback will be fired,
+ * which indicates that there is one input Image available. For non-
+ * {@link ImageFormat#PRIVATE PRIVATE} formats (
+ * {@link ImageWriter#getFormat()} != {@link ImageFormat#PRIVATE}), it is
* recommended to dequeue the next Image only after this callback is fired,
* in the steady state.
* </p>
* <p>
- * If the ImageWriter is opaque ({@link ImageWriter#getFormat()} ==
- * {@link ImageFormat#PRIVATE}), the image buffer is inaccessible to
- * the application, and calling this method will result in an
- * {@link IllegalStateException}. Instead, the application should acquire
- * opaque images from some other component (e.g. an opaque
+ * If the format of ImageWriter is {@link ImageFormat#PRIVATE PRIVATE} (
+ * {@link ImageWriter#getFormat()} == {@link ImageFormat#PRIVATE}), the
+ * image buffer is inaccessible to the application, and calling this method
+ * will result in an {@link IllegalStateException}. Instead, the application
+ * should acquire images from some other component (e.g. an
* {@link ImageReader}), and queue them directly to this ImageWriter via the
* {@link ImageWriter#queueInputImage queueInputImage()} method.
* </p>
*
* @return The next available input Image from this ImageWriter.
* @throws IllegalStateException if {@code maxImages} Images are currently
- * dequeued, or the ImageWriter is opaque.
+ * dequeued, or the ImageWriter format is
+ * {@link ImageFormat#PRIVATE PRIVATE}.
* @see #queueInputImage
* @see Image#close
*/
public Image dequeueInputImage() {
if (mWriterFormat == ImageFormat.PRIVATE) {
throw new IllegalStateException(
- "Opaque ImageWriter doesn't support this operation since opaque images are"
+ "PRIVATE format ImageWriter doesn't support this operation since the images are"
+ " inaccessible to the application!");
}
@@ -229,10 +231,10 @@
* </p>
* <p>
* After this method is called and the downstream consumer consumes and
- * releases the Image, an {@link ImageListener#onInputImageReleased
- * onInputImageReleased()} callback will fire. The application can use this
- * callback to avoid sending Images faster than the downstream consumer
- * processing rate in steady state.
+ * releases the Image, an {@link OnImageReleasedListener#onImageReleased}
+ * callback will fire. The application can use this callback to avoid
+ * sending Images faster than the downstream consumer processing rate in
+ * steady state.
* </p>
* <p>
* Passing in an Image from some other component (e.g. an
@@ -271,12 +273,12 @@
}
ImageReader prevOwner = (ImageReader) image.getOwner();
- // Only do the image attach for opaque images for now. Do the image
+ // Only do the image attach for PRIVATE format images for now. Do the image
// copy for other formats. TODO: use attach for other formats to
// improve the performance, and fall back to copy when attach/detach
// fails. Right now, detach is guaranteed to fail as the buffer is
// locked when ImageReader#acquireNextImage is called. See bug 19962027.
- if (image.isOpaque()) {
+ if (image.getFormat() == ImageFormat.PRIVATE) {
prevOwner.detachImage(image);
attachAndQueueInputImage(image);
// This clears the native reference held by the original owner.
@@ -319,8 +321,9 @@
* Get the ImageWriter format.
* <p>
* This format may be different than the Image format returned by
- * {@link Image#getFormat()}. However, if the ImageWriter is opaque (format
- * == {@link ImageFormat#PRIVATE}) , the images from it will also be opaque.
+ * {@link Image#getFormat()}. However, if the ImageWriter format is
+ * {@link ImageFormat#PRIVATE PRIVATE}, calling {@link #dequeueInputImage()}
+ * will result in an {@link IllegalStateException}.
* </p>
*
* @return The ImageWriter format.
@@ -333,7 +336,7 @@
* ImageWriter callback interface, used to to asynchronously notify the
* application of various ImageWriter events.
*/
- public interface ImageListener {
+ public interface OnImageReleasedListener {
/**
* <p>
* Callback that is called when an input Image is released back to
@@ -361,7 +364,7 @@
* @see ImageWriter
* @see Image
*/
- void onInputImageReleased(ImageWriter writer);
+ void onImageReleased(ImageWriter writer);
}
/**
@@ -375,7 +378,7 @@
* @throws IllegalArgumentException If no handler specified and the calling
* thread has no looper.
*/
- public void setImageListener(ImageListener listener, Handler handler) {
+ public void setOnImageReleasedListener(OnImageReleasedListener listener, Handler handler) {
synchronized (mListenerLock) {
if (listener != null) {
Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
@@ -408,7 +411,7 @@
*/
@Override
public void close() {
- setImageListener(null, null);
+ setOnImageReleasedListener(null, null);
for (Image image : mDequeuedImages) {
image.close();
}
@@ -431,19 +434,18 @@
* Attach and queue input Image to this ImageWriter.
* </p>
* <p>
- * When an Image is from an opaque source (e.g. an opaque ImageReader
- * created by {@link ImageReader#newOpaqueInstance}), or the source Image is
- * so large that copying its data is too expensive, this method can be used
- * to migrate the source Image into ImageWriter without a data copy, and
- * then queue it to this ImageWriter. The source Image must be detached from
- * its previous owner already, or this call will throw an
+ * When the format of an Image is {@link ImageFormat#PRIVATE PRIVATE}, or
+ * the source Image is so large that copying its data is too expensive, this
+ * method can be used to migrate the source Image into ImageWriter without a
+ * data copy, and then queue it to this ImageWriter. The source Image must
+ * be detached from its previous owner already, or this call will throw an
* {@link IllegalStateException}.
* </p>
* <p>
* After this call, the ImageWriter takes ownership of this Image. This
* ownership will automatically be removed from this writer after the
* consumer releases this Image, that is, after
- * {@link ImageListener#onInputImageReleased}. The caller is responsible for
+ * {@link OnImageReleasedListener#onImageReleased}. The caller is responsible for
* closing this Image through {@link Image#close()} to free up the resources
* held by this Image.
* </p>
@@ -492,12 +494,12 @@
@Override
public void handleMessage(Message msg) {
- ImageListener listener;
+ OnImageReleasedListener listener;
synchronized (mListenerLock) {
listener = mListener;
}
if (listener != null) {
- listener.onInputImageReleased(ImageWriter.this);
+ listener.onImageReleased(ImageWriter.this);
}
}
}
@@ -647,13 +649,6 @@
}
@Override
- public boolean isOpaque() {
- throwISEIfImageIsInvalid();
-
- return getFormat() == ImageFormat.PRIVATE;
- }
-
- @Override
public Plane[] getPlanes() {
throwISEIfImageIsInvalid();
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 72198b6..6f28bf6 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -660,7 +660,7 @@
* surface in the current state.
* @throws IllegalArgumentException if the new surface is not of a suitable type for the codec.
*/
- public void setSurface(@NonNull Surface surface) {
+ public void setOutputSurface(@NonNull Surface surface) {
if (!mHasSurface) {
throw new IllegalStateException("codec was not configured for an output surface");
}
@@ -677,7 +677,7 @@
* <p>
* The application is responsible for calling release() on the Surface when done.
*
- * @return an input surface that can be used with {@link #usePersistentInputSurface}.
+ * @return an input surface that can be used with {@link #setInputSurface}.
*/
@NonNull
public static Surface createPersistentInputSurface() {
@@ -707,17 +707,17 @@
* @throws IllegalArgumentException if the surface was not created by
* {@link #createPersistentInputSurface}.
*/
- public void usePersistentInputSurface(@NonNull Surface surface) {
+ public void setInputSurface(@NonNull Surface surface) {
if (!(surface instanceof PersistentSurface)) {
throw new IllegalArgumentException("not a PersistentSurface");
}
- native_usePersistentInputSurface(surface);
+ native_setInputSurface(surface);
}
@NonNull
private static native final PersistentSurface native_createPersistentInputSurface();
private static native final void native_releasePersistentInputSurface(@NonNull Surface surface);
- private native final void native_usePersistentInputSurface(@NonNull Surface surface);
+ private native final void native_setInputSurface(@NonNull Surface surface);
private native final void native_setCallback(@Nullable Callback cb);
diff --git a/media/java/android/media/MediaDataSource.java b/media/java/android/media/MediaDataSource.java
index 246c0ef..948da0b 100644
--- a/media/java/android/media/MediaDataSource.java
+++ b/media/java/android/media/MediaDataSource.java
@@ -18,6 +18,7 @@
package android.media;
import java.io.Closeable;
+import java.io.IOException;
/**
* For supplying media data to the framework. Implement this if your app has
@@ -29,34 +30,32 @@
* you don't need to do your own synchronization unless you're modifying the
* MediaDataSource from another thread while it's being used by the framework.</p>
*/
-public interface MediaDataSource extends Closeable {
+public abstract class MediaDataSource implements Closeable {
/**
* Called to request data from the given position.
*
* Implementations should should write up to {@code size} bytes into
* {@code buffer}, and return the number of bytes written.
*
- * Return {@code 0} to indicate that {@code position} is at, or beyond, the
- * end of the source.
+ * Return {@code 0} if size is zero (thus no bytes are read).
*
- * Return {@code -1} to indicate that a fatal error occurred. The failed
- * read will not be retried, so transient errors should be handled
- * internally.
- *
- * Throwing an exception from this method will have the same effect as
- * returning {@code -1}.
+ * Return {@code -1} to indicate that end of stream is reached.
*
* @param position the position in the data source to read from.
* @param buffer the buffer to read the data into.
+ * @param offset the offset within buffer to read the data into.
* @param size the number of bytes to read.
+ * @throws IOException on fatal errors.
* @return the number of bytes read, or -1 if there was an error.
*/
- public int readAt(long position, byte[] buffer, int size);
+ public abstract int readAt(long position, byte[] buffer, int offset, int size)
+ throws IOException;
/**
* Called to get the size of the data source.
*
+ * @throws IOException on fatal errors
* @return the size of data source in bytes, or -1 if the size is unknown.
*/
- public long getSize();
+ public abstract long getSize() throws IOException;
}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index acff301..52ba9ec 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -110,10 +110,10 @@
private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;
private EventHandler mEventHandler;
- private EventHandler mOnKeysChangeEventHandler;
+ private EventHandler mOnKeyStatusChangeEventHandler;
private EventHandler mOnExpirationUpdateEventHandler;
private OnEventListener mOnEventListener;
- private OnKeysChangeListener mOnKeysChangeListener;
+ private OnKeyStatusChangeListener mOnKeyStatusChangeListener;
private OnExpirationUpdateListener mOnExpirationUpdateListener;
private long mNativeContext;
@@ -297,8 +297,8 @@
* @param handler the handler on which the listener should be invoked, or
* null if the listener should be invoked on the calling thread's looper.
*/
- public void setOnKeysChangeListener(
- @Nullable OnKeysChangeListener listener, @Nullable Handler handler) {
+ public void setOnKeyStatusChangeListener(
+ @Nullable OnKeyStatusChangeListener listener, @Nullable Handler handler) {
if (listener != null) {
Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
if (looper != null) {
@@ -307,14 +307,14 @@
}
}
}
- mOnKeysChangeListener = listener;
+ mOnKeyStatusChangeListener = listener;
}
/**
* Interface definition for a callback to be invoked when the keys in a drm
* session change states.
*/
- public interface OnKeysChangeListener
+ public interface OnKeyStatusChangeListener
{
/**
* Called when the keys in a session change status, such as when the license
@@ -328,64 +328,64 @@
* which may trigger an attempt to resume playback on the media stream
* if it is currently blocked waiting for a key.
*/
- void onKeysChange(
+ void onKeyStatusChange(
@NonNull MediaDrm md, @NonNull byte[] sessionId,
@NonNull List<KeyStatus> keyInformation,
boolean hasNewUsableKey);
}
/**
- * The key is currently usable to decrypt media data
- */
- public static final int KEY_STATUS_USABLE = 0;
-
- /**
- * The key is no longer usable to decrypt media data because its
- * expiration time has passed.
- */
- public static final int KEY_STATUS_EXPIRED = 1;
-
- /**
- * The key is not currently usable to decrypt media data because its
- * output requirements cannot currently be met.
- */
- public static final int KEY_STATUS_OUTPUT_NOT_ALLOWED = 2;
-
- /**
- * The status of the key is not yet known and is being determined.
- * The status will be updated with the actual status when it has
- * been determined.
- */
- public static final int KEY_STATUS_PENDING = 3;
-
- /**
- * The key is not currently usable to decrypt media data because of an
- * internal error in processing unrelated to input parameters. This error
- * is not actionable by an app.
- */
- public static final int KEY_STATUS_INTERNAL_ERROR = 4;
-
- /** @hide */
- @IntDef({
- KEY_STATUS_USABLE,
- KEY_STATUS_EXPIRED,
- KEY_STATUS_OUTPUT_NOT_ALLOWED,
- KEY_STATUS_PENDING,
- KEY_STATUS_INTERNAL_ERROR,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface KeyStatusCode {}
-
- /**
* Defines the status of a key.
* A KeyStatus for each key in a session is provided to the
- * {@link OnKeysChangeListener#onKeysChange}
+ * {@link OnKeyStatusChangeListener#onKeyStatusChange}
* listener.
*/
public static final class KeyStatus {
private final byte[] mKeyId;
private final int mStatusCode;
+ /**
+ * The key is currently usable to decrypt media data
+ */
+ public static final int STATUS_USABLE = 0;
+
+ /**
+ * The key is no longer usable to decrypt media data because its
+ * expiration time has passed.
+ */
+ public static final int STATUS_EXPIRED = 1;
+
+ /**
+ * The key is not currently usable to decrypt media data because its
+ * output requirements cannot currently be met.
+ */
+ public static final int STATUS_OUTPUT_NOT_ALLOWED = 2;
+
+ /**
+ * The status of the key is not yet known and is being determined.
+ * The status will be updated with the actual status when it has
+ * been determined.
+ */
+ public static final int STATUS_PENDING = 3;
+
+ /**
+ * The key is not currently usable to decrypt media data because of an
+ * internal error in processing unrelated to input parameters. This error
+ * is not actionable by an app.
+ */
+ public static final int STATUS_INTERNAL_ERROR = 4;
+
+ /** @hide */
+ @IntDef({
+ STATUS_USABLE,
+ STATUS_EXPIRED,
+ STATUS_OUTPUT_NOT_ALLOWED,
+ STATUS_PENDING,
+ STATUS_INTERNAL_ERROR,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface KeyStatusCode {}
+
KeyStatus(@NonNull byte[] keyId, @KeyStatusCode int statusCode) {
mKeyId = keyId;
mStatusCode = statusCode;
@@ -393,6 +393,9 @@
/**
* Returns the status code for the key
+ * @return one of {@link #STATUS_USABLE}, {@link #STATUS_EXPIRED},
+ * {@link #STATUS_OUTPUT_NOT_ALLOWED}, {@link #STATUS_PENDING}
+ * or {@link #STATUS_INTERNAL_ERROR}.
*/
@KeyStatusCode
public int getStatusCode() { return mStatusCode; }
@@ -484,7 +487,7 @@
private static final int DRM_EVENT = 200;
private static final int EXPIRATION_UPDATE = 201;
- private static final int KEYS_CHANGE = 202;
+ private static final int KEY_STATUS_CHANGE = 202;
private class EventHandler extends Handler
{
@@ -522,8 +525,8 @@
}
return;
- case KEYS_CHANGE:
- if (mOnKeysChangeListener != null) {
+ case KEY_STATUS_CHANGE:
+ if (mOnKeyStatusChangeListener != null) {
if (msg.obj != null && msg.obj instanceof Parcel) {
Parcel parcel = (Parcel)msg.obj;
byte[] sessionId = parcel.createByteArray();
@@ -531,9 +534,9 @@
List<KeyStatus> keyStatusList = keyStatusListFromParcel(parcel);
boolean hasNewUsableKey = (parcel.readInt() != 0);
- Log.i(TAG, "Drm keys change");
- mOnKeysChangeListener.onKeysChange(mMediaDrm, sessionId, keyStatusList,
- hasNewUsableKey);
+ Log.i(TAG, "Drm key status changed");
+ mOnKeyStatusChangeListener.onKeyStatusChange(mMediaDrm, sessionId,
+ keyStatusList, hasNewUsableKey);
}
}
}
@@ -641,30 +644,6 @@
public @interface KeyType {}
/**
- * Key request type is initial license request
- */
- public static final int REQUEST_TYPE_INITIAL = 0;
-
- /**
- * Key request type is license renewal
- */
- public static final int REQUEST_TYPE_RENEWAL = 1;
-
- /**
- * Key request type is license release
- */
- public static final int REQUEST_TYPE_RELEASE = 2;
-
- /** @hide */
- @IntDef({
- REQUEST_TYPE_INITIAL,
- REQUEST_TYPE_RENEWAL,
- REQUEST_TYPE_RELEASE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface RequestType {}
-
- /**
* Contains the opaque data an app uses to request keys from a license server
*/
public static final class KeyRequest {
@@ -672,6 +651,30 @@
private String mDefaultUrl;
private int mRequestType;
+ /**
+ * Key request type is initial license request
+ */
+ public static final int REQUEST_TYPE_INITIAL = 0;
+
+ /**
+ * Key request type is license renewal
+ */
+ public static final int REQUEST_TYPE_RENEWAL = 1;
+
+ /**
+ * Key request type is license release
+ */
+ public static final int REQUEST_TYPE_RELEASE = 2;
+
+ /** @hide */
+ @IntDef({
+ REQUEST_TYPE_INITIAL,
+ REQUEST_TYPE_RENEWAL,
+ REQUEST_TYPE_RELEASE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RequestType {}
+
KeyRequest() {}
/**
@@ -707,6 +710,8 @@
/**
* Get the type of the request
+ * @return one of {@link #REQUEST_TYPE_INITIAL},
+ * {@link #REQUEST_TYPE_RENEWAL} or {@link #REQUEST_TYPE_RELEASE}
*/
@RequestType
public int getRequestType() { return mRequestType; }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index aaafa55..f148606 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -40,6 +40,7 @@
import android.system.ErrnoException;
import android.system.OsConstants;
import android.util.Log;
+import android.util.Pair;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.widget.VideoView;
@@ -70,6 +71,8 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetSocketAddress;
+import java.util.BitSet;
+import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
@@ -639,9 +642,7 @@
}
mTimeProvider = new TimeProvider(this);
- mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
mOpenSubtitleSources = new Vector<InputStream>();
- mInbandSubtitleTracks = new SubtitleTrack[0];
IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
mAppOps = IAppOpsService.Stub.asInterface(b);
@@ -1360,6 +1361,8 @@
* frequency.
* When rate is larger than 1.0, pitch becomes higher.
* When rate is smaller than 1.0, pitch becomes lower.
+ *
+ * @hide
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
@@ -1372,6 +1375,8 @@
* <p>
* This mode is only supported for a limited range of playback speed factors,
* e.g. between 1/2x and 2x.
+ *
+ * @hide
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
@@ -1383,6 +1388,8 @@
* Try to keep audio pitch when changing the playback rate, but allow the
* system to determine how to change audio playback if the rate is out
* of range.
+ *
+ * @hide
*/
public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
@@ -1406,8 +1413,11 @@
* @throws IllegalStateException if the internal player engine has not been
* initialized.
* @throws IllegalArgumentException if audioMode is not supported.
+ *
+ * @hide
*/
- public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) {
+ @NonNull
+ public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) {
PlaybackParams params = new PlaybackParams();
params.allowDefaults();
switch (audioMode) {
@@ -1425,7 +1435,7 @@
final String msg = "Audio playback mode " + audioMode + " is not supported";
throw new IllegalArgumentException(msg);
}
- setPlaybackParams(params);
+ return params;
}
/**
@@ -1481,23 +1491,22 @@
public native void seekTo(int msec) throws IllegalStateException;
/**
- * Get current playback position.
+ * Get current playback position as a {@link MediaTimestamp}.
* <p>
* The MediaTimestamp represents how the media time correlates to the system time in
- * a linear fashion. It contains the media time and system timestamp of an anchor frame
- * ({@link MediaTimestamp#mediaTimeUs} and {@link MediaTimestamp#nanoTime})
- * and the speed of the media clock ({@link MediaTimestamp#clockRate}).
+ * a linear fashion using an anchor and a clock rate. During regular playback, the media
+ * time moves fairly constantly (though the anchor frame may be rebased to a current
+ * system time, the linear correlation stays steady). Therefore, this method does not
+ * need to be called often.
* <p>
- * During regular playback, the media time moves fairly constantly (though the
- * anchor frame may be rebased to a current system time, the linear correlation stays
- * steady). Therefore, this method does not need to be called often.
- * <p>
- * To help users to get current playback position, this method always returns the timestamp of
- * just-rendered frame, i.e., {@link System#nanoTime} and its corresponding media time. They
- * can be used as current playback position.
+ * To help users get current playback position, this method always anchors the timestamp
+ * to the current {@link System#nanoTime system time}, so
+ * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
*
* @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
* is available, e.g. because the media player has not been initialized.
+ *
+ * @see MediaTimestamp
*/
@Nullable
public MediaTimestamp getTimestamp()
@@ -1685,8 +1694,6 @@
}
mOpenSubtitleSources.clear();
}
- mOutOfBandSubtitleTracks.clear();
- mInbandSubtitleTracks = new SubtitleTrack[0];
if (mSubtitleController != null) {
mSubtitleController.reset();
}
@@ -1701,6 +1708,11 @@
if (mEventHandler != null) {
mEventHandler.removeCallbacksAndMessages(null);
}
+
+ synchronized (mIndexTrackPairs) {
+ mIndexTrackPairs.clear();
+ mInbandTrackIndices.clear();
+ };
}
private native void _reset();
@@ -2042,6 +2054,16 @@
};
+ // We would like domain specific classes with more informative names than the `first` and `second`
+ // in generic Pair, but we would also like to avoid creating new/trivial classes. As a compromise
+ // we document the meanings of `first` and `second` here:
+ //
+ // Pair.first - inband track index; non-null iff representing an inband track.
+ // Pair.second - a SubtitleTrack registered with mSubtitleController; non-null iff representing
+ // an inband subtitle track or any out-of-band track (subtitle or timedtext).
+ private Vector<Pair<Integer, SubtitleTrack>> mIndexTrackPairs = new Vector<>();
+ private BitSet mInbandTrackIndices = new BitSet();
+
/**
* Returns an array of track information.
*
@@ -2053,17 +2075,20 @@
public TrackInfo[] getTrackInfo() throws IllegalStateException {
TrackInfo trackInfo[] = getInbandTrackInfo();
// add out-of-band tracks
- TrackInfo allTrackInfo[] = new TrackInfo[trackInfo.length + mOutOfBandSubtitleTracks.size()];
- System.arraycopy(trackInfo, 0, allTrackInfo, 0, trackInfo.length);
- int i = trackInfo.length;
- for (SubtitleTrack track: mOutOfBandSubtitleTracks) {
- int type = track.isTimedText()
- ? TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT
- : TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
- allTrackInfo[i] = new TrackInfo(type, track.getFormat());
- ++i;
+ synchronized (mIndexTrackPairs) {
+ TrackInfo allTrackInfo[] = new TrackInfo[mIndexTrackPairs.size()];
+ for (int i = 0; i < allTrackInfo.length; i++) {
+ Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+ if (p.first != null) {
+ // inband track
+ allTrackInfo[i] = trackInfo[p.first];
+ } else {
+ SubtitleTrack track = p.second;
+ allTrackInfo[i] = new TrackInfo(track.getTrackType(), track.getFormat());
+ }
+ }
+ return allTrackInfo;
}
- return allTrackInfo;
}
private TrackInfo[] getInbandTrackInfo() throws IllegalStateException {
@@ -2159,22 +2184,21 @@
}
}
- private final Object mInbandSubtitleLock = new Object();
- private SubtitleTrack[] mInbandSubtitleTracks;
private int mSelectedSubtitleTrackIndex = -1;
- private Vector<SubtitleTrack> mOutOfBandSubtitleTracks;
private Vector<InputStream> mOpenSubtitleSources;
private OnSubtitleDataListener mSubtitleDataListener = new OnSubtitleDataListener() {
@Override
public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
int index = data.getTrackIndex();
- if (index >= mInbandSubtitleTracks.length) {
- return;
- }
- SubtitleTrack track = mInbandSubtitleTracks[index];
- if (track != null) {
- track.onData(data);
+ synchronized (mIndexTrackPairs) {
+ for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
+ if (p.first != null && p.first == index && p.second != null) {
+ // inband subtitle track that owns data
+ SubtitleTrack track = p.second;
+ track.onData(data);
+ }
+ }
}
}
};
@@ -2193,18 +2217,24 @@
if (track == null) {
return;
}
- for (int i = 0; i < mInbandSubtitleTracks.length; i++) {
- if (mInbandSubtitleTracks[i] == track) {
- Log.v(TAG, "Selecting subtitle track " + i);
- mSelectedSubtitleTrackIndex = i;
- try {
- selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, true);
- } catch (IllegalStateException e) {
+
+ synchronized (mIndexTrackPairs) {
+ for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
+ if (p.first != null && p.second == track) {
+ // inband subtitle track that is selected
+ mSelectedSubtitleTrackIndex = p.first;
+ break;
}
- setOnSubtitleDataListener(mSubtitleDataListener);
- break;
}
}
+
+ if (mSelectedSubtitleTrackIndex >= 0) {
+ try {
+ selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, true);
+ } catch (IllegalStateException e) {
+ }
+ setOnSubtitleDataListener(mSubtitleDataListener);
+ }
// no need to select out-of-band tracks
}
@@ -2244,7 +2274,9 @@
mOpenSubtitleSources.remove(fIs);
}
scanner.close();
- mOutOfBandSubtitleTracks.add(track);
+ synchronized (mIndexTrackPairs) {
+ mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
+ }
track.onData(contents.getBytes(), true /* eos */, ~0 /* runID: keep forever */);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
}
@@ -2262,27 +2294,37 @@
private void scanInternalSubtitleTracks() {
if (mSubtitleController == null) {
- Log.e(TAG, "Should have subtitle controller already set");
- return;
+ Log.w(TAG, "setSubtitleAnchor in MediaPlayer");
+ setSubtitleAnchor();
}
+ populateInbandTracks();
+
+ if (mSubtitleController != null) {
+ mSubtitleController.selectDefaultTrack();
+ }
+ }
+
+ private void populateInbandTracks() {
TrackInfo[] tracks = getInbandTrackInfo();
- synchronized (mInbandSubtitleLock) {
- SubtitleTrack[] inbandTracks = new SubtitleTrack[tracks.length];
- for (int i=0; i < tracks.length; i++) {
+ synchronized (mIndexTrackPairs) {
+ for (int i = 0; i < tracks.length; i++) {
+ if (mInbandTrackIndices.get(i)) {
+ continue;
+ } else {
+ mInbandTrackIndices.set(i);
+ }
+
+ // newly appeared inband track
if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
- if (i < mInbandSubtitleTracks.length) {
- inbandTracks[i] = mInbandSubtitleTracks[i];
- } else {
- SubtitleTrack track = mSubtitleController.addTrack(
- tracks[i].getFormat());
- inbandTracks[i] = track;
- }
+ SubtitleTrack track = mSubtitleController.addTrack(
+ tracks[i].getFormat());
+ mIndexTrackPairs.add(Pair.create(i, track));
+ } else {
+ mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(i, null));
}
}
- mInbandSubtitleTracks = inbandTracks;
}
- mSubtitleController.selectDefaultTrack();
}
/* TODO: Limit the total number of external timed text source to a reasonable number.
@@ -2430,7 +2472,9 @@
mSubtitleController.registerRenderer(new SRTRenderer(context, mEventHandler));
}
final SubtitleTrack track = mSubtitleController.addTrack(fFormat);
- mOutOfBandSubtitleTracks.add(track);
+ synchronized (mIndexTrackPairs) {
+ mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
+ }
final FileDescriptor fd3 = fd2;
final long offset2 = offset;
@@ -2502,12 +2546,18 @@
* @see #deselectTrack(int)
*/
public int getSelectedTrack(int trackType) throws IllegalStateException {
- if (trackType == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE && mSubtitleController != null) {
+ if (mSubtitleController != null
+ && (trackType == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
+ || trackType == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT)) {
SubtitleTrack subtitleTrack = mSubtitleController.getSelectedTrack();
if (subtitleTrack != null) {
- int index = mOutOfBandSubtitleTracks.indexOf(subtitleTrack);
- if (index >= 0) {
- return mInbandSubtitleTracks.length + index;
+ synchronized (mIndexTrackPairs) {
+ for (int i = 0; i < mIndexTrackPairs.size(); i++) {
+ Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+ if (p.second == subtitleTrack && subtitleTrack.getTrackType() == trackType) {
+ return i;
+ }
+ }
}
}
}
@@ -2519,8 +2569,16 @@
request.writeInt(INVOKE_ID_GET_SELECTED_TRACK);
request.writeInt(trackType);
invoke(request, reply);
- int selectedTrack = reply.readInt();
- return selectedTrack;
+ int inbandTrackIndex = reply.readInt();
+ synchronized (mIndexTrackPairs) {
+ for (int i = 0; i < mIndexTrackPairs.size(); i++) {
+ Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+ if (p.first != null && p.first == inbandTrackIndex) {
+ return i;
+ }
+ }
+ }
+ return -1;
} finally {
request.recycle();
reply.recycle();
@@ -2580,36 +2638,30 @@
private void selectOrDeselectTrack(int index, boolean select)
throws IllegalStateException {
// handle subtitle track through subtitle controller
- SubtitleTrack track = null;
- synchronized (mInbandSubtitleLock) {
- if (mInbandSubtitleTracks.length == 0) {
- TrackInfo[] tracks = getInbandTrackInfo();
- mInbandSubtitleTracks = new SubtitleTrack[tracks.length];
- for (int i=0; i < tracks.length; i++) {
- if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
- mInbandSubtitleTracks[i] = mSubtitleController.addTrack(tracks[i].getFormat());
- }
- }
- }
+ populateInbandTracks();
+
+ Pair<Integer,SubtitleTrack> p = null;
+ try {
+ p = mIndexTrackPairs.get(index);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // ignore bad index
+ return;
}
- if (index < mInbandSubtitleTracks.length) {
- track = mInbandSubtitleTracks[index];
- } else if (index < mInbandSubtitleTracks.length + mOutOfBandSubtitleTracks.size()) {
- track = mOutOfBandSubtitleTracks.get(index - mInbandSubtitleTracks.length);
+ SubtitleTrack track = p.second;
+ if (track == null) {
+ // inband (de)select
+ selectOrDeselectInbandTrack(p.first, select);
+ return;
}
- if (mSubtitleController != null && track != null) {
- if (select) {
- if (track.isTimedText()) {
- int ttIndex = getSelectedTrack(TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
- if (ttIndex >= 0 && ttIndex < mInbandSubtitleTracks.length) {
- // deselect inband counterpart
- selectOrDeselectInbandTrack(ttIndex, false);
- }
- }
- mSubtitleController.selectTrack(track);
- } else if (mSubtitleController.getSelectedTrack() == track) {
+ if (mSubtitleController == null) {
+ return;
+ }
+
+ if (!select) {
+ // out-of-band deselect
+ if (mSubtitleController.getSelectedTrack() == track) {
mSubtitleController.selectTrack(null);
} else {
Log.w(TAG, "trying to deselect track that was not selected");
@@ -2617,7 +2669,20 @@
return;
}
- selectOrDeselectInbandTrack(index, select);
+ // out-of-band select
+ if (track.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+ int ttIndex = getSelectedTrack(TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
+ synchronized (mIndexTrackPairs) {
+ if (ttIndex >= 0 && ttIndex < mIndexTrackPairs.size()) {
+ Pair<Integer,SubtitleTrack> p2 = mIndexTrackPairs.get(ttIndex);
+ if (p2.first != null && p2.second == null) {
+ // deselect inband counterpart
+ selectOrDeselectInbandTrack(p2.first, false);
+ }
+ }
+ }
+ }
+ mSubtitleController.selectTrack(track);
}
private void selectOrDeselectInbandTrack(int index, boolean select)
@@ -2866,14 +2931,14 @@
return;
case MEDIA_META_DATA:
- if (mOnTimedMetaDataListener == null) {
+ if (mOnTimedMetaDataAvailableListener == null) {
return;
}
if (msg.obj instanceof Parcel) {
Parcel parcel = (Parcel) msg.obj;
TimedMetaData data = TimedMetaData.createTimedMetaDataFromParcel(parcel);
parcel.recycle();
- mOnTimedMetaDataListener.onTimedMetaData(mMediaPlayer, data);
+ mOnTimedMetaDataAvailableListener.onTimedMetaDataAvailable(mMediaPlayer, data);
}
return;
@@ -3117,9 +3182,9 @@
* Interface definition of a callback to be invoked when a
* track has timed metadata available.
*
- * @see MediaPlayer#setOnTimedMetaDataListener(OnTimedMetaDataListener)
+ * @see MediaPlayer#setOnTimedMetaDataAvailableListener(OnTimedMetaDataAvailableListener)
*/
- public interface OnTimedMetaDataListener
+ public interface OnTimedMetaDataAvailableListener
{
/**
* Called to indicate avaliable timed metadata
@@ -3131,7 +3196,7 @@
* @param mp the MediaPlayer associated with this callback
* @param data the timed metadata sample associated with this event
*/
- public void onTimedMetaData(MediaPlayer mp, TimedMetaData data);
+ public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data);
}
/**
@@ -3141,17 +3206,17 @@
* {@link TimedMetaData}.
*
* @see MediaPlayer#selectTrack(int)
- * @see MediaPlayer.OnTimedMetaDataListener
+ * @see MediaPlayer.OnTimedMetaDataAvailableListener
* @see TimedMetaData
*
* @param listener the callback that will be run
*/
- public void setOnTimedMetaDataListener(OnTimedMetaDataListener listener)
+ public void setOnTimedMetaDataAvailableListener(OnTimedMetaDataAvailableListener listener)
{
- mOnTimedMetaDataListener = listener;
+ mOnTimedMetaDataAvailableListener = listener;
}
- private OnTimedMetaDataListener mOnTimedMetaDataListener;
+ private OnTimedMetaDataAvailableListener mOnTimedMetaDataAvailableListener;
/* Do not change these values without updating their counterparts
* in include/media/mediaplayer.h!
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index f27e635..ed2c4cbd 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -156,14 +156,14 @@
* @see MediaCodec#createPersistentInputSurface
* @see MediaRecorder.VideoSource
*/
- public void usePersistentSurface(@NonNull Surface surface) {
+ public void setInputSurface(@NonNull Surface surface) {
if (!(surface instanceof MediaCodec.PersistentSurface)) {
throw new IllegalArgumentException("not a PersistentSurface");
}
- native_usePersistentSurface(surface);
+ native_setInputSurface(surface);
}
- private native final void native_usePersistentSurface(@NonNull Surface surface);
+ private native final void native_setInputSurface(@NonNull Surface surface);
/**
* Sets a Surface to show a preview of recorded media (video). Calls this
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index b7ef95c..b07931d 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -49,7 +49,7 @@
* sync.setAudioTrack(audioTrack);
* sync.setCallback(new MediaSync.Callback() {
* {@literal @Override}
- * public void onAudioBufferConsumed(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
+ * public void onAudioBufferConsumed(MediaSync sync, ByteBuffer audioBuffer, int bufferId) {
* ...
* }
* }, null);
@@ -62,8 +62,8 @@
* // videoDecoder.releaseOutputBuffer(videoOutputBufferIx, videoPresentationTimeNs);
* // More details are available as below.
* ...
- * sync.queueAudio(audioByteBuffer, bufferIndex, audioPresentationTimeUs); // non-blocking.
- * // The audioByteBuffer and bufferIndex will be returned via callback.
+ * sync.queueAudio(audioByteBuffer, bufferId, audioPresentationTimeUs); // non-blocking.
+ * // The audioByteBuffer and bufferId will be returned via callback.
* // More details are available as below.
* ...
* ...
@@ -75,22 +75,22 @@
* // The following code snippet illustrates how video/audio raw frames are created by
* // MediaCodec's, how they are fed to MediaSync and how they are returned by MediaSync.
* // This is the callback from MediaCodec.
- * onOutputBufferAvailable(MediaCodec codec, int bufferIndex, BufferInfo info) {
+ * onOutputBufferAvailable(MediaCodec codec, int bufferId, BufferInfo info) {
* // ...
* if (codec == videoDecoder) {
* // surface timestamp must contain media presentation time in nanoseconds.
- * codec.releaseOutputBuffer(bufferIndex, 1000 * info.presentationTime);
+ * codec.releaseOutputBuffer(bufferId, 1000 * info.presentationTime);
* } else {
- * ByteBuffer audioByteBuffer = codec.getOutputBuffer(bufferIndex);
- * sync.queueByteBuffer(audioByteBuffer, bufferIndex, info.size, info.presentationTime);
+ * ByteBuffer audioByteBuffer = codec.getOutputBuffer(bufferId);
+ * sync.queueByteBuffer(audioByteBuffer, bufferId, info.size, info.presentationTime);
* }
* // ...
* }
*
* // This is the callback from MediaSync.
- * onAudioBufferConsumed(MediaSync sync, ByteBuffer buffer, int bufferIndex) {
+ * onAudioBufferConsumed(MediaSync sync, ByteBuffer buffer, int bufferId) {
* // ...
- * audioDecoder.releaseBuffer(bufferIndex, false);
+ * audioDecoder.releaseBuffer(bufferId, false);
* // ...
* }
*
@@ -123,10 +123,11 @@
*
* @param sync The MediaSync object.
* @param audioBuffer The returned audio buffer.
- * @param bufferIndex The index associated with the audio buffer
+ * @param bufferId The ID associated with audioBuffer as passed into
+ * {@link MediaSync#queueAudio}.
*/
public abstract void onAudioBufferConsumed(
- @NonNull MediaSync sync, @NonNull ByteBuffer audioBuffer, int bufferIndex);
+ @NonNull MediaSync sync, @NonNull ByteBuffer audioBuffer, int bufferId);
}
/** Audio track failed.
@@ -172,10 +173,10 @@
public int mBufferIndex;
long mPresentationTimeUs;
- public AudioBuffer(@NonNull ByteBuffer byteBuffer, int bufferIndex,
+ public AudioBuffer(@NonNull ByteBuffer byteBuffer, int bufferId,
long presentationTimeUs) {
mByteBuffer = byteBuffer;
- mBufferIndex = bufferIndex;
+ mBufferIndex = bufferId;
mPresentationTimeUs = presentationTimeUs;
}
}
@@ -351,89 +352,6 @@
public native final Surface createInputSurface();
/**
- * Resample audio data when changing playback speed.
- * <p>
- * Resample the waveform based on the requested playback rate to get
- * a new waveform, and play back the new waveform at the original sampling
- * frequency.
- * <p><ul>
- * <li>When rate is larger than 1.0, pitch becomes higher.
- * <li>When rate is smaller than 1.0, pitch becomes lower.
- * </ul>
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
-
- /**
- * Time stretch audio when changing playback speed.
- * <p>
- * Time stretching changes the duration of the audio samples without
- * affecting their pitch. This is only supported for a limited range
- * of playback speeds, e.g. from 1/2x to 2x. If the rate is adjusted
- * beyond this limit, the rate change will fail.
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
-
- /**
- * Time stretch audio when changing playback speed, and may mute if
- * stretching is no longer supported.
- * <p>
- * Time stretching changes the duration of the audio samples without
- * affecting their pitch. This is only supported for a limited range
- * of playback speeds, e.g. from 1/2x to 2x. When it is no longer
- * supported, the audio may be muted. Using this mode will not fail
- * for non-negative playback rates.
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
-
- /** @hide */
- @IntDef(
- value = {
- PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
- PLAYBACK_RATE_AUDIO_MODE_STRETCH,
- PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface PlaybackRateAudioMode {}
-
- /**
- * Sets playback rate and audio mode.
- *
- * @param rate the ratio between desired playback rate and normal one. 1.0 means normal
- * playback speed. 0.0 means pause. Value larger than 1.0 means faster playback,
- * while value between 0.0 and 1.0 for slower playback. <b>Note:</b> the normal rate
- * does not change as a result of this call. To restore the original rate at any time,
- * use 1.0.
- * @param audioMode audio playback mode. Must be one of the supported
- * audio modes.
- *
- * @throws IllegalStateException if the internal sync engine or the audio track has not
- * been initialized.
- * @throws IllegalArgumentException if audioMode is not supported.
- */
- public void setPlaybackRate(float rate, @PlaybackRateAudioMode int audioMode) {
- PlaybackParams rateParams = new PlaybackParams();
- rateParams.allowDefaults();
- switch (audioMode) {
- case PLAYBACK_RATE_AUDIO_MODE_DEFAULT:
- rateParams.setSpeed(rate).setPitch(1.0f);
- break;
- case PLAYBACK_RATE_AUDIO_MODE_STRETCH:
- rateParams.setSpeed(rate).setPitch(1.0f)
- .setAudioFallbackMode(rateParams.AUDIO_FALLBACK_MODE_FAIL);
- break;
- case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE:
- rateParams.setSpeed(rate).setPitch(rate);
- break;
- default:
- {
- final String msg = "Audio playback mode " + audioMode + " is not supported";
- throw new IllegalArgumentException(msg);
- }
- }
- setPlaybackParams(rateParams);
- }
-
- /**
* Sets playback rate using {@link PlaybackParams}.
* <p>
* When using MediaSync with {@link AudioTrack}, set playback params using this
@@ -523,24 +441,23 @@
}
/**
- * Get current playback position.
- * <p>
- * The MediaTimestamp represents how the media time correlates to the system time in
- * a linear fashion. It contains the media time and system timestamp of an anchor frame
- * ({@link MediaTimestamp#mediaTimeUs} and {@link MediaTimestamp#nanoTime})
- * and the speed of the media clock ({@link MediaTimestamp#clockRate}).
- * <p>
- * During regular playback, the media time moves fairly constantly (though the
- * anchor frame may be rebased to a current system time, the linear correlation stays
- * steady). Therefore, this method does not need to be called often.
- * <p>
- * To help users to get current playback position, this method always returns the timestamp of
- * just-rendered frame, i.e., {@link System#nanoTime} and its corresponding media time. They
- * can be used as current playback position.
- *
- * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
- * is available, e.g. because the media sync has not been initialized.
- */
+ * Get current playback position.
+ * <p>
+ * The MediaTimestamp represents how the media time correlates to the system time in
+ * a linear fashion using an anchor and a clock rate. During regular playback, the media
+ * time moves fairly constantly (though the anchor frame may be rebased to a current
+ * system time, the linear correlation stays steady). Therefore, this method does not
+ * need to be called often.
+ * <p>
+ * To help users get current playback position, this method always anchors the timestamp
+ * to the current {@link System#nanoTime system time}, so
+ * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
+ *
+ * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
+ * is available, e.g. because the media player has not been initialized.
+ *
+ * @see MediaTimestamp
+ */
@Nullable
public MediaTimestamp getTimestamp()
{
@@ -563,22 +480,23 @@
* Queues the audio data asynchronously for playback (AudioTrack must be in streaming mode).
* @param audioData the buffer that holds the data to play. This buffer will be returned
* to the client via registered callback.
- * @param bufferIndex the buffer index used to identify audioData. It will be returned to
- * the client along with audioData. This helps applications to keep track of audioData.
+ * @param bufferId an integer used to identify audioData. It will be returned to
+ * the client along with audioData. This helps applications to keep track of audioData,
+ * e.g., it can be used to store the output buffer index used by the audio codec.
* @param presentationTimeUs the presentation timestamp in microseconds for the first frame
* in the buffer.
* @throws IllegalStateException if audio track is not set or internal configureation
* has not been done correctly.
*/
public void queueAudio(
- @NonNull ByteBuffer audioData, int bufferIndex, long presentationTimeUs) {
+ @NonNull ByteBuffer audioData, int bufferId, long presentationTimeUs) {
if (mAudioTrack == null || mAudioThread == null) {
throw new IllegalStateException(
"AudioTrack is NOT set or audio thread is not created");
}
synchronized(mAudioLock) {
- mAudioBuffers.add(new AudioBuffer(audioData, bufferIndex, presentationTimeUs));
+ mAudioBuffers.add(new AudioBuffer(audioData, bufferId, presentationTimeUs));
}
if (mPlaybackRate != 0.0) {
diff --git a/media/java/android/media/MediaTimestamp.java b/media/java/android/media/MediaTimestamp.java
index d3d5618..5ea6bbe 100644
--- a/media/java/android/media/MediaTimestamp.java
+++ b/media/java/android/media/MediaTimestamp.java
@@ -37,22 +37,36 @@
public final class MediaTimestamp
{
/**
- * Media time in microseconds.
+ * Get the media time of the anchor in microseconds.
*/
- public final long mediaTimeUs;
+ public long getAnchorMediaTimeUs() {
+ return mediaTimeUs;
+ }
/**
- * The {@link java.lang.System#nanoTime system time} corresponding to the media time
+ * Get the {@link java.lang.System#nanoTime system time} corresponding to the media time
* in nanoseconds.
*/
- public final long nanoTime;
+ public long getAnchorSytemNanoTime() {
+ return nanoTime;
+ }
/**
- * The rate of the media clock in relation to the system time.
+ * Get the rate of the media clock in relation to the system time.
+ * <p>
* It is 1.0 if media clock advances in sync with the system clock;
* greater than 1.0 if media clock is faster than the system clock;
* less than 1.0 if media clock is slower than the system clock.
*/
+ public float getMediaClockRate() {
+ return clockRate;
+ }
+
+ /** @hide - accessor shorthand */
+ public final long mediaTimeUs;
+ /** @hide - accessor shorthand */
+ public final long nanoTime;
+ /** @hide - accessor shorthand */
public final float clockRate;
/** @hide */
diff --git a/media/java/android/media/SubtitleController.java b/media/java/android/media/SubtitleController.java
index f82dbe0..fd72b39 100644
--- a/media/java/android/media/SubtitleController.java
+++ b/media/java/android/media/SubtitleController.java
@@ -20,6 +20,7 @@
import java.util.Vector;
import android.content.Context;
+import android.media.MediaPlayer.TrackInfo;
import android.media.SubtitleTrack.RenderingWidget;
import android.os.Handler;
import android.os.Looper;
@@ -275,7 +276,8 @@
mSelectedTrack.getFormat().getInteger(
MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
show();
- } else if (mSelectedTrack != null && !mSelectedTrack.isTimedText()) {
+ } else if (mSelectedTrack != null
+ && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
hide();
}
mVisibilityIsExplicit = false;
diff --git a/media/java/android/media/SubtitleTrack.java b/media/java/android/media/SubtitleTrack.java
index c760810..6c8e323 100644
--- a/media/java/android/media/SubtitleTrack.java
+++ b/media/java/android/media/SubtitleTrack.java
@@ -17,6 +17,7 @@
package android.media;
import android.graphics.Canvas;
+import android.media.MediaPlayer.TrackInfo;
import android.os.Handler;
import android.util.Log;
import android.util.LongSparseArray;
@@ -609,8 +610,10 @@
}
/** @hide whether this is a text track who fires events instead getting rendered */
- public boolean isTimedText() {
- return getRenderingWidget() == null;
+ public int getTrackType() {
+ return getRenderingWidget() == null
+ ? TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT
+ : TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
}
diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java
index dceb050..0ab52d7 100644
--- a/media/java/android/media/TimedMetaData.java
+++ b/media/java/android/media/TimedMetaData.java
@@ -19,21 +19,20 @@
import android.os.Parcel;
/**
- * Class that embodies a piece of timed metadata, including
+ * Class that embodies one timed metadata access unit, including
*
* <ul>
* <li> a time stamp, and </li>
* <li> raw uninterpreted byte-array extracted directly from the container. </li>
* </ul>
*
- * @see MediaPlayer#setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener)
+ * @see MediaPlayer#setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataListener)
*/
-
-public class TimedMetaData {
+public final class TimedMetaData {
private static final String TAG = "TimedMetaData";
- private long mTimeUs;
- private byte[] mRawData;
+ private long mTimestampUs;
+ private byte[] mMetaData;
/**
* @hide
@@ -48,12 +47,20 @@
}
}
- public long getTimeUs() {
- return mTimeUs;
+ /**
+ * @return the timestamp associated with this metadata access unit in microseconds;
+ * 0 denotes playback start.
+ */
+ public long getTimestamp() {
+ return mTimestampUs;
}
- public byte[] getRawData() {
- return mRawData;
+ /**
+ * @return raw, uninterpreted content of this metadata access unit; for ID3 tags this includes
+ * everything starting from the 3 byte signature "ID3".
+ */
+ public byte[] getMetaData() {
+ return mMetaData;
}
private boolean parseParcel(Parcel parcel) {
@@ -62,9 +69,9 @@
return false;
}
- mTimeUs = parcel.readLong();
- mRawData = new byte[parcel.readInt()];
- parcel.readByteArray(mRawData);
+ mTimestampUs = parcel.readLong();
+ mMetaData = new byte[parcel.readInt()];
+ parcel.readByteArray(mMetaData);
return true;
}
diff --git a/media/java/android/media/midi/IMidiManager.aidl b/media/java/android/media/midi/IMidiManager.aidl
index 74c63b4..fcd4aff 100644
--- a/media/java/android/media/midi/IMidiManager.aidl
+++ b/media/java/android/media/midi/IMidiManager.aidl
@@ -26,7 +26,7 @@
/** @hide */
interface IMidiManager
{
- MidiDeviceInfo[] getDeviceList();
+ MidiDeviceInfo[] getDevices();
// for device creation & removal notifications
void registerListener(IBinder token, in IMidiDeviceListener listener);
diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java
index 6b36554..6526adc 100644
--- a/media/java/android/media/midi/MidiDevice.java
+++ b/media/java/android/media/midi/MidiDevice.java
@@ -136,11 +136,14 @@
/**
* Connects the supplied {@link MidiInputPort} to the output port of this device
* with the specified port number. Once the connection is made, the MidiInput port instance
- * can no longer receive data via its {@link MidiReceiver#onReceive} method.
- * This method returns a {@link MidiDevice.MidiConnection} object, which can be used to close the connection
+ * can no longer receive data via its {@link MidiReceiver#onSend} method.
+ * This method returns a {@link MidiDevice.MidiConnection} object, which can be used
+ * to close the connection.
+ *
* @param inputPort the inputPort to connect
* @param outputPortNumber the port number of the output port to connect inputPort to.
- * @return {@link MidiDevice.MidiConnection} object if the connection is successful, or null in case of failure
+ * @return {@link MidiDevice.MidiConnection} object if the connection is successful,
+ * or null in case of failure.
*/
public MidiConnection connectPorts(MidiInputPort inputPort, int outputPortNumber) {
if (outputPortNumber < 0 || outputPortNumber >= mDeviceInfo.getOutputPortCount()) {
diff --git a/media/java/android/media/midi/MidiDeviceInfo.java b/media/java/android/media/midi/MidiDeviceInfo.java
index 57607e9..a59be54 100644
--- a/media/java/android/media/midi/MidiDeviceInfo.java
+++ b/media/java/android/media/midi/MidiDeviceInfo.java
@@ -49,6 +49,7 @@
/**
* Bundle key for the device's user visible name property.
+ * The value for this property is of type {@link java.lang.String}.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
* For USB devices, this is a concatenation of the manufacturer and product names.
*/
@@ -56,6 +57,7 @@
/**
* Bundle key for the device's manufacturer name property.
+ * The value for this property is of type {@link java.lang.String}.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
* Matches the USB device manufacturer name string for USB MIDI devices.
*/
@@ -63,6 +65,7 @@
/**
* Bundle key for the device's product name property.
+ * The value for this property is of type {@link java.lang.String}.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
* Matches the USB device product name string for USB MIDI devices.
*/
@@ -70,6 +73,7 @@
/**
* Bundle key for the device's version property.
+ * The value for this property is of type {@link java.lang.String}.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
* Matches the USB device version number for USB MIDI devices.
*/
@@ -77,20 +81,23 @@
/**
* Bundle key for the device's serial number property.
+ * The value for this property is of type {@link java.lang.String}.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
* Matches the USB device serial number for USB MIDI devices.
*/
public static final String PROPERTY_SERIAL_NUMBER = "serial_number";
/**
- * Bundle key for the device's {@link android.hardware.usb.UsbDevice}.
+ * Bundle key for the device's corresponding USB device.
+ * The value for this property is of type {@link android.hardware.usb.UsbDevice}.
* Only set for USB MIDI devices.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
*/
public static final String PROPERTY_USB_DEVICE = "usb_device";
/**
- * Bundle key for the device's {@link android.bluetooth.BluetoothDevice}.
+ * Bundle key for the device's corresponding Bluetooth device.
+ * The value for this property is of type {@link android.bluetooth.BluetoothDevice}.
* Only set for Bluetooth MIDI devices.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
*/
@@ -98,6 +105,7 @@
/**
* Bundle key for the device's ALSA card number.
+ * The value for this property is an integer.
* Only set for USB MIDI devices.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
*
@@ -107,6 +115,7 @@
/**
* Bundle key for the device's ALSA device number.
+ * The value for this property is an integer.
* Only set for USB MIDI devices.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
*
@@ -115,7 +124,8 @@
public static final String PROPERTY_ALSA_DEVICE = "alsa_device";
/**
- * {@link android.content.pm.ServiceInfo} for the service hosting the device implementation.
+ * ServiceInfo for the service hosting the device implementation.
+ * The value for this property is of type {@link android.content.pm.ServiceInfo}.
* Only set for Virtual MIDI devices.
* Used with the {@link android.os.Bundle} returned by {@link #getProperties}
*
@@ -249,18 +259,18 @@
*
* @return array of {@link PortInfo}
*/
- public PortInfo[] getPortList() {
- PortInfo[] portInfoList = new PortInfo[mInputPortCount + mOutputPortCount];
+ public PortInfo[] getPorts() {
+ PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount];
int index = 0;
for (int i = 0; i < mInputPortCount; i++) {
- portInfoList[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
+ ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
}
for (int i = 0; i < mOutputPortCount; i++) {
- portInfoList[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
+ ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
}
- return portInfoList;
+ return ports;
}
/**
diff --git a/media/java/android/media/midi/MidiDeviceStatus.java b/media/java/android/media/midi/MidiDeviceStatus.java
index d4abeff..acb54de 100644
--- a/media/java/android/media/midi/MidiDeviceStatus.java
+++ b/media/java/android/media/midi/MidiDeviceStatus.java
@@ -69,6 +69,7 @@
/**
* Returns true if an input port is open.
+ * An input port can only be opened by one client at a time.
*
* @param portNumber the input port's port number
* @return input port open status
@@ -78,7 +79,8 @@
}
/**
- * Returns the open count for an output port.
+ * Returns the number of clients currently connected to the specified output port.
+ * Unlike input ports, an output port can be opened by multiple clients at the same time.
*
* @param portNumber the output port's port number
* @return output port open count
diff --git a/media/java/android/media/midi/MidiInputPort.java b/media/java/android/media/midi/MidiInputPort.java
index ff16a57..af5a86c 100644
--- a/media/java/android/media/midi/MidiInputPort.java
+++ b/media/java/android/media/midi/MidiInputPort.java
@@ -49,6 +49,8 @@
/* package */ MidiInputPort(IMidiDeviceServer server, IBinder token,
ParcelFileDescriptor pfd, int portNumber) {
+ super(MidiPortImpl.MAX_PACKET_DATA_SIZE);
+
mDeviceServer = server;
mToken = token;
mParcelFileDescriptor = pfd;
@@ -71,7 +73,7 @@
}
@Override
- public void onReceive(byte[] msg, int offset, int count, long timestamp) throws IOException {
+ public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
if (offset < 0 || count < 0 || offset + count > msg.length) {
throw new IllegalArgumentException("offset or count out of range");
}
@@ -89,7 +91,7 @@
}
@Override
- public void flush() throws IOException {
+ public void onFlush() throws IOException {
synchronized (mBuffer) {
if (mOutputStream == null) {
throw new IOException("MidiInputPort is closed");
@@ -113,11 +115,6 @@
}
@Override
- public int getMaxMessageSize() {
- return MidiPortImpl.MAX_PACKET_DATA_SIZE;
- }
-
- @Override
public void close() throws IOException {
synchronized (mGuard) {
if (mIsClosed) return;
diff --git a/media/java/android/media/midi/MidiManager.java b/media/java/android/media/midi/MidiManager.java
index 0ba1744..d19cf36 100644
--- a/media/java/android/media/midi/MidiManager.java
+++ b/media/java/android/media/midi/MidiManager.java
@@ -151,29 +151,16 @@
}
/**
- * Callback class used for receiving the results of {@link #openDevice}
+ * Listener class used for receiving the results of {@link #openDevice} and
+ * {@link #openBluetoothDevice}
*/
- abstract public static class DeviceOpenCallback {
+ public interface OnDeviceOpenedListener {
/**
* Called to respond to a {@link #openDevice} request
*
- * @param deviceInfo the {@link MidiDeviceInfo} for the device to open
* @param device a {@link MidiDevice} for opened device, or null if opening failed
*/
- abstract public void onDeviceOpened(MidiDeviceInfo deviceInfo, MidiDevice device);
- }
-
- /**
- * Callback class used for receiving the results of {@link #openBluetoothDevice}
- */
- abstract public static class BluetoothOpenCallback {
- /**
- * Called to respond to a {@link #openBluetoothDevice} request
- *
- * @param bluetoothDevice the {@link android.bluetooth.BluetoothDevice} to open
- * @param device a {@link MidiDevice} for opened device, or null if opening failed
- */
- abstract public void onDeviceOpened(BluetoothDevice bluetoothDevice, MidiDevice device);
+ abstract public void onDeviceOpened(MidiDevice device);
}
/**
@@ -224,38 +211,25 @@
*
* @return an array of all MIDI devices
*/
- public MidiDeviceInfo[] getDeviceList() {
+ public MidiDeviceInfo[] getDevices() {
try {
- return mService.getDeviceList();
+ return mService.getDevices();
} catch (RemoteException e) {
- Log.e(TAG, "RemoteException in getDeviceList");
+ Log.e(TAG, "RemoteException in getDevices");
return new MidiDeviceInfo[0];
}
}
- private void sendOpenDeviceResponse(final MidiDeviceInfo deviceInfo, final MidiDevice device,
- final DeviceOpenCallback callback, Handler handler) {
+ private void sendOpenDeviceResponse(final MidiDevice device,
+ final OnDeviceOpenedListener listener, Handler handler) {
if (handler != null) {
handler.post(new Runnable() {
@Override public void run() {
- callback.onDeviceOpened(deviceInfo, device);
+ listener.onDeviceOpened(device);
}
});
} else {
- callback.onDeviceOpened(deviceInfo, device);
- }
- }
-
- private void sendBluetoothDeviceResponse(final BluetoothDevice bluetoothDevice,
- final MidiDevice device, final BluetoothOpenCallback callback, Handler handler) {
- if (handler != null) {
- handler.post(new Runnable() {
- @Override public void run() {
- callback.onDeviceOpened(bluetoothDevice, device);
- }
- });
- } else {
- callback.onDeviceOpened(bluetoothDevice, device);
+ listener.onDeviceOpened(device);
}
}
@@ -263,12 +237,13 @@
* Opens a MIDI device for reading and writing.
*
* @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
- * @param callback a {@link MidiManager.DeviceOpenCallback} to be called to receive the result
+ * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
+ * to receive the result
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
* the result. If handler is null, then the thread used for the
- * callback is unspecified.
+ * listener is unspecified.
*/
- public void openDevice(MidiDeviceInfo deviceInfo, DeviceOpenCallback callback,
+ public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener,
Handler handler) {
MidiDevice device = null;
try {
@@ -283,7 +258,7 @@
intent.setComponent(new ComponentName(serviceInfo.packageName,
serviceInfo.name));
final MidiDeviceInfo deviceInfoF = deviceInfo;
- final DeviceOpenCallback callbackF = callback;
+ final OnDeviceOpenedListener listenerF = listener;
final Handler handlerF = handler;
if (mContext.bindService(intent,
new ServiceConnection() {
@@ -291,8 +266,9 @@
public void onServiceConnected(ComponentName name, IBinder binder) {
IMidiDeviceServer server =
IMidiDeviceServer.Stub.asInterface(binder);
- MidiDevice device = new MidiDevice(deviceInfoF, server, mContext, this);
- sendOpenDeviceResponse(deviceInfoF, device, callbackF, handlerF);
+ MidiDevice device = new MidiDevice(deviceInfoF, server, mContext,
+ this);
+ sendOpenDeviceResponse(device, listenerF, handlerF);
}
@Override
@@ -314,21 +290,21 @@
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in openDevice");
}
- sendOpenDeviceResponse(deviceInfo, device, callback, handler);
+ sendOpenDeviceResponse(device, listener, handler);
}
/**
* Opens a Bluetooth MIDI device for reading and writing.
*
* @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device
- * @param callback a {@link MidiManager.BluetoothOpenCallback} to be called to receive the
+ * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called to receive the
* result
* @param handler the {@link android.os.Handler Handler} that will be used for delivering
* the result. If handler is null, then the thread used for the
- * callback is unspecified.
+ * listener is unspecified.
*/
public void openBluetoothDevice(final BluetoothDevice bluetoothDevice,
- final BluetoothOpenCallback callback, final Handler handler) {
+ final OnDeviceOpenedListener listener, final Handler handler) {
Intent intent = new Intent(BLUETOOTH_MIDI_SERVICE_INTENT);
intent.setComponent(new ComponentName(BLUETOOTH_MIDI_SERVICE_PACKAGE,
BLUETOOTH_MIDI_SERVICE_CLASS));
@@ -343,10 +319,10 @@
// fetch MidiDeviceInfo from the server
MidiDeviceInfo deviceInfo = server.getDeviceInfo();
MidiDevice device = new MidiDevice(deviceInfo, server, mContext, this);
- sendBluetoothDeviceResponse(bluetoothDevice, device, callback, handler);
+ sendOpenDeviceResponse(device, listener, handler);
} catch (RemoteException e) {
Log.e(TAG, "remote exception in onServiceConnected");
- sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler);
+ sendOpenDeviceResponse(null, listener, handler);
}
}
@@ -358,7 +334,7 @@
Context.BIND_AUTO_CREATE))
{
Log.e(TAG, "Unable to bind service: " + intent);
- sendBluetoothDeviceResponse(bluetoothDevice, null, callback, handler);
+ sendOpenDeviceResponse(null, listener, handler);
}
}
diff --git a/media/java/android/media/midi/MidiOutputPort.java b/media/java/android/media/midi/MidiOutputPort.java
index 7491f3c..0096995 100644
--- a/media/java/android/media/midi/MidiOutputPort.java
+++ b/media/java/android/media/midi/MidiOutputPort.java
@@ -70,7 +70,7 @@
long timestamp = MidiPortImpl.getPacketTimestamp(buffer, count);
// dispatch to all our receivers
- mDispatcher.sendWithTimestamp(buffer, offset, size, timestamp);
+ mDispatcher.send(buffer, offset, size, timestamp);
break;
}
case MidiPortImpl.PACKET_TYPE_FLUSH:
@@ -114,12 +114,12 @@
}
@Override
- public void connect(MidiReceiver receiver) {
+ public void onConnect(MidiReceiver receiver) {
mDispatcher.getSender().connect(receiver);
}
@Override
- public void disconnect(MidiReceiver receiver) {
+ public void onDisconnect(MidiReceiver receiver) {
mDispatcher.getSender().disconnect(receiver);
}
diff --git a/media/java/android/media/midi/MidiReceiver.java b/media/java/android/media/midi/MidiReceiver.java
index f8799d4..85c451f 100644
--- a/media/java/android/media/midi/MidiReceiver.java
+++ b/media/java/android/media/midi/MidiReceiver.java
@@ -22,19 +22,35 @@
* Interface for sending and receiving data to and from a MIDI device.
*/
abstract public class MidiReceiver {
+
+ private final int mMaxMessageSize;
+
/**
- * Although public, this method should be considered a private implementation
- * detail. Client code should call {@link #send} or {@link #sendWithTimestamp}
- * instead.
- *
- * Called to pass MIDI data to the receiver.
+ * Default MidiReceiver constructor. Maximum message size is set to
+ * {@link java.lang.Integer#MAX_VALUE}
+ */
+ public MidiReceiver() {
+ mMaxMessageSize = Integer.MAX_VALUE;
+ }
+
+ /**
+ * MidiReceiver constructor.
+ * @param maxMessageSize the maximum size of a message this receiver can receive
+ */
+ public MidiReceiver(int maxMessageSize) {
+ mMaxMessageSize = maxMessageSize;
+ }
+
+ /**
+ * Called whenever the receiver is passed new MIDI data.
+ * Subclasses override this method to receive MIDI data.
* May fail if count exceeds {@link #getMaxMessageSize}.
*
* NOTE: the msg array parameter is only valid within the context of this call.
* The msg bytes should be copied by the receiver rather than retaining a reference
* to this parameter.
* Also, modifying the contents of the msg array parameter may result in other receivers
- * in the same application receiving incorrect values in their {link #onReceive} method.
+ * in the same application receiving incorrect values in their {link #onSend} method.
*
* @param msg a byte array containing the MIDI data
* @param offset the offset of the first byte of the data in the array to be processed
@@ -42,28 +58,37 @@
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
* @throws IOException
*/
- abstract public void onReceive(byte[] msg, int offset, int count, long timestamp)
+ abstract public void onSend(byte[] msg, int offset, int count, long timestamp)
throws IOException;
/**
- * Instructs the receiver to discard all pending events.
+ * Instructs the receiver to discard all pending MIDI data.
* @throws IOException
*/
public void flush() throws IOException {
+ onFlush();
+ }
+
+ /**
+ * Called when the receiver is instructed to discard all pending MIDI data.
+ * Subclasses should override this method if they maintain a list or queue of MIDI data
+ * to be processed in the future.
+ * @throws IOException
+ */
+ public void onFlush() throws IOException {
}
/**
* Returns the maximum size of a message this receiver can receive.
- * Defaults to {@link java.lang.Integer#MAX_VALUE} unless overridden.
* @return maximum message size
*/
- public int getMaxMessageSize() {
- return Integer.MAX_VALUE;
+ public final int getMaxMessageSize() {
+ return mMaxMessageSize;
}
/**
* Called to send MIDI data to the receiver
- * Data will get split into multiple calls to {@link #onReceive} if count exceeds
+ * Data will get split into multiple calls to {@link #onSend} if count exceeds
* {@link #getMaxMessageSize}.
*
* @param msg a byte array containing the MIDI data
@@ -72,12 +97,12 @@
* @throws IOException
*/
public void send(byte[] msg, int offset, int count) throws IOException {
- sendWithTimestamp(msg, offset, count, System.nanoTime());
+ send(msg, offset, count, System.nanoTime());
}
/**
* Called to send MIDI data to the receiver to be handled at a specified time in the future
- * Data will get split into multiple calls to {@link #onReceive} if count exceeds
+ * Data will get split into multiple calls to {@link #onSend} if count exceeds
* {@link #getMaxMessageSize}.
*
* @param msg a byte array containing the MIDI data
@@ -86,12 +111,12 @@
* @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
* @throws IOException
*/
- public void sendWithTimestamp(byte[] msg, int offset, int count, long timestamp)
+ public void send(byte[] msg, int offset, int count, long timestamp)
throws IOException {
int messageSize = getMaxMessageSize();
while (count > 0) {
int length = (count > messageSize ? messageSize : count);
- onReceive(msg, offset, length, timestamp);
+ onSend(msg, offset, length, timestamp);
offset += length;
count -= length;
}
diff --git a/media/java/android/media/midi/MidiSender.java b/media/java/android/media/midi/MidiSender.java
index f64fc3c..c5f1edc 100644
--- a/media/java/android/media/midi/MidiSender.java
+++ b/media/java/android/media/midi/MidiSender.java
@@ -21,17 +21,42 @@
* MidiReceivers to a MIDI device.
*/
abstract public class MidiSender {
+
+ /**
+ * Connects a {@link MidiReceiver} to the sender
+ *
+ * @param receiver the receiver to connect
+ */
+ public void connect(MidiReceiver receiver) {
+ if (receiver == null) {
+ throw new NullPointerException("receiver null in MidiSender.connect");
+ }
+ onConnect(receiver);
+ }
+
+ /**
+ * Disconnects a {@link MidiReceiver} from the sender
+ *
+ * @param receiver the receiver to disconnect
+ */
+ public void disconnect(MidiReceiver receiver) {
+ if (receiver == null) {
+ throw new NullPointerException("receiver null in MidiSender.disconnect");
+ }
+ onDisconnect(receiver);
+ }
+
/**
* Called to connect a {@link MidiReceiver} to the sender
*
* @param receiver the receiver to connect
*/
- abstract public void connect(MidiReceiver receiver);
+ abstract public void onConnect(MidiReceiver receiver);
/**
* Called to disconnect a {@link MidiReceiver} from the sender
*
* @param receiver the receiver to disconnect
*/
- abstract public void disconnect(MidiReceiver receiver);
+ abstract public void onDisconnect(MidiReceiver receiver);
}
diff --git a/media/java/android/media/midi/package.html b/media/java/android/media/midi/package.html
index 9e7e8b1..8850e6f 100644
--- a/media/java/android/media/midi/package.html
+++ b/media/java/android/media/midi/package.html
@@ -30,13 +30,13 @@
messages.
<li> Support transmission of arbitrary length data for SysEx, etc.
<li> Timestamps to avoid jitter.
- <li> Support direction connection or “patching” of devices for lower latency.
+ <li> Support direction connection or “patching” of devices for lower latency.
</ul>
<h2 id=transports_supported>Transports Supported</h2>
-<p>The API is “transport agnostic”. But there are several transports currently
+<p>The API is “transport agnostic”. But there are several transports currently
supported:</p>
<ul>
@@ -83,7 +83,7 @@
information can be presented to a user, allowing them to choose a device.</p>
<pre class=prettyprint>
-MidiDeviceInfo[] infos = m.getDeviceList();
+MidiDeviceInfo[] infos = m.getDevices();
</pre>
@@ -116,9 +116,9 @@
</pre>
-<p>Note that “input” and “output” are from the standpoint of the device. So a
-synthesizer will have an “input” port that receives messages. A keyboard will
-have an “output” port that sends messages.</p>
+<p>Note that “input” and “output” are from the standpoint of the device. So a
+synthesizer will have an “input” port that receives messages. A keyboard will
+have an “output” port that sends messages.</p>
<p>The MidiDeviceInfo has a bundle of properties.</p>
@@ -148,12 +148,11 @@
Handler if you want the callback to occur on a specific Thread.</p>
<pre class=prettyprint>
-m.openDevice(info, new MidiManager.DeviceOpenCallback() {
+m.openDevice(info, new MidiManager.OnDeviceOpenedListener() {
@Override
- public void onDeviceOpened(MidiDeviceInfo deviceInfo,
- MidiDevice device) {
+ public void onDeviceOpened(MidiDevice device) {
if (device == null) {
- Log.e(TAG, "could not open " + deviceInfo);
+ Log.e(TAG, "could not open device " + info);
} else {
...
}, new Handler(Looper.getMainLooper())
@@ -164,7 +163,7 @@
<h2 id=open_a_midi_input_port>Open a MIDI Input Port</h2>
-<p>If you want to send a message to a MIDI Device then you need to open an “input”
+<p>If you want to send a message to a MIDI Device then you need to open an “input”
port with exclusive access.</p>
<pre class=prettyprint>
@@ -199,7 +198,7 @@
<pre class=prettyprint>
long now = System.nanoTime();
long future = now + (2 * 1000000000);
-inputPort.sendWithTimestamp(buffer, offset, numBytes, future);
+inputPort.send(buffer, offset, numBytes, future);
</pre>
@@ -212,7 +211,7 @@
<p>If there were any MIDI NoteOff message left in the buffer then they will be
-discarded and you may get stuck notes. So we recommend sending “all notes off”
+discarded and you may get stuck notes. So we recommend sending “all notes off”
after doing a flush.</p>
<h2 id=receive_a_note>Receive a Note</h2>
@@ -223,7 +222,7 @@
<pre class=prettyprint>
class MyReceiver extends MidiReceiver {
- public void onReceive(byte[] data, int offset,
+ public void onSend(byte[] data, int offset,
int count, long timestamp) throws IOException {
// parse MIDI or whatever
}
@@ -264,7 +263,7 @@
<p>The details of the resource in this example is stored in
-“res/xml/synth_device_info.xml”.</p>
+“res/xml/synth_device_info.xml”.</p>
<pre class=prettyprint>
<devices>
@@ -279,7 +278,7 @@
<p>You then define your server by extending android.media.midi.MidiDeviceService.
-Let’s assume you have a MySynthEngine class that extends MidiReceiver.</p>
+Let‘s assume you have a MySynthEngine class that extends MidiReceiver.</p>
<pre class=prettyprint>
import android.media.midi.MidiDeviceService;
diff --git a/telecomm/java/android/telecom/CameraCapabilities.aidl b/media/java/android/media/tv/DvbDeviceInfo.aidl
similarity index 68%
copy from telecomm/java/android/telecom/CameraCapabilities.aidl
copy to media/java/android/media/tv/DvbDeviceInfo.aidl
index c8e0c5e..4851050 100644
--- a/telecomm/java/android/telecom/CameraCapabilities.aidl
+++ b/media/java/android/media/tv/DvbDeviceInfo.aidl
@@ -1,22 +1,20 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Copyright 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
+ * 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
+ * limitations under the License.
*/
-package android.telecom;
+package android.media.tv;
-/**
- * {@hide}
- */
-parcelable CameraCapabilities;
+parcelable DvbDeviceInfo;
\ No newline at end of file
diff --git a/media/java/android/media/tv/DvbDeviceInfo.java b/media/java/android/media/tv/DvbDeviceInfo.java
new file mode 100644
index 0000000..1885a34
--- /dev/null
+++ b/media/java/android/media/tv/DvbDeviceInfo.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.tv;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.media.tv.TvInputManager;
+import android.util.Log;
+
+import java.lang.IllegalArgumentException;
+
+/**
+ * Simple container for information about DVB device.
+ * Not for third-party developers.
+ *
+ * @hide
+ */
+public final class DvbDeviceInfo implements Parcelable {
+ static final String TAG = "DvbDeviceInfo";
+
+ public static final Parcelable.Creator<DvbDeviceInfo> CREATOR =
+ new Parcelable.Creator<DvbDeviceInfo>() {
+ @Override
+ public DvbDeviceInfo createFromParcel(Parcel source) {
+ try {
+ return new DvbDeviceInfo(source);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating DvbDeviceInfo from parcel", e);
+ return null;
+ }
+ }
+
+ @Override
+ public DvbDeviceInfo[] newArray(int size) {
+ return new DvbDeviceInfo[size];
+ }
+ };
+
+ private final int mAdapterId;
+ private final int mDeviceId;
+
+ private DvbDeviceInfo(Parcel source) {
+ mAdapterId = source.readInt();
+ mDeviceId = source.readInt();
+ }
+
+ /**
+ * Constructs a new {@link DvbDeviceInfo} with the given adapter ID and device ID.
+ */
+ public DvbDeviceInfo(int adapterId, int deviceId) {
+ mAdapterId = adapterId;
+ mDeviceId = deviceId;
+ }
+
+ /**
+ * Returns the adapter ID of DVB device, in terms of enumerating the DVB device adapters
+ * installed in the system. The adapter ID counts from zero.
+ */
+ public int getAdapterId() {
+ return mAdapterId;
+ }
+
+ /**
+ * Returns the device ID of DVB device, in terms of enumerating the DVB devices attached to
+ * the same device adapter. The device ID counts from zero.
+ */
+ public int getDeviceId() {
+ return mDeviceId;
+ }
+
+ // Parcelable
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mAdapterId);
+ dest.writeInt(mDeviceId);
+ }
+}
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 078fb2f..6fe5dbb 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -18,6 +18,7 @@
import android.content.ComponentName;
import android.graphics.Rect;
+import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
@@ -29,6 +30,7 @@
import android.media.tv.TvTrackInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
import android.view.Surface;
/**
@@ -91,4 +93,8 @@
boolean captureFrame(in String inputId, in Surface surface, in TvStreamConfig config,
int userId);
boolean isSingleSessionActive(int userId);
+
+ // For DVB device binding
+ List<DvbDeviceInfo> getDvbDeviceList();
+ ParcelFileDescriptor openDvbDevice(in DvbDeviceInfo info, int device);
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 0191652..58954bd 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.graphics.Rect;
+import android.media.PlaybackParams;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -172,7 +173,10 @@
break;
}
case DO_TIME_SHIFT_SET_PLAYBACK_RATE: {
- mTvInputSessionImpl.timeShiftSetPlaybackRate((Float) msg.obj, msg.arg1);
+ PlaybackParams params = new PlaybackParams()
+ .setSpeed((Float) msg.obj)
+ .setAudioFallbackMode(msg.arg1);
+ mTvInputSessionImpl.timeShiftSetPlaybackParams(params);
break;
}
case DO_TIME_SHIFT_ENABLE_POSITION_TRACKING: {
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 705aa3d6..caa8a09 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -20,13 +20,13 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Rect;
-import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Log;
@@ -55,6 +55,25 @@
public final class TvInputManager {
private static final String TAG = "TvInputManager";
+ static final int DVB_DEVICE_START = 0;
+ static final int DVB_DEVICE_END = 2;
+
+ /**
+ * A demux device of DVB API for controlling the filters of DVB hardware/software.
+ * @hide
+ */
+ public static final int DVB_DEVICE_DEMUX = DVB_DEVICE_START;
+ /**
+ * A DVR device of DVB API for reading transport streams.
+ * @hide
+ */
+ public static final int DVB_DEVICE_DVR = 1;
+ /**
+ * A frontend device of DVB API for controlling the tuner and DVB demodulator hardware.
+ * @hide
+ */
+ public static final int DVB_DEVICE_FRONTEND = DVB_DEVICE_END;
+
static final int VIDEO_UNAVAILABLE_REASON_START = 0;
static final int VIDEO_UNAVAILABLE_REASON_END = 4;
@@ -1258,6 +1277,43 @@
}
/**
+ * Returns the list of currently available DVB devices on the system.
+ *
+ * @return the list of {@link DvbDeviceInfo} objects representing available DVB devices.
+ * @hide
+ */
+ public List<DvbDeviceInfo> getDvbDeviceList() {
+ try {
+ return mService.getDvbDeviceList();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Returns a {@link ParcelFileDescriptor} of a specified DVB device for a given
+ * {@link DvbDeviceInfo}
+ *
+ * @param info A {@link DvbDeviceInfo} to open a DVB device.
+ * @param device A DVB device. The DVB device can be {@link #DVB_DEVICE_DEMUX},
+ * {@link #DVB_DEVICE_DVR} or {@link #DVB_DEVICE_FRONTEND}.
+ * @return a {@link ParcelFileDescriptor} of a specified DVB device for a given
+ * {@link DvbDeviceInfo}, or {@code null} if the given {@link DvbDeviceInfo} was invalid
+ * or the specified DVB device was busy with a previous request.
+ * @hide
+ */
+ public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device) {
+ try {
+ if (DVB_DEVICE_START > device || DVB_DEVICE_END < device) {
+ throw new IllegalArgumentException("Invalid DVB device: " + device);
+ }
+ return mService.openDvbDevice(info, device);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* The Session provides the per-session functionality of TV inputs.
* @hide
*/
@@ -1706,9 +1762,6 @@
Log.w(TAG, "The session has been already released");
return;
}
- if (audioMode != MediaPlayer.PLAYBACK_RATE_AUDIO_MODE_RESAMPLE) {
- throw new IllegalArgumentException("Unknown audio playback mode " + audioMode);
- }
try {
mService.timeShiftSetPlaybackRate(mToken, rate, audioMode, mUserId);
} catch (RemoteException e) {
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 8b0472a..4b84090 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -26,6 +26,8 @@
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.PlaybackParams;
+import android.media.tv.TvInputService.HardwareSession;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -586,7 +588,7 @@
* set playback rate and audio mode. The implementation should override
* {@link #onTimeShiftPause}, {@link #onTimeShiftResume}, {@link #onTimeShiftSeekTo},
* {@link #onTimeShiftGetStartPosition}, {@link #onTimeShiftGetCurrentPosition} and
- * {@link #onTimeShiftSetPlaybackRate}.
+ * {@link #onTimeShiftSetPlaybackParams}.
*
* @param status The current time shift status. Should be one of the followings.
* <ul>
@@ -853,7 +855,7 @@
*
* @see #onTimeShiftResume
* @see #onTimeShiftSeekTo
- * @see #onTimeShiftSetPlaybackRate
+ * @see #onTimeShiftSetPlaybackParams
* @see #onTimeShiftGetStartPosition
* @see #onTimeShiftGetCurrentPosition
*/
@@ -865,7 +867,7 @@
*
* @see #onTimeShiftPause
* @see #onTimeShiftSeekTo
- * @see #onTimeShiftSetPlaybackRate
+ * @see #onTimeShiftSetPlaybackParams
* @see #onTimeShiftGetStartPosition
* @see #onTimeShiftGetCurrentPosition
*/
@@ -881,7 +883,7 @@
* @param timeMs The time position to seek to, in milliseconds since the epoch.
* @see #onTimeShiftResume
* @see #onTimeShiftPause
- * @see #onTimeShiftSetPlaybackRate
+ * @see #onTimeShiftSetPlaybackParams
* @see #onTimeShiftGetStartPosition
* @see #onTimeShiftGetCurrentPosition
*/
@@ -889,25 +891,20 @@
}
/**
- * Called when the application sets playback rate and audio mode.
+ * Called when the application sets playback parameters containing the speed and audio mode.
*
- * <p>Once a playback rate is set, the implementation should honor the value until a new
- * tune request. Pause/resume/seek request does not reset the playback rate previously set.
+ * <p>Once the playback parameters are set, the implementation should honor the current
+ * settings until the next tune request. Pause/resume/seek request does not reset the
+ * parameters previously set.
*
- * @param rate The ratio between desired playback rate and normal one.
- * @param audioMode Audio playback mode. Must be one of the supported audio modes:
- * <ul>
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_DEFAULT}
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH}
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
- * </ul>
+ * @param params The playback params.
* @see #onTimeShiftResume
* @see #onTimeShiftPause
* @see #onTimeShiftSeekTo
* @see #onTimeShiftGetStartPosition
* @see #onTimeShiftGetCurrentPosition
*/
- public void onTimeShiftSetPlaybackRate(float rate, int audioMode) {
+ public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
}
/**
@@ -924,7 +921,7 @@
* @see #onTimeShiftResume
* @see #onTimeShiftPause
* @see #onTimeShiftSeekTo
- * @see #onTimeShiftSetPlaybackRate
+ * @see #onTimeShiftSetPlaybackParams
* @see #onTimeShiftGetCurrentPosition
*/
public long onTimeShiftGetStartPosition() {
@@ -939,7 +936,7 @@
* @see #onTimeShiftResume
* @see #onTimeShiftPause
* @see #onTimeShiftSeekTo
- * @see #onTimeShiftSetPlaybackRate
+ * @see #onTimeShiftSetPlaybackParams
* @see #onTimeShiftGetStartPosition
*/
public long onTimeShiftGetCurrentPosition() {
@@ -1273,10 +1270,10 @@
}
/**
- * Calls {@link #onTimeShiftSetPlaybackRate}.
+ * Calls {@link #onTimeShiftSetPlaybackParams}.
*/
- void timeShiftSetPlaybackRate(float rate, int audioMode) {
- onTimeShiftSetPlaybackRate(rate, audioMode);
+ void timeShiftSetPlaybackParams(PlaybackParams params) {
+ onTimeShiftSetPlaybackParams(params);
}
/**
diff --git a/media/java/android/media/tv/TvTrackInfo.java b/media/java/android/media/tv/TvTrackInfo.java
index 2c956e9..ed432c46 100644
--- a/media/java/android/media/tv/TvTrackInfo.java
+++ b/media/java/android/media/tv/TvTrackInfo.java
@@ -45,7 +45,7 @@
private final int mType;
private final String mId;
private final String mLanguage;
- private final String mDescription;
+ private final CharSequence mDescription;
private final int mAudioChannelCount;
private final int mAudioSampleRate;
private final int mVideoWidth;
@@ -54,7 +54,7 @@
private final float mVideoPixelAspectRatio;
private final Bundle mExtra;
- private TvTrackInfo(int type, String id, String language, String description,
+ private TvTrackInfo(int type, String id, String language, CharSequence description,
int audioChannelCount, int audioSampleRate, int videoWidth, int videoHeight,
float videoFrameRate, float videoPixelAspectRatio, Bundle extra) {
mType = type;
@@ -110,7 +110,7 @@
/**
* Returns a user readable description for the current track.
*/
- public final String getDescription() {
+ public final CharSequence getDescription() {
return mDescription;
}
@@ -201,7 +201,7 @@
dest.writeInt(mType);
dest.writeString(mId);
dest.writeString(mLanguage);
- dest.writeString(mDescription);
+ dest.writeString(mDescription != null ? mDescription.toString() : null);
dest.writeInt(mAudioChannelCount);
dest.writeInt(mAudioSampleRate);
dest.writeInt(mVideoWidth);
@@ -231,7 +231,7 @@
private final String mId;
private final int mType;
private String mLanguage;
- private String mDescription;
+ private CharSequence mDescription;
private int mAudioChannelCount;
private int mAudioSampleRate;
private int mVideoWidth;
@@ -274,7 +274,7 @@
*
* @param description The user readable description.
*/
- public final Builder setDescription(String description) {
+ public final Builder setDescription(CharSequence description) {
mDescription = description;
return this;
}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index ebe281f..6169eea 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -24,9 +24,11 @@
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
+import android.media.PlaybackParams;
import android.media.tv.TvInputManager.Session;
import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
import android.media.tv.TvInputManager.SessionCallback;
+import android.media.tv.TvView.TimeShiftPositionCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -468,19 +470,13 @@
}
/**
- * Sets playback rate and audio mode.
+ * Sets playback rate using {@link android.media#PlaybackParams}.
*
- * @param rate The ratio between desired playback rate and normal one.
- * @param audioMode Audio playback mode. Must be one of the supported audio modes:
- * <ul>
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_DEFAULT}
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_STRETCH}
- * <li> {@link android.media.MediaPlayer#PLAYBACK_RATE_AUDIO_MODE_RESAMPLE}
- * </ul>
+ * @param params The playback params.
*/
- public void timeShiftSetPlaybackRate(float rate, int audioMode) {
+ public void timeShiftSetPlaybackParams(@NonNull PlaybackParams params) {
if (mSession != null) {
- mSession.timeShiftSetPlaybackRate(rate, audioMode);
+ mSession.timeShiftSetPlaybackRate(params.getSpeed(), params.getAudioFallbackMode());
}
}
@@ -820,6 +816,9 @@
* limitation on storage space). The application should not allow the user to seek to a
* position earlier than the start position.
*
+ * <p>Note that {@code timeMs} is not relative time in the program but wall-clock time,
+ * which is intended to avoid calling this method unnecessarily around program boundaries.
+ *
* @param inputId The ID of the TV input bound to this view.
* @param timeMs The start playback position of the time shifted program, in milliseconds
* since the epoch.
@@ -830,6 +829,9 @@
/**
* This is called when the current playback position is changed.
*
+ * <p>Note that {@code timeMs} is not relative time in the program but wall-clock time,
+ * which is intended to avoid calling this method unnecessarily around program boundaries.
+ *
* @param inputId The ID of the TV input bound to this view.
* @param timeMs The current playback position of the time shifted program, in milliseconds
* since the epoch.
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index 043e20b..49614bd 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -1222,6 +1222,19 @@
}
}
+static jint Image_getFormat(JNIEnv* env, jobject thiz, jint readerFormat)
+{
+ if (isFormatOpaque(readerFormat)) {
+ // Assuming opaque reader produce opaque images.
+ return static_cast<jint>(PublicFormat::PRIVATE);
+ } else {
+ CpuConsumer::LockedBuffer* buffer = Image_getLockedBuffer(env, thiz);
+ PublicFormat publicFmt = android_view_Surface_mapHalFormatDataspaceToPublicFormat(
+ buffer->flexFormat, buffer->dataSpace);
+ return static_cast<jint>(publicFmt);
+ }
+}
+
} // extern "C"
// ----------------------------------------------------------------------------
@@ -1240,8 +1253,9 @@
{"nativeImageGetBuffer", "(II)Ljava/nio/ByteBuffer;", (void*)Image_getByteBuffer },
{"nativeCreatePlane", "(II)Landroid/media/ImageReader$SurfaceImage$SurfacePlane;",
(void*)Image_createSurfacePlane },
- {"nativeGetWidth", "(I)I", (void*)Image_getWidth },
- {"nativeGetHeight", "(I)I", (void*)Image_getHeight },
+ {"nativeGetWidth", "(I)I", (void*)Image_getWidth },
+ {"nativeGetHeight", "(I)I", (void*)Image_getHeight },
+ {"nativeGetFormat", "(I)I", (void*)Image_getFormat },
};
int register_android_media_ImageReader(JNIEnv *env) {
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 31fb37c..93b8ec7 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -272,9 +272,9 @@
return mCodec->createInputSurface(bufferProducer);
}
-status_t JMediaCodec::usePersistentInputSurface(
+status_t JMediaCodec::setInputSurface(
const sp<PersistentSurface> &surface) {
- return mCodec->usePersistentInputSurface(surface);
+ return mCodec->setInputSurface(surface);
}
status_t JMediaCodec::start() {
@@ -1034,9 +1034,9 @@
// no need to release surface as it will be released by Surface's jni
}
-static void android_media_MediaCodec_usePersistentInputSurface(
+static void android_media_MediaCodec_setInputSurface(
JNIEnv* env, jobject thiz, jobject object) {
- ALOGV("android_media_MediaCodec_usePersistentInputSurface");
+ ALOGV("android_media_MediaCodec_setInputSurface");
sp<JMediaCodec> codec = getMediaCodec(env, thiz);
if (codec == NULL) {
@@ -1047,7 +1047,7 @@
sp<PersistentSurface> persistentSurface =
android_media_MediaCodec_getPersistentInputSurface(env, object);
- status_t err = codec->usePersistentInputSurface(persistentSurface);
+ status_t err = codec->setInputSurface(persistentSurface);
if (err != NO_ERROR) {
throwExceptionAsNecessary(env, err);
}
@@ -1741,8 +1741,8 @@
"()Landroid/media/MediaCodec$PersistentSurface;",
(void *)android_media_MediaCodec_createPersistentInputSurface },
- { "native_usePersistentInputSurface", "(Landroid/view/Surface;)V",
- (void *)android_media_MediaCodec_usePersistentInputSurface },
+ { "native_setInputSurface", "(Landroid/view/Surface;)V",
+ (void *)android_media_MediaCodec_setInputSurface },
{ "native_setCallback",
"(Landroid/media/MediaCodec$Callback;)V",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index bf61f42..a4ed67b 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -58,7 +58,7 @@
const sp<IGraphicBufferProducer> &surface);
status_t createInputSurface(sp<IGraphicBufferProducer>* bufferProducer);
- status_t usePersistentInputSurface(const sp<PersistentSurface> &surface);
+ status_t setInputSurface(const sp<PersistentSurface> &surface);
status_t start();
status_t stop();
diff --git a/media/jni/android_media_MediaDataSource.cpp b/media/jni/android_media_MediaDataSource.cpp
index 1e6d2af..025133f 100644
--- a/media/jni/android_media_MediaDataSource.cpp
+++ b/media/jni/android_media_MediaDataSource.cpp
@@ -39,7 +39,7 @@
ScopedLocalRef<jclass> mediaDataSourceClass(env, env->GetObjectClass(mMediaDataSourceObj));
CHECK(mediaDataSourceClass.get() != NULL);
- mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BI)I");
+ mReadMethod = env->GetMethodID(mediaDataSourceClass.get(), "readAt", "(J[BII)I");
CHECK(mReadMethod != NULL);
mGetSizeMethod = env->GetMethodID(mediaDataSourceClass.get(), "getSize", "()J");
CHECK(mGetSizeMethod != NULL);
@@ -80,7 +80,7 @@
JNIEnv* env = AndroidRuntime::getJNIEnv();
jint numread = env->CallIntMethod(mMediaDataSourceObj, mReadMethod,
- (jlong)offset, mByteArrayObj, (jint)size);
+ (jlong)offset, mByteArrayObj, (jint)0, (jint)size);
if (env->ExceptionCheck()) {
ALOGW("An exception occurred in readAt()");
LOGW_EX(env);
@@ -89,9 +89,14 @@
return -1;
}
if (numread < 0) {
- ALOGW("An error occurred in readAt()");
- mJavaObjStatus = UNKNOWN_ERROR;
- return -1;
+ if (numread != -1) {
+ ALOGW("An error occurred in readAt()");
+ mJavaObjStatus = UNKNOWN_ERROR;
+ return -1;
+ } else {
+ // numread == -1 indicates EOF
+ return 0;
+ }
}
if ((size_t)numread > size) {
ALOGE("readAt read too many bytes.");
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index f8146a7..d456dc10 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -99,7 +99,7 @@
struct EventWhat {
jint kWhatDrmEvent;
jint kWhatExpirationUpdate;
- jint kWhatKeysChange;
+ jint kWhatKeyStatusChange;
} gEventWhat;
struct KeyTypes {
@@ -221,7 +221,7 @@
jwhat = gEventWhat.kWhatExpirationUpdate;
break;
case DrmPlugin::kDrmPluginEventKeysChange:
- jwhat = gEventWhat.kWhatKeysChange;
+ jwhat = gEventWhat.kWhatKeyStatusChange;
break;
default:
ALOGE("Invalid event DrmPlugin::EventType %d, ignored", (int)eventType);
@@ -609,8 +609,8 @@
gEventWhat.kWhatDrmEvent = env->GetStaticIntField(clazz, field);
GET_STATIC_FIELD_ID(field, clazz, "EXPIRATION_UPDATE", "I");
gEventWhat.kWhatExpirationUpdate = env->GetStaticIntField(clazz, field);
- GET_STATIC_FIELD_ID(field, clazz, "KEYS_CHANGE", "I");
- gEventWhat.kWhatKeysChange = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "KEY_STATUS_CHANGE", "I");
+ gEventWhat.kWhatKeyStatusChange = env->GetStaticIntField(clazz, field);
GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_STREAMING", "I");
gKeyTypes.kKeyTypeStreaming = env->GetStaticIntField(clazz, field);
@@ -619,13 +619,6 @@
GET_STATIC_FIELD_ID(field, clazz, "KEY_TYPE_RELEASE", "I");
gKeyTypes.kKeyTypeRelease = env->GetStaticIntField(clazz, field);
- GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
- gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
- GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
- gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
- GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
- gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);
-
GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_NONE", "I");
gCertificateTypes.kCertificateTypeNone = env->GetStaticIntField(clazz, field);
GET_STATIC_FIELD_ID(field, clazz, "CERTIFICATE_TYPE_X509", "I");
@@ -636,6 +629,13 @@
GET_FIELD_ID(gFields.keyRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
GET_FIELD_ID(gFields.keyRequest.requestType, clazz, "mRequestType", "I");
+ GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_INITIAL", "I");
+ gKeyRequestTypes.kKeyRequestTypeInitial = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RENEWAL", "I");
+ gKeyRequestTypes.kKeyRequestTypeRenewal = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "REQUEST_TYPE_RELEASE", "I");
+ gKeyRequestTypes.kKeyRequestTypeRelease = env->GetStaticIntField(clazz, field);
+
FIND_CLASS(clazz, "android/media/MediaDrm$ProvisionRequest");
GET_FIELD_ID(gFields.provisionRequest.data, clazz, "mData", "[B");
GET_FIELD_ID(gFields.provisionRequest.defaultUrl, clazz, "mDefaultUrl", "Ljava/lang/String;");
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index b6b7a80..4e9b726 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -715,6 +715,11 @@
status_t err = extractor->setDataSource(bridge);
if (err != OK) {
+ // Clear bridge so that JMediaDataSource::close() is called _before_
+ // we throw the IOException.
+ // Otherwise close() gets called when we go out of scope, it calls
+ // Java with a pending exception and crashes the process.
+ bridge.clear();
jniThrowException(
env,
"java/io/IOException",
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 0044bed..f60af63 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -496,16 +496,16 @@
android_media_MediaRecorder_release(env, thiz);
}
-void android_media_MediaRecorder_usePersistentSurface(
+void android_media_MediaRecorder_setInputSurface(
JNIEnv* env, jobject thiz, jobject object) {
- ALOGV("android_media_MediaRecorder_usePersistentSurface");
+ ALOGV("android_media_MediaRecorder_setInputSurface");
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
sp<PersistentSurface> persistentSurface = get_persistentSurface(env, object);
- process_media_recorder_call(env, mr->usePersistentSurface(persistentSurface),
- "java/lang/IllegalArgumentException", "native_usePersistentSurface failed.");
+ process_media_recorder_call(env, mr->setInputSurface(persistentSurface),
+ "java/lang/IllegalArgumentException", "native_setInputSurface failed.");
}
// ----------------------------------------------------------------------------
@@ -534,7 +534,7 @@
{"native_setup", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V",
(void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
- {"native_usePersistentSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_usePersistentSurface },
+ {"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
};
// This function only registers the native methods, and is called from
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 84ae3b4..8038cdf 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -229,7 +229,7 @@
{
ALOGV("unload: sampleID=%d", sampleID);
Mutex::Autolock lock(&mLock);
- return mSamples.removeItem(sampleID);
+ return mSamples.removeItem(sampleID) >= 0; // removeItem() returns index or BAD_VALUE
}
int SoundPool::play(int sampleID, float leftVolume, float rightVolume,
@@ -738,12 +738,16 @@
// do not create a new audio track if current track is compatible with sample parameters
#ifdef USE_SHARED_MEM_BUFFER
newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
- channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData);
+ channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData,
+ 0 /*default notification frames*/, AUDIO_SESSION_ALLOCATE,
+ AudioTrack::TRANSFER_DEFAULT,
+ NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes());
#else
uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount;
newTrack = new AudioTrack(streamType, sampleRate, sample->format(),
channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData,
- bufferFrames);
+ bufferFrames, AUDIO_SESSION_ALLOCATE, AudioTrack::TRANSFER_DEFAULT,
+ NULL /*offloadInfo*/, -1 /*uid*/, -1 /*pid*/, mSoundPool->attributes());
#endif
oldTrack = mAudioTrack;
status = newTrack->initCheck();
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
index 0ccbf6a..60c6570 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothMidiDevice.java
@@ -234,10 +234,10 @@
break;
}
try {
- mPacketEncoder.sendWithTimestamp(event.data, 0, event.count,
+ mPacketEncoder.send(event.data, 0, event.count,
event.getTimestamp());
} catch (IOException e) {
- Log.e(TAG, "mPacketAccumulator.sendWithTimestamp failed", e);
+ Log.e(TAG, "mPacketAccumulator.send failed", e);
}
mEventScheduler.addEventToPool(event);
}
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java
index 1bce9fb..ea95a01 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketDecoder.java
@@ -86,7 +86,7 @@
if (dataCount > 0) {
// send previous message separately since it has a different timestamp
try {
- receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp);
+ receiver.send(mBuffer, 0, dataCount, nanoTimestamp);
} catch (IOException e) {
// ???
}
@@ -106,7 +106,7 @@
if (dataCount > 0) {
try {
- receiver.sendWithTimestamp(mBuffer, 0, dataCount, nanoTimestamp);
+ receiver.send(mBuffer, 0, dataCount, nanoTimestamp);
} catch (IOException e) {
// ???
}
diff --git a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java
index 99ea353..5fb162c 100644
--- a/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java
+++ b/media/packages/BluetoothMidiService/src/com/android/bluetoothmidiservice/BluetoothPacketEncoder.java
@@ -53,7 +53,7 @@
// This receives normalized data from mMidiFramer and accumulates it into a packet buffer
private final MidiReceiver mFramedDataReceiver = new MidiReceiver() {
@Override
- public void onReceive(byte[] msg, int offset, int count, long timestamp)
+ public void onSend(byte[] msg, int offset, int count, long timestamp)
throws IOException {
synchronized (mLock) {
@@ -130,7 +130,8 @@
flushLocked(true);
appendHeader(milliTimestamp);
}
- mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | (milliTimestamp & 0x7F));
+ mAccumulationBuffer[mAccumulatedBytes++] =
+ (byte)(0x80 | (milliTimestamp & 0x7F));
mAccumulationBuffer[mAccumulatedBytes++] = MidiConstants.STATUS_END_SYSEX;
}
} else {
@@ -146,7 +147,8 @@
// now copy data bytes
int dataLength = count - 1;
- System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes, dataLength);
+ System.arraycopy(msg, offset + 1, mAccumulationBuffer, mAccumulatedBytes,
+ dataLength);
mAccumulatedBytes += dataLength;
}
@@ -160,7 +162,8 @@
// write header if we are starting a new packet
if (mAccumulatedBytes == 0) {
// header byte with timestamp bits 7 - 12
- mAccumulationBuffer[mAccumulatedBytes++] = (byte)(0x80 | ((milliTimestamp >> 7) & 0x3F));
+ mAccumulationBuffer[mAccumulatedBytes++] =
+ (byte)(0x80 | ((milliTimestamp >> 7) & 0x3F));
mPacketTimestamp = milliTimestamp;
return true;
} else {
@@ -177,10 +180,10 @@
}
@Override
- public void onReceive(byte[] msg, int offset, int count, long timestamp)
+ public void onSend(byte[] msg, int offset, int count, long timestamp)
throws IOException {
// normalize the data by passing it through a MidiFramer first
- mMidiFramer.sendWithTimestamp(msg, offset, count, timestamp);
+ mMidiFramer.send(msg, offset, count, timestamp);
}
@Override
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
index 563b0f3..35540e3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
@@ -252,7 +252,7 @@
if (persistentSurface != null) {
Log.v(TAG, "using persistent surface");
surface = persistentSurface;
- recorder.usePersistentSurface(surface);
+ recorder.setInputSurface(surface);
}
recorder.prepare();
if (persistentSurface == null) {
diff --git a/obex/javax/obex/ClientOperation.java b/obex/javax/obex/ClientOperation.java
index cc20d39..883c8c6 100644
--- a/obex/javax/obex/ClientOperation.java
+++ b/obex/javax/obex/ClientOperation.java
@@ -784,12 +784,12 @@
mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
}
- while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+ while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) {
if (!sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL)) {
break;
}
}
- while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+ while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE && !mOperationDone) {
mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL, null,
mReplyHeader, mPrivateInput, false);
// Regardless of the SRM state, wait for the response.
diff --git a/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml b/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
index 1b5741f..213b31f 100644
--- a/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-uz-rUZ/strings.xml
@@ -19,7 +19,7 @@
<string name="backup_confirm_title" msgid="827563724209303345">"To‘liq zahira"</string>
<string name="restore_confirm_title" msgid="5469365809567486602">"To‘liq tiklash"</string>
<string name="backup_confirm_text" msgid="1878021282758896593">"Barcha ma’lumotlarni ulangan kompyuterga to‘liq zahiralash so‘raldi. Bunga ruxsat berasizmi?\n\nZahiralashni o‘zingiz so‘ramagan bo‘lsangiz, jarayonni davom etishiga ruxsat bermang."</string>
- <string name="allow_backup_button_label" msgid="4217228747769644068">"Ma’lumotlarimni zahiralash"</string>
+ <string name="allow_backup_button_label" msgid="4217228747769644068">"Ma’lumotlarni zaxiralash"</string>
<string name="deny_backup_button_label" msgid="6009119115581097708">"Zahiralamang"</string>
<string name="restore_confirm_text" msgid="7499866728030461776">"Barcha ma’lumotlarni ulangan kompyuterdan to‘liq tiklash so‘raldi. Bunga ruxsat berasizmi?\n\nTiklashni o‘zingiz so‘ramagan bo‘lsangiz, jarayonni davom etishiga ruxsat bermang. U qurilmadagi hozirda mavjud bo‘lgan barcha ma’lumotlarni almashtirib tashlaydi!"</string>
<string name="allow_restore_button_label" msgid="3081286752277127827">"Ma’lumotlarimni tiklash"</string>
diff --git a/packages/Keyguard/res/layout/keyguard_status_area.xml b/packages/Keyguard/res/layout/keyguard_status_area.xml
index 7d8977c..8fe2835 100644
--- a/packages/Keyguard/res/layout/keyguard_status_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_area.xml
@@ -30,6 +30,8 @@
android:layout_height="wrap_content"
android:textColor="@color/clock_white"
style="@style/widget_label"
+ android:textAllCaps="true"
+ android:letterSpacing="0.15"
android:gravity="center"
/>
<TextView android:id="@+id/alarm_status"
@@ -38,6 +40,8 @@
android:drawablePadding="6dp"
android:drawableStart="@drawable/ic_access_alarms_big"
android:textColor="@color/clock_gray"
+ android:letterSpacing="0.15"
+ android:textAllCaps="true"
style="@style/widget_label"
android:layout_marginStart="6dp"
android:gravity="center"
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 69f510e..fc0b568 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -57,6 +57,7 @@
android:layout_gravity="center_horizontal"
android:textColor="@color/clock_gray"
android:textSize="@dimen/widget_label_font_size"
+ android:letterSpacing="0.05"
android:ellipsize="marquee"
android:singleLine="true" />
diff --git a/packages/Keyguard/res/values-gu-rIN/strings.xml b/packages/Keyguard/res/values-gu-rIN/strings.xml
index 4923221..a51b05d 100644
--- a/packages/Keyguard/res/values-gu-rIN/strings.xml
+++ b/packages/Keyguard/res/values-gu-rIN/strings.xml
@@ -45,7 +45,6 @@
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM કાર્ડ, PUK-લૉક કરેલ છે."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM કાર્ડ અનલૉક કરી રહ્યાં છે…"</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"પેટર્ન અનલૉક."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ફેસ અનલૉક"</string>
<string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"પિન અનલૉક."</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"પાસવર્ડ અનલૉક કરો."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"પેટર્ન ક્ષેત્ર."</string>
diff --git a/packages/Keyguard/res/values-h650dp/dimens.xml b/packages/Keyguard/res/values-h650dp/dimens.xml
index 4864326..92035bb 100644
--- a/packages/Keyguard/res/values-h650dp/dimens.xml
+++ b/packages/Keyguard/res/values-h650dp/dimens.xml
@@ -16,5 +16,5 @@
-->
<resources>
- <dimen name="widget_big_font_size">112dp</dimen>
+ <dimen name="widget_big_font_size">104dp</dimen>
</resources>
\ No newline at end of file
diff --git a/packages/Keyguard/res/values-pa-rIN/strings.xml b/packages/Keyguard/res/values-pa-rIN/strings.xml
index 479ccc8..ff52a87 100644
--- a/packages/Keyguard/res/values-pa-rIN/strings.xml
+++ b/packages/Keyguard/res/values-pa-rIN/strings.xml
@@ -45,7 +45,6 @@
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM ਕਾਰਡ PUK-ਲੌਕਡ ਹੈ।"</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SIM ਕਾਰਡ ਅਨਲੌਕ ਕਰ ਰਿਹਾ ਹੈ…"</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"ਪੈਟਰਨ ਅਨਲੌਕ।"</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"ਚਿਹਰਾ ਅਨਲੌਕ।"</string>
<string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Pin ਅਨਲੌਕ।"</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"ਪਾਸਵਰਡ ਅਨਲੌਕ।"</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"ਪੈਟਰਨ ਖੇਤਰ।"</string>
diff --git a/packages/Keyguard/res/values-sq-rAL/strings.xml b/packages/Keyguard/res/values-sq-rAL/strings.xml
index f3943ea..7f21138 100644
--- a/packages/Keyguard/res/values-sq-rAL/strings.xml
+++ b/packages/Keyguard/res/values-sq-rAL/strings.xml
@@ -45,7 +45,6 @@
<string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"Karta SIM është e kyçur me PUK."</string>
<string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Po shkyç kartën SIM…"</string>
<string name="keyguard_accessibility_pattern_unlock" msgid="1490840706075246612">"Shkyçje me motiv."</string>
- <string name="keyguard_accessibility_face_unlock" msgid="4817282543351718535">"Shkyçje me fytyrë."</string>
<string name="keyguard_accessibility_pin_unlock" msgid="2469687111784035046">"Shkyçje me PIN."</string>
<string name="keyguard_accessibility_password_unlock" msgid="7675777623912155089">"Shkyçja e fjalëkalimit."</string>
<string name="keyguard_accessibility_pattern_area" msgid="7679891324509597904">"Zona e motivit."</string>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index 5de1d11..b181682 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -26,7 +26,7 @@
<dimen name="keyguard_security_view_margin">12dp</dimen>
<!-- Overload default clock widget parameters -->
- <dimen name="widget_big_font_size">140dp</dimen>
+ <dimen name="widget_big_font_size">125dp</dimen>
<dimen name="widget_label_font_size">16sp</dimen>
<dimen name="bottom_text_spacing_digital">-16dp</dimen>
diff --git a/packages/Keyguard/res/values-sw720dp/dimens.xml b/packages/Keyguard/res/values-sw720dp/dimens.xml
index 428c18e..08ab791 100644
--- a/packages/Keyguard/res/values-sw720dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw720dp/dimens.xml
@@ -24,5 +24,5 @@
<!-- Height of the sliding KeyguardSecurityContainer (includes 2x keyguard_security_view_margin) -->
<dimen name="keyguard_security_height">420dp</dimen>
- <dimen name="widget_big_font_size">150dp</dimen>
+ <dimen name="widget_big_font_size">138dp</dimen>
</resources>
diff --git a/packages/Keyguard/res/values/colors.xml b/packages/Keyguard/res/values/colors.xml
index 3b741ea..3998c5b 100644
--- a/packages/Keyguard/res/values/colors.xml
+++ b/packages/Keyguard/res/values/colors.xml
@@ -17,5 +17,5 @@
<!-- Clock -->
<color name="clock_white">#ffffffff</color>
- <color name="clock_gray">#99ffffff</color>
+ <color name="clock_gray">@*android:color/secondary_text_default_material_dark</color>
</resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index 9290236..18d893a 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -40,7 +40,7 @@
<!-- Default clock parameters -->
<dimen name="bottom_text_spacing_digital">-10dp</dimen>
- <dimen name="widget_label_font_size">16sp</dimen>
+ <dimen name="widget_label_font_size">14sp</dimen>
<dimen name="widget_big_font_size">88dp</dimen>
<!-- The y translation to apply at the start in appear animations. -->
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index 404a17e..943c3ea 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -41,7 +41,7 @@
</style>
<style name="widget_big_thin">
<item name="android:textSize">@dimen/widget_big_font_size</item>
- <item name="android:fontFamily">sans-serif-thin</item>
+ <item name="android:fontFamily">sans-serif-light</item>
</style>
<style name="BouncerSecurityContainer">
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index c4f4b9a..54bbd5a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import android.content.Context;
+import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -25,6 +26,7 @@
import android.view.View;
import android.widget.LinearLayout;
+import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
/**
@@ -34,6 +36,7 @@
implements KeyguardSecurityView, EmergencyButton.EmergencyButtonCallback {
protected KeyguardSecurityCallback mCallback;
protected LockPatternUtils mLockPatternUtils;
+ protected AsyncTask<?, ?, ?> mPendingLockCheck;
protected SecurityMessageDisplay mSecurityMessageDisplay;
protected View mEcaView;
protected boolean mEnableHaptics;
@@ -106,8 +109,27 @@
}
protected void verifyPasswordAndUnlock() {
- String entry = getPasswordText();
- if (mLockPatternUtils.checkPassword(entry, KeyguardUpdateMonitor.getCurrentUser())) {
+ final String entry = getPasswordText();
+ setPasswordEntryEnabled(false);
+ if (mPendingLockCheck != null) {
+ mPendingLockCheck.cancel(false);
+ }
+ mPendingLockCheck = LockPatternChecker.checkPassword(
+ mLockPatternUtils,
+ entry,
+ KeyguardUpdateMonitor.getCurrentUser(),
+ new LockPatternChecker.OnCheckCallback() {
+ @Override
+ public void onChecked(boolean matched) {
+ setPasswordEntryEnabled(true);
+ mPendingLockCheck = null;
+ onPasswordChecked(entry, matched);
+ }
+ });
+ }
+
+ private void onPasswordChecked(String entry, boolean matched) {
+ if (matched) {
mCallback.reportUnlockAttempt(true);
mCallback.dismiss(true);
} else {
@@ -152,9 +174,16 @@
}.start();
}
+ protected void onUserInput() {
+ if (mCallback != null) {
+ mCallback.userActivity();
+ }
+ mSecurityMessageDisplay.setMessage("", false);
+ }
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- mCallback.userActivity();
+ onUserInput();
return false;
}
@@ -165,7 +194,10 @@
@Override
public void onPause() {
-
+ if (mPendingLockCheck != null) {
+ mPendingLockCheck.cancel(false);
+ mPendingLockCheck = null;
+ }
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index 7ddeab4..40fd920 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -88,24 +88,33 @@
}
}
+ @Override
public void setMessage(CharSequence msg, boolean important) {
if (!TextUtils.isEmpty(msg) && important) {
mMessageArea.mMessage = msg;
mMessageArea.securityMessageChanged();
+ } else {
+ mMessageArea.clearMessage();
}
}
+ @Override
public void setMessage(int resId, boolean important) {
if (resId != 0 && important) {
mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
mMessageArea.securityMessageChanged();
+ } else {
+ mMessageArea.clearMessage();
}
}
+ @Override
public void setMessage(int resId, boolean important, Object... formatArgs) {
if (resId != 0 && important) {
mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
mMessageArea.securityMessageChanged();
+ } else {
+ mMessageArea.clearMessage();
}
}
@@ -176,6 +185,11 @@
(SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY));
}
+ public void clearMessage() {
+ mHandler.removeCallbacks(mClearMessageRunnable);
+ mHandler.post(mClearMessageRunnable);
+ }
+
/**
* Update the status lines based on these rules:
* AlarmStatus: Alarm state always gets it's own line.
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 929258d..3fcc3c3 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -20,6 +20,7 @@
import android.graphics.Rect;
import android.text.Editable;
import android.text.InputType;
+import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.TextKeyListener;
import android.util.AttributeSet;
@@ -138,20 +139,6 @@
// Set selected property on so the view can send accessibility events.
mPasswordEntry.setSelected(true);
- mPasswordEntry.addTextChangedListener(new TextWatcher() {
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- public void afterTextChanged(Editable s) {
- if (mCallback != null) {
- mCallback.userActivity();
- }
- }
- });
-
mPasswordEntry.requestFocus();
// If there's more than one IME, enable the IME switcher button
@@ -293,6 +280,11 @@
@Override
public void afterTextChanged(Editable s) {
+ // Poor man's user edit detection, assuming empty text is programmatic and everything else
+ // is from the user.
+ if (!TextUtils.isEmpty(s)) {
+ onUserInput();
+ }
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 557cd13..35c6873 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -20,6 +20,7 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
+import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.text.TextUtils;
@@ -32,6 +33,7 @@
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
+import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
@@ -59,6 +61,7 @@
private CountDownTimer mCountdownTimer = null;
private LockPatternUtils mLockPatternUtils;
+ private AsyncTask<?, ?, ?> mPendingLockCheck;
private LockPatternView mLockPatternView;
private KeyguardSecurityCallback mCallback;
@@ -205,6 +208,7 @@
public void onPatternStart() {
mLockPatternView.removeCallbacks(mCancelPatternRunnable);
+ mSecurityMessageDisplay.setMessage("", false);
}
public void onPatternCleared() {
@@ -214,8 +218,28 @@
mCallback.userActivity();
}
- public void onPatternDetected(List<LockPatternView.Cell> pattern) {
- if (mLockPatternUtils.checkPattern(pattern, KeyguardUpdateMonitor.getCurrentUser())) {
+ public void onPatternDetected(final List<LockPatternView.Cell> pattern) {
+ mLockPatternView.disableInput();
+ if (mPendingLockCheck != null) {
+ mPendingLockCheck.cancel(false);
+ }
+
+ mPendingLockCheck = LockPatternChecker.checkPattern(
+ mLockPatternUtils,
+ pattern,
+ KeyguardUpdateMonitor.getCurrentUser(),
+ new LockPatternChecker.OnCheckCallback() {
+ @Override
+ public void onChecked(boolean matched) {
+ mLockPatternView.enableInput();
+ mPendingLockCheck = null;
+ onPatternChecked(pattern, matched);
+ }
+ });
+ }
+
+ private void onPatternChecked(List<LockPatternView.Cell> pattern, boolean matched) {
+ if (matched) {
mCallback.reportUnlockAttempt(true);
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
mCallback.dismiss(true);
@@ -277,6 +301,10 @@
mCountdownTimer.cancel();
mCountdownTimer = null;
}
+ if (mPendingLockCheck != null) {
+ mPendingLockCheck.cancel(false);
+ mPendingLockCheck = null;
+ }
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index bca0305..84b4cf8 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -148,7 +148,14 @@
// Poke the wakelock any time the text is selected or modified
mPasswordEntry.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
- mCallback.userActivity();
+ onUserInput();
+ }
+ });
+
+ mPasswordEntry.setUserActivityListener(new PasswordTextView.UserActivityListener() {
+ @Override
+ public void onUserActivity() {
+ onUserInput();
}
});
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index d13d71c..5fece8d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -24,7 +24,6 @@
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -56,7 +55,6 @@
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
-import android.hardware.fingerprint.FingerprintUtils;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -102,7 +100,6 @@
private static final int MSG_SIM_STATE_CHANGE = 304;
private static final int MSG_RINGER_MODE_CHANGED = 305;
private static final int MSG_PHONE_STATE_CHANGED = 306;
- private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
private static final int MSG_DEVICE_PROVISIONED = 308;
private static final int MSG_DPM_STATE_CHANGED = 309;
private static final int MSG_USER_SWITCHING = 310;
@@ -174,9 +171,6 @@
case MSG_PHONE_STATE_CHANGED:
handlePhoneStateChanged((String) msg.obj);
break;
- case MSG_CLOCK_VISIBILITY_CHANGED:
- handleClockVisibilityChanged();
- break;
case MSG_DEVICE_PROVISIONED:
handleDeviceProvisioned();
break;
@@ -367,14 +361,8 @@
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
return;
}
- final ContentResolver res = mContext.getContentResolver();
- final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId);
- for (int i = 0; i < ids.length; i++) {
- // TODO: fix once HAL supports storing group id
- final boolean isCorrectUser = true || (groupId == userId);
- if (ids[i] == fingerId && isCorrectUser) {
- onFingerprintAuthenticated(userId);
- }
+ if (groupId == userId) {
+ onFingerprintAuthenticated(groupId);
}
} finally {
setFingerprintRunningDetectionRunning(false);
@@ -764,15 +752,11 @@
public void onUserSwitching(int newUserId, IRemoteCallback reply) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
newUserId, 0, reply));
- mSwitchingUser = true;
- updateFingerprintListeningState();
}
@Override
public void onUserSwitchComplete(int newUserId) throws RemoteException {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
newUserId, 0));
- mSwitchingUser = false;
- updateFingerprintListeningState();
}
@Override
public void onForegroundProfileSwitch(int newProfileId) {
@@ -877,6 +861,9 @@
* Handle {@link #MSG_USER_SWITCHING}
*/
protected void handleUserSwitching(int userId, IRemoteCallback reply) {
+ mSwitchingUser = true;
+ updateFingerprintListeningState();
+
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -893,6 +880,9 @@
* Handle {@link #MSG_USER_SWITCH_COMPLETE}
*/
protected void handleUserSwitchComplete(int userId) {
+ mSwitchingUser = false;
+ updateFingerprintListeningState();
+
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -1052,19 +1042,6 @@
}
/**
- * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
- */
- private void handleClockVisibilityChanged() {
- if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
- for (int i = 0; i < mCallbacks.size(); i++) {
- KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
- if (cb != null) {
- cb.onClockVisibilityChanged();
- }
- }
- }
-
- /**
* Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
*/
private void handleKeyguardVisibilityChanged(int showing) {
@@ -1108,21 +1085,6 @@
}
}
- public boolean isKeyguardVisible() {
- return mKeyguardIsVisible;
- }
-
- /**
- * @return if the keyguard is currently in bouncer mode.
- */
- public boolean isKeyguardBouncer() {
- return mBouncer;
- }
-
- public boolean isSwitchingUser() {
- return mSwitchingUser;
- }
-
private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
final boolean nowPluggedIn = current.isPluggedIn();
final boolean wasPluggedIn = old.isPluggedIn();
@@ -1148,13 +1110,6 @@
}
/**
- * @return The default plmn (no service)
- */
- private CharSequence getDefaultPlmn() {
- return mContext.getResources().getText(R.string.keyguard_carrier_default);
- }
-
- /**
* Remove the given observer's callback.
*
* @param callback The callback to remove
@@ -1219,11 +1174,6 @@
message.sendToTarget();
}
- public void reportClockVisible(boolean visible) {
- mClockVisible = visible;
- mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
- }
-
/**
* Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
* have the information earlier than waiting for the intent
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
index 67ddcfa..50e7ecb 100644
--- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -92,6 +92,11 @@
private Interpolator mDisappearInterpolator;
private Interpolator mFastOutSlowInInterpolator;
private boolean mShowPassword;
+ private UserActivityListener mUserActivityListener;
+
+ public interface UserActivityListener {
+ void onUserActivity();
+ }
public PasswordTextView(Context context) {
this(context, null);
@@ -206,8 +211,15 @@
sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length(), 0, 1);
}
+ public void setUserActivityListener(UserActivityListener userActivitiListener) {
+ mUserActivityListener = userActivitiListener;
+ }
+
private void userActivity() {
mPM.userActivity(SystemClock.uptimeMillis(), false);
+ if (mUserActivityListener != null) {
+ mUserActivityListener.onUserActivity();
+ }
}
public void deleteLastChar() {
diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
index 26b5c9f..d44f524 100644
--- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
+++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml
@@ -61,7 +61,7 @@
<string name="choose_print_service" msgid="3740309762324459694">"Chop etish xizmatini tanlang"</string>
<string name="print_searching_for_printers" msgid="6550424555079932867">"Printerlarni izlash"</string>
<string name="print_no_printers" msgid="4869403323900054866">"Printerlar topilmadi"</string>
- <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> chop etilmoqda"</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>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ni taqiqladi"</string>
@@ -79,7 +79,7 @@
<item msgid="2762241247228983754">"Rang"</item>
</string-array>
<string-array name="duplex_mode_labels">
- <item msgid="3882302912790928315">"Hech biri"</item>
+ <item msgid="3882302912790928315">"Yo‘q"</item>
<item msgid="7296563835355641719">"Uzun tomoni"</item>
<item msgid="79513688117503758">"Qisqa tomoni"</item>
</string-array>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
index 377d2d5..49e6740 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java
@@ -63,6 +63,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -757,7 +758,7 @@
out = mStatePersistFile.startWrite();
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.startTag(null, TAG_SPOOLER);
@@ -952,7 +953,7 @@
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(in, null);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
parseState(parser);
} catch (IllegalStateException ise) {
Slog.w(LOG_TAG, "Failed parsing ", ise);
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
index 22a7f86..80c28e0 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java
@@ -46,6 +46,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -562,7 +563,7 @@
try {
List<PrinterInfo> printers = new ArrayList<>();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(in, null);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
parseState(parser, printers);
// Take a note which version of the history was read.
mLastReadHistoryTimestamp = mStatePersistFile.getBaseFile().lastModified();
@@ -686,7 +687,7 @@
out = mStatePersistFile.startWrite();
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.startTag(null, TAG_PRINTERS);
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index b702e35..377a9a4 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -48,6 +48,8 @@
<string name="wifi_security_psk_generic">@string/wifi_security_wpa_wpa2</string>
<!-- Do not translate. Concise terminology for wifi with 802.1x EAP security -->
<string name="wifi_security_eap">802.1x EAP</string>
+ <!-- Do not translate. Concise terminology for Passpoint network -->
+ <string name="wifi_security_passpoint">Passpoint</string>
<!-- Summary for the remembered network. -->
<string name="wifi_remembered">Saved</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java
index 60b5ba5..8b38a5f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/PermissionsInfo.java
@@ -22,7 +22,6 @@
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.UserHandle;
@@ -80,8 +79,10 @@
if (info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS) {
group = new PermissionGroup();
// TODO: Add default permission icon.
- group.icon = info.icon != 0 ? info.loadIcon(mPm) : new ShapeDrawable();
+ group.icon = info.icon != 0 ? info.loadIcon(mPm) : mContext.getDrawable(
+ com.android.internal.R.drawable.ic_perm_device_info);
group.name = info.name;
+ group.packageName = info.packageName;
group.label = info.loadLabel(mPm).toString();
mGroups.add(group);
mGroupLookup.put(permission, group);
@@ -103,8 +104,10 @@
for (PermissionGroupInfo groupInfo : groups) {
PermissionGroup group = new PermissionGroup();
// TODO: Add default permission icon.
- group.icon = groupInfo.icon != 0 ? groupInfo.loadIcon(mPm) : new ShapeDrawable();
+ group.icon = groupInfo.icon != 0 ? groupInfo.loadIcon(mPm) : mContext.getDrawable(
+ com.android.internal.R.drawable.ic_perm_device_info);
group.name = groupInfo.name;
+ group.packageName = groupInfo.packageName;
group.label = groupInfo.loadLabel(mPm).toString();
synchronized (mGroups) {
mGroups.add(group);
@@ -172,6 +175,7 @@
public final List<String> possibleApps = new ArrayList<>();
public final List<String> grantedApps = new ArrayList<>();
public String name;
+ public String packageName;
public String label;
public Drawable icon;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 7eaa728..7049d6a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -248,6 +248,9 @@
public String getSecurityString(boolean concise) {
Context context = mContext;
+ if (mConfig != null && mConfig.isPasspoint()) {
+ return context.getString(R.string.wifi_security_passpoint);
+ }
switch(security) {
case SECURITY_EAP:
return concise ? context.getString(R.string.wifi_security_short_eap) :
@@ -826,6 +829,9 @@
}
static String removeDoubleQuotes(String string) {
+ if (TextUtils.isEmpty(string)) {
+ return "";
+ }
int length = string.length();
if ((length > 1) && (string.charAt(0) == '"')
&& (string.charAt(length - 1) == '"')) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 28fa8fb..7060c64 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -95,20 +95,20 @@
public WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper,
boolean includeSaved, boolean includeScans, boolean includePasspoints) {
this(context, wifiListener, workerLooper, includeSaved, includeScans, includePasspoints,
- (WifiManager) context.getSystemService(Context.WIFI_SERVICE));
+ (WifiManager) context.getSystemService(Context.WIFI_SERVICE), Looper.myLooper());
}
@VisibleForTesting
WifiTracker(Context context, WifiListener wifiListener, Looper workerLooper,
boolean includeSaved, boolean includeScans, boolean includePasspoints,
- WifiManager wifiManager) {
+ WifiManager wifiManager, Looper currentLooper) {
if (!includeSaved && !includeScans) {
throw new IllegalArgumentException("Must include either saved or scans");
}
mContext = context;
- mMainHandler = new MainHandler();
+ mMainHandler = new MainHandler(currentLooper);
mWorkHandler = new WorkHandler(
- workerLooper != null ? workerLooper : Looper.myLooper());
+ workerLooper != null ? workerLooper : currentLooper);
mWifiManager = wifiManager;
mIncludeSaved = includeSaved;
mIncludeScans = includeScans;
@@ -189,6 +189,8 @@
*/
public void stopTracking() {
if (mRegistered) {
+ mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_ACCESS_POINTS);
+ mWorkHandler.removeMessages(WorkHandler.MSG_UPDATE_NETWORK_INFO);
mContext.unregisterReceiver(mReceiver);
mRegistered = false;
}
@@ -437,6 +439,10 @@
private static final int MSG_WIFI_STATE_CHANGED = 1;
private static final int MSG_ACCESS_POINT_CHANGED = 2;
+ public MainHandler(Looper looper) {
+ super(looper);
+ }
+
@Override
public void handleMessage(Message msg) {
if (mListener == null) {
@@ -479,7 +485,7 @@
@VisibleForTesting
class Scanner extends Handler {
- private static final int MSG_SCAN = 0;
+ static final int MSG_SCAN = 0;
private int mRetry = 0;
diff --git a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 8eb1ca4..103cd3a 100644
--- a/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -23,9 +23,12 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiSsid;
+import android.os.HandlerThread;
+import android.os.Looper;
import android.util.Log;
import com.android.settingslib.BaseTest;
+import com.android.settingslib.wifi.WifiTracker.Scanner;
import com.android.settingslib.wifi.WifiTracker.WifiListener;
import org.mockito.ArgumentCaptor;
@@ -54,13 +57,25 @@
private WifiTracker mWifiTracker;
+ private HandlerThread mWorkerThread;
+ private Looper mLooper;
+ private HandlerThread mMainThread;
+ private Looper mMainLooper;
+
@Override
protected void setUp() throws Exception {
super.setUp();
mWifiManager = Mockito.mock(WifiManager.class);
mWifiListener = Mockito.mock(WifiListener.class);
- mWifiTracker = new WifiTracker(mContext, mWifiListener, true, true, mWifiManager);
+ mWorkerThread = new HandlerThread("TestHandlerThread");
+ mWorkerThread.start();
+ mLooper = mWorkerThread.getLooper();
+ mMainThread = new HandlerThread("TestHandlerThread");
+ mMainThread.start();
+ mMainLooper = mMainThread.getLooper();
+ mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, true, true, true,
+ mWifiManager, mMainLooper);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
Mockito.when(mWifiManager.isWifiEnabled()).thenReturn(true);
}
@@ -76,13 +91,14 @@
}
public void testAccessPointsCallback() {
- sendScanResultsAvailable();
+ sendScanResultsAndProcess(false);
Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onAccessPointsChanged();
}
public void testConnectedCallback() {
sendConnected();
+ waitForThreads();
Mockito.verify(mWifiListener, Mockito.atLeastOnce()).onConnectedChanged();
assertEquals(true, mWifiTracker.isConnected());
@@ -94,6 +110,7 @@
Intent i = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
i.putExtra(WifiManager.EXTRA_WIFI_STATE, TEST_WIFI_STATE);
mWifiTracker.mReceiver.onReceive(mContext, i);
+ waitForThreads();
ArgumentCaptor<Integer> wifiState = ArgumentCaptor.forClass(Integer.class);
Mockito.verify(mWifiListener, Mockito.atLeastOnce())
@@ -106,7 +123,7 @@
// Make scans be successful.
Mockito.when(mWifiManager.startScan()).thenReturn(true);
- mWifiTracker.mScanner.handleMessage(null);
+ mWifiTracker.mScanner.handleMessage(mWifiTracker.mScanner.obtainMessage(Scanner.MSG_SCAN));
Mockito.verify(mWifiManager, Mockito.atLeastOnce()).startScan();
}
@@ -121,7 +138,7 @@
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
- sendScanResultsAvailable();
+ sendScanResultsAndProcess(false);
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
assertEquals("Expected number of results", NUM_NETWORKS, accessPoints.size());
@@ -131,7 +148,8 @@
}
public void testSavedOnly() {
- mWifiTracker = new WifiTracker(mContext, mWifiListener, true, false, mWifiManager);
+ mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, true, false, true,
+ mWifiManager, mMainLooper);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
@@ -144,7 +162,7 @@
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
- sendScanResultsAvailable();
+ sendScanResultsAndProcess(false);
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
// Only expect the first two to come back in the results.
@@ -154,7 +172,8 @@
}
public void testAvailableOnly() {
- mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager);
+ mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, false, true, true,
+ mWifiManager, mMainLooper);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
@@ -167,7 +186,7 @@
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
- sendScanResultsAvailable();
+ sendScanResultsAndProcess(false);
// Expect the last one (sorted order) to be left off since its only saved.
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
@@ -178,12 +197,13 @@
}
public void testNonEphemeralConnected() {
- mWifiTracker = new WifiTracker(mContext, mWifiListener, false, true, mWifiManager);
+ mWifiTracker = new WifiTracker(mContext, mWifiListener, mLooper, false, true, true,
+ mWifiManager, mMainLooper);
mWifiTracker.mScanner = mWifiTracker.new Scanner();
List<WifiConfiguration> wifiConfigs = new ArrayList<WifiConfiguration>();
List<ScanResult> scanResults = new ArrayList<ScanResult>();
- String[] expectedSsids = generateTestNetworks(wifiConfigs, scanResults, false);
+ generateTestNetworks(wifiConfigs, scanResults, false);
// Tell WifiTracker we are connected now.
sendConnected();
@@ -191,9 +211,8 @@
// Send all of the configs and scan results to the tracker.
Mockito.when(mWifiManager.getConfiguredNetworks()).thenReturn(wifiConfigs);
Mockito.when(mWifiManager.getScanResults()).thenReturn(scanResults);
- sendScanResultsAvailable();
// Do this twice to catch a bug that was happening in the caching, making things ephemeral.
- sendScanResultsAvailable();
+ sendScanResultsAndProcess(true);
List<AccessPoint> accessPoints = mWifiTracker.getAccessPoints();
assertEquals("Expected number of results", NUM_NETWORKS - 1, accessPoints.size());
@@ -299,9 +318,28 @@
mWifiTracker.mReceiver.onReceive(mContext, intent);
}
- private void sendScanResultsAvailable() {
+ private void sendScanResultsAndProcess(boolean sendTwice) {
Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mWifiTracker.mReceiver.onReceive(mContext, i);
+ if (sendTwice) {
+ mWifiTracker.mReceiver.onReceive(mContext, i);
+ }
+ waitForThreads();
+ }
+
+ private void waitForThreads() {
+ // Run all processing.
+ mWorkerThread.quitSafely();
+ try {
+ mWorkerThread.join();
+ } catch (InterruptedException e) {
+ }
+ // Send all callbacks.
+ mMainThread.quitSafely();
+ try {
+ mMainThread.join();
+ } catch (InterruptedException e) {
+ }
}
}
diff --git a/packages/SettingsProvider/res/values-gu-rIN/defaults.xml b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
new file mode 100644
index 0000000..22443a5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+ <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-gu-rIN/strings.xml b/packages/SettingsProvider/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..7241974
--- /dev/null
+++ b/packages/SettingsProvider/res/values-gu-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2007, 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="4567566098528588863">"સેટિંગ્સ સંગ્રહ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-sq-rAL/strings.xml b/packages/SettingsProvider/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..a8e66d5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-sq-rAL/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2007, 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="4567566098528588863">"Hapësira ruajtëse e \"Cilësimeve\""</string>
+</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index f853f3f..9209c26 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -38,6 +38,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -353,7 +354,7 @@
out = destination.startWrite();
XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument(null, true);
serializer.startTag(null, TAG_SETTINGS);
@@ -406,7 +407,7 @@
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(in, null);
+ parser.setInput(in, StandardCharsets.UTF_8.name());
parseStateLocked(parser);
} catch (XmlPullParserException | IOException e) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index dda9358..fd0ba73 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -95,6 +95,8 @@
<uses-permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
<uses-permission android:name="android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS" />
<uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" />
+ <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
+ <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
<application android:label="@string/app_label">
<provider
diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml
index a254192..6a5358b 100644
--- a/packages/Shell/res/values-hy-rAM/strings.xml
+++ b/packages/Shell/res/values-hy-rAM/strings.xml
@@ -17,7 +17,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="3701846017049540910">"Խեցի"</string>
- <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց ստացվեց"</string>
+ <string name="bugreport_finished_title" msgid="2293711546892863898">"Վրիպակի զեկույց է ստացվել"</string>
<string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string>
<string name="bugreport_finished_text" product="default" msgid="3559904746859400732">"Հպեք` ձեր վրիպակի մասին զեկույցը տարածելու համար"</string>
<string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string>
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java
index fb30bc1..3b59fd6 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/AbstractStatementRetriever.java
@@ -90,7 +90,7 @@
* Creates a new StatementRetriever that directly retrieves statements from the asset.
*
* <p> For web assets, {@link AbstractStatementRetriever} will try to retrieve the statement
- * file from URL: {@code [webAsset.site]/.well-known/associations.json"} where {@code
+ * file from URL: {@code [webAsset.site]/.well-known/statements.json"} where {@code
* [webAsset.site]} is in the form {@code http{s}://[hostname]:[optional_port]}. The file
* should contain one JSON array of statements.
*
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
index 3ad71c4..6516516 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/DirectStatementRetriever.java
@@ -38,7 +38,7 @@
private static final int HTTP_CONNECTION_TIMEOUT_MILLIS = 5000;
private static final long HTTP_CONTENT_SIZE_LIMIT_IN_BYTES = 1024 * 1024;
private static final int MAX_INCLUDE_LEVEL = 1;
- private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/associations.json";
+ private static final String WELL_KNOWN_STATEMENT_PATH = "/.well-known/statements.json";
private final URLFetcher mUrlFetcher;
private final AndroidPackageInfoFetcher mAndroidFetcher;
diff --git a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java
index f83edaf..da3c355 100644
--- a/packages/StatementService/src/com/android/statementservice/retriever/Statement.java
+++ b/packages/StatementService/src/com/android/statementservice/retriever/Statement.java
@@ -21,7 +21,7 @@
/**
* An immutable value type representing a statement, consisting of a source, target, and relation.
* This reflects an assertion that the relation holds for the source, target pair. For example, if a
- * web site has the following in its associations.json file:
+ * web site has the following in its statements.json file:
*
* <pre>
* {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 209a233..e47c7a0 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -184,16 +184,17 @@
<activity android:name=".tuner.TunerActivity"
android:enabled="false"
- android:icon="@drawable/icon"
+ android:icon="@drawable/tuner"
android:theme="@android:style/Theme.Material.Settings"
android:label="@string/system_ui_tuner"
+ android:process=":tuner"
android:exported="true">
<intent-filter>
<action android:name="com.android.settings.action.EXTRA_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.category"
- android:value="com.android.settings.category.device" />
+ android:value="com.android.settings.category.system" />
</activity>
<!-- Alternate Recents -->
@@ -319,6 +320,19 @@
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".egg.ShruggyActivity"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:exported="true"
+ android:launchMode="singleInstance"
+ android:screenOrientation="locked"
+ android:process=":sweetsweetdesserts"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.internal.category.PLATLOGO" />
</intent-filter>
</activity>
diff --git a/packages/SystemUI/docs/demo_mode.md b/packages/SystemUI/docs/demo_mode.md
index 18ae4cb..258c76b 100644
--- a/packages/SystemUI/docs/demo_mode.md
+++ b/packages/SystemUI/docs/demo_mode.md
@@ -38,6 +38,8 @@
| | ```datatype``` | Values: ```1x```, ```3g```, ```4g```, ```e```, ```g```, ```h```, ```lte```, ```roam```, any other value to hide
| | ```level``` | Sets mobile signal strength level (null or 0-4)
| ```carriernetworkchange``` | | Sets mobile signal icon to carrier network change UX when disconnected (```show``` to show icon, any other value to hide)
+ | ```sims``` | | Sets the number of sims (1-8)
+ | ```nosim``` | | ```show``` to show icon, any other value to hide
```bars``` | | | Control the visual style of the bars (opaque, translucent, etc)
| ```mode``` | | Sets the bars visual style (opaque, translucent, semi-transparent)
```status``` | | | Control the system status icons
diff --git a/packages/SystemUI/res/drawable-nodpi/icon.xml b/packages/SystemUI/res/drawable-nodpi/icon.xml
index dc1e633..7b8975a 100644
--- a/packages/SystemUI/res/drawable-nodpi/icon.xml
+++ b/packages/SystemUI/res/drawable-nodpi/icon.xml
@@ -14,47 +14,30 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
- android:viewportWidth="560.0"
- android:viewportHeight="560.0">
+ android:width="48.0dp"
+ android:height="48.0dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
<path
- android:pathData="M280.000000,288.000000m-260.000000,0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,520.000000 0.000000a260.000000,260.000000 0.000000,1.000000 1.000000,-520.000000 0.000000"
- android:fillColor="#14000000"/>
+ android:pathData="M24.0,2.0C11.8,2.0 2.0,11.8 2.0,24.0c0.0,6.1 2.5,11.6 6.4,15.6L39.6,8.4C35.6,4.5 30.1,2.0 24.0,2.0z"
+ android:fillColor="#F57C00"/>
<path
- android:pathData="M280.000000,285.000000m-255.000000,0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,510.000000 0.000000a255.000000,255.000000 0.000000,1.000000 1.000000,-510.000000 0.000000"
- android:fillColor="#26000000"/>
+ android:pathData="M39.6,8.4L8.4,39.6c4.0,4.0 9.5,6.4 15.6,6.4c12.2,0.0 22.0,-9.8 22.0,-22.0C46.0,17.9 43.5,12.4 39.6,8.4z"
+ android:fillColor="#FF9800"/>
<path
- android:pathData="M280.000000,282.000000m-252.000000,0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,504.000000 0.000000a252.000000,252.000000 0.000000,1.000000 1.000000,-504.000000 0.000000"
- android:fillColor="#26000000"/>
+ android:pathData="M45.9,25.9L34.0,14.0L14.0,34.0l11.9,11.9C36.5,45.0 45.0,36.5 45.9,25.9z"
+ android:fillAlpha="0.33"
+ android:fillColor="#F57C00"/>
<path
- android:pathData="M280.000000,280.000000m-250.000000,0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,500.000000 0.000000a250.000000,250.000000 0.000000,1.000000 1.000000,-500.000000 0.000000"
- android:fillColor="#9C27B0"/>
- <path
- android:pathData="M265.786011,244.938004l0.000000,8.768000c6.527000,-6.384000 15.303000,-10.321000 25.063000,-10.321000c20.214001,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.215000,36.500000 -36.429001,36.500000c-9.759000,0.000000 -18.107000,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L265.786011,244.937988L265.786011,244.938004zM267.330994,266.490997c-0.420000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.197000,13.339000 22.882999,13.339000c14.671000,0.000000 26.742001,-11.999000 26.742001,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.742001,-26.607000C280.454987,253.365997 271.963989,258.625000 267.330994,266.490997z"
+ android:pathData="M24.0,24.0c0.0,0.0 0.0,2.2 0.0,5.0s0.0,5.0 0.0,5.0l10.0,-10.0L34.0,14.0L24.0,24.0z"
android:fillColor="#FFFFFF"/>
<path
- android:pathData="M427.973999,244.938004l0.000000,8.768000c6.526000,-6.384000 15.304000,-10.321000 25.062000,-10.321000c20.215000,0.000000 36.429001,16.500000 36.429001,36.714001c0.000000,20.072001 -16.214001,36.500000 -36.429001,36.500000c-9.758000,0.000000 -18.106001,-3.651000 -24.634001,-9.759000l0.000000,25.839001l-10.107000,0.000000l0.000000,-87.740997L427.973999,244.937988L427.973999,244.938004zM429.518005,266.490997c-0.419000,0.706000 -1.125000,1.821000 -1.125000,4.277000l0.000000,18.813000c0.000000,1.759000 0.420000,2.740000 0.982000,3.723000c4.634000,7.929000 13.196000,13.339000 22.884001,13.339000c14.670000,0.000000 26.740999,-11.999000 26.740999,-26.669001c0.000000,-14.536000 -12.071000,-26.607000 -26.740999,-26.607000C442.643005,253.365997 434.152008,258.625000 429.518005,266.490997z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M24.0,24.0L14.0,14.0l0.0,10.0l10.0,10.0c0.0,0.0 0.0,-2.2 0.0,-5.0S24.0,24.0 24.0,24.0z"
+ android:fillColor="#EEEEEE"/>
<path
- android:pathData="M181.330994,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.438000,36.715000c-20.214001,0.000000 -36.643002,-16.500999 -36.643002,-36.715000c0.000000,-20.070999 16.419001,-36.500000 36.643002,-36.500000C164.973007,243.393005 181.330994,259.821014 181.330994,279.893005zM171.151993,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.259001,-26.669001c-14.741000,0.000000 -26.250000,12.000000 -26.250000,26.669001c0.000000,14.536000 11.509000,26.607000 26.250000,26.607000C159.429001,306.634003 171.151993,294.562012 171.151993,280.036011z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M14.0,34.0l10.0,0.0 -10.0,-10.0z"
+ android:fillColor="#DDDDDD"/>
<path
- android:pathData="M408.384003,279.893005c0.000000,20.214001 -16.357000,36.715000 -36.437000,36.715000c-20.215000,0.000000 -36.644001,-16.500999 -36.644001,-36.715000c0.000000,-20.070999 16.420000,-36.500000 36.644001,-36.500000C392.026001,243.393005 408.384003,259.821014 408.384003,279.893005zM398.204987,280.036011c0.000000,-14.669000 -11.723000,-26.669001 -26.257999,-26.669001c-14.742000,0.000000 -26.250999,12.000000 -26.250999,26.669001c0.000000,14.536000 11.509000,26.607000 26.250999,26.607000C386.481995,306.634003 398.204987,294.562012 398.204987,280.036011z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M234.481995,227.320999l9.973000,0.000000l0.000000,10.250000l-9.973000,0.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M234.481995,244.865997l9.973000,0.000000l0.000000,70.195999l-9.973000,0.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M88.392998,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M191.231995,227.320999l9.973000,0.000000l0.000000,87.740997l-9.973000,0.000000z"
- android:fillColor="#FFFFFF"/>
- <path
- android:pathData="M212.856995,227.320999l9.974000,0.000000l0.000000,87.740997l-9.974000,0.000000z"
- android:fillColor="#FFFFFF"/>
+ android:pathData="M34.0,34.0l0.0,-10.0 -10.0,10.0z"
+ android:fillColor="#DDDDDD"/>
</vector>
diff --git a/packages/SystemUI/res/drawable-nodpi/tuner.xml b/packages/SystemUI/res/drawable-nodpi/tuner.xml
new file mode 100644
index 0000000..e27423f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-nodpi/tuner.xml
@@ -0,0 +1,27 @@
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48.0dp"
+ android:height="48.0dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M29.9,24.8c0.0,-0.3 0.1,-0.5 0.1,-0.8s0.0,-0.5 -0.1,-0.8l1.7,-1.3c0.2,-0.1 0.2,-0.3 0.1,-0.5l-1.6,-2.8c-0.1,-0.2 -0.3,-0.2 -0.5,-0.2l-2.0,0.8c-0.4,-0.3 -0.9,-0.6 -1.4,-0.8L26.0,16.3c0.0,-0.2 -0.2,-0.3 -0.4,-0.3l-3.2,0.0c-0.2,0.0 -0.4,0.1 -0.4,0.3l-0.3,2.1c-0.5,0.2 -0.9,0.5 -1.4,0.8l-2.0,-0.8c-0.2,-0.1 -0.4,0.0 -0.5,0.2l-1.6,2.8c-0.1,0.2 -0.1,0.4 0.1,0.5l1.7,1.3c0.0,0.3 -0.1,0.5 -0.1,0.8s0.0,0.5 0.1,0.8l-1.7,1.3c-0.2,0.1 -0.2,0.3 -0.1,0.5l1.6,2.8c0.1,0.2 0.3,0.2 0.5,0.2l2.0,-0.8c0.4,0.3 0.9,0.6 1.4,0.8l0.3,2.1c0.0,0.2 0.2,0.3 0.4,0.3l3.2,0.0c0.2,0.0 0.4,-0.1 0.4,-0.3l0.3,-2.1c0.5,-0.2 0.9,-0.5 1.4,-0.8l2.0,0.8c0.2,0.1 0.4,0.0 0.5,-0.2l1.6,-2.8c0.1,-0.2 0.1,-0.4 -0.1,-0.5L29.9,24.8zM24.0,26.8c-1.5,0.0 -2.8,-1.3 -2.8,-2.8s1.3,-2.8 2.8,-2.8s2.8,1.3 2.8,2.8S25.5,26.8 24.0,26.8z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M18.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S18.6,38.0 18.0,38.0zM24.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S24.6,38.0 24.0,38.0zM30.0,38.0c-0.6,0.0 -1.0,-0.4 -1.0,-1.0s0.4,-1.0 1.0,-1.0s1.0,0.4 1.0,1.0S30.6,38.0 30.0,38.0zM42.0,6.0L6.0,6.0c-2.2,0.0 -4.0,1.8 -4.0,4.0l0.0,28.0c0.0,2.2 1.8,4.0 4.0,4.0l36.0,0.0c2.2,0.0 4.0,-1.8 4.0,-4.0L46.0,10.0C46.0,7.8 44.2,6.0 42.0,6.0zM42.0,34.0L6.0,34.0L6.0,14.0l36.0,0.0L42.0,34.0zM9.0,12.0L7.0,12.0l0.0,-2.0l2.0,0.0L9.0,12.0zM13.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L13.0,12.0zM17.0,12.0l-2.0,0.0l0.0,-2.0l2.0,0.0L17.0,12.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 539aabf..03b6dca 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -63,7 +63,7 @@
android:layout_gravity="@integer/notification_panel_layout_gravity"
android:paddingLeft="@dimen/notification_side_padding"
android:paddingRight="@dimen/notification_side_padding"
- android:visibility="gone">
+ android:visibility="invisible">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/tuner_qs.xml b/packages/SystemUI/res/layout/tuner_qs.xml
new file mode 100644
index 0000000..9a51e0c
--- /dev/null
+++ b/packages/SystemUI/res/layout/tuner_qs.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<com.android.systemui.tuner.AutoScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/system_secondary_color" >
+ <LinearLayout
+ android:id="@+id/all_details"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:gravity="center"
+ android:orientation="vertical">
+
+ <View
+ android:background="@color/qs_tile_divider"
+ android:layout_width="match_parent"
+ android:layout_height="2dp" />
+
+ <FrameLayout
+ android:id="@+id/remove_target"
+ android:layout_width="105dp"
+ android:layout_height="@dimen/qs_tile_height" />
+
+ <FrameLayout
+ android:id="@+id/add_target"
+ android:layout_width="105dp"
+ android:layout_height="@dimen/qs_tile_height" />
+ </LinearLayout>
+</com.android.systemui.tuner.AutoScrollView>
diff --git a/packages/SystemUI/res/layout/volume_zen_footer.xml b/packages/SystemUI/res/layout/volume_zen_footer.xml
index 998741c..eede804 100644
--- a/packages/SystemUI/res/layout/volume_zen_footer.xml
+++ b/packages/SystemUI/res/layout/volume_zen_footer.xml
@@ -26,7 +26,7 @@
android:layout_height="1dp"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
- android:background="#4dffffff" />
+ android:background="@color/qs_tile_divider" />
<LinearLayout
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 2160ca3..731d4c1 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -61,6 +61,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="24dp"
+ android:textDirection="locale"
android:lineSpacingMultiplier="1.20029"
android:layout_toStartOf="@id/zen_introduction_confirm"
android:textAppearance="@style/TextAppearance.QS.Introduction" />
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 098d8c3..104e5e3 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Deursoek"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Foon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Stembystand"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ontsluit"</string>
<string name="unlock_label" msgid="8779712358041029439">"ontsluit"</string>
<string name="phone_label" msgid="2320074140205331708">"maak foon oop"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"maak stembystand oop"</string>
<string name="camera_label" msgid="7261107956054836961">"maak kamera oop"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Kies nuwe taakuitleg"</string>
<string name="cancel" msgid="6442560571259935130">"Kanselleer"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Minder dringende kennisgewings hieronder"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Raak weer om oop te maak"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Sleep op om te ontsluit"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Swiep vanaf ikoon vir foon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Swiep vanaf ikoon vir stembystand"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Swiep vanaf ikoon vir kamera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Volkome stilte"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Net prioriteit"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Net wekkers"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Versteek alles"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Beëindig nou"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Vou uit"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Vou in"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skerm is vasgespeld"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Dit hou dit in sig totdat jy dit ontspeld. Raak en hou Terug en Oorsig op dieselfde tyd om te ontspeld."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Dit hou dit in sig totdat jy ontspeld. Raak en hou Oorsig om te ontspeld."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is die volumedialoog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Raak om die oorspronklike terug te stel."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Jy is in die Work-profiel"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 3fb27b2..99de3d8 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ፈልግ"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ካሜራ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ስልክ"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"የድምጽ እርዳታ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ክፈት"</string>
<string name="unlock_label" msgid="8779712358041029439">"ክፈት"</string>
<string name="phone_label" msgid="2320074140205331708">"ስልክ ክፈት"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"የድምጽ ረዳትን ክፈት"</string>
<string name="camera_label" msgid="7261107956054836961">"ካሜራ ክፈት"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"የአዲስ ተግባር አቀማመጥን ይምረጡ"</string>
<string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"በጣም አስቸካይ ያልሆኑ ማሳወቂያዎች ከታች"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ለመክፈት ዳግም ይንኩ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ለማስከፈት ወደ ላይ ያንሸራትቱ"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ለስልክ ከአዶ ላይ ጠረግ ያድርጉ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"ለድምጽ ረዳት ከአዶ ጠረግ ያድርጉ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ለካሜራ ከአዶ ላይ ጠረግ ያድርጉ"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"ሙሉ ለሙሉ ጸጥታ"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ቅድሚያ የሚሰጠው ብቻ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"ማንቂያዎች ብቻ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"ሁሉንም ደብቅ"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>። <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"አሁን ጨርስ"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"አስፋ"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ሰብስብ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"ማያ ገጽ ተሰክቷል"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"ይህ እስከሚነቅሉት ድረስ ድረስ በዕይታ ውስጥ እንዲቆይ ያደርገዋል። ለመንቀል በተመሳሳይ ጊዜ ተመለስን እና አጠቃላይ ዕይታን አንድ ላይ ነክተው ይያዙ።"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ይህ እስከሚነቅሉት ድረስ በዕይታ ውስጥ ያቆየዋል። እንዲነቀል ለማድረግ አጠቃላይ ዕይታን ነካ አድርገው ይያዙት።"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> የድምጽ መጠን መገናኛው ነው"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"የመጀመሪያውን ወደነበረበት ለመመለስ ይንኩ።"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"እርስዎ በስራ መገለጫ ውስጥ ነዎት"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 59be694..0b5af65 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -400,4 +400,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> هو مربع حوار مستوى الصوت"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"المس لاستعادة الإعداد الأصلي."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"أنت في الملف الشخصي للعمل"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 0898bec..073ddaa 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Търсене"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласова помощ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Отключване"</string>
<string name="unlock_label" msgid="8779712358041029439">"отключване"</string>
<string name="phone_label" msgid="2320074140205331708">"отваряне на телефона"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"отваряне на гласовата помощ"</string>
<string name="camera_label" msgid="7261107956054836961">"отваряне на камерата"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Избиране на ново оформление за задачите"</string>
<string name="cancel" msgid="6442560571259935130">"Отказ"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Ппоказване на по-малко спешните известия по-долу"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Докоснете отново за отваряне"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Прекарайте пръст нагоре, за да отключите"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Прекарайте пръст от иконата, за да използвате телефона"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Прекарайте пръст от иконата, за да получите гласова помощ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Прекарайте пръст от иконата, за да включите камерата"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Пълна тишина"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Само с приоритет"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Само будилници"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Скриване на всичко"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Прекратяване сега"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Разгъване"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Свиване"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Екранът е фиксиран"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Така екранът ще се показва, докато не го освободите. За да направите това, докоснете и задръжте бутона за връщане назад и този за общ преглед едновременно."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Така екранът ще се показва, докато не го освободите. За да направите това, докоснете и задръжте бутона за общ преглед."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> изпълнява ролята на диалоговия прозорец за силата на звука"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Докоснете, за да възстановите оригинала."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Влезли сте в потребителски профил в Work"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index e9bc159..6590d77 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"অনুসন্ধান করুন"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ক্যামেরা"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ফোন"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ভয়েস সহায়তা"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"আনলক করুন"</string>
<string name="unlock_label" msgid="8779712358041029439">"আনলক করুন"</string>
<string name="phone_label" msgid="2320074140205331708">"ফোন খুলুন"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ভয়েস সহায়তা খুলুন"</string>
<string name="camera_label" msgid="7261107956054836961">"ক্যামেরা খুলুন"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"নতুন কার্য লেআউট নির্বাচন করুন"</string>
<string name="cancel" msgid="6442560571259935130">"বাতিল করুন"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"নিচে অপেক্ষাকৃত কম জরুরী বিজ্ঞপ্তিগুলি"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"খোলার জন্য আবার স্পর্শ করুন"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"আনলক করতে উপরের দিকে সোয়াইপ করুন"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ফোনের জন্য আইকন থেকে সোয়াইপ করুন"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"ভয়েস সহায়তার জন্য আইকন থেকে সোয়াইপ করুন"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ক্যামেরার জন্য আইকন থেকে সোয়াইপ করুন"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"একদম নিরব"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"শুধুমাত্র অগ্রাধিকার"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"শুধুমাত্র অ্যালার্মগুলি"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"সবগুলি লুকান"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"এখন সমাপ্ত করুন"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"প্রসারিত করুন"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"সঙ্কুচিত করুন"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"স্ক্রীন পিন করা হয়েছে"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"এটি আপনার আনপিন না করা পর্যন্ত এটিকে দর্শনে রাখে৷ আনপিন করতে একই সময়ে ফিরুন এবং ওভারভিউ এ স্পর্শ করে ধরে রাখুন৷"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"এটি আপনার আনপিন না করা পর্যন্ত এটিকে দর্শনে রাখে৷ আনপিন করতে ওভারভিউ এ স্পর্শ করে ধরে রাখুন৷"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"আসলটি পুনঃস্থাপন করতে স্পর্শ করুন৷"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"আপনি কাজের প্রোফাইলে রয়েছেন"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 14e990b..e89fa3a2 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Cerca"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Càmera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telèfon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistència per veu"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloqueja"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloqueja"</string>
<string name="phone_label" msgid="2320074140205331708">"obre el telèfon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"obre l\'assistència per veu"</string>
<string name="camera_label" msgid="7261107956054836961">"obre la càmera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el disseny de la tasca nova"</string>
<string name="cancel" msgid="6442560571259935130">"Cancel·la"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacions menys urgents a continuació"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Torna a tocar per obrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Fes lliscar el dit cap amunt per desbloquejar el teclat."</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Fes lliscar el dit des de la icona per obrir el telèfon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Fes lliscar el dit des de la icona per obrir l\'ass. per veu"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Fes lliscar el dit des de la icona per obrir la càmera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silenci total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Només amb prioritat"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Només alarmes"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Amaga-les totes"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Finalitza ara"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Amplia"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Replega"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"La pantalla està fixada"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Continuarà a la visualització fins que n\'anul·lis la fixació. Per fer-ho, toca i mantén premuts els botons Enrere i Visió general a la vegada."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Continuarà a la visualització fins que n\'anul·lis la fixació. Per fer-ho, toca i mantén premut el botó Visió general."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> és el diàleg de volum"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca per restaurar l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Estàs utilitzant el perfil professional"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 3c82ccb..829b4a4 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Hledat"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparát"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasová asistence"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odemknout"</string>
<string name="unlock_label" msgid="8779712358041029439">"odemknout"</string>
<string name="phone_label" msgid="2320074140205331708">"otevřít telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"otevřít hlasovou asistenci"</string>
<string name="camera_label" msgid="7261107956054836961">"spustit fotoaparát"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Vybrat nové rozvržení úkolů"</string>
<string name="cancel" msgid="6442560571259935130">"Zrušit"</string>
@@ -320,12 +318,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Méně urgentní oznámení níže"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Otevřete opětovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zařízení odemknete přejetím prstem nahoru"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Telefon otevřete přejetím prstem od ikony"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Hlasovou asistenci otevřete přejetím prstem od ikony"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Fotoaparát otevřete přejetím prstem od ikony"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Úplné ticho"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Pouze prioritní"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Pouze budíky"</string>
@@ -389,10 +384,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skrýt vše"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Ukončit"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbalit"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sbalit"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je připnuta"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Chcete-li jej uvolnit, stiskněte a podržte současně tlačítka Zpět a Přehled."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Obsah bude připnut v zobrazení, dokud jej neuvolníte. Uvolníte jej stisknutím a podržením tlačítka Přehled."</string>
@@ -407,4 +400,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialog hlasitosti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Nacházíte se v pracovním profilu"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 5fb0f8d..7df138d 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Søg"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås op"</string>
<string name="unlock_label" msgid="8779712358041029439">"lås op"</string>
<string name="phone_label" msgid="2320074140205331708">"åbn telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"åbn talehjælp"</string>
<string name="camera_label" msgid="7261107956054836961">"åbn kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Vælg nyt opgavelayout"</string>
<string name="cancel" msgid="6442560571259935130">"Annuller"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende underretninger nedenfor"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tryk igen for at åbne"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Stryg for at låse op"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Stryg fra telefonikonet"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Stryg fra talehjælpsikonet"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Stryg fra kameraikonet"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Total stilhed"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Kun prioritet"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Kun Alarmer"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skjul alle"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Afslut nu"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Udvid"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skærmen er fastgjort"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Dette fastholder den i visningen, indtil du frigør den. Tryk på Tilbage og Oversigt på samme tid, og hold dem nede for at frigøre denne skærm."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Dette fastholder den i visningen, indtil du frigør den. Tryk på Oversigt, og hold den nede for at frigøre denne skærm."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er dialogboksen for lydstyrke"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tryk for at gendanne originalen."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Du er i arbejdsprofilen"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 27202d3..8765ef6 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Suchen"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sprachassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Entsperren"</string>
<string name="unlock_label" msgid="8779712358041029439">"Entsperren"</string>
<string name="phone_label" msgid="2320074140205331708">"Telefon öffnen"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"Sprachassistent öffnen"</string>
<string name="camera_label" msgid="7261107956054836961">"Kamera öffnen"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Neues Aufgabenlayout auswählen"</string>
<string name="cancel" msgid="6442560571259935130">"Abbrechen"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Weniger dringende Benachrichtigungen unten"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Zum Öffnen erneut berühren"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zum Entsperren nach oben wischen"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Zum Öffnen des Telefons vom Symbol wegwischen"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Zum Öffnen des Sprachassistenten vom Symbol wegwischen"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Zum Öffnen der Kamera vom Symbol wegwischen"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Lautlos"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Nur wichtige Unterbrechungen"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Nur Wecker"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Alle ausblenden"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Jetzt beenden"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Maximieren"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minimieren"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Bildschirm ist fixiert"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Der Bildschirm wird solange angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Zurück\" und \"Übersicht\" gleichzeitig, um die Fixierung aufzuheben."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Der Bildschirm wird solange angezeigt, bis Sie die Fixierung aufheben. Berühren und halten Sie \"Übersicht\", wenn Sie die Fixierung aufheben möchten."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> regelt die Lautstärke."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Zum Wiederherstellen des Originals hier tippen"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Sie befinden sich im Arbeitsprofil."</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index d2ef477..abc3f79 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Αναζήτηση"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Φωτογραφική μηχανή"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Τηλέφωνο"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Φωνητική υποβοήθηση"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ξεκλείδωμα"</string>
<string name="unlock_label" msgid="8779712358041029439">"ξεκλείδωμα"</string>
<string name="phone_label" msgid="2320074140205331708">"άνοιγμα τηλεφώνου"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"άνοιγμα φωνητικής υποβοήθησης"</string>
<string name="camera_label" msgid="7261107956054836961">"άνοιγμα φωτογραφικής μηχανής"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Επιλέξτε τη νέα διάταξη εργασίας"</string>
<string name="cancel" msgid="6442560571259935130">"Ακύρωση"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Λιγότερο επείγουσες ειδοποιήσεις παρακάτω"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Αγγίξτε ξανά για άνοιγμα"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Σύρετε για να ξεκλειδώσετε"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Σύρετε από το εικονίδιο για τηλέφωνο"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Σύρετε από το εικονίδιο για φωνητική υποβοήθηση"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Σύρετε από το εικονίδιο για κάμερα"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Πλήρης σίγαση"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Μόνο προτεραιότητας"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Μόνο ειδοποιήσεις"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Aπόκρυψη όλων"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Τερματισμός τώρα"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ανάπτυξη"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Σύμπτυξη"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Η οθόνη καρφιτσώθηκε"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Με αυτόν τον τρόπο παραμένει σε προβολή έως ότου την ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα \"Επιστροφή\" και \"Επισκόπηση\" ταυτόχρονα για ξεκαρφίτσωμα."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Με αυτόν τον τρόπο παραμένει σε προβολή έως ότου την ξεκαρφιτσώσετε. Αγγίξτε παρατεταμένα \"Επισκόπηση\" για ξεκαρφίτσωμα."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> αποτελεί το παράθυρο διαλόγου ελέγχου έντασης"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Αγγίξτε για επαναφορά αρχικού."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Χρησιμοποιείτε προφίλ εργασίας"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 89f725c..2de7a60 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"You are in the Work profile"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 89f725c..2de7a60 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"You are in the Work profile"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 89f725c..2de7a60 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is the volume dialogue"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touch to restore the original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"You are in the Work profile"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 8e9efc8..7a47b11 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string>
<string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Selecciona el nuevo diseño de la tarea."</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgentes abajo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir."</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslizar el dedo hacia arriba para desbloquear"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Desliza el dedo desde el ícono para acceder al teléfono."</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Desliza el dedo desde el ícono para abrir asistente de voz."</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Desliza el dedo desde el ícono para acceder a la cámara."</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silencio total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Solo prioridad"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Solo alarmas"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar todas"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar ahora"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fija"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Esta función mantiene fija la vista de la pantalla hasta que la desactivas. Mantén presionados los botones Atrás y Recientes al mismo tiempo para anular la fijación."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Esta función mantiene fija la vista de la pantalla hasta que la desactivas. Mantén presionado el botón Recientes para anular la fijación."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar el original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Estás usando el perfil de Work."</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index b7fb565..10a58cf 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"abrir el asistente de voz"</string>
<string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar diseño de tarea nueva"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Desliza el dedo hacia arriba para desbloquear"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Desliza el dedo desde el icono para abrir el teléfono"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Desliza el dedo desde el icono para abrir asistente de voz"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Desliza el dedo desde el icono para abrir la cámara"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silencio total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Solo prioritarias"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Solo alarmas"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar todas"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar ahora"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mostrar"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ocultar"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Pantalla fijada"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"La pantalla se mantendrá visible hasta que dejes de fijarla. Para ello, mantén pulsados los botones de retroceso e información general."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"La pantalla se mantendrá visible hasta que dejes de fijarla. Para ello, mantén pulsado el botón de información general."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> es el cuadro de diálogo de volumen"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar la versión original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Estás en el perfil de trabajo"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index bd15bec..132e867 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Otsing"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kaamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Häälabi"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Luku avamine"</string>
<string name="unlock_label" msgid="8779712358041029439">"ava lukk"</string>
<string name="phone_label" msgid="2320074140205331708">"ava telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ava häälabi"</string>
<string name="camera_label" msgid="7261107956054836961">"ava kaamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Uue toimingu paigutuse valimine"</string>
<string name="cancel" msgid="6442560571259935130">"Tühista"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähem kiireloomulised märguanded on allpool"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Avamiseks puudutage uuesti"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Lukustuse tühistamiseks pühkige üles"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Telefoni kasutamiseks pühkige ikoonilt eemale"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Häälabi kasutamiseks pühkige ikoonilt eemale"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Kaamera kasutamiseks pühkige ikoonilt eemale"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Täielik vaikus"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Ainult prioriteetsed"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Ainult alarmid"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Peida kõik"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Lõpeta nüüd"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Laiendamine"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Ahendamine"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekraan on kinnitatud"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"See hoiab selle kuval, kuni selle vabastate. Vabastamiseks puudutage ning hoidke korraga all nuppe Tagasi ja Ülevaade."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"See hoiab selle kuval, kuni selle vabastate. Vabastamiseks puudutage ja hoidke all nuppu Ülevaade."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on helitugevuse dialoog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Originaali taastamiseks puudutage."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Olete tööprofiilil"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 10e0fe4..d1b5c02 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Bilatu"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonoa"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ahots-laguntza"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desblokeatu"</string>
<string name="unlock_label" msgid="8779712358041029439">"desblokeatu"</string>
<string name="phone_label" msgid="2320074140205331708">"ireki telefonoan"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ireki ahots-laguntza"</string>
<string name="camera_label" msgid="7261107956054836961">"ireki kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Hautatu zereginen diseinua"</string>
<string name="cancel" msgid="6442560571259935130">"Utzi"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Horren premiazkoak ez diren jakinarazpenak daude behean"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Irekitzeko, ukitu berriro"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Desblokeatzeko, pasatu hatza gorantz"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Pasatu hatza ikonotik, telefonoa irekitzeko"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Pasatu hatza ikonotik, ahots-laguntza irekitzeko"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Pasatu hatza ikonotik, kamera irekitzeko"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Isiltasun osoa"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Lehentasunezkoak"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Alarmak soilik"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ezkutatu guztiak"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Amaitu"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zabaldu"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tolestu"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Pantaila ainguratuta dago"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Horrela, ikusgai mantenduko da aingura kendu arte. Aingura kentzeko, eduki ukituta aldi berean \"Atzera\" eta \"Ikuspegi orokorra\" botoiak."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Horrela, ikusgai mantenduko da, aingura kendu arte. Aingura kentzeko, eduki ukituta \"Ikuspegi orokorra\" botoia."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> da bolumenaren leihoa"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Ukitu jatorrizkora leheneratzeko"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Work profil bat erabiltzen ari zara"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 544552b4..d611335 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"جستجو"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"دوربین"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"تلفن"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"دستیار صوتی"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"باز کردن قفل"</string>
<string name="unlock_label" msgid="8779712358041029439">"بازکردن قفل"</string>
<string name="phone_label" msgid="2320074140205331708">"باز کردن تلفن"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"دستیار صوتی را باز کنید"</string>
<string name="camera_label" msgid="7261107956054836961">"باز کردن دوربین"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"انتخاب طرحبندی جدید کار"</string>
<string name="cancel" msgid="6442560571259935130">"لغو"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"برای باز کردن دوباره لمس کنید"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"برای باز کردن قفل سریع به بالا بکشید"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"انگشتتان را از نماد تلفن تند بکشید"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"از نماد دستیار صوتی انگشتتان را تند بکشید"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"انگشتتان را از نماد دوربین تند بکشید"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"سکوت کامل"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"فقط اولویتدار"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"فقط هشدارها"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"پنهان کردن همه"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"اکنون به پایان برسد"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"بزرگ کردن"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"کوچک کردن"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"صفحه نمایش پین شد"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، برگشت و نمای کلی را به صورت همزمان لمس کنید و نگهدارید."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"تا زمانی که پین را بردارید، در نما نگهداشته میشود. برای برداشتن پین، نمای کلی را لمس کنید و نگهدارید."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترلکننده صدا است"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"برای بازیابی کنترلکننده اصلی، لمس کنید."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"در نمایه کاری هستید"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index fc5f8dd..ced87b2 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Haku"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Puhelin"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ääniapuri"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Avaa lukitus"</string>
<string name="unlock_label" msgid="8779712358041029439">"avaa lukitus"</string>
<string name="phone_label" msgid="2320074140205331708">"avaa puhelin"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"Avaa ääniapuri"</string>
<string name="camera_label" msgid="7261107956054836961">"avaa kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Valitse uusi tehtävien asettelu"</string>
<string name="cancel" msgid="6442560571259935130">"Peruuta"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Vähemmän kiireelliset ilmoitukset ovat alla"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Avaa koskettamalla uudelleen"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Avaa lukitus pyyhkäisemällä ylös"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Avaa puhelu pyyhkäisemällä kuvakkeesta."</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Avaa ääniapuri pyyhkäisemällä kuvakkeesta."</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Avaa kamera pyyhkäisemällä kuvakkeesta."</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Täydellinen hiljaisuus"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Vain tärkeät"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Vain herätykset"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Piilota kaikki"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Lopeta nyt"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Laajenna."</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Tiivistä."</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Näyttö on kiinnitetty"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Tämä pitää sen näkyvissä, kunnes poistat kiinnityksen. Kosketa Edellinen- ja Viimeisimmät-kohtaa samanaikaisesti pitkään kiinnityksen poistamiseksi."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Tämä pitää sen näkyvissä, kunnes poistat kiinnityksen. Kosketa Viimeisimmät-kohtaa pitkään kiinnityksen poistamiseksi."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> on äänenvoimakkuusvalinta."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Palauta alkuperäinen koskettamalla."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Olet Work-profiilissa"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 6b40037..781f932 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Rechercher"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphone"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string>
<string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string>
<string name="phone_label" msgid="2320074140205331708">"Ouvrir le téléphone"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string>
<string name="camera_label" msgid="7261107956054836961">"Ouvrir l\'appareil photo"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau format de tâche"</string>
<string name="cancel" msgid="6442560571259935130">"Annuler"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes affichées ci-dessous"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Touchez à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Glissez vers le haut pour déverrouiller"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Balayez à partir de l\'icône pour accéder au téléphone"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Balayez à partir de l\'icône pour accéder à l\'assist. vocale"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Balayez à partir de l\'icône pour accéder à l\'appareil photo"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Aucune interruption"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Priorités seulement"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Alarmes uniquement"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Tout masquer"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Arrêter maintenant"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"L\'écran est épinglé"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez un doigt simultanément sur « Retour » et « Aperçu »."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Cet écran est épinglé jusqu\'à ce que vous annuliez l\'opération. Pour annuler l\'épinglage, maintenez le doigt sur « Aperçu »."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Touchez pour restaurer l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Vous avez activé le profil professionnel"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index eedaaad..f6ad433 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Rechercher"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphoner"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistance vocale"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Déverrouiller"</string>
<string name="unlock_label" msgid="8779712358041029439">"déverrouiller"</string>
<string name="phone_label" msgid="2320074140205331708">"ouvrir le téléphone"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ouvrir l\'assistance vocale"</string>
<string name="camera_label" msgid="7261107956054836961">"ouvrir l\'appareil photo"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Sélectionner un nouveau plan de tâche"</string>
<string name="cancel" msgid="6442560571259935130">"Annuler"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifications moins urgentes ci-dessous"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Appuyer à nouveau pour ouvrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Faire glisser pour déverrouiller"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Balayer l\'écran depuis l\'icône pour le téléphone"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Balayer l\'écran depuis l\'icône pour l\'assistance vocale"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Balayer l\'écran depuis l\'icône pour l\'appareil photo"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Aucune interruption"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Priorit. uniquement"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Alarmes uniquement"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Tout masquer"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Arrêter maintenant"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Développer"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Réduire"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Écran épinglé"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Cet écran est épinglé jusqu\'à annulation de l\'opération. Pour annuler l\'épinglage, appuyez simultanément sur \"Retour\" et \"Aperçu\" de manière prolongée."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Cet écran est épinglé jusqu\'à annulation de l\'opération. Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Aperçu\"."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> correspond à la boîte de dialogue du volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Appuyez pour restaurer l\'interface d\'origine."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Vous consultez le profil professionnel."</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index fb3c6d8..03ece76 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistente de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir teléfono"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"abrir asistente de voz"</string>
<string name="camera_label" msgid="7261107956054836961">"abrir cámara"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Seleccionar novo deseño de tarefas"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificacións menos urxentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Toca outra vez para abrir o elemento"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Pasa o dedo cara arriba para desbloquear"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Pasa o dedo desde a icona para acceder ao teléfono"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Pasa o dedo desde a icona para acceder ao asistente de voz"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Pasa o dedo desde a icona para acceder á cámara"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silencio total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Só prioridade"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Só alarmas"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar todo"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ampliar"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Contraer"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"A pantalla está fixada"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"A pantalla manterase visible ata que anules a fixación. Para facelo, mantén premido Atrás e Visión xeral ao mesmo tempo."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"A pantalla manterase visible ata que anules a fixación. Para facelo, mantén premido Visión xeral."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é o cadro de diálogo de volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toca para restaurar o orixinal."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Está no perfil de traballo"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 499553e..809616e 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -83,9 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"શોધો"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"કૅમેરો"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ફોન"</string>
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"વૉઇસ સહાય"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"અનલૉક કરો"</string>
<string name="unlock_label" msgid="8779712358041029439">"અનલૉક કરો"</string>
<string name="phone_label" msgid="2320074140205331708">"ફોન ખોલો"</string>
+ <string name="voice_assist_label" msgid="3956854378310019854">"વૉઇસ સહાય ખોલો"</string>
<string name="camera_label" msgid="7261107956054836961">"કૅમેરો ખોલો"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"નવું કાર્ય લેઆઉટ પસંદ કરો"</string>
<string name="cancel" msgid="6442560571259935130">"રદ કરો"</string>
@@ -121,6 +123,8 @@
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX બે બાર."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ત્રણ બાર."</string>
<string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"પૂર્ણ WiMAX સિગ્નલ."</string>
+ <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"ઇથરનેટ ડિસ્કનેક્ટ થયું."</string>
+ <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"ઇથરનેટ કનેક્ટ થયું."</string>
<string name="accessibility_no_signal" msgid="7064645320782585167">"કોઈ સિગ્નલ નથી."</string>
<string name="accessibility_not_connected" msgid="6395326276213402883">"કનેક્ટ થયેલ નથી."</string>
<string name="accessibility_zero_bars" msgid="3806060224467027887">"શૂન્ય બાર."</string>
@@ -162,13 +166,14 @@
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખી."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"તમામ તાજેતરની એપ્લિકેશન્સ કાઢી નાખી."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી રહ્યું છે."</string>
+ <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"સૂચના કાઢી નાખી."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"સૂચના શેડ."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ઝડપી સેટિંગ્સ."</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"લૉક સ્ક્રીન."</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"સેટિંગ્સ"</string>
<string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"વિહંગાવલોકન."</string>
- <string name="accessibility_desc_confirm" msgid="3446792278337969766">"પુષ્ટિ કરો"</string>
+ <string name="accessibility_desc_close" msgid="7479755364962766729">"બંધ કરો"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"વપરાશકર્તા <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi બંધ કર્યું."</string>
@@ -180,7 +185,7 @@
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"એરપ્લેન મોડ બંધ કર્યું."</string>
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"એરપ્લેન મોડ ચાલુ કર્યો."</string>
<string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"ખલેલ પાડશો નહીં ચાલુ, ફક્ત પ્રાધાન્યતા."</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="5910777408232088752">"ખલેલ પાડશો નહીં ચાલુ, કોઈ વિક્ષેપ નહીં."</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"ખલેલ પાડશો નહીં ચાલુ, સાવ શાંતિ."</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"ખલેલ પાડશો નહીં ચાલુ, ફક્ત એલાર્મ્સ."</string>
<string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"ખલેલ પાડશો નહીં બંધ."</string>
<string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"ખલેલ પાડશો નહીં બંધ કર્યું."</string>
@@ -235,7 +240,7 @@
<string name="quick_settings_dnd_label" msgid="8735855737575028208">"ખલેલ પાડશો નહીં"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ફક્ત પ્રાધાન્યતા"</string>
<string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ફક્ત એલાર્મ્સ"</string>
- <string name="quick_settings_dnd_none_label" msgid="7309935569360609114">"કોઈ વિક્ષેપ નહીં"</string>
+ <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"સાવ શાંતિ"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> ઉપકરણો)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth બંધ"</string>
@@ -302,26 +307,20 @@
<string name="description_target_search" msgid="3091587249776033139">"શોધો"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ઉપર સ્લાઇડ કરો."</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> માટે ડાબે સ્લાઇડ કરો."</string>
- <string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"કોઈ વિક્ષેપ નહીં. એલાર્મ્સ પણ નહીં."</string>
- <string name="zen_priority_introduction" msgid="7253045784560169993">"તમને તમે ઉલ્લેખિત એલાર્મ્સ, સ્મૃતિપત્રો, ઇવેન્ટ્સ અને કૉલર્સ સિવાય સાઉન્ડ્સ અને વાઇબ્રેશન્સથી ખલેલ પહોંચાડવામાં આવશે નહીં."</string>
+ <string name="zen_priority_introduction" msgid="3070506961866919502">"તમને તમે ઉલ્લેખિત એલાર્મ્સ, સ્મૃતિપત્રો, ઇવેન્ટ્સ અને કૉલર્સ સિવાયના ધ્વનિઓ અને વાઇબ્રેશન્સથી ખલેલ પહોંચાડવામાં આવશે નહીં."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"કસ્ટમાઇઝ કરો"</string>
- <string name="zen_no_interruptions" msgid="7970973750143632592">"કોઈ વિક્ષેપ નહીં"</string>
- <string name="zen_important_interruptions" msgid="3477041776609757628">"ફક્ત પ્રાધાન્યતા વિક્ષેપો"</string>
- <string name="zen_alarms" msgid="5055668280767657759">"ફક્ત એલાર્મ્સ"</string>
- <string name="zen_alarm_information_time" msgid="5235772206174372272">"<xliff:g id="ALARM_TIME">%s</xliff:g> પર તમારો આગલો એલાર્મ"</string>
- <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"<xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g> પર તમારો આગલો એલાર્મ છે"</string>
- <string name="zen_alarm_warning" msgid="6873910860111498041">"તમે <xliff:g id="ALARM_TIME">%s</xliff:g> એ તમારો એલાર્મ સાંભળશો નહીં"</string>
+ <string name="zen_silence_introduction" msgid="575422795504098868">"આ એલાર્મ્સ, સંગીત, વિડિઓઝ અને રમતો સહિત બધા ધ્વનિઓ અને વાઇબ્રેશન્સને અવરોધિત કરે છે. તમે હજુ પણ ફોન કૉલ્સ કરવા માટે સમર્થ હશો."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"નીચે ઓછી તાકીદની સૂચનાઓ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ખોલવા માટે ફરી ટચ કરો"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"અનલૉક કરવા માટે ઉપર સ્વાઇપ કરો"</string>
- <string name="phone_hint" msgid="3101468054914424646">"ફોન માટે જમણે સ્વાઇપ કરો"</string>
- <string name="camera_hint" msgid="5241441720959174226">"કૅમેરા માટે ડાબે સ્વાઇપ કરો"</string>
- <string name="interruption_level_none" msgid="8284541443482072628">"કોઈ વિક્ષેપ નહીં"</string>
+ <string name="phone_hint" msgid="4872890986869209950">"ફોન માટે આયકનમાંથી સ્વાઇપ કરો"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"વૉઇસ સહાય માટે આયકનમાંથી સ્વાઇપ કરો"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"કૅમેરા માટે આયકનમાંથી સ્વાઇપ કરો"</string>
+ <string name="interruption_level_none" msgid="6000083681244492992">"સાવ શાંતિ"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ફક્ત પ્રાધાન્યતા"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"ફક્ત એલાર્મ્સ"</string>
- <string name="interruption_level_all" msgid="1330581184930945764">"તમામ"</string>
- <string name="interruption_level_none_twoline" msgid="3942121050170227056">"કોઈ\nવિક્ષેપ નહીં"</string>
+ <string name="interruption_level_none_twoline" msgid="3957581548190765889">"સાવ\nશાંતિ"</string>
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ફક્ત\nપ્રાધાન્યતા"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ફક્ત\nએલાર્મ્સ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ચાર્જ થઈ રહ્યું છે (પૂર્ણ થવામાં <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> બાકી)"</string>
@@ -363,12 +362,15 @@
<string name="disable_vpn" msgid="4435534311510272506">"VPN અક્ષમ કરો"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"VPN ડિસ્કનેક્ટ કરો"</string>
<string name="monitoring_description_device_owned" msgid="5780988291898461883">"તમારું ઉપકરણ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક સેટિંગ્સ, કોર્પોરેટ ઍક્સેસ, એપ્લિકેશન્સ, તમારા ઉપકરણ સાથે સંકળાયેલ ડેટા અને તમારા ઉપકરણની સ્થાન માહિતી મોનિટર અને સંચાલિત કરી શકે છે. વધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
- <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક, ઇમેઇલ્સ, એપ્લિકેશન્સ અને સુરક્ષિત વેબસાઇટ્સ સહિતની તમારી નેટવર્ક પ્રવૃત્તિ મોનિટર કરવા માટે સક્ષમ છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"તમારું ઉપકરણ આમના દ્વારા સંચાલિત થાય છે:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nતમારી પ્રોફાઇલ આમના દ્વારા સંચાલિત છે:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nતમારા વ્યવસ્થાપક તમારા ઉપકરણ અને ઇમેઇલ્સ, એપ્લિકેશન્સ અને સુરક્ષિત વેબસાઇટ્સ સહિત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
- <string name="monitoring_description_vpn" msgid="912328761766161919">"તમે એક એપ્લિકેશનને VPN કનેક્શનને સેટ કરવાની પરવાનગી આપી છે.\n\nઆ એપ્લિકેશન તમારા ઉપકરણ અને ઇમેઇલ્સ, એપ્લિકેશન્સ અને સુરક્ષિત વેબસાઇટ્સ સહિત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
+ <string name="monitoring_description_vpn" msgid="996222259035614736">"તમે VPN કનેક્શન સેટ કરવા માટે એપ્લિકેશન પરવાનગી આપી.\n\nઆ એપ્લિકેશન ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિત તમારા ઉપકરણ અને નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
<string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"તમારું ઉપકરણ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક સેટિંગ્સ, કોર્પોરેટ ઍક્સેસ, એપ્લિકેશન્સ, તમારા ઉપકરણ સાથે સંકળાયેલ ડેટા અને તમારા ઉપકરણની સ્થાન માહિતી મોનિટર અને સંચાલિત કરી શકે છે.\n\nતમે VPN સાથે કનેક્ટ થયેલા છો જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની, તમારી નેટવર્ક પ્રવૃત્તિ મોનિટર કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક, ઇમેઇલ્સ, એપ્લિકેશન્સ અને સુરક્ષિત વેબસાઇટ્સ સહિતની તમારી નેટવર્ક પ્રવૃત્તિ મોનિટર કરવા માટે સક્ષમ છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો.\n\nતમે VPN સાથે પણ કનેક્ટ થયેલ છો, જે તમારી નેટવર્ક પ્રવૃત્તિને મોનિટર કરી શકે છે."</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"આ ઉપકરણ <xliff:g id="ORGANIZATION_0">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\nતમારી પ્રોફાઇલ આના દ્વારા સંચાલિત થાય છે:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nતમારા વ્યવસ્થાપક ઇમેઇલ્સ, એપ્લિકેશન્સ અને સુરક્ષિત વેબસાઇટ્સ સહિત તમારી નેટવર્ક પ્રવૃત્તિનું નિરીક્ષણ કરવામાં સક્ષમ હોય છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો.\n\nતમે VPN સાથે પણ કનેક્ટ થયેલ છો, જે તમારી વ્યક્તિગત માહિતીને મોનિટર કરી શકે છે"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી નેટવર્ક પ્રવૃત્તિને મૉનિટર કરવામાં સમર્થ છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો.\n\nતમે VPN સાથે પણ કનેક્ટ છો, જે તમારી નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
+ <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+ <string name="monitoring_description_app" msgid="6947928635272782570">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
+ <string name="monitoring_description_app_personal" msgid="8506133233655324426">"તમે <xliff:g id="APPLICATION">%1$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
+ <string name="monitoring_description_app_work" msgid="808687576155832307">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. તે <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ થયેલ છે, જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી કાર્ય નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
+ <string name="monitoring_description_app_personal_work" msgid="7711690793960304868">"તમારી કાર્ય પ્રોફાઇલ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે. તે <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> સાથે કનેક્ટ થયેલ છે, જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી કાર્ય નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> સાથે પણ કનેક્ટ થયેલ છો, જે તમારી વ્યક્તિગત નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"તમારું ઉપકરણ <xliff:g id="ORGANIZATION">%1$s</xliff:g> દ્વારા સંચાલિત થાય છે.\n\nતમારા વ્યવસ્થાપક, સેટિંગ્સ, કોર્પોરેટ ઍક્સેસ, એપ્લિકેશન્સ, તમારા ઉપકરણ સાથે સંકળાયેલ ડેટા અને તમારા ઉપકરણની સ્થાન માહિતીને મૉનિટર કરી અને સંચાલિત કરી શકે છે.\n\nતમે <xliff:g id="APPLICATION">%2$s</xliff:g> સાથે કનેક્ટ થયાં છો, જે ઇમેઇલ્સ, એપ્લિકેશન્સ અને વેબસાઇટ્સ સહિતની તમારી નેટવર્ક પ્રવૃત્તિને મૉનિટર કરી શકે છે.\n\nવધુ માહિતી માટે, તમારા વ્યવસ્થાપકનો સંપર્ક કરો."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"તમે ઉપકરણને મેન્યુઅલી અનલૉક કરશો નહીં ત્યાં સુધી તે લૉક રહેશે"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"વધુ ઝડપથી સૂચનાઓ મેળવો"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"તમે અનલૉક કરો તે પહેલાં તેમને જુઓ"</string>
@@ -377,6 +379,9 @@
<string name="notification_expand_button_text" msgid="1037425494153780718">"બધું જુઓ"</string>
<string name="notification_collapse_button_text" msgid="6883253262134328057">"બધું છુપાવો"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <string name="volume_zen_end_now" msgid="3179845345429841822">"હવે સમાપ્ત કરો"</string>
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"વિસ્તૃત કરો"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"સંકુચિત કરો"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"સ્ક્રીન પિન કરેલ છે"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યમાં રાખે છે. અનપિન કરવા માટે બેકને ટચ કરો અને પકડો અને તે જ સમયે વિહંગાવલોકન કરો."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"તમે જ્યાં સુધી અનપિન કરશો નહીં ત્યાં સુધી આ તેને દૃશ્યમાં રાખે છે. અનપિન કરવા માટે વિહંગાવલોકનને ટચ કરો અને પકડો."</string>
@@ -391,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ વૉલ્યૂમ સંવાદ છે"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"મૂળને પુનઃસ્થાપિત કરવા માટે ટચ કરો."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"તમે કાર્ય પ્રોફાઇલમાં છો"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e17cb0a..b2bd1b8 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"खोजें"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"कैमरा"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"फ़ोन"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"वॉइस सहायक"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करें"</string>
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करें"</string>
<string name="phone_label" msgid="2320074140205331708">"फ़ोन खोलें"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"वॉइस सहायक खोलें"</string>
<string name="camera_label" msgid="7261107956054836961">"कैमरा खोलें"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"नया कार्य लेआउट चुनें"</string>
<string name="cancel" msgid="6442560571259935130">"अभी नहीं"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"कम अत्यावश्यक सूचनाएं नीचे दी गई हैं"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"खोलने के लिए पुन: स्पर्श करें"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करने के लिए ऊपर स्वाइप करें"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"फ़ोन के लिए आइकन से स्वाइप करें"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"वॉइस सहायक के लिए आइकन से स्वाइप करें"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"कैमरे के लिए आइकन से स्वाइप करें"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"पूरी तरह शांत"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"केवल प्राथमिकता"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"केवल अलार्म"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"सभी छिपाएं"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"अब समाप्त करें"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करें"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त करें"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"स्क्रीन पिन कर दी गई है"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"इससे वह तब तक दृश्य में रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए वापस जाएं और अवलोकन करें को एक ही समय पर स्पर्श करके रखें."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"इससे वह तब तक दृश्य में बना रहता है जब तक कि आप उसे अनपिन नहीं कर देते. अनपिन करने के लिए अवलोकन करें को स्पर्श करके रखें."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> वॉल्यूम संवाद है"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूल वॉल्यूम को फिर से लाने के लिए स्पर्श करें."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"आप कार्य प्रोफ़ाइल में हैं"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 59d40c3..abec5af 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -84,13 +84,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Pretraži"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparat"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovna pomoć"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Otključavanje"</string>
<string name="unlock_label" msgid="8779712358041029439">"otključavanje"</string>
<string name="phone_label" msgid="2320074140205331708">"otvaranje telefona"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"otvaranje glasovne pomoći"</string>
<string name="camera_label" msgid="7261107956054836961">"otvaranje fotoaparata"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Odaberite novi izgled zadataka"</string>
<string name="cancel" msgid="6442560571259935130">"Odustani"</string>
@@ -317,12 +315,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Manje hitne obavijesti pri dnu"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Dodirnite ponovo da biste otvorili"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Prijeđite prstom prema gore za otključavanje"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Prijeđite prstom od ikone da biste otvorili telefon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Prijeđite prstom od ikone da biste otvorili glasovnu pomoć"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Prijeđite prstom od ikone da biste otvorili fotoaparat"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Potpuna tišina"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Samo prioritetno"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Samo alarmi"</string>
@@ -386,10 +381,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Sakrij sve"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Prekini sada"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Proširivanje"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sažimanje"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je prikvačen"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Istovremeno dodirnite i držite Natrag i Pregled da biste ga otkvačili."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Zaslon će tako ostati u prvom planu dok ga ne otkvačite. Dodirnite i držite Pregled da biste ga otkvačili."</string>
@@ -404,4 +397,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> predstavlja dijaloški okvir za upravljanje glasnoćom"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dodirnite da biste vratili izvorno."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Nalazite se na profilu Worka"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index f0ca9ce..d2108f4 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Keresés"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hangsegéd"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Feloldás"</string>
<string name="unlock_label" msgid="8779712358041029439">"feloldás"</string>
<string name="phone_label" msgid="2320074140205331708">"telefon megnyitása"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"hangsegéd megnyitása"</string>
<string name="camera_label" msgid="7261107956054836961">"kamera megnyitása"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Új feladatelrendezés kiválasztása"</string>
<string name="cancel" msgid="6442560571259935130">"Mégse"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"A kevésbé sürgős értesítések lentebb vannak"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Érintse meg ismét a megnyitáshoz"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Húzza felfelé az ujját a feloldáshoz"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"A telefon eléréséhez csúsztassa ujját az ikonról"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"A hangsegéd eléréséhez csúsztassa ujját az ikonról"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"A fényképezőgép eléréséhez csúsztassa ujját az ikonról"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Teljes némítás"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Csak prioritásos"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Csak riasztások"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Az összes elrejtése"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Befejezés most"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kibontás"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Összecsukás"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"A képernyő rögzítve van"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Megjelenítve tartja addig, amíg Ön fel nem oldja fel a rögzítést. A rögzítés feloldásához tartsa egyszerre lenyomva a Vissza és az Áttekintés lehetőséget."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Megjelenítve tartja addig, amíg Ön fel nem oldja a rögzítést. A feloldáshoz tartsa lenyomva az Áttekintés lehetőséget."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás kezeli a hangerőt"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Érintse meg az eredeti érték visszaállításához."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"A munkaprofilt használja"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 6162ed4..4ccc304 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Որոնել"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Ֆոտոխցիկ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Հեռախոս"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ձայնային հուշումներ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ապակողպել"</string>
<string name="unlock_label" msgid="8779712358041029439">"ապակողպել"</string>
<string name="phone_label" msgid="2320074140205331708">"բացել հեռախոսը"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"բացեք ձայնային հուշումը"</string>
<string name="camera_label" msgid="7261107956054836961">"բացել ֆոտոխցիկը"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Ընտրել առաջադրանքի նոր դասավորություն"</string>
<string name="cancel" msgid="6442560571259935130">"Չեղարկել"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Պակաս հրատապ ծանուցումները ստորև"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Կրկին հպեք՝ բացելու համար"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Սահեցրեք վերև` ապակողպելու համար"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Սահահարվածեք հեռախոսի պատկերակից"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Սահահարվածեք ձայնային հուշման պատկերակից"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Սահահարվածեք խցիկի պատկերակից"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Ընդհանուր լուռ վիճակը"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Միայն կարևորները"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Միայն զարթուցիչ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Թաքցնել բոլորը"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Ավարտել"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Ընդարձակել"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Կոծկել"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Էկրանն ամրացված է"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար միաժամանակ հպեք և պահեք Համատեսքի և Հետ կոճակները:"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Էկրանը կմնա տեսադաշտում, մինչև այն ապամրացնեք: Ապամրացնելու համար հպեք և պահեք Համատեսքի կոճակը:"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Դիպչեք՝ սկզբնօրինակը վերականգնելու համար:"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Դուք աշխատանքային պրոֆիլում եք"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index c179b84..80d631a 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah dialog volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan aslinya."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Anda berada di Profil kerja"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 6a15a1b..50a7b49 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Leita"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Myndavél"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Sími"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Raddaðstoð"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Taka úr lás"</string>
<string name="unlock_label" msgid="8779712358041029439">"taka úr lás"</string>
<string name="phone_label" msgid="2320074140205331708">"opna síma"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"opna raddaðstoð"</string>
<string name="camera_label" msgid="7261107956054836961">"opna myndavél"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Velja nýtt útlit verkefna"</string>
<string name="cancel" msgid="6442560571259935130">"Hætta við"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Minna áríðandi tilkynningar fyrir neðan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Snertu aftur til að opna"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Strjúktu upp til að opna"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Strjúktu frá tákninu fyrir síma"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Strjúktu frá tákninu fyrir raddaðstoð"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Strjúktu frá tákninu fyrir myndavél"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Algjör þögn"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Aðeins forgangur"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Aðeins vekjarar"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Fela allt"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Hætta núna"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Stækka"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Minnka"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skjárinn er festur"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Þetta heldur þessu opnu þangað til þú losar. Haltu bakk- og yfirlitshnöppunum inni á sama tíma til að losa."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Þetta heldur þessu opnu þangað til þú losar. Haltu yfirlitshnappinum inni til að losa."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er hljóðstyrksvalmyndin"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Snertu til að færa í upprunalegt horf."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Þú ert í vinnusniðinu"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 51b7bcd..339cc8b 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Cerca"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotocamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefono"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Sblocca"</string>
<string name="unlock_label" msgid="8779712358041029439">"sblocca"</string>
<string name="phone_label" msgid="2320074140205331708">"apri telefono"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"apri Voice Assist"</string>
<string name="camera_label" msgid="7261107956054836961">"apri fotocamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Seleziona un nuovo layout per le attività"</string>
<string name="cancel" msgid="6442560571259935130">"Annulla"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notifiche meno urgenti in basso"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tocca di nuovo per aprire"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Scorri verso l\'alto per sbloccare"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Scorri dall\'icona per accedere al telefono"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Scorri dall\'icona per accedere a Voice Assist"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Scorri dall\'icona per accedere alla fotocamera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silenzio totale"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Solo con priorità"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Solo sveglie"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Nascondi tutto"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Termina adesso"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Espandi"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Comprimi"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"La schermata è bloccata"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"La schermata rimane visibile finché la sblocchi. Tocca e tieni premuti contemporaneamente Indietro e Panoramica per sbloccare."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"La schermata rimane visibile finché la sblocchi. Tocca Panoramica e tieni premuto per sbloccare."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> rappresenta la finestra di dialogo relativa al volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tocca per ripristinare l\'originale."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Hai attivato il profilo di lavoro"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 36eb5a7..aaf3fa3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"חפש"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"מצלמה"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"טלפון"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"מסייע קולי"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ביטול נעילה"</string>
<string name="unlock_label" msgid="8779712358041029439">"בטל את הנעילה"</string>
<string name="phone_label" msgid="2320074140205331708">"פתח את הטלפון"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"פתח את המסייע הקולי"</string>
<string name="camera_label" msgid="7261107956054836961">"פתח את המצלמה"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"בחר פריסה חדשה להצגת משימות"</string>
<string name="cancel" msgid="6442560571259935130">"ביטול"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"הודעות בדחיפות נמוכה יותר בהמשך"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"גע שוב כדי לפתוח"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"החלק מעלה כדי לבטל את הנעילה"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"החלק מהסמל להפעלת הטלפון"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"החלק מהסמל להפעלת המסייע הקולי"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"החלק מהסמל להפעלת המצלמה"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"שקט מוחלט"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"עדיפות בלבד"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"התראות בלבד"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"הסתר הכל"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"סיים כעת"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"הרחב"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"כווץ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"המסך מוצמד"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"שומר בתצוגה עד לביטול ההצמדה. גע והחזק בו-זמנית ב\'הקודם\' ו\'סקירה\' כדי לבטל הצמדה."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"שומר בתצוגה עד לביטול ההצמדה. גע והחזק בו-זמנית ב\'הקודם\' ו\'סקירה\' כדי לבטל הצמדה."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"גע כדי לשחזר את עוצמת הקול המקורית."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"אתה נמצא בפרופיל העבודה"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 62baa69..729945d 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"検索"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"カメラ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"音声アシスト"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ロック解除"</string>
<string name="unlock_label" msgid="8779712358041029439">"ロック解除"</string>
<string name="phone_label" msgid="2320074140205331708">"電話を起動"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"音声アシストを開く"</string>
<string name="camera_label" msgid="7261107956054836961">"カメラを起動"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"新しいタスクレイアウトの選択"</string>
<string name="cancel" msgid="6442560571259935130">"キャンセル"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"緊急度の低い通知を下に表示"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"開くにはもう一度タップしてください"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ロック解除するには上にスワイプしてください"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"アイコンからスワイプしてスマートフォンを起動"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"アイコンからスワイプして音声アシストを起動"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"アイコンからスワイプしてカメラを起動"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"サイレント"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"優先する通知のみ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"アラームのみ"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"すべて非表示"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"今すぐ終了"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"折りたたむ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"画面が固定されました"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"固定を解除するまで画面が常に表示されるようになります。[戻る]と[最近]を同時に押し続けると固定が解除されます。"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"固定を解除するまで画面が常に表示されるようになります。[最近]を押し続けると固定が解除されます。"</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"タップすると元の音量ダイアログが復元されます。"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"仕事用プロファイルを使用しています"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 5fc889e..de41277 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ხმოვან დიალოგშია"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ორიგინალის აღდგენისათვის, შეეხეთ."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"თქვენ სამუშაო პროფილში ხართ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index cb9c7ab..6338b12 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Іздеу"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дауыс көмекшісі"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Бекітпесін ашу"</string>
<string name="unlock_label" msgid="8779712358041029439">"бекітпесін ашу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонды ашу"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ашық дауыс көмекшісі"</string>
<string name="camera_label" msgid="7261107956054836961">"камераны ашу"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Жаңа тапсырма пішімін таңдау"</string>
<string name="cancel" msgid="6442560571259935130">"Бас тарту"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Шұғылдығы азырақ хабарландырулар төменде"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ашу үшін қайтадан түртіңіз"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Бекітпесін ашу үшін жанаңыз"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Белгішеден телефонға қарай сырғытыңыз"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Дауыс көмекшісі үшін белгішеден сырғытыңыз"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Белгішеден камераға қарай сырғытыңыз"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Толық тыныштық"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Тек басымдық"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Тек дабылдар"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Барлығын жасыру"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Қазір өшіру"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Кеңейту"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Тасалау"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Экран түйрелді"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Бұл сіз оны босатқанша оны көрсетіп тұрады. Босату үшін «Кері» және «Шолу» түймелерін бір уақытта басып тұрыңыз."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Бұл сіз оны босатқанша оны көрсетіп тұрады. Босату үшін «Шолу» түймесін бір уақытта басып тұрыңыз."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнұсқаны қалпына келтіру үшін түртіңіз."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Жұмыс профиліндесіз"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 9c7bdaa..97c2fae 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ស្វែងរក"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ម៉ាស៊ីនថត"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ទូរស័ព្ទ"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ជំនួយសំឡេង"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ដោះសោ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ដោះសោ"</string>
<string name="phone_label" msgid="2320074140205331708">"បើកទូរស័ព្ទ"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"បើកជំនួយសំឡេង"</string>
<string name="camera_label" msgid="7261107956054836961">"បើកម៉ាស៊ីនថត"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"ជ្រើសប្លង់ភារកិច្ចថ្មី"</string>
<string name="cancel" msgid="6442560571259935130">"បោះបង់"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ការជូនដំណឹងមិនសូវបន្ទាន់ខាងក្រោម"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ប៉ះម្ដងទៀតដើម្បីបើក"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"អូសឡើងលើ ដើម្បីដោះសោ"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"អូសចេញពីរូបតំណាងដើម្បីប្រើទូរស័ព្ទ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"អូសចេញពីរូបតំណាងដើម្បីប្រើជំនួយសំឡេង"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"អូសចេញពីរូបតំណាងដើម្បីប្រើកាមេរ៉ា"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"ស្ងៀមស្ងាត់ទាំងស្រុង"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"អាទិភាពប៉ុណ្ណោះ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"សំឡេងរោទ៍ប៉ុណ្ណោះ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"លាក់ទាំងអស់"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"បញ្ចប់ឥឡូវនេះ"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"ពង្រីក"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"បង្រួម"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"អេក្រង់ត្រូវបានភ្ជាប់"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"រក្សាទុកវាក្នុងទិដ្ឋភាពរហូតដល់អ្នកផ្ដាច់។ ប៉ះ ហើយសង្កត់ថយក្រោយ និងទិដ្ឋភាពនៅពេលតែមួយដើម្បីផ្ដាច់។"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"វារក្សាទុកក្នុងទិដ្ឋភាពរហូតដល់អ្នកផ្ដាច់។ ប៉ះ និងសង្កត់ទិដ្ឋភាពដើម្បីផ្ដាច់។"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ប៉ះដើម្បីស្តារច្បាប់ដើម។"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"អ្នកកំពុងនៅក្នុងប្រវត្តិរូបការងារ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 3c12cde..9580004 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ಹುಡುಕು"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ಕ್ಯಾಮರಾ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ಫೋನ್"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ಅನ್ಲಾಕ್"</string>
<string name="unlock_label" msgid="8779712358041029439">"ಅನ್ಲಾಕ್ ಮಾಡು"</string>
<string name="phone_label" msgid="2320074140205331708">"ಫೋನ್ ತೆರೆಯಿರಿ"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ಧ್ವನಿ ಸಹಾಯಕವನ್ನು ತೆರೆ"</string>
<string name="camera_label" msgid="7261107956054836961">"ಕ್ಯಾಮರಾ ತೆರೆಯಿರಿ"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"ಹೊಸ ಕಾರ್ಯ ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="cancel" msgid="6442560571259935130">"ರದ್ದುಮಾಡು"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ಕೆಳಗೆ ಕಡಿಮೆ ಅವಸರದ ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ತೆರೆಯಲು ಮತ್ತೊಮ್ಮೆ ಸ್ಪರ್ಶಿಸಿ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಸ್ವೈಪ್ ಮಾಡಿ"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ಫೋನ್ಗಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"ಧ್ವನಿ ಸಹಾಯಕ್ಕಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ಕ್ಯಾಮರಾಗಾಗಿ ಐಕಾನ್ನಿಂದ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"ಸಂಪೂರ್ಣ ನಿಶ್ಯಬ್ಧ"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ಆದ್ಯತೆ ಮಾತ್ರ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"ಅಲಾರಮ್ಗಳು ಮಾತ್ರ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"ಎಲ್ಲ ಮರೆಮಾಡಿ"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ಈಗಲೇ ಅಂತ್ಯಗೊಳಿಸು"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"ವಿಸ್ತರಿಸು"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ಸಂಕುಚಿಸು"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"ಪರದೆಯನ್ನು ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"ನೀವು ಅನ್ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್ಪಿನ್ ಮಾಡಲು ಒಂದೇ ಸಮಯದಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ ಹಾಗೂ ಅವಲೋಕಿಸಿ."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ನೀವು ಅನ್ಪಿನ್ ಮಾಡುವವರೆಗೆ ಅದನ್ನು ವೀಕ್ಷಣೆಯಲ್ಲಿಡುತ್ತದೆ. ಅನ್ಪಿನ್ ಮಾಡಲು ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ಮೂಲ ಮರುಸ್ಥಾಪಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"ನೀವು ಕೆಲಸದ ಪ್ರೊಫೈಲ್ನಲ್ಲಿರುವಿರಿ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index dc717ec..45dc188 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"검색"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"카메라"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"전화"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"음성 지원"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"잠금 해제"</string>
<string name="unlock_label" msgid="8779712358041029439">"잠금 해제"</string>
<string name="phone_label" msgid="2320074140205331708">"휴대전화 열기"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"음성 지원 열기"</string>
<string name="camera_label" msgid="7261107956054836961">"카메라 열기"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"새 작업 레이아웃 선택"</string>
<string name="cancel" msgid="6442560571259935130">"취소"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"아래에 덜 급한 알림 표시"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"다시 터치하여 열기"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"위로 스와이프하여 잠금 해제"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"전화 기능을 사용하려면 아이콘에서 스와이프하세요."</string>
+ <string name="voice_hint" msgid="8939888732119726665">"음성 지원을 사용하려면 아이콘에서 스와이프하세요."</string>
+ <string name="camera_hint" msgid="7939688436797157483">"카메라를 사용하려면 아이콘에서 스와이프하세요."</string>
<string name="interruption_level_none" msgid="6000083681244492992">"모두 차단"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"중요 알림만"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"알람만 수신"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"모두 숨기기"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"지금 종료"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"펼치기"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"접기"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"화면 고정됨"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"고정 해제하기 전까지 계속 표시됩니다. 고정 해제하려면 뒤로와 최근 사용을 동시에 길게 터치합니다."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"고정 해제하기 전까지 계속 표시됩니다. 고정 해제하려면 최근 사용을 길게 터치합니다."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"원본을 복원하려면 터치하세요."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"현재 직장 프로필에 있음"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index c695314..be7c5770 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -107,13 +107,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Издөө"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Үн жардамчысы"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Кулпусун ачуу"</string>
<string name="unlock_label" msgid="8779712358041029439">"кулпуну ачуу"</string>
<string name="phone_label" msgid="2320074140205331708">"телефонду ачуу"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"үн жардамчысысын ачуу"</string>
<string name="camera_label" msgid="7261107956054836961">"камераны ачуу"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Жаңы тапшырманын планын тандаңыз"</string>
<!-- no translation found for cancel (6442560571259935130) -->
@@ -341,12 +339,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Анчейин шашылыш эмес эскертмелер төмөндө"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Ачуу үчүн кайра тийиңиз"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Кулпуну ачуу үчүн серпип коюңуз"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Сүрөтчөнү серпип телефонго өтүңүз"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Сүрөтчөнү серпип үн жардамчысына өтүңүз"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Сүрөтчөнү серпип камерага өтүңүз"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Тымтырс"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Артыкчылык гана"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Ойготкучтар гана"</string>
@@ -410,10 +405,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Баарын жашыруу"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Азыр бүтүрүү"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Жайып көрсөтүү"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Жыйнап коюу"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Экран кадалган"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Бул бошотулмайынча көрүнө берет. Бошотуу үчүн, бир убакта Артка жана Карап чыгууну коё бербей басып туруңуз."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Бул бошотулмайынча көрүнө берет. Бошотуу үчүн, Карап чыгууну коё бербей басып туруңуз."</string>
@@ -428,4 +421,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> үндү катуулатуу диалогу"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Түпнусканы калыбына келтирүү үчүн тийип коюңуз."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Сиз Жумуш профилиндесиз"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index dcae291..63d569c 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ຊອກຫາ"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ກ້ອງ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ໂທລະສັບ"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ຊ່ວຍເຫຼືອທາງສຽງ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ປົດລັອກ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ປົດລັອກ"</string>
<string name="phone_label" msgid="2320074140205331708">"ເປີດແປ້ນໂທລະສັບ"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"ຊ່ວເຫຼືອເປີດສຽງ"</string>
<string name="camera_label" msgid="7261107956054836961">"ເປີດກ້ອງ"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"ເລືອກແຜນຜັງໜ້າວຽກໃໝ່"</string>
<string name="cancel" msgid="6442560571259935130">"ຍົກເລີກ"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ການແຈ້ງເຕືອນທີ່ສຳຄັນໜ້ອຍກວ່າຢູ່ດ້ານລຸ່ມ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ແຕະອີກເທື່ອນຶ່ງເພື່ອເປີດ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ເລື່ອນຂຶ້ນເພື່ອປົດລັອກ"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ປັດຈາກໄອຄອນສຳລັບໂທລະສັບ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"ປັດຈາກໄອຄອນສຳລັບການຊ່ວຍທາງສຽງ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ປັດຈາກໄອຄອນສຳລັບກ້ອງຖ່າຍຮູບ"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"ຄວາມງຽບທັງໝົດ"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ບຸລິມະສິດເທົ່ານັ້ນ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"ໂມງປຸກເທົ່ານັ້ນ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"ເຊື່ອງທັງຫມົດ"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ຢຸດດຽວນີ້"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"ຂະຫຍາຍ"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ຫຍໍ້ລົງ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"ມັນຈະຮັກສາໜ້າຈໍໄວ້ໃນມຸມມອງຂອງທ່ານຈົນກວ່າທ່ານຈະຖອດໝຸດ. ແຕະປຸ່ມ ກັບຄືນ ແລະ ພາບຮວມ ຄ້າງໄວ້ພ້ອມກັນເພື່ອຖອດໝຸດ."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ມັນຈະຮັກສາໜ້າຈໍໄວ້ໃນມຸມມອງຂອງທ່ານຈົນກວ່າທ່ານຈະຖອດໝຸດ. ແຕະປຸ່ມ ພາບຮວມ ຄ້າງໄວ້ເພື່ອຖອດໝຸດ."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນໜ້າຕ່າງລະດັບສຽງ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ສໍາຜັດເພື່ອກູ້ຄືນຕົ້ນສະບັບ."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"ທ່ານຢູ່ໃນໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 31dd582f..d8106b2 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Ieškoti"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparatas"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonas"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atrakinti"</string>
<string name="unlock_label" msgid="8779712358041029439">"atrakinti"</string>
<string name="phone_label" msgid="2320074140205331708">"atidaryti telefoną"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"atidaryti „Voice Assist“"</string>
<string name="camera_label" msgid="7261107956054836961">"atidaryti fotoaparatą"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Pasirinkti naują užduoties išdėstymą"</string>
<string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mažiau skubūs pranešimai toliau"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Palieskite dar kartą, kad atidarytumėte"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Perbraukite aukštyn, kad atrakintumėte"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Perbraukite iš telefono piktogramos"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Perbraukite iš „Voice Assist“ piktogramos"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Perbraukite iš fotoaparato piktogramos"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Visiška tyla"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Tik prioritetiniai"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Tik signalai"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Slėpti viską"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Baigti dabar"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Išskleisti"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sutraukti"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekranas prisegtas"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Tai bus rodoma, kol atsegsite. Kad atsegtumėte, tuo pačiu metu palieskite ir laikykite „Atgal“ ir „Apžvalga“."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Tai bus rodoma, kol atsegsite. Kad atsegtumėte, palieskite ir laikykite „Apžvalga“."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra garsumo valdymo dialogo langas"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Palieskite, kad atkurtumėte originalą."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Naudojate „Work“ profilį"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 7a2679f..a941359 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -84,13 +84,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Meklēt"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Tālruņa numurs"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Balss palīgs"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Atbloķēt"</string>
<string name="unlock_label" msgid="8779712358041029439">"atbloķēt"</string>
<string name="phone_label" msgid="2320074140205331708">"atvērt tālruni"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"atvērt balss palīgu"</string>
<string name="camera_label" msgid="7261107956054836961">"atvērt kameru"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Atlasiet jaunu uzdevumu izkārtojumu"</string>
<string name="cancel" msgid="6442560571259935130">"Atcelt"</string>
@@ -317,12 +315,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mazāk steidzami paziņojumi tiek rādīti tālāk"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Pieskarieties vēlreiz, lai atvērtu."</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Velciet uz augšu, lai atbloķētu"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Lai lietotu tālruni, velciet no ikonas"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Lai lietotu balss palīgu, velciet no ikonas"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Lai lietotu kameru, velciet no ikonas"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Pilnīgs klusums"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Tikai prioritārie"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Tikai signāli"</string>
@@ -386,10 +381,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Slēpt visus"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Izslēgt"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Izvērst"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Sakļaut"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekrāns ir piesprausts"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, vienlaikus pieskarieties vienumiem “Atpakaļ” un “Pārskats” un turiet tos nospiestus."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Šādi tas būs redzams līdz brīdim, kad to atspraudīsiet. Lai atspraustu, pieskarieties vienumam “Pārskats” un turiet to nospiestu."</string>
@@ -404,4 +397,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ir skaļuma dialoglodziņš"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Pieskarieties, lai atjaunotu sākotnējo."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Jūs esat pierakstījies darba profilā."</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index b8df531..276d771 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Пребарај"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Фотоапарат"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помош"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Отклучување"</string>
<string name="unlock_label" msgid="8779712358041029439">"отклучи"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовна помош"</string>
<string name="camera_label" msgid="7261107956054836961">"отвори камера"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Изберете нов распоред на задача"</string>
<string name="cancel" msgid="6442560571259935130">"Откажи"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Долу се помалку итни известувања"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Допрете повторно за да отворите"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Повлечете за да се отклучи"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Повлечете од иконата за телефонот"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Повлечете од иконата за гласовна помош"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Повлечете од иконата за камерата"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Целосна тишина"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Само приоритетно"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Само аларми"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Сокриј ги сите"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Заврши сега"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Собери"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Екранот е прикачен"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Ќе се гледа сè додека не го откачите. Допрете и држете Назад и Краток преглед истовремено за откачување."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ќе се гледа сè додека не го откачите. Допрете и држете Краток преглед за откачување."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> е дијалог за јачина на звук"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Допрете за да го вратите оригиналот."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Вие сте во работен профил"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 615b1e2..612ca16 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"തിരയൽ"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ക്യാമറ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ഫോണ്"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"വോയ്സ് സഹായം"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"അണ്ലോക്ക് ചെയ്യുക"</string>
<string name="unlock_label" msgid="8779712358041029439">"അൺലോക്കുചെയ്യുക"</string>
<string name="phone_label" msgid="2320074140205331708">"ഫോൺ തുറക്കുക"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"വോയ്സ് അസിസ്റ്റ് തുറക്കുക"</string>
<string name="camera_label" msgid="7261107956054836961">"ക്യാമറ തുറക്കുക"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"പുതിയ ടാസ്ക് ലേഔട്ട് തിരഞ്ഞെടുക്കുക"</string>
<string name="cancel" msgid="6442560571259935130">"റദ്ദാക്കുക"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"ആവശ്യം കുറഞ്ഞ അറിയിപ്പുകൾ ചുവടെ നൽകിയിരിക്കുന്നു"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"തുറക്കുന്നതിന് വീണ്ടും സ്പർശിക്കുക"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"അൺലോക്കുചെയ്യുന്നതിന് മുകളിലേക്ക് സ്വൈപ്പുചെയ്യുക"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ഫോണിനായുള്ള ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"വോയ്സ് അസിസ്റ്റിനായുള്ള ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ക്യാമറയ്ക്കായുള്ള ഐക്കണിൽ നിന്ന് സ്വൈപ്പുചെയ്യുക"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"പൂർണ്ണ നിശബ്ദത"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"മുൻഗണന മാത്രം"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"അലാറങ്ങൾ മാത്രം"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"എല്ലാം മറയ്ക്കുക"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ഇപ്പോള് അവസാനിപ്പിക്കുക"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"വികസിപ്പിക്കുക"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ചുരുക്കുക"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"സ്ക്രീൻ പിൻ ചെയ്തു"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തുന്നു. അൺപിൻ ചെയ്യാൻ \'മടങ്ങുക\', \'ചുരുക്കവിവരണം\' എന്നിവ ഒരേ സമയം സ്പർശിച്ച് പിടിക്കുക."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"നിങ്ങൾ അൺപിൻ ചെയ്യുന്നതുവരെ ഇത് കാണുന്ന വിധത്തിൽ നിലനിർത്തുന്നു. അൺപിൻ ചെയ്യുന്നതിന് \'ചുരുക്കവിവരണം\' സ്പർശിച്ചുപിടിക്കുക."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ആദ്യത്തേത് പുനഃസ്ഥാപിക്കാൻ സ്പർശിക്കുക."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"നിങ്ങൾ ഔദ്യോഗിക പ്രൊഫൈലിൽ ആണ്"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index e2bfc8d..72a0aba 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -81,13 +81,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Хайх"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камер"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Утас"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Дуут туслах"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Тайлах"</string>
<string name="unlock_label" msgid="8779712358041029439">"тайлах"</string>
<string name="phone_label" msgid="2320074140205331708">"утас нээх"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"нээлттэй дуут туслах"</string>
<string name="camera_label" msgid="7261107956054836961">"камер нээх"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Шинэ ажиллах талбарыг сонгоно уу"</string>
<string name="cancel" msgid="6442560571259935130">"Цуцлах"</string>
@@ -314,12 +312,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Яаралтай биш мэдэгдлүүдийг доор"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Нээхийн тулд дахин хүрнэ үү"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Түгжээг тайлах бол шудрана уу"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Утсыг гаргахын тулд тэмдгээс шудрах"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Дуут туслахыг нээхийн тулд тэмдгээс шудрах"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Камер нээхийн тулд тэмдгээс шудрах"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Дуугүй болгох"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Зөвхөн чухал зүйлс"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Зөвхөн сэрүүлэг"</string>
@@ -383,10 +378,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Бүгдийг нуух"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Одоо дуусгах"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Дэлгэх"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Хумих"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Дэлгэц эхэнд байрлуулагдсан"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Таныг эхэнд нээхийг болиулах хүртэл харагдана. Хүрээд, Back дээр удаан дараад хаахдаа Overview-ийг дар"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Таныг эхэнд нээхийг болиулах хүртэл харагдана. Хаахын тулд хүрээдOverview-ийг дар"</string>
@@ -401,4 +394,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Анхны хувилбарыг эргүүлэн хадгалахыг хүсвэл хүрнэ үү."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Та Work профайлд байна"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index b3ea98f..27abc4411 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"शोधा"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"कॅमेरा"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"व्हॉइस सहाय्य"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"अनलॉक करा"</string>
<string name="unlock_label" msgid="8779712358041029439">"अनलॉक करा"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन उघडा"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"व्हॉइस सहाय्य उघडा"</string>
<string name="camera_label" msgid="7261107956054836961">"कॅमेरा उघडा"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"नवीन कार्य लेआउट निवडा"</string>
<string name="cancel" msgid="6442560571259935130">"रद्द करा"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"खाली कमी तातडीच्या सूचना"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"उघडण्यासाठी पुन्हा स्पर्श करा"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"अनलॉक करण्यासाठी स्वाइप करा"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"फोनसाठी चिन्हावरून स्वाइप करा"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"व्हॉइस सहाय्यासाठी चिन्हावरून स्वाइप करा"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"कॅमेर्यासाठी चिन्हावरून स्वाइप करा"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"संपूर्ण शांतता"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"केवळ प्राधान्य"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"केवळ अलार्म"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"सर्व लपवा"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"आता समाप्त करा"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तृत करा"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संकुचित करा"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"स्क्रीन पिन केलेली आहे"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"हे आपण अनपिन करेपर्यंत दृश्यामध्ये ते ठेवते. अनपिन करण्यासाठी एकाच वेळी परत आणि अलीकडील ला स्पर्श करा आणि धरून ठेवा आणि विहंगावलोकन करा."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"हे आपण अनपिन करेपर्यंत दृश्यामध्ये ते ठेवते. अनपिन करण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा व्हॉल्यूम संवाद आहे"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूळ पुनर्संचयित करण्यासाठी स्पर्श करा."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"आपण कार्य प्रोफाईल मध्ये आहात"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 2a84991..2336643 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Cari"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Bantuan Suara"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Buka kunci"</string>
<string name="unlock_label" msgid="8779712358041029439">"buka kunci"</string>
<string name="phone_label" msgid="2320074140205331708">"buka telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"buka bantuan suara"</string>
<string name="camera_label" msgid="7261107956054836961">"buka kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Pilih reka letak tugas baharu"</string>
<string name="cancel" msgid="6442560571259935130">"Batal"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Pemberitahuan kurang penting di bawah"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Sentuh sekali lagi untuk membuka"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Leret ke atas untuk membuka kunci"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Leret dari ikon untuk telefon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Leret dari ikon untuk bantuan suara"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Leret dari ikon untuk kamera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Senyap sepenuhnya"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Keutamaan sahaja"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Penggera sahaja"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Sembunyikan semua"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Tamatkan sekarang"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Kembangkan"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Runtuhkan"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skrin telah disemat"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Ini akan memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh dan tahan Kembali dan Gambaran Keseluruhan pada masa yang sama untuk menyahsemat."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ini akan memastikan skrin kelihatan sehingga anda menyahsemat. Sentuh dan tahan Gambaran Keseluruhan untuk menyahsemat."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah dialog kelantangan"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Sentuh untuk memulihkan yang asal."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Anda berada dalam profil Kerja"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 4e77360..45753dc 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ရှာဖွေရန်"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ကင်မရာ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ဖုန်း"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"အသံ အကူအညီ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"သော့ဖွင့်ရန်"</string>
<string name="unlock_label" msgid="8779712358041029439">"သော့ဖွင့်ရန်"</string>
<string name="phone_label" msgid="2320074140205331708">"ဖုန်းကို ဖွင့်ရန်"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
<string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"အလုပ်သစ်စီစဥ်မှုကို ရွေးပါ။"</string>
<string name="cancel" msgid="6442560571259935130">"ထားတော့"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"အရေးပါမှု နည်းသည့် အကြောင်းကြားချက်များ အောက်မှာ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ဖွင့်ရန် ထပ်ပြီး ထိပါ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"သော့ဖွင့်ရန် အပေါ်သို့ ပွတ်ဆွဲပါ"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ဖုန်းအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"အသံအကူအညီအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ကင်မရာအတွက် သင်္ကေတပုံအား ပွတ်ဆွဲပါ"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"လုံးဝ တိတ်ဆိတ်ခြင်း"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ဦးစားပေးများသာ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"နှိုးစက်များသာ"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"အားလုံး ဝှက်ထားရန်"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>။ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ယခု အဆုံးသတ်ရန်"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"တိုးချဲ့ရန်"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ခေါက်သိမ်းရန်..."</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"မျက်နှာပြင် ပင်ထိုးပြီးပါပြီ"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"သင်ပင်ဖြုတ်သည့် တိုင်အောင် ၎င်းအား မြင်ကွင်းတွင် ထားရှိပါမည်။ ပင်ဖြုတ်ရန် အနောက်နှင့် ခြုံငုံကြည့်ခြင်းကို ဖိ၍ နှိပ်ထားနိုင်သည်။"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"သင်ပင်ဖြုတ်သည့် တိုင်အောင် ၎င်းအား မြင်ကွင်းတွင် ထားရှိပါမည်။ ပင်ဖြုတ်ရန် ခြုံငုံကြည့်ခြင်းကို ဖိ၍ နှိပ်ထားနိုင်သည်။"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အသံဒိုင်ယာလော့ခ်ဖြစ်သည်"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"မူရင်းအားပြန်လည်သိမ်းဆည်းရန် ထိပါ။"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"သင်သည် အလုပ်ပရိုဖိုင်တွင် ဖြစ်သည်"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 675fc39..9e18705 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Søk"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonnummer"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Talehjelp"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås opp"</string>
<string name="unlock_label" msgid="8779712358041029439">"lås opp"</string>
<string name="phone_label" msgid="2320074140205331708">"åpne telefonen"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"åpne talehjelp"</string>
<string name="camera_label" msgid="7261107956054836961">"åpne kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Velg en ny utforming for oppgaver"</string>
<string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre presserende varsler nedenfor"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Trykk på nytt for å åpne"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Sveip oppover for å låse opp"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Sveip fra ikonet for å åpne telefonen"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Sveip fra ikonet for å åpne talehjelp"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Sveip fra ikonet for å åpne kameraet"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Total stillhet"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Bare prioritet"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Bare alarmer"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skjul alle"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Avslutt nå"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utvid"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Skjul"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skjermen er låst"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk på og hold inne Tilbake og Oversikt samtidig for å låse opp."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk på og hold inne Tilbake og Oversikt for å låse opp."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> er volumdialogen"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Trykk for å gå tilbake til den opprinnelige volumdialogen."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Du er i Work-profilen"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index 6860d78..e3ea513 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"खोज्नुहोस्"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"क्यामेरा"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"फोन"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"सहयोगी आवाज"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"खोल्नुहोस्"</string>
<string name="unlock_label" msgid="8779712358041029439">"खोल्नुहोस्"</string>
<string name="phone_label" msgid="2320074140205331708">"फोन खोल्नुहोस्"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"सहयोगी आवाज खोल्नुहोस्"</string>
<string name="camera_label" msgid="7261107956054836961">"क्यामेरा खोल्नुहोस्"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"नयाँ कार्य लेआउट चयन गर्नुहोस्"</string>
<string name="cancel" msgid="6442560571259935130">"रद्द गर्नुहोस्"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"तल कम जरुरी सूचनाहरू"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"खोल्न फेरि छुनुहोस्"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"अनलक गर्न स्वाप गर्नुहोस्"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"फोनको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"सहयोगी आवाजका लागि आइकन बाट स्वाइप गर्नुहोस्"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"क्यामेराको लागि आइकनबाट स्वाइप गर्नुहोस्"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"पूरै शान्त"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"प्राथमिकता मात्र"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"अलार्महरू मात्र"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"सबै लुकाउनुहोस्"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"अहिल्यै अन्त्य गर्नुहोस्"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"विस्तार गर्नुहोस्"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"संक्षिप्त पार्नुहोस्"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"पर्दा राखेका छ"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन फिर्ता र सिंहावलोकन नै समय मा पकड।"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"तपाईं अनपिन सम्म यो दृश्य मा राख्छ। छुनुहोस् र अनपिन गर्न सिंहावलोकन पकड।"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> भोल्यूम संवाद हो"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"मूल पुनर्स्थापना गर्न छुनुहोस्।"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"तपाईँ कार्य प्रोफाइलमा हुनुहुन्छ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 937ac34..34616c8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Zoeken"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Spraakassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Ontgrendelen"</string>
<string name="unlock_label" msgid="8779712358041029439">"ontgrendelen"</string>
<string name="phone_label" msgid="2320074140205331708">"telefoon openen"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"spraakassistent openen"</string>
<string name="camera_label" msgid="7261107956054836961">"camera openen"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Nieuwe taakindeling selecteren"</string>
<string name="cancel" msgid="6442560571259935130">"Annuleren"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Minder urgente meldingen onderaan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Raak opnieuw aan om te openen"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Veeg omhoog om te ontgrendelen"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Vegen vanaf pictogram voor telefoon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Vegen vanaf pictogram voor spraakassistent"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Vegen vanaf pictogram voor camera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Totale stilte"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Alleen prioriteit"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Alleen alarmen"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Alles verbergen"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Nu uitschakelen"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Uitvouwen"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Samenvouwen"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Scherm is vastgezet"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Het scherm blijft zichtbaar totdat u het u losmaakt. Houd \'Terug\' en \'Overzicht\' tegelijkertijd aangeraakt om het los te maken."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Het scherm blijft zichtbaar totdat u het u losmaakt. Houd \'Overzicht\' aangeraakt om het los te maken."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> is het volumedialoogvenster"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tik hierop om het origineel te herstellen."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"U bevindt zich in het werkprofiel"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index 723a4d4..f082631 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -83,9 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ਖੋਜੋ"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"ਕੈਮਰਾ"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ਫੋਨ"</string>
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ਵੌਇਸ ਅਸਿਸਟ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ਅਨਲੌਕ ਕਰੋ"</string>
<string name="unlock_label" msgid="8779712358041029439">"ਅਨਲੌਕ ਕਰੋ"</string>
<string name="phone_label" msgid="2320074140205331708">"ਫੋਨ ਖੋਲ੍ਹੋ"</string>
+ <string name="voice_assist_label" msgid="3956854378310019854">"ਵੌਇਸ ਅਸਿਸਟ ਖੋਲ੍ਹੋ"</string>
<string name="camera_label" msgid="7261107956054836961">"ਕੈਮਰਾ ਖੋਲ੍ਹੋ"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"ਨਵਾਂ ਕੰਮ ਲੇਆਉਟ ਚੁਣੋ"</string>
<string name="cancel" msgid="6442560571259935130">"ਰੱਦ ਕਰੋ"</string>
@@ -121,6 +123,8 @@
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ਦੋ ਬਾਰਸ।"</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ਤਿੰਨ ਬਾਰਸ।"</string>
<string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX ਸਿਗਨਲ ਪੂਰਾ।"</string>
+ <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"ਈਥਰਨੈੱਟ ਡਿਸਕਨੈਕਟ ਹੋ ਗਿਆ।"</string>
+ <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"ਈਥਰਨੈੱਟ ਕਨੈਕਟ ਹੋ ਗਿਆ।"</string>
<string name="accessibility_no_signal" msgid="7064645320782585167">"ਕੋਈ ਸਿਗਨਲ ਨਹੀਂ।"</string>
<string name="accessibility_not_connected" msgid="6395326276213402883">"ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ।"</string>
<string name="accessibility_zero_bars" msgid="3806060224467027887">"ਸਿਫ਼ਰ ਬਾਰਸ।"</string>
@@ -162,13 +166,14 @@
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ਰੱਦ ਕੀਤਾ।"</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ਸਾਰੀਆਂ ਹਾਲੀਆ ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੱਦ ਕੀਤੀਆਂ।"</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string>
+ <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"ਸੂਚਨਾ ਰੱਦ ਕੀਤੀ।"</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"ਸੂਚਨਾ ਸ਼ੇਡ।"</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ।"</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ਲੌਕ ਸਕ੍ਰੀਨ।"</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"ਸੈਟਿੰਗਾਂ"</string>
<string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ਰੂਪ-ਰੇਖਾ।"</string>
- <string name="accessibility_desc_confirm" msgid="3446792278337969766">"ਪੁਸ਼ਟੀ ਕਰੋ"</string>
+ <string name="accessibility_desc_close" msgid="7479755364962766729">"ਬੰਦ ਕਰੋ"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ਉਪਭੋਗਤਾ <xliff:g id="USER">%s</xliff:g>।"</string>
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi ਬੰਦ ਕੀਤਾ।"</string>
@@ -180,7 +185,7 @@
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"ਏਅਰਪਲੇਨ ਮੋਡ ਬੰਦ ਹੈ।"</string>
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"ਏਅਰਪਲੇਨ ਮੋਡ ਚਾਲੂ ਹੋਇਆ"</string>
<string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ, ਕੇਵਲ ਤਰਜੀਹੀ।"</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="5910777408232088752">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ, ਕੋਈ ਰੁਕਾਵਟਾਂ ਨਹੀਂ।"</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ ਕਰੋ, ਕੁਲ ਚੁੱਪੀ।"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਚਾਲੂ, ਕੇਵਲ ਅਲਾਰਮ।"</string>
<string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਬੰਦ।"</string>
<string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ ਬੰਦ ਕੀਤਾ।"</string>
@@ -235,7 +240,7 @@
<string name="quick_settings_dnd_label" msgid="8735855737575028208">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"ਕੇਵਲ ਤਰਜੀਹੀ"</string>
<string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"ਕੇਵਲ ਅਲਾਰਮ"</string>
- <string name="quick_settings_dnd_none_label" msgid="7309935569360609114">"ਕੋਈ ਰੁਕਾਵਟਾਂ ਨਹੀਂ"</string>
+ <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"ਕੁਲ ਚੁੱਪੀ"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> ਡਿਵਾਈਸਾਂ)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth ਬੰਦ"</string>
@@ -302,26 +307,20 @@
<string name="description_target_search" msgid="3091587249776033139">"ਖੋਜੋ"</string>
<string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਲਈ ਉੱਪਰ ਸਲਾਈਡ ਕਰੋ।"</string>
<string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ਤੱਕ ਖੱਬੇ ਪਾਸੇ ਸਲਾਈਡ ਕਰੋ।"</string>
- <string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"ਕੋਈ ਰੁਕਾਵਟਾਂ ਨਹੀਂ। ਅਲਾਰਮ ਵੀ ਨਹੀਂ।"</string>
- <string name="zen_priority_introduction" msgid="7253045784560169993">"ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਨਿਰਦਿਸ਼ਟ ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਇਵੈਂਟਸ, ਅਤੇ ਕਾਲਰਸ ਤੋਂ ਇਲਾਵਾ, ਧੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਤੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ."</string>
+ <string name="zen_priority_introduction" msgid="3070506961866919502">"ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਦੁਆਰਾ ਨਿਰਦਿਸ਼ਟ ਅਲਾਰਮ, ਰਿਮਾਈਂਡਰ, ਇਵੈਂਟਸ, ਅਤੇ ਕਾਲਰਸ ਤੋਂ ਇਲਾਵਾ, ਧੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਤੋਂ ਪਰੇਸ਼ਾਨ ਨਹੀਂ ਕੀਤਾ ਜਾਵੇਗਾ।"</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"ਅਨੁਕੂਲਿਤ ਕਰੋ"</string>
- <string name="zen_no_interruptions" msgid="7970973750143632592">"ਕੋਈ ਰੁਕਾਵਟਾਂ ਨਹੀਂ"</string>
- <string name="zen_important_interruptions" msgid="3477041776609757628">"ਕੇਵਲ ਤਰਜੀਹ ਰੁਕਾਵਟਾਂ"</string>
- <string name="zen_alarms" msgid="5055668280767657759">"ਕੇਵਲ ਅਲਾਰਮ"</string>
- <string name="zen_alarm_information_time" msgid="5235772206174372272">"ਤੁਹਾਡਾ ਅਗਲਾ ਅਲਾਰਮ <xliff:g id="ALARM_TIME">%s</xliff:g> ਤੇ ਹੈ"</string>
- <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"ਤੁਹਾਡਾ ਅਗਲਾ ਅਲਾਰਮ ਹੈ <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
- <string name="zen_alarm_warning" msgid="6873910860111498041">"ਤੁਸੀਂ <xliff:g id="ALARM_TIME">%s</xliff:g> ਤੇ ਅਲਾਰਮ ਨਹੀਂ ਸੁਣੋਗੇ"</string>
+ <string name="zen_silence_introduction" msgid="575422795504098868">"ਇਹ ਅਲਾਰਮ, ਸੰਗੀਤ, ਵੀਡੀਓਜ਼, ਅਤੇ ਗੇਮਸ ਸਮੇਤ, ਸਾਰੀ ਦੁਨੀ ਅਤੇ ਵਾਇਬ੍ਰੇਸ਼ਨ ਨੂੰ ਬਲੌਕ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਅਜੇ ਵੀ ਫ਼ੋਨ ਕਾਲ ਕਰਨ ਦੇ ਯੋਗ ਹੋਵੋਗੇ।"</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"ਹੇਠਾਂ ਘੱਟ ਲਾਜ਼ਮੀ ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"ਖੋਲ੍ਹਣ ਲਈ ਦੁਬਾਰਾ ਛੋਹਵੋ"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"ਅਨਲੌਕ ਕਰਨ ਲਈ ਉੱਪਰ ਸਵਾਈਪ ਕਰੋ।"</string>
- <string name="phone_hint" msgid="3101468054914424646">"ਫੋਨ ਲਈ ਸੱਜੇ ਪਾਸੇ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="camera_hint" msgid="5241441720959174226">"ਕੈਮਰੇ ਲਈ ਖੱਬੇ ਪਾਸੇ ਸਵਾਈਪ ਕਰੋ"</string>
- <string name="interruption_level_none" msgid="8284541443482072628">"ਕੋਈ ਰੁਕਾਵਟਾਂ ਨਹੀਂ"</string>
+ <string name="phone_hint" msgid="4872890986869209950">"ਫ਼ੋਨ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"ਵੌਇਸ ਅਸਿਸਟ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"ਕੈਮਰੇ ਲਈ ਆਈਕਨ ਤੋਂ ਸਵਾਈਪ ਕਰੋ"</string>
+ <string name="interruption_level_none" msgid="6000083681244492992">"ਕੁਲ ਚੁੱਪੀ"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ਕੇਵਲ ਤਰਜੀਹੀ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"ਕੇਵਲ ਅਲਾਰਮ"</string>
- <string name="interruption_level_all" msgid="1330581184930945764">"ਸਭ"</string>
- <string name="interruption_level_none_twoline" msgid="3942121050170227056">"ਕੋਈ\nਰੁਕਾਵਟਾਂ ਨਹੀਂ"</string>
+ <string name="interruption_level_none_twoline" msgid="3957581548190765889">"ਕੁਲ \n ਚੁੱਪੀ"</string>
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"ਕੇਵਲ\nਤਰਜੀਹੀ"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"ਕੇਵਲ\nਅਲਾਰਮ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ਚਾਰਜਿੰਗ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ਪੂਰਾ ਹੋਣ ਤੱਕ)"</string>
@@ -363,12 +362,15 @@
<string name="disable_vpn" msgid="4435534311510272506">"VPN ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"VPN ਨੂੰ ਡਿਸਕਨੈਕਟ ਕਰੋ"</string>
<string name="monitoring_description_device_owned" msgid="5780988291898461883">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਬੰਧਕ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਸ, ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਜਾਣਕਾਰੀ ਦਾ ਨਿਰੀਖਣ ਅਤੇ ਉਸਨੂੰ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦਾ ਹੈ। ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
- <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"ਤੁਹਾਡੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ <xliff:g id="ORGANIZATION">%1$s</xliff:g>ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਬੰਧਕ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੈ, ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ ਸਮੇਤ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣਾ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਇਸ ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nਤੁਹਾਡੀ ਕੰਮਪ੍ਰੋਫਾਈਲ ਇਸ ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nਤੁਹਾਡਾ ਪ੍ਰਬੰਧਕ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਅਤੇ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ ਜਿਸ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
- <string name="monitoring_description_vpn" msgid="912328761766161919">"ਤੁਸੀਂ ਇੱਕ ਐਪ ਨੂੰ ਇੱਕ VPN ਕਨੈਕਸ਼ਨ ਸੈਟ ਅਪ ਕਰਨ ਦੀ ਅਨੁਮਤੀ ਦਿੱਤੀ ਹੈ।\n\nਇਹ ਐਪ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਅਤੇ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ, ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ ਸਮੇਤ।"</string>
+ <string name="monitoring_description_vpn" msgid="996222259035614736">"ਤੁਸੀਂ ਕਿਸੇ ਐਪ ਨੂੰ ਇੱਕ ਕਨੈਕਸ਼ਨ ਸੈੱਟ ਅੱਪ ਕਰਨ ਦੀ ਅਨੁਮਤੀ ਦਿੱਤੀ ਹੈ।\n\nਇਹ ਐਪ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਆਪਣੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ <xliff:g id="ORGANIZATION">%1$s</xliff:g>ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਪ੍ਰਬੰਧਕ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਸ, ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਜਾਣਕਾਰੀ ਦਾ ਨਿਰੀਖਣ ਅਤੇ ਉਸਨੂੰ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦਾ ਹੈ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਕੀਤਾ ਹੈ, ਜੋ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ, ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਵੈਬਸਾਈਟਾਂ ਸਮੇਤ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"ਤੁਹਾਡੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ <xliff:g id="ORGANIZATION">%1$s</xliff:g>ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਬੰਧਕ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੈ, ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ ਸਮੇਤ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣਾ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਕੀਤਾ ਹੈ, ਜੋ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ।"</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\nਤੁਹਾਡੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਇਸ ਵੱਲੋਂ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nਤੁਹਾਡਾ ਪ੍ਰਬੰਧਕ ਤੁਹਾਡੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰਨ ਵਿੱਚ ਸਮਰੱਥ ਹੈ ਜਿਸ ਵਿੱਚ ਸ਼ਾਮਲ ਹਨ ਈਮੇਲਾਂ, ਐਪਸ ਅਤੇ ਸੁਰੱਖਿਅਤ ਵੈਬਸਾਈਟਾਂ। \n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ ਇੱਕ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਕੀਤਾ ਹੈ, ਜੋ ਤੁਹਾਡੀ ਨਿੱਜੀ ਨੈਟਵਰਕ ਗਤੀਵਿਧੀ ਦਾ ਨਿਰੀਖਣ ਕਰ ਸਕਦਾ ਹੈ"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫ਼ਾਈਲ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਦੁਆਰਾ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਈਮੇਲ, ਐਪਸ, ਅਤੇ ਵੈੱਬਪੰਨੇ ਸੰਤੇ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਨ ਦੇ ਸਮਰੱਥ ਹੈ।\n\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।\n\nਤੁਸੀਂ VPN ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋ, ਜੋ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+ <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+ <string name="monitoring_description_app" msgid="6947928635272782570">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਆਪਣੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_app_personal" msgid="8506133233655324426">"ਤੁਸੀਂ <xliff:g id="APPLICATION">%1$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਆਪਣੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_app_work" msgid="808687576155832307">"ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫ਼ਾਈਲ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਦੁਆਰਾ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਸੀਂ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਆਪਣੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਵਧੇਰੇ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਸ਼ਾਸਕ ਨਾਲ ਸੰਪਰਕ ਕਰੋ।"</string>
+ <string name="monitoring_description_app_personal_work" msgid="7711690793960304868">"ਤੁਹਾਡੀ ਕਾਰਜ ਪ੍ਰੋਫ਼ਾਈਲ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਦੁਆਰਾ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ। ਤੁਸੀਂ <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਆਪਣੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦੀ ਹੈ।\n\nਤੁਸੀਂ <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> ਨਾਲ ਵੀ ਕਨੈਕਟ ਹੋ, ਜੋ ਤੁਹਾਡੀ ਵਿਅਕਤੀਗਤ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰਦੀ ਹੈ।"</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"ਤੁਹਾਡੀ ਡਿਵਾਈਸ <xliff:g id="ORGANIZATION">%1$s</xliff:g> ਦੁਆਰਾ ਵਿਵਸਥਿਤ ਕੀਤੀ ਜਾਂਦੀ ਹੈ।\n\nਪ੍ਰਬੰਧਕ ਸੈਟਿੰਗਾਂ, ਕਾਰਪੋਰੇਟ ਪਹੁੰਚ, ਐਪਸ, ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਨਾਲ ਸੰਬੰਧਿਤ ਡਾਟਾ ਅਤੇ ਤੁਹਾਡੀ ਡਿਵਾਈਸ ਦੀ ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਜਾਣਕਾਰੀ ਦਾ ਨਿਰੀਖਣ ਅਤੇ ਉਸਨੂੰ ਵਿਵਸਥਿਤ ਕਰ ਸਕਦਾ ਹੈ।\n\nਤੁਸੀਂ ਇੱਕ <xliff:g id="APPLICATION">%2$s</xliff:g> ਨਾਲ ਕਨੈਕਟ ਹੋ, ਜੋ ਈਮੇਲ, ਐਪਸ ਅਤੇ ਵੈੱਬਪੰਨੇ ਸਮੇਤ ਤੁਹਾਡੀ ਨੈੱਟਵਰਕ ਗਤੀਵਿਧੀ ਦੀ ਨਿਗਰਾਨੀ ਕਰ ਸਕਦਾ ਹੈ।\n\nਹੋਰ ਜਾਣਕਾਰੀ ਲਈ, ਆਪਣੇ ਪ੍ਰਬੰਧਕ ਨੂੰ ਸੰਪਰਕ ਕਰੋ।"</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"ਡਿਵਾਈਸ ਲੌਕ ਰਹੇਗੀ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਮੈਨੂਅਲੀ ਅਨਲੌਕ ਨਹੀਂ ਕਰਦੇ"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"ਤੇਜ਼ੀ ਨਾਲ ਸੂਚਨਾਵਾਂ ਪ੍ਰਾਪਤ ਕਰੋ"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"ਅਨਲੌਕ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਉਹਨਾਂ ਨੂੰ ਦੇਖੋ"</string>
@@ -377,6 +379,9 @@
<string name="notification_expand_button_text" msgid="1037425494153780718">"ਸਭ ਦੇਖੋ"</string>
<string name="notification_collapse_button_text" msgid="6883253262134328057">"ਸਾਰੇ ਲੁਕਾਓ"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <string name="volume_zen_end_now" msgid="3179845345429841822">"ਹੁਣੇ ਸਮਾਪਤ ਕਰੋ"</string>
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"ਵਿਸਤਾਰ ਕਰੋ"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ਨਸ਼ਟ ਕਰੋ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"ਇਹ ਇਸਨੂੰ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿਨ ਕਰਨ ਲਈ ਪਿੱਛੇ ਅਤੇ ਰੂਪ-ਰੇਖਾ ਨੂੰ ਇੱਕੋ ਸਮੇਂ ਛੋਹਵੋ ਅਤੇ ਹੋਲਡ ਕਰੋ।"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ਇਹ ਇਸਨੂੰ ਦ੍ਰਿਸ਼ ਵਿੱਚ ਰੱਖਦਾ ਹੈ ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਅਨਪਿਨ ਨਹੀਂ ਕਰਦੇ। ਅਨਪਿਨ ਕਰਨ ਲਈ ਰੂਪ-ਰੇਖਾ ਨੂੰ ਛੋਹਵੋ ਅਤੇ ਹੋਲਡ ਕਰੋ।"</string>
@@ -391,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"ਅਸਲੀ ਨੂੰ ਰੀਸਟੋਰ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"ਤੁਸੀਂ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਿੱਚ ਹੋ"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 1acd7b7..e4298e5 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Szukaj"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Aparat"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asystent głosowy"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odblokuj"</string>
<string name="unlock_label" msgid="8779712358041029439">"odblokuj"</string>
<string name="phone_label" msgid="2320074140205331708">"otwórz telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"otwórz pomoc głosową"</string>
<string name="camera_label" msgid="7261107956054836961">"otwórz aparat"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Wybierz nowy układ zadań"</string>
<string name="cancel" msgid="6442560571259935130">"Anuluj"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Poniżej widać mniej pilne powiadomienia"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Kliknij ponownie, by otworzyć"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Przesuń w górę, by odblokować"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Aby włączyć telefon, przesuń palcem od ikony"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Aby uzyskać pomoc głosową, przesuń palcem od ikony"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Aby włączyć aparat, przesuń palcem od ikony"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Całkowita cisza"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Tylko priorytetowe"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Tylko alarmy"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ukrywaj wszystkie"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Zakończ teraz"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozwiń"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zwiń"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekran jest przypięty"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj jednocześnie Wstecz i Przegląd."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ekran będzie widoczny, dopóki go nie odepniesz. Aby to zrobić, kliknij i przytrzymaj Przegląd."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> steruje głośnością"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dotknij, by przywrócić pierwotną."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Korzystasz z profilu do pracy"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 669229e..8f667d4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Pesquisar"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Câmara"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telemóvel"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistente de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir telemóvel"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"abrir assistente de voz"</string>
<string name="camera_label" msgid="7261107956054836961">"abrir câmara"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo esquema de tarefa"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tocar novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslizar rapidamente com o dedo para cima para desbloquear"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Deslize rapid. a partir do ícone para aceder ao telemóvel"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Deslize rapid. a partir do ícone para aceder ao assist. voz"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Deslize rapidamente a partir do ícone para aceder à câmara"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silêncio total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Apenas prioridade"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Apenas alarmes"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar tudo"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Terminar agora"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Reduzir"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"O ecrã está fixado"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Será mantido na vista até soltar. Toque sem soltar em Anterior e Vista geral em simultâneo para soltar."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Será mantido na vista até soltar. Toque sem soltar em Vista geral para soltar."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo do volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Está no Perfil de trabalho"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 995eec4..5dba631 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Pesquisar"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Câmera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefone"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Assistência de voz"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Desbloquear"</string>
<string name="unlock_label" msgid="8779712358041029439">"desbloquear"</string>
<string name="phone_label" msgid="2320074140205331708">"abrir telefone"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"abrir assistência de voz"</string>
<string name="camera_label" msgid="7261107956054836961">"abrir câmera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Selecionar novo layout da tarefa"</string>
<string name="cancel" msgid="6442560571259935130">"Cancelar"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificações menos urgentes abaixo"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Toque novamente para abrir"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Deslize para cima para desbloquear"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Deslize a partir do ícone do telefone"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Deslize a partir do ícone de assistência de voz"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Deslize a partir do ícone da câmera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Silêncio total"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Só prioridade"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Somente alarmes"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ocultar tudo"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Finalizar agora"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Expandir"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Recolher"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"A tela está fixada"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Ela é mantida à vista até que seja liberada. Toque em \"Voltar\" e \"Visão Geral\" e mantenha essas opções pressionadas ao mesmo tempo para liberar."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ela é mantida à vista até que seja liberada. Toque em \"Visão geral\" e mantenha essa opção pressionada para liberar."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> é a caixa de diálogo referente ao volume"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Toque para restaurar o original."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Você está no Perfil de trabalho"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 8046b8a..4ee2692 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -84,13 +84,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Căutați"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Cameră foto"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Asistent vocal"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Deblocați"</string>
<string name="unlock_label" msgid="8779712358041029439">"deblocați"</string>
<string name="phone_label" msgid="2320074140205331708">"deschideți telefonul"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"deschideți asistentul vocal"</string>
<string name="camera_label" msgid="7261107956054836961">"deschideți camera foto"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Selectați noul aspect pentru activitate"</string>
<string name="cancel" msgid="6442560571259935130">"Anulați"</string>
@@ -317,12 +315,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Notificările mai puțin urgente mai jos"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Atingeți din nou pentru a deschide"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Glisați în sus pentru a debloca"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Glisați dinspre pictogramă pentru telefon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Glisați dinspre pictogramă pentru asistentul vocal"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Glisați dinspre pictogramă pentru camera foto"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Niciun sunet"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Numai cu prioritate"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Numai alarme"</string>
@@ -386,10 +381,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ascundeți toate"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Opriți acum"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Extindeți"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Restrângeți"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ecranul este fixat"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Ecranul este afișat până anulați fixarea. Apăsați lung pe Înapoi și pe Vizualizare generală simultan pentru a anula fixarea."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Ecranul este afișat până anulați fixarea. Apăsați lung pe Vizualizare generală pentru a anula fixarea."</string>
@@ -404,4 +397,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> afișează caseta de dialog pentru volum"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Atingeți pentru a reveni la setarea inițială."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Vă aflați în profilul de serviciu"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 08ca544..8881b57 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Поиск"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон."</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Аудиоподсказки"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Разблокировать."</string>
<string name="unlock_label" msgid="8779712358041029439">"Разблокировать."</string>
<string name="phone_label" msgid="2320074140205331708">"Открыть телефон."</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"включить аудиоподсказки"</string>
<string name="camera_label" msgid="7261107956054836961">"Открыть камеру."</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Выберите другой макет"</string>
<string name="cancel" msgid="6442560571259935130">"Отмена"</string>
@@ -320,12 +318,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Показать менее важные оповещения"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Нажмите ещё раз, чтобы открыть"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Проведите вверх, чтобы разблокировать"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Телефон: проведите пальцем в любую сторону от значка"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Аудиоподсказки: проведите пальцем в любую сторону от значка"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Камера: проведите пальцем в любую сторону от значка"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Полная тишина"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Только важные"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Только будильник"</string>
@@ -389,10 +384,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Скрыть все"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>."</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Завершить"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Развернуть"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Свернуть"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Блокировка в приложении включена"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Это приложение останется активным, пока вы не отмените блокировку, одновременно нажав кнопки \"Назад\" и \"Обзор\"."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Приложение останется активным, пока вы не отмените блокировку, одновременно нажав кнопки Назад и Обзор."</string>
@@ -407,4 +400,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> назначено регулятором громкости"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Нажмите, чтобы восстановить приложение по умолчанию."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Вы вошли в профиль Android for Work"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index f3b6d0a..2b34d96 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"මුල් තත්ත්වය නැවත ප්රතිසාධනය කිරීමට ස්පර්ශ කරන්න."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"ඔබ කාර්යාල පැතිකඩේ සිටියි"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index dadf388..08b22db 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Hľadať"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparát"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefón"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Hlasový asistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odomknúť"</string>
<string name="unlock_label" msgid="8779712358041029439">"odomknúť"</string>
<string name="phone_label" msgid="2320074140205331708">"otvoriť telefón"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"otvoriť hlasového asistenta"</string>
<string name="camera_label" msgid="7261107956054836961">"spustiť fotoaparát"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Vyberte nové rozloženie úlohy"</string>
<string name="cancel" msgid="6442560571259935130">"Zrušiť"</string>
@@ -320,12 +318,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Menej naliehavé upozornenia sa nachádzajú nižšie"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Otvorte opätovným klepnutím"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Zariadenie odomknete prejdením prstom nahor"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Telefón otvoríte prejdením prstom od ikony"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Hlasového asistenta otvoríte prejdením prstom od ikony"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Fotoaparát otvoríte prejdením prstom od ikony"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Úplné ticho"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Iba prioritné"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Iba budíky"</string>
@@ -389,10 +384,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skryť všetko"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Skončiť"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Rozbaliť"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Zbaliť"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Obrazovka je pripnutá"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Ak ho chcete uvoľniť, stlačte a podržte súčasne tlačidlá Späť a Prehľad."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Obsah bude pripnutý v zobrazení, dokým ho neuvoľníte. Uvoľníte ho stlačením a podržaním tlačidla Prehľad."</string>
@@ -407,4 +400,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je dialóg hlasitosti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Klepnutím obnovíte originál."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Nachádzate sa v pracovnom profile"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index be3e7be..76e28bb 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Iskanje"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparat"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Glasovni pomočnik"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Odkleni"</string>
<string name="unlock_label" msgid="8779712358041029439">"odkleni"</string>
<string name="phone_label" msgid="2320074140205331708">"odpri telefon"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"odpri glasovnega pomočnika"</string>
<string name="camera_label" msgid="7261107956054836961">"odpri fotoaparat"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Izberite novo postavitev opravil"</string>
<string name="cancel" msgid="6442560571259935130">"Prekliči"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Manj nujna obvestila spodaj"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Dotaknite se znova, če želite odpreti"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Povlecite, da odklenete"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Povlecite z ikone za telefon"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Povlecite z ikone za glasovnega pomočnika"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Povlecite z ikone za fotoaparat"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Popolna tišina"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Samo prednostno"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Samo alarmi"</string>
@@ -371,13 +366,13 @@
<string name="monitoring_description_device_owned" msgid="5780988291898461883">"Napravo upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, podatke, povezane z napravo, in podatke o lokaciji naprave. Če želite več informacij, se obrnite na skrbnika."</string>
<string name="monitoring_description_vpn" msgid="996222259035614736">"Aplikaciji ste dovolili vzpostavitev povezave z omrežjem VPN.\n\nTa aplikacija lahko nadzira napravo in omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
<string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Napravo upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, podatke, povezane z napravo, in podatke o lokaciji naprave.\n\nPovezani ste z omrežjem VPN, ki lahko nadzira vašo omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Delovni profil upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika.\n\nPovezani ste tudi z omrežjem VPN, ki lahko nadzira omrežno dejavnost."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika.\n\nPovezani ste tudi z omrežjem VPN, ki lahko nadzira omrežno dejavnost."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
<string name="monitoring_description_app" msgid="6947928635272782570">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
<string name="monitoring_description_app_personal" msgid="8506133233655324426">"Povezani ste z aplikacijo <xliff:g id="APPLICATION">%1$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti."</string>
- <string name="monitoring_description_app_work" msgid="808687576155832307">"Delovni profil upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
- <string name="monitoring_description_app_personal_work" msgid="7711690793960304868">"Delovni profil upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je z aplikacijo <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nPovezani ste tudi z aplikacijo <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost."</string>
- <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Napravo upravlja: <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, podatke, povezane z napravo, in podatke o lokaciji naprave.\n\nPovezani ste z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
+ <string name="monitoring_description_app_work" msgid="808687576155832307">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
+ <string name="monitoring_description_app_personal_work" msgid="7711690793960304868">"Delovni profil upravlja organizacija <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Povezan je z aplikacijo <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, ki lahko nadzira vašo delovno omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nPovezani ste tudi z aplikacijo <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, ki lahko nadzira vašo osebno omrežno dejavnost."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Napravo upravlja organizcija <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nSkrbnik lahko nadzira in upravlja nastavitve, dostop za podjetje, aplikacije, podatke, povezane z napravo, in podatke o lokaciji naprave.\n\nPovezani ste z aplikacijo <xliff:g id="APPLICATION">%2$s</xliff:g>, ki lahko nadzira omrežno dejavnost, vključno z e-pošto, aplikacijami in spletnimi mesti.\n\nČe želite več informacij, se obrnite na skrbnika."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Naprava bo ostala zaklenjena, dokler je ročno ne odklenete."</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Hitrejše prejemanje obvestil"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Oglejte si jih pred odklepanjem"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Skrij vse"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Končaj zdaj"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Razširi"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Strni"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Zaslon je pripet"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"S tem ostane zaslon v pogledu, dokler ga ne odpnete. Hkrati pridržite tipko za nazaj in tipko za pregled, če ga želite odpeti."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"S tem ostane zaslon v pogledu, dokler ga ne odpnete. Pridržite tipko za pregled, če ga želite odpeti."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pogovorno okno glede prostornine"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Dotaknite se, če želite obnoviti izvirnik."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Ste v profilu za Android Work"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 38fdcfd..b0aa189 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -83,9 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Kërko"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefoni"</string>
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Ndihma zanore"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Shkyç"</string>
<string name="unlock_label" msgid="8779712358041029439">"shkyç"</string>
<string name="phone_label" msgid="2320074140205331708">"hap telefonin"</string>
+ <string name="voice_assist_label" msgid="3956854378310019854">"hap ndihmën zanore"</string>
<string name="camera_label" msgid="7261107956054836961">"hap kamerën"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Zgjidh strukturën e re të detyrës"</string>
<string name="cancel" msgid="6442560571259935130">"Anulo"</string>
@@ -121,6 +123,8 @@
<string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"WiMAX ka dy vija."</string>
<string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"WiMAX ka tre vija."</string>
<string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"WiMAX ka sinjal të plotë."</string>
+ <string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"Lidhja e eternetit u shkëput."</string>
+ <string name="accessibility_ethernet_connected" msgid="2692130313069182636">"Lidhja e eternetit u lidh."</string>
<string name="accessibility_no_signal" msgid="7064645320782585167">"Nuk ka sinjal."</string>
<string name="accessibility_not_connected" msgid="6395326276213402883">"Nuk është i lidhur."</string>
<string name="accessibility_zero_bars" msgid="3806060224467027887">"Zero vija."</string>
@@ -162,13 +166,14 @@
<string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> është hequr."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Të gjitha aplikacionet e fundit u larguan."</string>
<string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Po nis <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Njoftimi është hequr."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Streha e njoftimeve."</string>
<string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Cilësime të shpejta."</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Ekrani i kyçjes."</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"Cilësimet"</string>
<string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Përmbledhja."</string>
- <string name="accessibility_desc_confirm" msgid="3446792278337969766">"Konfirmo"</string>
+ <string name="accessibility_desc_close" msgid="7479755364962766729">"Mbylle"</string>
<string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Përdoruesi <xliff:g id="USER">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi është i çaktivizuar."</string>
@@ -180,7 +185,7 @@
<string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Modaliteti \"në aeroplan\" është i çaktivizuar."</string>
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Modaliteti \"në aeroplan\" është i aktivizuar."</string>
<string name="accessibility_quick_settings_dnd_priority_on" msgid="1448402297221249355">"\"Mos shqetëso\" është i aktivizuar, vetëm me prioritet."</string>
- <string name="accessibility_quick_settings_dnd_none_on" msgid="5910777408232088752">"\"Mos shqetëso\" është i aktivizuar, asnjë ndërprerje."</string>
+ <string name="accessibility_quick_settings_dnd_none_on" msgid="6882582132662613537">"\"Mos shqetëso\" është aktiv, heshtje e plotë."</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="9152834845587554157">"\"Mos shqetëso\" është i aktivizuar, vetëm alarmet."</string>
<string name="accessibility_quick_settings_dnd_off" msgid="2371832603753738581">"\"Mos shqetëso\" është i çaktivizuar."</string>
<string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"\"Mos shqetëso\" është i çaktivizuar."</string>
@@ -235,7 +240,7 @@
<string name="quick_settings_dnd_label" msgid="8735855737575028208">"Mos shqetëso"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Vetëm me prioritet"</string>
<string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Vetëm alarmet"</string>
- <string name="quick_settings_dnd_none_label" msgid="7309935569360609114">"Nuk ka ndërprerje"</string>
+ <string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Heshtje e plotë"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"\"Bluetooth-i\" (<xliff:g id="NUMBER">%d</xliff:g> pajisje)"</string>
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"\"Bluetooth-i\" është i çaktivizuar"</string>
@@ -302,26 +307,20 @@
<string name="description_target_search" msgid="3091587249776033139">"Kërko"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Rrëshqit lart për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Rrëshqit majtas për <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="zen_no_interruptions_with_warning" msgid="4396898053735625287">"Nuk ka ndërprerje. Nuk ka as alarme."</string>
- <string name="zen_priority_introduction" msgid="7253045784560169993">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç alarmeve, alarmeve rikujtuese, ngjarjeve dhe telefonuesve që specifikon."</string>
+ <string name="zen_priority_introduction" msgid="3070506961866919502">"Nuk do të shqetësohesh nga tingujt dhe dridhjet, përveç atyre nga alarmet, rikujtesat, ngjarjet dhe telefonuesit që specifikon."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Personalizo"</string>
- <string name="zen_no_interruptions" msgid="7970973750143632592">"Nuk ka ndërprerje"</string>
- <string name="zen_important_interruptions" msgid="3477041776609757628">"Vetëm ndërprerje prioritare"</string>
- <string name="zen_alarms" msgid="5055668280767657759">"Vetëm alarmet"</string>
- <string name="zen_alarm_information_time" msgid="5235772206174372272">"Alarmi i radhës është në <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
- <string name="zen_alarm_information_day_time" msgid="8422733576255047893">"Alarmi i radhës është më <xliff:g id="ALARM_DAY_AND_TIME">%s</xliff:g>"</string>
- <string name="zen_alarm_warning" msgid="6873910860111498041">"Nuk do ta dëgjosh alarmin në <xliff:g id="ALARM_TIME">%s</xliff:g>"</string>
+ <string name="zen_silence_introduction" msgid="575422795504098868">"Kjo bllokon TË GJITHË tingujt dhe dridhjet, duke përfshirë edhe nga alarmet, muzika, videot dhe lojërat. Përsëri do të mund të bësh telefonata."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"Njoftimet më pak urgjente, më poshtë!"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Prek sërish për ta hapur"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Rrëshqit për të shkyçur"</string>
- <string name="phone_hint" msgid="3101468054914424646">"Rrëshqit djathtas për të hapur telefonin"</string>
- <string name="camera_hint" msgid="5241441720959174226">"Rrëshqit majtas për kamerën"</string>
- <string name="interruption_level_none" msgid="8284541443482072628">"Nuk ka ndërprerje"</string>
+ <string name="phone_hint" msgid="4872890986869209950">"Rrëshqit nga ikona për telefonin"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Rrëshqit nga ikona për ndihmën zanore"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Rrëshqit nga ikona për kamerën"</string>
+ <string name="interruption_level_none" msgid="6000083681244492992">"Heshtje e plotë"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Vetëm me prioritet"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Vetëm alarmet"</string>
- <string name="interruption_level_all" msgid="1330581184930945764">"Të gjitha"</string>
- <string name="interruption_level_none_twoline" msgid="3942121050170227056">"Nuk ka\nndërprerje"</string>
+ <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Heshtje\ne plotë"</string>
<string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Vetëm\nme prioritet"</string>
<string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Vetëm\nalarmet"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Po ngarkohet (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> deri sa të mbushet)"</string>
@@ -363,12 +362,15 @@
<string name="disable_vpn" msgid="4435534311510272506">"Çaktivizo VPN-në"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"Shkëput VPN-në"</string>
<string name="monitoring_description_device_owned" msgid="5780988291898461883">"Pajisja jote menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë dhe të menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen tënde, si dhe informacionet e vendndodhjes së pajisjes tënde. Për më shumë informacione, kontakto me administratorin tënd."</string>
- <string name="monitoring_description_profile_owned" msgid="8110044290898637925">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë aktivitetin e rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e sigurta të uebit.\n\nPër më shumë informacione, kontakto me administratorin tënd."</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="1664428184778531249">"Pajisja jote menaxhohet nga:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nProfili yt i punës menaxhohet nga:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministratori yt mund të monitorojë pajisjen tënde dhe aktivitetin e rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e sigurta të uebit.\n\nPër më shumë informacione, kontakto me administratorin."</string>
- <string name="monitoring_description_vpn" msgid="912328761766161919">"I dhe leje një aplikacioni që të konfigurojë një lidhje VPN.\n\nKy aplikacion mund të monitorojë pajisjen tënde dhe aktivitetin e rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e sigurta të uebit."</string>
+ <string name="monitoring_description_vpn" msgid="996222259035614736">"I dhe leje një aplikacioni që të konfigurojë një lidhje VPN.\n\nKy aplikacion mund të monitorojë pajisjen tënde dhe aktivitetin e rrjetit, duke përfshirë mail-at, aplikacionet dhe faqet e internetit."</string>
<string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"Pajisja jote menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë dhe të menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat e lidhura me pajisjen dhe informacionet e vendndodhjes së pajisjes.\n\nJe i lidhur me një rrjet VPN që mund të monitorojë aktivitetin tënd të rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e uebit.\n\nPër më shumë informacione, kontakto me administratorin."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2224494839524715272">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë aktivitetin tënd të rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e sigurta të uebit.\n\nPër më shumë informacione, kontakto me administratorin tënd.\n\nJe i lidhur po ashtu me një rrjet VPN që mund të monitorojë aktivitetin tënd të rrjetit."</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="2198546817407897093">"Pajisja jote menaxhohet nga <xliff:g id="ORGANIZATION_0">%1$s</xliff:g>.\nProfili yt i punës menaxhohet nga:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>.\n\nAdministratori yt mund të monitorojë aktivitetin tënd të rrjetit, duke përfshirë emailet, aplikacionet dhe sajtet e sigurta të uebit.\n\nPër më shumë informacione, kontakto me administratorin tënd.\n\nJe i lidhur po ashtu me një rrjet VPN që mund të monitorojë aktivitetin e rrjetit tënd personal"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori yt mund të monitorojë aktivitetin tënd të rrjetit, duke përfshirë mail-at, aplikacionet dhe faqet e internetit.\n\nPër më shumë informacion, kontakto me administratorin tënd.\n\nJe i lidhur edhe me një VPN, që mund të monitorojë aktivitetin tënd të rrjetit."</string>
+ <string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
+ <string name="monitoring_description_app" msgid="6947928635272782570">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g>, që mund të monitorojë aktivitetin tënd në rrjet përfshirë mail-at, aplikacionet dhe faqet e internetit."</string>
+ <string name="monitoring_description_app_personal" msgid="8506133233655324426">"Je i lidhur me aplikacionin <xliff:g id="APPLICATION">%1$s</xliff:g>, që mund të monitorojë aktivitetin tënd personal në rrjet përfshirë mail-at, aplikacionet dhe faqet e internetit."</string>
+ <string name="monitoring_description_app_work" msgid="808687576155832307">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ai është i lidhur me <xliff:g id="APPLICATION">%2$s</xliff:g>, që mund të monitorojë aktivitetin tënd të punës në rrjet përfshirë mail-at, aplikacionet dhe faqet e internetit.\n\nPër më shumë informacion, kontakto me administratorin tënd."</string>
+ <string name="monitoring_description_app_personal_work" msgid="7711690793960304868">"Profili yt i punës menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>. Ai është i lidhur me <xliff:g id="APPLICATION_WORK">%2$s</xliff:g>, që mund të monitorojë aktivitetin tënd të punës në rrjet përfshirë mail-at, aplikacionet dhe faqet e internetit.\n\nJe lidhur gjithashtu edhe me <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g>, që mund të monitorojë aktivitetin tënd personal në rrjet."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"Pajisja jote menaxhohet nga <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nAdministratori mund të monitorojë dhe menaxhojë cilësimet, qasjen e korporatës, aplikacionet, të dhënat që shoqërojnë pajisjen tënde si dhe informacionin e vendndodhjes së pajisjes.\n\nJe i lidhur me <xliff:g id="APPLICATION">%2$s</xliff:g>, që mund të monitorojë aktivitetin tënd të punës në rrjet përfshirë mail-at, aplikacionet dhe faqet e internetit.\n\nPër më shumë informacion, kontakto me administratorin tënd."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Pajisje do të qëndrojë e kyçur derisa ta shkyçësh manualisht"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Merr njoftime më shpejt"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Shikoji para se t\'i shkyçësh"</string>
@@ -377,6 +379,9 @@
<string name="notification_expand_button_text" msgid="1037425494153780718">"Shikoji të gjitha"</string>
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Fshihi të gjitha"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
+ <string name="volume_zen_end_now" msgid="3179845345429841822">"Përfundo tani"</string>
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Zgjeroje"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Mbylle"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekrani u gozhdua"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Kjo e ruan në pamje derisa e heq nga gozhdimi. Prek dhe mbaj shtypur njëkohësisht \"Prapa\" dhe \"Përmbledhje\" për ta hequr nga gozhdimi."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Kjo e ruan në pamje derisa e heq nga gozhdimi. Prek dhe mbaj shtypur njëkohësisht \"Përmbledhje\" për ta hequr nga gozhdimi."</string>
@@ -391,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> është dialogu i volumit"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Prek për të restauruar origjinalin."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Ndodhesh në profilin e Punës"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f2f126e..c412527 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -84,13 +84,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Претражите"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Телефон"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Гласовна помоћ"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Откључајте"</string>
<string name="unlock_label" msgid="8779712358041029439">"откључај"</string>
<string name="phone_label" msgid="2320074140205331708">"отвори телефон"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"отвори гласовну помоћ"</string>
<string name="camera_label" msgid="7261107956054836961">"отвори камеру"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Изабери нови распоред задатака"</string>
<string name="cancel" msgid="6442560571259935130">"Откажи"</string>
@@ -317,12 +315,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Мање хитна обавештења су у наставку"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Додирните поново да бисте отворили"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Превуците нагоре да бисте откључали"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Превуците од иконе за телефон"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Превуците од иконе за гласовну помоћ"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Превуците од иконе за камеру"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Потпуна тишина"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Само приоритетни прекиди"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Само аларми"</string>
@@ -386,10 +381,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Сакриј све"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Прекини одмах"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Прошири"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Скупи"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Екран је закачен"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"На овај начин ово остаје приказано док га не откачите. Истовремено додирните и задржите Назад и Преглед да бисте га откачили."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"На овај начин ово остаје приказано док га не откачите. Додирните и задржите Преглед да бисте га откачили."</string>
@@ -404,4 +397,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> је дијалог за јачину звука"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Додирните да бисте вратили оригинал."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Налазите се на профилу за Work"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7aea1e8..5dfe041 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Sök"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Mobil"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Röstassistent"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Lås upp"</string>
<string name="unlock_label" msgid="8779712358041029439">"lås upp"</string>
<string name="phone_label" msgid="2320074140205331708">"öppna mobilen"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"öppna röstassistenten"</string>
<string name="camera_label" msgid="7261107956054836961">"öppna kameran"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Välj en ny layout för uppgiften"</string>
<string name="cancel" msgid="6442560571259935130">"Avbryt"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Mindre brådskande aviseringar nedan"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Tryck igen för att öppna"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Dra uppåt om du vill låsa upp"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Dra från ikonen om du vill visa telefonen"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Dra från ikonen om du vill visa röstassistenten"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Dra från ikonen om du vill visa kameran"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Helt tyst"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Bara prioriterade"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Endast alarm"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Dölj alla"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Sluta nu"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Utöka"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Komprimera"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skärmen har fästs"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Detta visar skärmen tills du lossar den. Tryck länge på bakåtknappen och Översikt samtidigt om du vill lossa skärmen."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Detta visar skärmen tills du lossar den. Tryck länge på Översikt om du vill lossa skärmen."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> används som volymkontroll"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Tryck här om du vill återställa den ursprungliga appen."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Du använder Work-profilen"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 7ee5705..f7c10e1 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Tafuta"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Simu"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Mapendekezo ya Sauti"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Fungua"</string>
<string name="unlock_label" msgid="8779712358041029439">"fungua"</string>
<string name="phone_label" msgid="2320074140205331708">"fungua simu"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"fungua mapendekezo ya sauti"</string>
<string name="camera_label" msgid="7261107956054836961">"fungua kamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Chagua muundo mpya wa kazi"</string>
<string name="cancel" msgid="6442560571259935130">"Ghairi"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Arifa zisizo za dharura sana ziko hapo chini"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Gusa tena ili ufungue"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Telezesha kidole ili ufungue"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Telezesha kidole kutoka kwa aikoni ili ufikie simu"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Telezesha kidole kutoka aikoni ili upate mapendekezo ya sauti"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Telezesha kidole kutoka aikoni ili ufikie kamera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Kimya kabisa"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Kipaumbele tu"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Kengele pekee"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ficha zote"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Komesha sasa"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Panua"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Kunja"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Skrini imebandikwa"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Hii itaendelea kuonyesha hadi ubandue. Gusa na ushikilie Nyuma na Muhtasari kwa wakati mmoja ili ubandue."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Hii itaendelea kuonyesha hadi uibandue. Gusa na ushikilie Muhtasari ili ubandue."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ni mazungumzo ya sauti"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Gusa ili urejeshe ya awali."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Uko katika wasifu wa Kazi"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 360e675..dc375be 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"தேடு"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"கேமரா"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ஃபோன்"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"குரல் உதவி"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"திற"</string>
<string name="unlock_label" msgid="8779712358041029439">"திற"</string>
<string name="phone_label" msgid="2320074140205331708">"ஃபோனைத் திற"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"குரல் உதவியைத் திற"</string>
<string name="camera_label" msgid="7261107956054836961">"கேமராவைத் திற"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"புதிய பணி தளவமைப்பைத் தேர்ந்தெடுக்கவும்"</string>
<string name="cancel" msgid="6442560571259935130">"ரத்துசெய்"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"அவசர நிலைக் குறைவான அறிவிப்புகள் கீழே உள்ளன"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"திறக்க, மீண்டும் தட்டவும்"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"திறக்க, மேலே ஸ்வைப் செய்யவும்"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ஃபோனிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"குரல் உதவிக்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"கேமராவிற்கு ஐகானிலிருந்து ஸ்வைப் செய்யவும்"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"அறிவிப்புகள் வேண்டாம்"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"முன்னுரிமை மட்டும்"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"அலாரங்கள் மட்டும்"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"எல்லாம் மறை"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"இப்போது முடி"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"விரிவாக்கு"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"சுருக்கு"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"திரை பொருத்தப்பட்டது"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"பொருத்தியதை விலக்கும்வரை இதைக் காட்சியில் வைக்கும். விலக்க, பின் மற்றும் மேலோட்டப் பார்வையை ஒரே நேரத்தில் தொட்டுப் பிடிக்கவும்."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"பொருத்தியதை விலக்கும்வரை இதைக் காட்சியில் வைக்கும். விலக்க, மேலோட்டப் பார்வையைத் தொட்டுப் பிடிக்கவும்."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"அசலை மீட்டமைக்கத் தொடவும்."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"பணி சுயவிவரத்தில் இருக்கிறீர்கள்"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 8b64b3a..d2fc929 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"శోధించు"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"కెమెరా"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"ఫోన్"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"వాయిస్ సహాయకం"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"అన్లాక్ చేయి"</string>
<string name="unlock_label" msgid="8779712358041029439">"అన్లాక్ చేయి"</string>
<string name="phone_label" msgid="2320074140205331708">"ఫోన్ను తెరువు"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"వాయిస్ సహాయకం తెరువు"</string>
<string name="camera_label" msgid="7261107956054836961">"కెమెరాను తెరువు"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"కొత్త విధి లేఅవుట్ను ఎంచుకోండి"</string>
<string name="cancel" msgid="6442560571259935130">"రద్దు చేయండి"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"తక్కువ అత్యవసర నోటిఫికేషన్లు దిగువన"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"తెరవడానికి మళ్లీ తాకండి"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"అన్లాక్ చేయడానికి ఎగువకు స్వైప్ చేయండి"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"ఫోన్ చిహ్నం నుండి స్వైప్"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"వాయిస్ సహాయకం చిహ్నం నుండి స్వైప్"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"కెమెరా చిహ్నం నుండి స్వైప్"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"మొత్తం నిశ్శబ్దం"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"ప్రాధాన్యత మాత్రమే"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"అలారాలు మాత్రమే"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"అన్నీ దాచిపెట్టు"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ఇప్పుడే ముగించు"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"విస్తరింపజేయండి"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"కుదించండి"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"స్క్రీన్ పిన్ చేయబడింది"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"ఇది మీరు అన్పిన్ చేసే వరకు దీన్ని వీక్షణలో ఉంచుతుంది. అన్పిన్ చేయడానికి వెనుకకు మరియు స్థూలదృష్టిని ఒకేసారి తాకి, ఉంచండి."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"ఇది మీరు అన్పిన్ చేసే వరకు దీన్ని వీక్షణలో ఉంచుతుంది. అన్పిన్ చేయడానికి స్థూలదృష్టిని తాకి, ఉంచండి."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> అనేది వాల్యూమ్ డైలాగ్"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"అసలుదాన్ని పునరుద్ధరించడానికి తాకండి."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"మీరు కార్యాలయ ప్రొఫైల్లో ఉన్నారు"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index b1a6954..5e39621 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"ค้นหา"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"กล้องถ่ายรูป"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"โทรศัพท์"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"ตัวช่วยเสียง"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"ปลดล็อก"</string>
<string name="unlock_label" msgid="8779712358041029439">"ปลดล็อก"</string>
<string name="phone_label" msgid="2320074140205331708">"เปิดโทรศัพท์"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"เปิดตัวช่วยเสียง"</string>
<string name="camera_label" msgid="7261107956054836961">"เปิดกล้อง"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"เลือกรูปแบบงานใหม่"</string>
<string name="cancel" msgid="6442560571259935130">"ยกเลิก"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"การแจ้งเตือนที่เร่งด่วนน้อยด้านล่าง"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"แตะอีกครั้งเพื่อเปิด"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"กวาดขึ้นเพื่อปลดล็อก"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"กวาดนิ้วจากไอคอนโทรศัพท์"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"กวาดนิ้วจากไอคอนตัวช่วยเสียง"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"กวาดนิ้วจากไอคอนกล้อง"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"ปิดเสียงทั้งหมด"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"เฉพาะเรื่องสำคัญ"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"เฉพาะปลุกเท่านั้น"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"ซ่อนทั้งหมด"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g> <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ไม่ใช้แล้ว"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"ขยาย"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"ยุบ"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"ตรึงหน้าจอแล้ว"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"การดำเนินการนี้จะเปิดหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"กลับ\" และ \"ภาพรวม\" พร้อมกันค้างไว้เพื่อเลิกตรึง"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"การดำเนินการนี้จะเปิดหน้าจอนี้ไว้เสมอจนกว่าคุณจะเลิกตรึง แตะ \"ภาพรวม\" ค้างไว้เพื่อเลิกตรึง"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"แตะเพื่อคืนค่าดั้งเดิม"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"คุณกำลังอยู่ในโปรไฟล์งาน"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 7c8530c..2b801b7 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Hanapin"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telepono"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"I-unlock"</string>
<string name="unlock_label" msgid="8779712358041029439">"i-unlock"</string>
<string name="phone_label" msgid="2320074140205331708">"buksan ang telepono"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"buksan ang voice assist"</string>
<string name="camera_label" msgid="7261107956054836961">"buksan ang camera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Pumili ng bagong layout ng gawain"</string>
<string name="cancel" msgid="6442560571259935130">"Kanselahin"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Nasa ibaba ang mga notification na hindi masyadong mahalaga"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Pinduting muli upang buksan"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Mag-swipe pataas upang i-unlock"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Mag-swipe mula sa icon para sa telepono"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Mag-swipe mula sa icon para sa voice assist"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Mag-swipe mula sa icon para sa camera"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Ganap na katahimikan"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Priyoridad lang"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Mga alarm lang"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Itago lahat"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Tapusin ngayon"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Palawakin"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"I-collapse"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Naka-pin ang screen"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Pinapanatili nitong nasa view ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Bumalik at Pangkalahatang-ideya nang sabay upang mag-unpin."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Pinapanatili nitong nasa view ito hanggang sa mag-unpin ka. Pindutin nang matagal ang Pangkalahatang-ideya upang mag-unpin."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ang volume dialog"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Pindutin upang ibalik ang orihinal."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Nandito ka sa profile sa Trabaho"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 0ae2b11..c1b1552 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Ara"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Sesli Yardım"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Kilidi aç"</string>
<string name="unlock_label" msgid="8779712358041029439">"kilidi aç"</string>
<string name="phone_label" msgid="2320074140205331708">"telefonu aç"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"sesli yardımı aç"</string>
<string name="camera_label" msgid="7261107956054836961">"kamerayı aç"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Yeni görev düzenini seçin"</string>
<string name="cancel" msgid="6442560571259935130">"İptal"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Daha az acil bildirimler aşağıdadır"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Açmak için tekrar dokunun"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Kilidi açmak için hızlıca yukarı kaydırın"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Telefon için, simgeden hızlıca kaydırın"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Sesli yardım için, simgeden hızlıca kaydırın"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Kamera için, simgeden hızlıca kaydırın"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Tamamen sessiz"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Yalnızca öncelikli"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Yalnızca alarmlar"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Tümünü gizle"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Şimdi sona erdir"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Genişlet"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Daralt"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Ekran sabitlendi"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Böylece siz sabitlemesini kaldırana kadar görüntülenmeye devam eder. Sabitlemeyi kaldırmak için Geri ve Genel Bakış öğesine aynı anda dokunun ve basılı tutun."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Böylece siz sabitlemesini kaldırana kadar görüntülenmeye devam eder. Sabitlemeyi kaldırmak için Genel Bakış\'a dokunun ve basılı tutun."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ses denetimi iletişim kutusu olarak ayarlandı"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Orijinali geri yüklemek için dokunun."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"İş profilindesiniz"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index a3776c3..718abc1 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -85,13 +85,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Пошук"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Номер телефону"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Голосові підказки"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Розблокувати"</string>
<string name="unlock_label" msgid="8779712358041029439">"розблокувати"</string>
<string name="phone_label" msgid="2320074140205331708">"відкрити телефон"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"запустити голосові підказки"</string>
<string name="camera_label" msgid="7261107956054836961">"відкрити камеру"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Виберіть новий макет завдання"</string>
<string name="cancel" msgid="6442560571259935130">"Скасувати"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Менше термінових сповіщень нижче"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Торкніться знову, щоб відкрити"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Проведіть пальцем угору, щоб розблокувати"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Потягніть значок, щоб скористатися телефоном"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Потягніть значок, щоб увімкнути голосові підказки"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Потягніть значок, щоб відкрити камеру"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Без сигналів"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Лише пріоритетні"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Лише сигнали"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Сховати всі"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Закрити"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Розгорнути"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Згорнути"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Екран закріплено"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Закріпить екран, щоб ви могли постійно його бачити, доки не відкріпите. Щоб відкріпити, одночасно натисніть і втримуйте кнопки \"Назад\" і \"Огляд\"."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Закріпить екран, щоб ви могли постійно його бачити, доки не відкріпите. Щоб відкріпити, натисніть і втримуйте кнопку \"Огляд\"."</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> призначено регулятором гучності"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Торкніться, щоб відновити оригінал."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Ви в робочому профілі"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 46723f1..a30f5f86 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"تلاش کریں"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"کیمرا"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"فون"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"صوتی معاون"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"غیر مقفل کریں"</string>
<string name="unlock_label" msgid="8779712358041029439">"غیر مقفل کریں"</string>
<string name="phone_label" msgid="2320074140205331708">"فون کھولیں"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"صوتی معاون کھولیں"</string>
<string name="camera_label" msgid="7261107956054836961">"کیمرا کھولیں"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"نئے کام کا لے آؤٹ منتخب کریں"</string>
<string name="cancel" msgid="6442560571259935130">"منسوخ کریں"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"کم اہم اطلاعات ذیل میں ہیں"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"کھولنے کیلئے دوبارہ ٹچ کریں"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"غیر مقفل کرنے کیلئے اوپر سوائپ کریں"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"فون کیلئے آئیکن سے سوائپ کریں"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"صوتی معاون کیلئے آئیکن سے سوائپ کریں"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"کیمرہ کیلئے آئیکن سے سوائپ کریں"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"مکمل خاموشی"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"صرف ترجیحی"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"صرف الارمز"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"سبھی چھپائیں"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>۔ <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"ابھی ختم کریں"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"پھیلائیں"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"سکیڑیں"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"اسکرین پن کردہ ہے"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے واپس اور عمومی جائزہ کو ایک ساتھ ٹچ کریں اور پکڑ کر رکھیں۔"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"یہ اس کو اس وقت تک منظر میں رکھتا ہے جب تک آپ اس سے پن نہیں ہٹا دیتے۔ پن ہٹانے کیلئے عمومی جائزہ کو ٹچ کریں اور پکڑ کر رکھیں۔"</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"اصل کو بحال کرنے کیلئے ٹچ کریں۔"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"آپ دفتری پروفائل میں ہیں"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 621acde..715a55e 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -148,7 +148,7 @@
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"SIM karta yo‘q."</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth bog‘landi."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Bluetooth modem"</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Parvoz rejimi"</string>
<string name="accessibility_carrier_network_change_mode" msgid="4017301580441304305">"Mobil tarmoqni o‘zgartirish"</string>
<string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
@@ -288,11 +288,11 @@
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Qolayotgan ma\'lumot"</string>
<string name="quick_settings_cellular_detail_over_limit" msgid="967669665390990427">"Limitdan oshgan"</string>
<string name="quick_settings_cellular_detail_data_used" msgid="1476810587475761478">"<xliff:g id="DATA_USED">%s</xliff:g> foydalanilgan"</string>
- <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"<xliff:g id="DATA_LIMIT">%s</xliff:g> chegarasi"</string>
+ <string name="quick_settings_cellular_detail_data_limit" msgid="56011158504994128">"Cheklov: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ogohlantirish: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="8682129509540827999">"Siz yaqinda ishlatgan ilova ekranlari bu yerda ko‘rinadi"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Ilova haqida ma’lumot"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ekranni qadab qo‘yish"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"o‘zgarmas ekran"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string>
<string name="recents_dismiss_all_message" msgid="8495275386693095768">"Barcha ilovalarni olib tashlash"</string>
@@ -396,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ovoz balandligini boshqaradi"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Aslini tiklash uchun bosing."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Siz Android for Work profiliga kirgansiz"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 823d3bb..a47e2f4 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Tìm kiếm"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Máy ảnh"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Điện thoại"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Trợ lý thoại"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Mở khóa"</string>
<string name="unlock_label" msgid="8779712358041029439">"mở khóa"</string>
<string name="phone_label" msgid="2320074140205331708">"mở điện thoại"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"mở trợ lý thoại"</string>
<string name="camera_label" msgid="7261107956054836961">"mở máy ảnh"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Chọn bố cục tác vụ mới"</string>
<string name="cancel" msgid="6442560571259935130">"Hủy"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Thông báo ít khẩn cấp hơn bên dưới"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Chạm lại để mở"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Vuốt lên để mở khóa"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Vuốt từ biểu tượng để mở điện thoại"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Vuốt từ biểu tượng để mở trợ lý thoại"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Vuốt từ biểu tượng để mở máy ảnh"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Hoàn toàn tắt tiếng"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Chỉ ưu tiên"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Chỉ báo thức"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Ẩn tất cả"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Kết thúc bây giờ"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Mở rộng"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Thu gọn"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Màn hình được ghim"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Chạm và giữ nút Quay lại và Tổng quan cùng một lúc để bỏ ghim."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Thao tác này sẽ duy trì hiển thị màn hình cho đến khi bạn bỏ ghim. Chạm và giữ nút Quay lại để bỏ ghim."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> là hộp thoại khối lượng"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Chạm để khôi phục bản gốc."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Bạn đang trên hồ sơ công việc"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 1499d59..1d4af1d 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"搜索"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"相机"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"电话"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"语音助理"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解锁"</string>
<string name="unlock_label" msgid="8779712358041029439">"解锁"</string>
<string name="phone_label" msgid="2320074140205331708">"打开电话"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"打开语音助理"</string>
<string name="camera_label" msgid="7261107956054836961">"打开相机"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"选择新的任务布局"</string>
<string name="cancel" msgid="6442560571259935130">"取消"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"不太紧急的通知会显示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次触摸即可打开"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上滑动即可解锁"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"滑动图标即可打开电话"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"滑动图标即可打开语音助理"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"滑动图标即可打开相机"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"完全静音"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"仅限优先打扰"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"仅限闹钟"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"全部隐藏"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>(<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>)"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"立即结束"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"展开"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收起"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"已固定屏幕"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"这将会固定显示此屏幕,直到您取消固定为止。触摸并同时按住“返回”和“概览”即可取消固定屏幕。"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"这将会固定显示此屏幕,直到您取消固定为止。触摸并按住“概览”即可取消固定屏幕。"</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"触摸即可恢复原始设置。"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"您正在使用工作资料"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 0fc3f47..b55e79f 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -398,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」為音量對話框"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸即可復原。"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"您正在「工作設定檔」頁面"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 4958481..4240dd6 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"搜尋"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"相機"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"語音小幫手"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"解除鎖定"</string>
<string name="unlock_label" msgid="8779712358041029439">"解除鎖定"</string>
<string name="phone_label" msgid="2320074140205331708">"開啟電話"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"開啟語音小幫手"</string>
<string name="camera_label" msgid="7261107956054836961">"開啟攝影機"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"選取新工作版面配置"</string>
<string name="cancel" msgid="6442560571259935130">"取消"</string>
@@ -318,12 +316,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"較不緊急的通知會顯示在下方"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"再次輕觸即可開啟"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"向上滑動即可解鎖"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"滑動手機圖示即可啟用"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"滑動語音小幫手圖示即可啟用"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"滑動相機圖示即可啟用"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"完全靜音"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"僅顯示優先通知"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"僅允許鬧鐘"</string>
@@ -387,10 +382,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"全部隱藏"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>。<xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"立刻結束"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"展開"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"收合"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"螢幕已固定"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。同時按住返回按鈕和總覽按鈕即可取消固定。"</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"這會讓目前的螢幕畫面保持顯示狀態,直到取消固定為止。按住總覽按鈕即可取消固定。"</string>
@@ -405,4 +398,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"輕觸這裡即可恢復原始設定。"</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"您目前在 Work 設定檔"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 689bc99..d6f62f0 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -83,13 +83,11 @@
<string name="accessibility_search_light" msgid="1103867596330271848">"Sesha"</string>
<string name="accessibility_camera_button" msgid="8064671582820358152">"Ikhamela"</string>
<string name="accessibility_phone_button" msgid="6738112589538563574">"Ifoni"</string>
- <!-- no translation found for accessibility_voice_assist_button (487611083884852965) -->
- <skip />
+ <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Isisekeli sezwi"</string>
<string name="accessibility_unlock_button" msgid="128158454631118828">"Vula"</string>
<string name="unlock_label" msgid="8779712358041029439">"vula"</string>
<string name="phone_label" msgid="2320074140205331708">"vula ifoni"</string>
- <!-- no translation found for voice_assist_label (3956854378310019854) -->
- <skip />
+ <string name="voice_assist_label" msgid="3956854378310019854">"vula isilekeleli sezwi"</string>
<string name="camera_label" msgid="7261107956054836961">"vula ikhamera"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"Khetha isakhiwo somsebenzi omusha"</string>
<string name="cancel" msgid="6442560571259935130">"Khansela"</string>
@@ -316,12 +314,9 @@
<string name="speed_bump_explanation" msgid="1288875699658819755">"Izaziso ezingasheshi kakhulu ezingezansi"</string>
<string name="notification_tap_again" msgid="8524949573675922138">"Thinta futhi ukuze uvule"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"Swayiphela phezulu ukuze uvule"</string>
- <!-- no translation found for phone_hint (4872890986869209950) -->
- <skip />
- <!-- no translation found for voice_hint (8939888732119726665) -->
- <skip />
- <!-- no translation found for camera_hint (7939688436797157483) -->
- <skip />
+ <string name="phone_hint" msgid="4872890986869209950">"Swayiphela ifoni kusukela kusithonjana"</string>
+ <string name="voice_hint" msgid="8939888732119726665">"Swayiphela isilekeleli sezwi kusukela kusithonjana"</string>
+ <string name="camera_hint" msgid="7939688436797157483">"Swayiphela ikhamela kusukela kusithonjana"</string>
<string name="interruption_level_none" msgid="6000083681244492992">"Ukuthula okuphelele"</string>
<string name="interruption_level_priority" msgid="6426766465363855505">"Okubalulekile kuphela"</string>
<string name="interruption_level_alarms" msgid="5226306993448328896">"Ama-alamu kuphela"</string>
@@ -385,10 +380,8 @@
<string name="notification_collapse_button_text" msgid="6883253262134328057">"Fihla wonke"</string>
<string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string>
<string name="volume_zen_end_now" msgid="3179845345429841822">"Qeda manje"</string>
- <!-- no translation found for accessibility_volume_expand (5946812790999244205) -->
- <skip />
- <!-- no translation found for accessibility_volume_collapse (3609549593031810875) -->
- <skip />
+ <string name="accessibility_volume_expand" msgid="5946812790999244205">"Nweba"</string>
+ <string name="accessibility_volume_collapse" msgid="3609549593031810875">"Goqa"</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"Isikrini siphiniwe"</string>
<string name="screen_pinning_description" msgid="1346522416878235405">"Lokhu kukugcina kubukeka uze ususe ukuphina. Thinta futhi ubambe u-Emuva no-Ukubuka konke ngesikhathi esisodwa ukuze ususe ukuphina."</string>
<string name="screen_pinning_description_accessible" msgid="8518446209564202557">"Lokhu kukugcina kubukeka uze ususe ukuphina. Thinta futhi ubambe u-Ukubuka konke ukuze ususe ukuphina."</string>
@@ -403,4 +396,12 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> yingxoxo yevolumu"</string>
<string name="volumeui_notification_text" msgid="1826889705095768656">"Thinta ukuze ubuyisele kokwangempela."</string>
<string name="managed_profile_foreground_toast" msgid="3199278359979281097">"Ukuphrofayela yomsebenzi"</string>
+ <!-- no translation found for system_ui_tuner (8982911407690974001) -->
+ <skip />
+ <!-- no translation found for quick_settings (10042998191725428) -->
+ <skip />
+ <!-- no translation found for add_tile (2995389510240786221) -->
+ <skip />
+ <!-- no translation found for broadcast_tile (3894036511763289383) -->
+ <skip />
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 6e79423..354e99d 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -69,9 +69,6 @@
<!-- Show rotation lock toggle in System UI-->
<bool name="config_showRotationLock">true</bool>
- <!-- Amount of time to hold off before showing the search panel when the user presses home -->
- <integer name="config_show_search_delay">200</integer>
-
<!-- Vibration duration for GlowPadView used in SearchPanelView -->
<integer translatable="false" name="config_vibration_duration">0</integer>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c74633c..f1bbb0d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1023,5 +1023,19 @@
<string name="volume_stream_vibrate_dnd" translatable="false">%s vibrate — Priority only</string>
<!-- Name of special SystemUI debug settings -->
- <string name="system_ui_tuner">SystemUI Tuner</string>
+ <string name="system_ui_tuner">System UI tuner</string>
+
+ <!-- Name of quick settings -->
+ <string name="quick_settings">Quick Settings</string>
+
+ <!-- Description for adding a quick settings tile -->
+ <string name="add_tile">Add tile</string>
+
+ <!-- Name of a quick settings tile controlled by broadcast -->
+ <string name="broadcast_tile">Broadcast Tile</string>
+
+ <!-- For preview release. DO NOT TRANSLATE -->
+ <string name="regrettable_lack_of_easter_egg">
+ ¯\\_(ツ)_/¯
+ </string>
</resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 263260e..deb3f4f 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -19,4 +19,8 @@
<!-- Tuner prefs go here -->
+ <Preference
+ android:key="qs_tuner"
+ android:title="@string/quick_settings" />
+
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 3fbc76b..0d331d1 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -225,23 +225,23 @@
mSubpixelSmoothingRight = context.getResources().getFraction(
R.fraction.battery_subpixel_smoothing_right, 1, 1);
- mFramePaint = new Paint();
+ mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mFramePaint.setColor(frameColor);
mFramePaint.setDither(true);
mFramePaint.setStrokeWidth(0);
mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mBatteryPaint = new Paint();
+ mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBatteryPaint.setDither(true);
mBatteryPaint.setStrokeWidth(0);
mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
- mTextPaint = new Paint();
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
mTextPaint.setTypeface(font);
mTextPaint.setTextAlign(Paint.Align.CENTER);
- mWarningTextPaint = new Paint();
+ mWarningTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mWarningTextPaint.setColor(mColors[1]);
font = Typeface.create("sans-serif", Typeface.BOLD);
mWarningTextPaint.setTypeface(font);
@@ -249,7 +249,7 @@
mChargeColor = context.getColor(R.color.batterymeter_charge_color);
- mBoltPaint = new Paint();
+ mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBoltPaint.setColor(context.getColor(R.color.batterymeter_bolt_color));
mBoltPoints = loadBoltPoints(res);
diff --git a/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java
new file mode 100644
index 0000000..7459957
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/egg/ShruggyActivity.java
@@ -0,0 +1,34 @@
+/*
+ * 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.systemui.egg;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Toast;
+import com.android.systemui.R;
+
+public class ShruggyActivity extends Activity {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Toast.makeText(this, getString(R.string.regrettable_lack_of_easter_egg),
+ Toast.LENGTH_SHORT).show();
+ Log.v("SystemUI", "Hey, it's just a preview; what did you expect?");
+ finish();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6479dc5..74962ec 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1335,7 +1335,7 @@
// Don't actually hide the Keyguard at the moment, wait for window
// manager until it tells us it's safe to do so with
// startKeyguardExitAnimation.
- mWM.keyguardGoingAway(
+ ActivityManagerNative.getDefault().keyguardGoingAway(
mStatusBarKeyguardViewManager.shouldDisableWindowAnimationsForUnlock(),
mStatusBarKeyguardViewManager.isGoingToNotificationShade());
} catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index ebb07a0..b4ae20d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -50,12 +50,12 @@
private static final float TILE_ASPECT = 1.2f;
private final Context mContext;
- private final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
+ protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
private final View mDetail;
private final ViewGroup mDetailContent;
private final TextView mDetailSettingsButton;
private final TextView mDetailDoneButton;
- private final View mBrightnessView;
+ protected final View mBrightnessView;
private final QSDetailClipper mClipper;
private final H mHandler = new H();
@@ -560,13 +560,13 @@
DetailAdapter detailAdapter;
}
- private static final class TileRecord extends Record {
- QSTile<?> tile;
- QSTileView tileView;
- int row;
- int col;
- boolean scanState;
- boolean openingDetail;
+ protected static final class TileRecord extends Record {
+ public QSTile<?> tile;
+ public QSTileView tileView;
+ public int row;
+ public int col;
+ public boolean scanState;
+ public boolean openingDetail;
}
private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 3b217df..72bb136 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -24,23 +24,21 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
-import com.android.internal.logging.MetricsLogger;
import com.android.systemui.qs.QSTile.State;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.FlashlightController;
+import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.Listenable;
import com.android.systemui.statusbar.policy.LocationController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
-import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.statusbar.policy.ZenModeController;
import java.util.Collection;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 1721335..dcf0438 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -30,9 +30,11 @@
import com.android.systemui.qs.QSTileView;
import com.android.systemui.qs.SignalTileView;
import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.MobileDataController;
import com.android.systemui.statusbar.policy.NetworkController.MobileDataController.DataUsageInfo;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
/** Quick settings tile: Cellular **/
public class CellularTile extends QSTile<QSTile.SignalState> {
@@ -63,9 +65,9 @@
@Override
public void setListening(boolean listening) {
if (listening) {
- mController.addNetworkSignalChangedCallback(mCallback);
+ mController.addSignalCallback(mSignalCallback);
} else {
- mController.removeNetworkSignalChangedCallback(mCallback);
+ mController.removeSignalCallback(mSignalCallback);
}
}
@@ -138,7 +140,6 @@
private static final class CallbackInfo {
boolean enabled;
boolean wifiEnabled;
- boolean wifiConnected;
boolean airplaneModeEnabled;
int mobileSignalIconId;
String signalContentDescription;
@@ -151,40 +152,39 @@
boolean isDataTypeIconWide;
}
- private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
+ private final SignalCallback mSignalCallback = new SignalCallbackAdapter() {
private final CallbackInfo mInfo = new CallbackInfo();
-
@Override
- public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId,
- boolean activityIn, boolean activityOut,
- String wifiSignalContentDescriptionId, String description) {
+ public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+ boolean activityIn, boolean activityOut, String description) {
mInfo.wifiEnabled = enabled;
- mInfo.wifiConnected = connected;
refreshState(mInfo);
}
@Override
- public void onMobileDataSignalChanged(boolean enabled,
- int mobileSignalIconId,
- String mobileSignalContentDescriptionId, int dataTypeIconId,
- boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description,
- boolean isDataTypeIconWide) {
- mInfo.enabled = enabled;
- mInfo.mobileSignalIconId = mobileSignalIconId;
- mInfo.signalContentDescription = mobileSignalContentDescriptionId;
- mInfo.dataTypeIconId = dataTypeIconId;
- mInfo.dataContentDescription = dataTypeContentDescriptionId;
+ public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon,
+ int darkStatusIcon, int statusType, int qsType, boolean activityIn,
+ boolean activityOut, String typeContentDescription, String description,
+ boolean isWide, int subId) {
+ if (qsIcon == null) {
+ // Not data sim, don't display.
+ return;
+ }
+ mInfo.enabled = qsIcon.visible;
+ mInfo.mobileSignalIconId = qsIcon.icon;
+ mInfo.signalContentDescription = qsIcon.contentDescription;
+ mInfo.dataTypeIconId = qsType;
+ mInfo.dataContentDescription = typeContentDescription;
mInfo.activityIn = activityIn;
mInfo.activityOut = activityOut;
mInfo.enabledDesc = description;
- mInfo.isDataTypeIconWide = isDataTypeIconWide;
+ mInfo.isDataTypeIconWide = qsType != 0 && isWide;
refreshState(mInfo);
}
@Override
- public void onNoSimVisibleChanged(boolean visible) {
- mInfo.noSim = visible;
+ public void setNoSims(boolean show) {
+ mInfo.noSim = show;
if (mInfo.noSim) {
// Make sure signal gets cleared out when no sims.
mInfo.mobileSignalIconId = 0;
@@ -199,12 +199,13 @@
}
@Override
- public void onAirplaneModeChanged(boolean enabled) {
- mInfo.airplaneModeEnabled = enabled;
+ public void setIsAirplaneMode(IconState icon) {
+ mInfo.airplaneModeEnabled = icon.visible;
refreshState(mInfo);
}
- public void onMobileDataEnabled(boolean enabled) {
+ @Override
+ public void setMobileDataEnabled(boolean enabled) {
mDetailAdapter.setMobileDataEnabled(enabled);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 5f24619..f4d6f04 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -102,7 +102,9 @@
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
final int zen = arg instanceof Integer ? (Integer) arg : mController.getZen();
- state.value = zen != Global.ZEN_MODE_OFF;
+ final boolean newValue = zen != Global.ZEN_MODE_OFF;
+ final boolean valueChanged = state.value != newValue;
+ state.value = newValue;
state.visible = isVisible(mContext);
switch (zen) {
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
@@ -133,6 +135,9 @@
if (mShowingDetail && !state.value) {
showDetail(false);
}
+ if (valueChanged) {
+ fireToggleStateChanged(state.value);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index c3f9e33..9504ea3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -16,8 +16,6 @@
package com.android.systemui.qs.tiles;
-import java.util.List;
-
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -36,7 +34,11 @@
import com.android.systemui.qs.SignalTileView;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.SignalCallbackAdapter;
+
+import java.util.List;
/** Quick settings tile: Wifi **/
public class WifiTile extends QSTile<QSTile.SignalState> {
@@ -67,9 +69,9 @@
@Override
public void setListening(boolean listening) {
if (listening) {
- mController.addNetworkSignalChangedCallback(mCallback);
+ mController.addSignalCallback(mSignalCallback);
} else {
- mController.removeNetworkSignalChangedCallback(mCallback);
+ mController.removeSignalCallback(mSignalCallback);
}
}
@@ -211,46 +213,21 @@
}
}
- private final NetworkSignalChangedCallback mCallback = new NetworkSignalChangedCallback() {
+ private final SignalCallback mSignalCallback = new SignalCallbackAdapter() {
@Override
- public void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId,
- boolean activityIn, boolean activityOut,
- String wifiSignalContentDescriptionId, String description) {
+ public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+ boolean activityIn, boolean activityOut, String description) {
if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
final CallbackInfo info = new CallbackInfo();
info.enabled = enabled;
- info.connected = connected;
- info.wifiSignalIconId = wifiSignalIconId;
+ info.connected = qsIcon.visible;
+ info.wifiSignalIconId = qsIcon.icon;
info.enabledDesc = description;
info.activityIn = activityIn;
info.activityOut = activityOut;
- info.wifiSignalContentDescription = wifiSignalContentDescriptionId;
+ info.wifiSignalContentDescription = qsIcon.contentDescription;
refreshState(info);
}
-
- @Override
- public void onMobileDataSignalChanged(boolean enabled,
- int mobileSignalIconId,
- String mobileSignalContentDescriptionId, int dataTypeIconId,
- boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description,
- boolean isDataTypeIconWide) {
- // noop
- }
-
- public void onNoSimVisibleChanged(boolean noSims) {
- // noop
- }
-
- @Override
- public void onAirplaneModeChanged(boolean enabled) {
- // noop
- }
-
- @Override
- public void onMobileDataEnabled(boolean enabled) {
- // noop
- }
};
private final class WifiDetailAdapter implements DetailAdapter,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 715f4e4..be33085 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -194,7 +194,7 @@
// we compose the final post-save notification below.
mNotificationBuilder.setLargeIcon(croppedIcon);
// But we still don't set it for the expanded view, allowing the smallIcon to show here.
- mNotificationStyle.bigLargeIcon(null);
+ mNotificationStyle.bigLargeIcon((Bitmap) null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 588ec26..1e488f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -395,11 +395,6 @@
Toast.LENGTH_SHORT).show();
}
}
- } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
- action)) {
- mUsersAllowingPrivateNotifications.clear();
- updateLockscreenNotificationSetting();
- updateNotifications();
} else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
NotificationManager noMan = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
@@ -419,6 +414,19 @@
}
};
+ private final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
+ isCurrentProfile(getSendingUserId())) {
+ mUsersAllowingPrivateNotifications.clear();
+ updateLockscreenNotificationSetting();
+ updateNotifications();
+ }
+ }
+ };
+
private final NotificationListenerService mNotificationListener =
new NotificationListenerService() {
@Override
@@ -631,9 +639,13 @@
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(BANNER_ACTION_CANCEL);
filter.addAction(BANNER_ACTION_SETUP);
- filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter);
+ IntentFilter allUsersFilter = new IntentFilter();
+ allUsersFilter.addAction(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
+ null, null);
updateCurrentProfilesCache();
}
@@ -1378,9 +1390,9 @@
final ImageView profileBadge = (ImageView) publicViewLocal.findViewById(
R.id.profile_badge_line3);
- final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(),
+ final StatusBarIcon ic = new StatusBarIcon(
entry.notification.getUser(),
- entry.notification.getNotification().icon,
+ entry.notification.getNotification().getSmallIcon(),
entry.notification.getNotification().iconLevel,
entry.notification.getNotification().number,
entry.notification.getNotification().tickerText);
@@ -1758,9 +1770,9 @@
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
- final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(),
+ final StatusBarIcon ic = new StatusBarIcon(
sbn.getUser(),
- n.icon,
+ n.getSmallIcon(),
n.iconLevel,
n.number,
n.tickerText);
@@ -1904,9 +1916,9 @@
try {
if (entry.icon != null) {
// Update the icon
- final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+ final StatusBarIcon ic = new StatusBarIcon(
notification.getUser(),
- n.icon,
+ n.getSmallIcon(),
n.iconLevel,
n.number,
n.tickerText);
@@ -1926,9 +1938,9 @@
}
if (!updateSuccessful) {
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
- final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+ final StatusBarIcon ic = new StatusBarIcon(
notification.getUser(),
- n.icon,
+ n.getSmallIcon(),
n.iconLevel,
n.number,
n.tickerText);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index f6629dd..14e491b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -33,6 +33,7 @@
import android.widget.LinearLayout;
import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.SecurityController;
@@ -42,7 +43,7 @@
// Intimately tied to the design of res/layout/signal_cluster_view.xml
public class SignalClusterView
extends LinearLayout
- implements NetworkControllerImpl.SignalCluster,
+ implements NetworkControllerImpl.SignalCallback,
SecurityController.SecurityControllerCallback {
static final String TAG = "SignalClusterView";
@@ -59,7 +60,7 @@
private int mWifiStrengthId = 0;
private boolean mIsAirplaneMode = false;
private int mAirplaneIconId = 0;
- private int mAirplaneContentDescription;
+ private String mAirplaneContentDescription;
private String mWifiDescription;
private String mEthernetDescription;
private ArrayList<PhoneState> mPhoneStates = new ArrayList<PhoneState>();
@@ -166,35 +167,36 @@
}
@Override
- public void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription) {
- mWifiVisible = visible;
- mWifiStrengthId = strengthIcon;
- mWifiDescription = contentDescription;
+ public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+ boolean activityIn, boolean activityOut, String description) {
+ mWifiVisible = statusIcon.visible;
+ mWifiStrengthId = statusIcon.icon;
+ mWifiDescription = statusIcon.contentDescription;
apply();
}
@Override
- public void setMobileDataIndicators(boolean visible, int strengthIcon, int darkStrengthIcon,
- int typeIcon, String contentDescription, String typeContentDescription,
- boolean isTypeIconWide, int subId) {
+ public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int darkStatusIcon,
+ int statusType, int qsType, boolean activityIn, boolean activityOut,
+ String typeContentDescription, String description, boolean isWide, int subId) {
PhoneState state = getOrInflateState(subId);
- state.mMobileVisible = visible;
- state.mMobileStrengthId = strengthIcon;
- state.mMobileDarkStrengthId = darkStrengthIcon;
- state.mMobileTypeId = typeIcon;
- state.mMobileDescription = contentDescription;
+ state.mMobileVisible = statusIcon.visible;
+ state.mMobileStrengthId = statusIcon.icon;
+ state.mMobileDarkStrengthId = darkStatusIcon;
+ state.mMobileTypeId = statusType;
+ state.mMobileDescription = statusIcon.contentDescription;
state.mMobileTypeDescription = typeContentDescription;
- state.mIsMobileTypeIconWide = isTypeIconWide;
+ state.mIsMobileTypeIconWide = statusType != 0 && isWide;
apply();
}
@Override
- public void setEthernetIndicators(boolean visible, int icon, String contentDescription) {
- mEthernetVisible = visible;
- mEthernetIconId = icon;
- mEthernetDescription = contentDescription;
+ public void setEthernetIndicators(IconState state) {
+ mEthernetVisible = state.visible;
+ mEthernetIconId = state.icon;
+ mEthernetDescription = state.contentDescription;
apply();
}
@@ -239,15 +241,20 @@
}
@Override
- public void setIsAirplaneMode(boolean is, int airplaneIconId, int contentDescription) {
- mIsAirplaneMode = is;
- mAirplaneIconId = airplaneIconId;
- mAirplaneContentDescription = contentDescription;
+ public void setIsAirplaneMode(IconState icon) {
+ mIsAirplaneMode = icon.visible;
+ mAirplaneIconId = icon.icon;
+ mAirplaneContentDescription = icon.contentDescription;
apply();
}
@Override
+ public void setMobileDataEnabled(boolean enabled) {
+ // Don't care.
+ }
+
+ @Override
public boolean dispatchPopulateAccessibilityEventInternal(AccessibilityEvent event) {
// Standard group layout onPopulateAccessibilityEvent() implementations
// ignore content description, so populate manually
@@ -343,8 +350,7 @@
if (mIsAirplaneMode) {
mAirplane.setImageResource(mAirplaneIconId);
- mAirplane.setContentDescription(mAirplaneContentDescription != 0 ?
- mContext.getString(mAirplaneContentDescription) : null);
+ mAirplane.setContentDescription(mAirplaneContentDescription);
mAirplane.setVisibility(View.VISIBLE);
} else {
mAirplane.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index e6847d8..3294e15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -24,6 +24,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AttributeSet;
@@ -100,13 +101,23 @@
return a.equals(b);
}
+ public boolean equalIcons(Icon a, Icon b) {
+ if (a == b) return true;
+ if (a.getType() != b.getType()) return false;
+ switch (a.getType()) {
+ case Icon.TYPE_RESOURCE:
+ return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId();
+ case Icon.TYPE_URI:
+ return a.getUriString().equals(b.getUriString());
+ default:
+ return false;
+ }
+ }
/**
* Returns whether the set succeeded.
*/
public boolean set(StatusBarIcon icon) {
- final boolean iconEquals = mIcon != null
- && streq(mIcon.iconPackage, icon.iconPackage)
- && mIcon.iconId == icon.iconId;
+ final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon);
final boolean levelEquals = iconEquals
&& mIcon.iconLevel == icon.iconLevel;
final boolean visibilityEquals = mIcon != null
@@ -167,45 +178,18 @@
}
/**
- * Returns the right icon to use for this item, respecting the iconId and
- * iconPackage (if set)
+ * Returns the right icon to use for this item
*
- * @param context Context to use to get resources if iconPackage is not set
+ * @param context Context to use to get resources
* @return Drawable for this item, or null if the package or item could not
* be found
*/
public static Drawable getIcon(Context context, StatusBarIcon icon) {
- Resources r = null;
-
- if (icon.iconPackage != null) {
- try {
- int userId = icon.user.getIdentifier();
- if (userId == UserHandle.USER_ALL) {
- userId = UserHandle.USER_OWNER;
- }
- r = context.getPackageManager()
- .getResourcesForApplicationAsUser(icon.iconPackage, userId);
- } catch (PackageManager.NameNotFoundException ex) {
- Log.e(TAG, "Icon package not found: " + icon.iconPackage);
- return null;
- }
- } else {
- r = context.getResources();
+ int userId = icon.user.getIdentifier();
+ if (userId == UserHandle.USER_ALL) {
+ userId = UserHandle.USER_OWNER;
}
-
- if (icon.iconId == 0) {
- return null;
- }
-
- try {
- return r.getDrawable(icon.iconId);
- } catch (RuntimeException e) {
- Log.w(TAG, "Icon not found in "
- + (icon.iconPackage != null ? icon.iconId : "<system>")
- + ": " + Integer.toHexString(icon.iconId));
- }
-
- return null;
+ return icon.icon.loadDrawableAsUser(context, userId);
}
public StatusBarIcon getStatusBarIcon() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 44168bc..26d1c86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.UserHandle;
import android.view.Gravity;
@@ -132,8 +133,7 @@
break;
} else {
StatusBarIcon icon = v.getStatusBarIcon();
- icon.iconPackage = iconPkg;
- icon.iconId = iconId;
+ icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
v.set(icon);
v.updateDrawable();
return;
@@ -152,4 +152,4 @@
v.set(icon);
addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 3eb6b13..e6da81e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -95,13 +95,15 @@
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
- if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)) {
+ if (mTouchingHeadsUpView && Math.abs(h) > mTouchSlop
+ && Math.abs(h) > Math.abs(x - mInitialTouchX)) {
setTrackingHeadsUp(true);
mCollapseSnoozes = h < 0;
mInitialTouchX = x;
mInitialTouchY = y;
int expandedHeight = mPickedChild.getActualHeight();
mPanel.startExpandMotion(x, y, true /* startTracking */, expandedHeight);
+ mHeadsUpManager.unpinAll();
return true;
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 38812ce..c8b8b24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -616,6 +616,9 @@
boolean expandBecauseOfFalsing) {
cancelPeek();
float target = expand ? getMaxPanelHeight() : 0.0f;
+ if (!expand) {
+ mClosing = true;
+ }
flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
}
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 8ccd222..2a9df19 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -79,6 +79,7 @@
import android.view.ThreadedRenderer;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewStub;
import android.view.WindowManager;
@@ -312,6 +313,9 @@
// tracking calls to View.setSystemUiVisibility()
int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+ // last value sent to window manager
+ private int mLastDispatchedSystemUiVisibility = ~View.SYSTEM_UI_FLAG_VISIBLE;
+
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
// XXX: gesture research
@@ -775,9 +779,9 @@
(SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
final SignalClusterView signalClusterQs =
(SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
- mNetworkController.addSignalCluster(signalCluster);
- mNetworkController.addSignalCluster(signalClusterKeyguard);
- mNetworkController.addSignalCluster(signalClusterQs);
+ mNetworkController.addSignalCallback(signalCluster);
+ mNetworkController.addSignalCallback(signalClusterKeyguard);
+ mNetworkController.addSignalCallback(signalClusterQs);
signalCluster.setSecurityController(mSecurityController);
signalCluster.setNetworkController(mNetworkController);
signalClusterKeyguard.setSecurityController(mSecurityController);
@@ -1194,8 +1198,7 @@
}
private void updateShowSearchHoldoff() {
- mShowSearchHoldoff = mContext.getResources().getInteger(
- R.integer.config_show_search_delay);
+ mShowSearchHoldoff = ViewConfiguration.getLongPressTimeout();
}
private void updateNotificationShade() {
@@ -1599,9 +1602,9 @@
if (DEBUG_MEDIA) {
Log.v(TAG, "DEBUG_MEDIA: updating album art for notification " + mMediaNotificationKey
- + " metadata=" + mMediaMetadata
- + " metaDataChanged=" + metaDataChanged
- + " state=" + mState);
+ + " metadata=" + mMediaMetadata
+ + " metaDataChanged=" + metaDataChanged
+ + " state=" + mState);
}
Bitmap artworkBitmap = null;
@@ -1869,24 +1872,30 @@
@Override
public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
if (inPinnedMode) {
- // We need to ensure that the touchable region is updated before the window will be
- // resized, in order to not catch any touches. A layout will ensure that
- // onComputeInternalInsets will be called and after that we can resize the layout. Let's
- // make sure that the window stays small for one frame until the touchableRegion is set.
- mNotificationPanel.requestLayout();
mStatusBarWindowManager.setHeadsUpShowing(true);
mStatusBarWindowManager.setForceStatusBarVisible(true);
- mStatusBarWindowManager.setForceWindowCollapsed(true);
- mNotificationPanel.post(new Runnable() {
- @Override
- public void run() {
- mStatusBarWindowManager.setForceWindowCollapsed(false);
- }
- });
+ if (mNotificationPanel.isFullyCollapsed()) {
+ // We need to ensure that the touchable region is updated before the window will be
+ // resized, in order to not catch any touches. A layout will ensure that
+ // onComputeInternalInsets will be called and after that we can resize the layout. Let's
+ // make sure that the window stays small for one frame until the touchableRegion is set.
+ mNotificationPanel.requestLayout();
+ mStatusBarWindowManager.setForceWindowCollapsed(true);
+ mNotificationPanel.post(new Runnable() {
+ @Override
+ public void run() {
+ mStatusBarWindowManager.setForceWindowCollapsed(false);
+ }
+ });
+ }
} else {
- if (!mNotificationPanel.isFullyCollapsed()) {
+ if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
+ // We are currently tracking or is open and the shade doesn't need to be kept
+ // open artificially.
mStatusBarWindowManager.setHeadsUpShowing(false);
} else {
+ // we need to keep the panel open artificially, let's wait until the animation
+ // is finished.
mHeadsUpManager.setHeadsUpGoingAway(true);
mStackScroller.runAfterAnimationFinished(new Runnable() {
@Override
@@ -2481,7 +2490,10 @@
private void notifyUiVisibilityChanged(int vis) {
try {
- mWindowManagerService.statusBarVisibilityChanged(vis);
+ if (mLastDispatchedSystemUiVisibility != vis) {
+ mWindowManagerService.statusBarVisibilityChanged(vis);
+ mLastDispatchedSystemUiVisibility = vis;
+ }
} catch (RemoteException ex) {
}
}
@@ -3075,6 +3087,16 @@
}
mContext.unregisterReceiver(mBroadcastReceiver);
mAssistManager.destroy();
+
+ final SignalClusterView signalCluster =
+ (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster);
+ final SignalClusterView signalClusterKeyguard =
+ (SignalClusterView) mKeyguardStatusBar.findViewById(R.id.signal_cluster);
+ final SignalClusterView signalClusterQs =
+ (SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
+ mNetworkController.addSignalCallback(signalCluster);
+ mNetworkController.addSignalCallback(signalClusterKeyguard);
+ mNetworkController.addSignalCallback(signalClusterQs);
}
private boolean mDemoModeAllowed;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 954eb10..0ef0fd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -67,11 +67,12 @@
private static final String TAG = "QSTileHost";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- private static final String TILES_SETTING = "sysui_qs_tiles";
+ protected static final String TILES_SETTING = "sysui_qs_tiles";
private final Context mContext;
private final PhoneStatusBar mStatusBar;
private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>();
+ private final ArrayList<String> mTileSpecs = new ArrayList<>();
private final Observer mObserver = new Observer();
private final BluetoothController mBluetooth;
private final LocationController mLocation;
@@ -81,7 +82,7 @@
private final HotspotController mHotspot;
private final CastController mCast;
private final Looper mLooper;
- private final CurrentUserTracker mUserTracker;
+ protected final CurrentUserTracker mUserTracker;
private final FlashlightController mFlashlight;
private final UserSwitcherController mUserSwitcherController;
private final KeyguardMonitor mKeyguard;
@@ -224,6 +225,7 @@
private void recreateTiles() {
if (DEBUG) Log.d(TAG, "Recreating tiles");
final List<String> tileSpecs = loadTileSpecs();
+ if (tileSpecs.equals(mTileSpecs)) return;
for (Map.Entry<String, QSTile<?>> tile : mTiles.entrySet()) {
if (!tileSpecs.contains(tile.getKey())) {
if (DEBUG) Log.d(TAG, "Destroying tile: " + tile.getKey());
@@ -243,7 +245,8 @@
}
}
}
- if (mTiles.equals(newTiles)) return;
+ mTileSpecs.clear();
+ mTileSpecs.addAll(tileSpecs);
mTiles.clear();
mTiles.putAll(newTiles);
if (mCallback != null) {
@@ -251,7 +254,7 @@
}
}
- private QSTile<?> createTile(String tileSpec) {
+ protected QSTile<?> createTile(String tileSpec) {
if (tileSpec.equals("wifi")) return new WifiTile(this);
else if (tileSpec.equals("bt")) return new BluetoothTile(this);
else if (tileSpec.equals("inversion")) return new ColorInversionTile(this);
@@ -267,7 +270,7 @@
else throw new IllegalArgumentException("Bad tile spec: " + tileSpec);
}
- private List<String> loadTileSpecs() {
+ protected List<String> loadTileSpecs() {
final Resources res = mContext.getResources();
final String defaultTileList = res.getString(R.string.quick_settings_tiles_default);
String tileList = Secure.getStringForUser(mContext.getContentResolver(), TILES_SETTING,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index acf2f57..450fdd9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -45,7 +45,7 @@
public static final long ANIMATION_DURATION = 220;
private static final float SCRIM_BEHIND_ALPHA = 0.62f;
- private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.55f;
+ private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.45f;
private static final float SCRIM_BEHIND_ALPHA_UNLOCKING = 0.2f;
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
private static final int TAG_KEY_ANIM = R.id.scrim;
@@ -115,6 +115,9 @@
if (mFraction != fraction) {
mFraction = fraction;
scheduleUpdate();
+ if (mPinnedHeadsUpCount != 0) {
+ updateHeadsUpScrim(false);
+ }
}
}
@@ -425,12 +428,16 @@
}
private float calculateHeadsUpAlpha() {
+ float alpha;
if (mPinnedHeadsUpCount >= 2) {
- return 1.0f;
+ alpha = 1.0f;
} else if (mPinnedHeadsUpCount == 0) {
- return 0.0f;
+ alpha = 0.0f;
} else {
- return 1.0f - mTopHeadsUpDragAmount;
+ alpha = 1.0f - mTopHeadsUpDragAmount;
}
+ float expandFactor = (1.0f - mFraction);
+ expandFactor = Math.max(expandFactor, 0.0f);
+ return alpha * expandFactor;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index 895af62..03409846 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -58,7 +58,7 @@
.withEndAction(new Runnable() {
@Override
public void run() {
- mBrightnessMirror.setVisibility(View.GONE);
+ mBrightnessMirror.setVisibility(View.INVISIBLE);
}
});
}
@@ -77,12 +77,18 @@
public void setLocation(View original) {
original.getLocationInWindow(mInt2Cache);
- int originalY = mInt2Cache[1];
- mBrightnessMirror.getLocationInWindow(mInt2Cache);
- int mirrorY = mInt2Cache[1];
- mBrightnessMirror.setTranslationY(mBrightnessMirror.getTranslationY()
- + originalY - mirrorY);
+ // Original is slightly larger than the mirror, so make sure to use the center for the
+ // positioning.
+ int originalX = mInt2Cache[0] + original.getWidth()/2;
+ int originalY = mInt2Cache[1];
+ mBrightnessMirror.setTranslationX(0);
+ mBrightnessMirror.setTranslationY(0);
+ mBrightnessMirror.getLocationInWindow(mInt2Cache);
+ int mirrorX = mInt2Cache[0] + mBrightnessMirror.getWidth()/2;
+ int mirrorY = mInt2Cache[1];
+ mBrightnessMirror.setTranslationX(originalX - mirrorX);
+ mBrightnessMirror.setTranslationY(originalY - mirrorY);
}
public View getMirror() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
new file mode 100644
index 0000000..7f52191
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -0,0 +1,181 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.telephony.SubscriptionInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * Implements network listeners and forwards the calls along onto other listeners but on
+ * the current or specified Looper.
+ */
+public class CallbackHandler extends Handler implements EmergencyListener, SignalCallback {
+ private static final int MSG_EMERGENCE_CHANGED = 0;
+ private static final int MSG_SUBS_CHANGED = 1;
+ private static final int MSG_NO_SIM_VISIBLE_CHANGED = 2;
+ private static final int MSG_ETHERNET_CHANGED = 3;
+ private static final int MSG_AIRPLANE_MODE_CHANGED = 4;
+ private static final int MSG_MOBILE_DATA_ENABLED_CHANGED = 5;
+ private static final int MSG_ADD_REMOVE_EMERGENCY = 6;
+ private static final int MSG_ADD_REMOVE_SIGNAL = 7;
+
+ // All the callbacks.
+ private final ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<>();
+ private final ArrayList<SignalCallback> mSignalCallbacks = new ArrayList<>();
+
+ public CallbackHandler() {
+ super();
+ }
+
+ @VisibleForTesting
+ CallbackHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_EMERGENCE_CHANGED:
+ for (EmergencyListener listener : mEmergencyListeners) {
+ listener.setEmergencyCallsOnly(msg.arg1 != 0);
+ }
+ break;
+ case MSG_SUBS_CHANGED:
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setSubs((List<SubscriptionInfo>) msg.obj);
+ }
+ break;
+ case MSG_NO_SIM_VISIBLE_CHANGED:
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setNoSims(msg.arg1 != 0);
+ }
+ break;
+ case MSG_ETHERNET_CHANGED:
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setEthernetIndicators((IconState) msg.obj);
+ }
+ break;
+ case MSG_AIRPLANE_MODE_CHANGED:
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setIsAirplaneMode((IconState) msg.obj);
+ }
+ break;
+ case MSG_MOBILE_DATA_ENABLED_CHANGED:
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setMobileDataEnabled(msg.arg1 != 0);
+ }
+ break;
+ case MSG_ADD_REMOVE_EMERGENCY:
+ if (msg.arg1 != 0) {
+ mEmergencyListeners.add((EmergencyListener) msg.obj);
+ } else {
+ mEmergencyListeners.remove((EmergencyListener) msg.obj);
+ }
+ break;
+ case MSG_ADD_REMOVE_SIGNAL:
+ if (msg.arg1 != 0) {
+ mSignalCallbacks.add((SignalCallback) msg.obj);
+ } else {
+ mSignalCallbacks.remove((SignalCallback) msg.obj);
+ }
+ break;
+ }
+ }
+
+ @Override
+ public void setWifiIndicators(final boolean enabled, final IconState statusIcon,
+ final IconState qsIcon, final boolean activityIn, final boolean activityOut,
+ final String description) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ for (SignalCallback callback : mSignalCallbacks) {
+ callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
+ description);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void setMobileDataIndicators(final IconState statusIcon, final IconState qsIcon,
+ final int darkStatusIcon, final int statusType, final int qsType,
+ final boolean activityIn, final boolean activityOut,
+ final String typeContentDescription, final String description, final boolean isWide,
+ final int subId) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ for (SignalCallback signalCluster : mSignalCallbacks) {
+ signalCluster.setMobileDataIndicators(statusIcon, qsIcon, darkStatusIcon,
+ statusType, qsType, activityIn, activityOut, typeContentDescription,
+ description, isWide, subId);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void setSubs(List<SubscriptionInfo> subs) {
+ obtainMessage(MSG_SUBS_CHANGED, subs).sendToTarget();
+ }
+
+ @Override
+ public void setNoSims(boolean show) {
+ obtainMessage(MSG_NO_SIM_VISIBLE_CHANGED, show ? 1 : 0, 0).sendToTarget();
+ }
+
+ @Override
+ public void setMobileDataEnabled(boolean enabled) {
+ obtainMessage(MSG_MOBILE_DATA_ENABLED_CHANGED, enabled ? 1 : 0, 0).sendToTarget();
+ }
+
+ @Override
+ public void setEmergencyCallsOnly(boolean emergencyOnly) {
+ obtainMessage(MSG_EMERGENCE_CHANGED, emergencyOnly ? 1 : 0, 0).sendToTarget();
+ }
+
+ @Override
+ public void setEthernetIndicators(IconState icon) {
+ obtainMessage(MSG_ETHERNET_CHANGED, icon).sendToTarget();;
+ }
+
+ @Override
+ public void setIsAirplaneMode(IconState icon) {
+ obtainMessage(MSG_AIRPLANE_MODE_CHANGED, icon).sendToTarget();;
+ }
+
+ public void setListening(EmergencyListener listener, boolean listening) {
+ obtainMessage(MSG_ADD_REMOVE_EMERGENCY, listening ? 1 : 0, 0, listener).sendToTarget();
+ }
+
+ public void setListening(SignalCallback listener, boolean listening) {
+ obtainMessage(MSG_ADD_REMOVE_SIGNAL, listening ? 1 : 0, 0, listener).sendToTarget();
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
index 9c044c4..a2cd50a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EthernetSignalController.java
@@ -18,22 +18,16 @@
import android.content.Context;
import android.net.NetworkCapabilities;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
-
-import java.util.List;
-import java.util.Objects;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
public class EthernetSignalController extends
SignalController<SignalController.State, SignalController.IconGroup> {
public EthernetSignalController(Context context,
- List<NetworkSignalChangedCallback> signalCallbacks,
- List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+ CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
super("EthernetSignalController", context, NetworkCapabilities.TRANSPORT_ETHERNET,
- signalCallbacks, signalClusters, networkController);
+ callbackHandler, networkController);
mCurrentState.iconGroup = mLastState.iconGroup = new IconGroup(
"Ethernet Icons",
EthernetIcons.ETHERNET_ICONS,
@@ -49,11 +43,8 @@
String contentDescription = getStringIfExists(getContentDescription());
// TODO: wire up data transfer using WifiSignalPoller.
- int signalClustersLength = mSignalClusters.size();
- for (int i = 0; i < signalClustersLength; i++) {
- mSignalClusters.get(i).setEthernetIndicators(ethernetVisible, getCurrentIconId(),
- contentDescription);
- }
+ mCallbackHandler.setEthernetIndicators(new IconState(ethernetVisible, getCurrentIconId(),
+ contentDescription));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 98822a9..14060df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -179,7 +179,7 @@
if (alert) {
HeadsUpEntry headsUpEntry = mHeadsUpEntries.get(headsUp.key);
headsUpEntry.updateEntry();
- setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
+ setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(headsUp));
}
}
@@ -190,13 +190,21 @@
headsUpEntry.setEntry(entry);
mHeadsUpEntries.put(entry.key, headsUpEntry);
entry.row.setHeadsUp(true);
- setEntryPinned(headsUpEntry, !mIsExpanded /* isPinned */);
+ setEntryPinned(headsUpEntry, shouldHeadsUpBecomePinned(entry));
for (OnHeadsUpChangedListener listener : mListeners) {
listener.onHeadsUpStateChanged(entry, true);
}
entry.row.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
}
+ private boolean shouldHeadsUpBecomePinned(NotificationData.Entry entry) {
+ return !mIsExpanded || hasFullScreenIntent(entry);
+ }
+
+ private boolean hasFullScreenIntent(NotificationData.Entry entry) {
+ return entry.notification.getNotification().fullScreenIntent != null;
+ }
+
private void setEntryPinned(HeadsUpEntry headsUpEntry, boolean isPinned) {
ExpandableNotificationRow row = headsUpEntry.entry.row;
if (row.isPinned() != isPinned) {
@@ -350,6 +358,10 @@
}
public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+ if (mIsExpanded) {
+ // The touchable region is always the full area when expanded
+ return;
+ }
if (mHasPinnedNotification) {
int minX = Integer.MAX_VALUE;
int maxX = 0;
@@ -445,7 +457,6 @@
if (isExpanded != mIsExpanded) {
mIsExpanded = isExpanded;
if (isExpanded) {
- unpinAll();
// make sure our state is sane
mWaitingOnCollapseWhenGoingAway = false;
mHeadsUpGoingAway = false;
@@ -542,7 +553,7 @@
earliestRemovaltime = currentTime + mMinimumDisplayTime;
postTime = Math.max(postTime, currentTime);
removeAutoRemovalCallbacks();
- if (canEntryDecay()) {
+ if (!hasFullScreenIntent(entry)) {
long finishTime = postTime + mHeadsUpNotificationDecay;
long removeDelay = Math.max(finishTime - currentTime, mMinimumDisplayTime);
mHandler.postDelayed(mRemoveHeadsUpRunnable, removeDelay);
@@ -550,10 +561,6 @@
updateSortOrder(HeadsUpEntry.this);
}
- private boolean canEntryDecay() {
- return entry.notification.getNotification().fullScreenIntent == null;
- }
-
@Override
public int compareTo(HeadsUpEntry o) {
return postTime < o.postTime ? 1
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 22bf47c..5515873 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.Intent;
import android.net.NetworkCapabilities;
+import android.os.Looper;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -31,12 +32,10 @@
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
import java.io.PrintWriter;
-import java.util.List;
import java.util.Objects;
@@ -66,17 +65,17 @@
// TODO: Reduce number of vars passed in, if we have the NetworkController, probably don't
// need listener lists anymore.
public MobileSignalController(Context context, Config config, boolean hasMobileData,
- TelephonyManager phone, List<NetworkSignalChangedCallback> signalCallbacks,
- List<SignalCluster> signalClusters, NetworkControllerImpl networkController,
- SubscriptionInfo info) {
+ TelephonyManager phone, CallbackHandler callbackHandler,
+ NetworkControllerImpl networkController, SubscriptionInfo info, Looper receiverLooper) {
super("MobileSignalController(" + info.getSubscriptionId() + ")", context,
- NetworkCapabilities.TRANSPORT_CELLULAR, signalCallbacks, signalClusters,
+ NetworkCapabilities.TRANSPORT_CELLULAR, callbackHandler,
networkController);
mNetworkToIconLookup = new SparseArray<>();
mConfig = config;
mPhone = phone;
mSubscriptionInfo = info;
- mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId());
+ mPhoneStateListener = new MobilePhoneStateListener(info.getSubscriptionId(),
+ receiverLooper);
mNetworkNameSeparator = getStringIfExists(R.string.status_bar_network_name_separator);
mNetworkNameDefault = getStringIfExists(
com.android.internal.R.string.lockscreen_carrier_default);
@@ -199,41 +198,29 @@
boolean showDataIcon = mCurrentState.dataConnected && mCurrentState.inetForNetwork != 0
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING;
+ IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
+ getCurrentIconId(), contentDescription);
+
+ int qsTypeIcon = 0;
+ IconState qsIcon = null;
+ String description = null;
// Only send data sim callbacks to QS.
if (mCurrentState.dataSim) {
- int qsTypeIcon = showDataIcon ? icons.mQsDataType[mCurrentState.inetForNetwork] : 0;
- int length = mSignalsChangedCallbacks.size();
- for (int i = 0; i < length; i++) {
- mSignalsChangedCallbacks.get(i).onMobileDataSignalChanged(mCurrentState.enabled
- && !mCurrentState.isEmergency,
- getQsCurrentIconId(), contentDescription,
- qsTypeIcon,
- mCurrentState.dataConnected
- && !mCurrentState.carrierNetworkChangeMode
- && mCurrentState.activityIn,
- mCurrentState.dataConnected
- && !mCurrentState.carrierNetworkChangeMode
- && mCurrentState.activityOut,
- dataContentDescription,
- mCurrentState.isEmergency ? null : mCurrentState.networkName,
- // Only wide if actually showing something.
- icons.mIsWide && qsTypeIcon != 0);
- }
+ qsTypeIcon = showDataIcon ? icons.mQsDataType[mCurrentState.inetForNetwork] : 0;
+ qsIcon = new IconState(mCurrentState.enabled
+ && !mCurrentState.isEmergency, getQsCurrentIconId(), contentDescription);
+ description = mCurrentState.isEmergency ? null : mCurrentState.networkName;
}
+ boolean activityIn = mCurrentState.dataConnected
+ && !mCurrentState.carrierNetworkChangeMode
+ && mCurrentState.activityIn;
+ boolean activityOut = mCurrentState.dataConnected
+ && !mCurrentState.carrierNetworkChangeMode
+ && mCurrentState.activityOut;
int typeIcon = showDataIcon ? icons.mDataType : 0;
- int signalClustersLength = mSignalClusters.size();
- for (int i = 0; i < signalClustersLength; i++) {
- mSignalClusters.get(i).setMobileDataIndicators(
- mCurrentState.enabled && !mCurrentState.airplaneMode,
- getCurrentIconId(),
- getCurrentDarkIconId(),
- typeIcon,
- contentDescription,
- dataContentDescription,
- // Only wide if actually showing something.
- icons.mIsWide && typeIcon != 0,
- mSubscriptionInfo.getSubscriptionId());
- }
+ mCallbackHandler.setMobileDataIndicators(statusIcon, qsIcon, getCurrentDarkIconId(),
+ typeIcon, qsTypeIcon, activityIn, activityOut, dataContentDescription, description,
+ icons.mIsWide, mSubscriptionInfo.getSubscriptionId());
}
private int getCurrentDarkIconId() {
@@ -425,8 +412,8 @@
}
class MobilePhoneStateListener extends PhoneStateListener {
- public MobilePhoneStateListener(int subId) {
- super(subId);
+ public MobilePhoneStateListener(int subId, Looper looper) {
+ super(subId, looper);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 9212837..070ca63 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -16,7 +16,9 @@
package com.android.systemui.statusbar.policy;
+import android.content.Context;
import android.content.Intent;
+import android.telephony.SubscriptionInfo;
import com.android.settingslib.wifi.AccessPoint;
@@ -25,25 +27,45 @@
public interface NetworkController {
boolean hasMobileDataFeature();
- void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
- void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb);
+ void addSignalCallback(SignalCallback cb);
+ void removeSignalCallback(SignalCallback cb);
void setWifiEnabled(boolean enabled);
void onUserSwitched(int newUserId);
AccessPointController getAccessPointController();
MobileDataController getMobileDataController();
- public interface NetworkSignalChangedCallback {
- void onWifiSignalChanged(boolean enabled, boolean connected, int wifiSignalIconId,
- boolean activityIn, boolean activityOut,
- String wifiSignalContentDescriptionId, String description);
- void onMobileDataSignalChanged(boolean enabled, int mobileSignalIconId,
- String mobileSignalContentDescriptionId, int dataTypeIconId,
- boolean activityIn, boolean activityOut,
- String dataTypeContentDescriptionId, String description,
- boolean isDataTypeIconWide);
- void onNoSimVisibleChanged(boolean visible);
- void onAirplaneModeChanged(boolean enabled);
- void onMobileDataEnabled(boolean enabled);
+ public interface SignalCallback {
+ void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+ boolean activityIn, boolean activityOut, String description);
+
+ void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int darkStatusIcon,
+ int statusType, int qsType, boolean activityIn, boolean activityOut,
+ String typeContentDescription, String description, boolean isWide, int subId);
+ void setSubs(List<SubscriptionInfo> subs);
+ void setNoSims(boolean show);
+
+ void setEthernetIndicators(IconState icon);
+
+ void setIsAirplaneMode(IconState icon);
+
+ void setMobileDataEnabled(boolean enabled);
+ }
+
+ public static class IconState {
+ public final boolean visible;
+ public final int icon;
+ public final String contentDescription;
+
+ public IconState(boolean visible, int icon, String contentDescription) {
+ this.visible = visible;
+ this.icon = icon;
+ this.contentDescription = contentDescription;
+ }
+
+ public IconState(boolean visible, int icon, int contentDescription,
+ Context context) {
+ this(visible, icon, context.getString(contentDescription));
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 92e0365..484f66a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -28,6 +28,7 @@
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
@@ -36,6 +37,7 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.MathUtils;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.PhoneConstants;
@@ -61,7 +63,7 @@
static final String TAG = "NetworkController";
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// additional diagnostics, but not logspew
- static final boolean CHATTY = Log.isLoggable(TAG + ".Chat", Log.DEBUG);
+ static final boolean CHATTY = Log.isLoggable(TAG + "Chat", Log.DEBUG);
private final Context mContext;
private final TelephonyManager mPhone;
@@ -99,20 +101,19 @@
private boolean mHasNoSims;
private Locale mLocale = null;
// This list holds our ordering.
- private List<SubscriptionInfo> mCurrentSubscriptions
- = new ArrayList<SubscriptionInfo>();
+ private List<SubscriptionInfo> mCurrentSubscriptions = new ArrayList<>();
- // All the callbacks.
- private ArrayList<EmergencyListener> mEmergencyListeners = new ArrayList<EmergencyListener>();
- private ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
- private ArrayList<NetworkSignalChangedCallback> mSignalsChangedCallbacks =
- new ArrayList<NetworkSignalChangedCallback>();
@VisibleForTesting
boolean mListening;
// The current user ID.
private int mCurrentUserId;
+ // Handler that all broadcasts are received on.
+ private final Handler mReceiverHandler;
+ // Handler that all callbacks are made on.
+ private final CallbackHandler mCallbackHandler;
+
/**
* Construct this controller object and register for updates.
*/
@@ -120,20 +121,24 @@
this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
(WifiManager) context.getSystemService(Context.WIFI_SERVICE),
- SubscriptionManager.from(context), Config.readConfig(context),
+ SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
+ new CallbackHandler(),
new AccessPointControllerImpl(context, bgLooper),
new MobileDataControllerImpl(context));
- registerListeners();
+ mReceiverHandler.post(mRegisterListeners);
}
@VisibleForTesting
NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
TelephonyManager telephonyManager, WifiManager wifiManager,
- SubscriptionManager subManager, Config config,
+ SubscriptionManager subManager, Config config, Looper bgLooper,
+ CallbackHandler callbackHandler,
AccessPointControllerImpl accessPointController,
MobileDataControllerImpl mobileDataController) {
mContext = context;
mConfig = config;
+ mReceiverHandler = new Handler(bgLooper);
+ mCallbackHandler = callbackHandler;
mSubscriptionManager = subManager;
mConnectivityManager = connectivityManager;
@@ -141,7 +146,7 @@
mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
// telephony
- mPhone = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ mPhone = telephonyManager;
// wifi
mWifiManager = wifiManager;
@@ -154,14 +159,13 @@
mMobileDataController.setCallback(new MobileDataControllerImpl.Callback() {
@Override
public void onMobileDataEnabled(boolean enabled) {
- notifyMobileDataEnabled(enabled);
+ mCallbackHandler.setMobileDataEnabled(enabled);
}
});
mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,
- mSignalsChangedCallbacks, mSignalClusters, this);
+ mCallbackHandler, this);
- mEthernetSignalController = new EthernetSignalController(mContext, mSignalsChangedCallbacks,
- mSignalClusters, this);
+ mEthernetSignalController = new EthernetSignalController(mContext, mCallbackHandler, this);
// AIRPLANE_MODE_CHANGED is sent at boot; we've probably already missed it
updateAirplaneMode(true /* force callback */);
@@ -186,7 +190,7 @@
filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
- mContext.registerReceiver(this, filter);
+ mContext.registerReceiver(this, filter, null, mReceiverHandler);
mListening = true;
updateMobileControllers();
@@ -216,15 +220,8 @@
}
public void addEmergencyListener(EmergencyListener listener) {
- mEmergencyListeners.add(listener);
- listener.setEmergencyCallsOnly(isEmergencyOnly());
- }
-
- private void notifyMobileDataEnabled(boolean enabled) {
- final int length = mSignalsChangedCallbacks.size();
- for (int i = 0; i < length; i++) {
- mSignalsChangedCallbacks.get(i).onMobileDataEnabled(enabled);
- }
+ mCallbackHandler.setListening(listener, true);
+ mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
}
public boolean hasMobileDataFeature() {
@@ -276,19 +273,15 @@
* so we should recheck and send out the state to listeners.
*/
void recalculateEmergency() {
- final boolean emergencyOnly = isEmergencyOnly();
- final int length = mEmergencyListeners.size();
- for (int i = 0; i < length; i++) {
- mEmergencyListeners.get(i).setEmergencyCallsOnly(emergencyOnly);
- }
+ mCallbackHandler.setEmergencyCallsOnly(isEmergencyOnly());
}
- public void addSignalCluster(SignalCluster cluster) {
- mSignalClusters.add(cluster);
- cluster.setSubs(mCurrentSubscriptions);
- cluster.setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
- R.string.accessibility_airplane_mode);
- cluster.setNoSims(mHasNoSims);
+ public void addSignalCallback(SignalCallback cb) {
+ mCallbackHandler.setListening(cb, true);
+ mCallbackHandler.setSubs(mCurrentSubscriptions);
+ mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
+ TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
+ mCallbackHandler.setNoSims(mHasNoSims);
mWifiSignalController.notifyListeners();
mEthernetSignalController.notifyListeners();
for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
@@ -296,19 +289,9 @@
}
}
- public void addNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
- mSignalsChangedCallbacks.add(cb);
- cb.onAirplaneModeChanged(mAirplaneMode);
- cb.onNoSimVisibleChanged(mHasNoSims);
- mWifiSignalController.notifyListeners();
- mEthernetSignalController.notifyListeners();
- for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
- mobileSignalController.notifyListeners();
- }
- }
-
- public void removeNetworkSignalChangedCallback(NetworkSignalChangedCallback cb) {
- mSignalsChangedCallbacks.remove(cb);
+ @Override
+ public void removeSignalCallback(SignalCallback cb) {
+ mCallbackHandler.setListening(cb, false);
}
@Override
@@ -427,10 +410,7 @@
: lhs.getSimSlotIndex() - rhs.getSimSlotIndex();
}
});
- final int length = mSignalClusters.size();
- for (int i = 0; i < length; i++) {
- mSignalClusters.get(i).setSubs(subscriptions);
- }
+ mCallbackHandler.setSubs(subscriptions);
mCurrentSubscriptions = subscriptions;
HashMap<Integer, MobileSignalController> cachedControllers =
@@ -444,8 +424,8 @@
mMobileSignalControllers.put(subId, cachedControllers.remove(subId));
} else {
MobileSignalController controller = new MobileSignalController(mContext, mConfig,
- mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks, mSignalClusters,
- this, subscriptions.get(i));
+ mHasMobileDataFeature, mPhone, mCallbackHandler,
+ this, subscriptions.get(i), mReceiverHandler.getLooper());
mMobileSignalControllers.put(subId, controller);
if (subscriptions.get(i).getSimSlotIndex() == 0) {
mDefaultSignalController = controller;
@@ -521,17 +501,9 @@
* notifyAllListeners.
*/
private void notifyListeners() {
- int length = mSignalClusters.size();
- for (int i = 0; i < length; i++) {
- mSignalClusters.get(i).setIsAirplaneMode(mAirplaneMode, TelephonyIcons.FLIGHT_MODE_ICON,
- R.string.accessibility_airplane_mode);
- mSignalClusters.get(i).setNoSims(mHasNoSims);
- }
- int signalsChangedLength = mSignalsChangedCallbacks.size();
- for (int i = 0; i < signalsChangedLength; i++) {
- mSignalsChangedCallbacks.get(i).onAirplaneModeChanged(mAirplaneMode);
- mSignalsChangedCallbacks.get(i).onNoSimVisibleChanged(mHasNoSims);
- }
+ mCallbackHandler.setIsAirplaneMode(new IconState(mAirplaneMode,
+ TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode, mContext));
+ mCallbackHandler.setNoSims(mHasNoSims);
}
/**
@@ -630,17 +602,15 @@
controller.resetLastState();
}
mWifiSignalController.resetLastState();
- registerListeners();
+ mReceiverHandler.post(mRegisterListeners);
notifyAllListeners();
} else if (mDemoMode && command.equals(COMMAND_NETWORK)) {
String airplane = args.getString("airplane");
if (airplane != null) {
boolean show = airplane.equals("show");
- int length = mSignalClusters.size();
- for (int i = 0; i < length; i++) {
- mSignalClusters.get(i).setIsAirplaneMode(show, TelephonyIcons.FLIGHT_MODE_ICON,
- R.string.accessibility_airplane_mode);
- }
+ mCallbackHandler.setIsAirplaneMode(new IconState(show,
+ TelephonyIcons.FLIGHT_MODE_ICON, R.string.accessibility_airplane_mode,
+ mContext));
}
String fully = args.getString("fully");
if (fully != null) {
@@ -664,32 +634,21 @@
}
String sims = args.getString("sims");
if (sims != null) {
- int num = Integer.parseInt(sims);
- List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
+ int num = MathUtils.constrain(Integer.parseInt(sims), 1, 8);
+ List<SubscriptionInfo> subs = new ArrayList<>();
if (num != mMobileSignalControllers.size()) {
mMobileSignalControllers.clear();
int start = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
for (int i = start /* get out of normal index range */; i < start + num; i++) {
- SubscriptionInfo info = new SubscriptionInfo(i, "", i, "", "", 0, 0, "", 0,
- null, 0, 0, "");
- subs.add(info);
- mMobileSignalControllers.put(i, new MobileSignalController(mContext,
- mConfig, mHasMobileDataFeature, mPhone, mSignalsChangedCallbacks,
- mSignalClusters, this, info));
+ subs.add(addSignalController(i, i));
}
}
- final int n = mSignalClusters.size();
- for (int i = 0; i < n; i++) {
- mSignalClusters.get(i).setSubs(subs);
- }
+ mCallbackHandler.setSubs(subs);
}
String nosim = args.getString("nosim");
if (nosim != null) {
boolean show = nosim.equals("show");
- final int n = mSignalClusters.size();
- for (int i = 0; i < n; i++) {
- mSignalClusters.get(i).setNoSims(show);
- }
+ mCallbackHandler.setNoSims(show);
}
String mobile = args.getString("mobile");
if (mobile != null) {
@@ -697,6 +656,16 @@
String datatype = args.getString("datatype");
String slotString = args.getString("slot");
int slot = TextUtils.isEmpty(slotString) ? 0 : Integer.parseInt(slotString);
+ slot = MathUtils.constrain(slot, 0, 8);
+ // Ensure we have enough sim slots
+ List<SubscriptionInfo> subs = new ArrayList<>();
+ while (mMobileSignalControllers.size() <= slot) {
+ int nextSlot = mMobileSignalControllers.size();
+ subs.add(addSignalController(nextSlot, nextSlot));
+ }
+ if (!subs.isEmpty()) {
+ mCallbackHandler.setSubs(subs);
+ }
// Hack to index linearly for easy use.
MobileSignalController controller = mMobileSignalControllers
.values().toArray(new MobileSignalController[0])[slot];
@@ -733,6 +702,15 @@
}
}
+ private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
+ SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
+ null, 0, 0, "");
+ mMobileSignalControllers.put(id, new MobileSignalController(mContext,
+ mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info,
+ mReceiverHandler.getLooper()));
+ return info;
+ }
+
private final OnSubscriptionsChangedListener mSubscriptionListener =
new OnSubscriptionsChangedListener() {
@Override
@@ -741,28 +719,21 @@
};
};
- public interface SignalCluster {
- void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription);
-
- void setMobileDataIndicators(boolean visible, int strengthIcon, int darkStrengthIcon,
- int typeIcon, String contentDescription, String typeContentDescription,
- boolean isTypeIconWide, int subId);
- void setSubs(List<SubscriptionInfo> subs);
- void setNoSims(boolean show);
-
- void setEthernetIndicators(boolean visible, int icon, String contentDescription);
-
- void setIsAirplaneMode(boolean is, int airplaneIcon, int contentDescription);
- }
+ /**
+ * Used to register listeners from the BG Looper, this way the PhoneStateListeners that
+ * get created will also run on the BG Looper.
+ */
+ private final Runnable mRegisterListeners = new Runnable() {
+ @Override
+ public void run() {
+ registerListeners();
+ }
+ };
public interface EmergencyListener {
void setEmergencyCallsOnly(boolean emergencyOnly);
}
- public interface CarrierLabelListener {
- void setCarrierLabel(String label);
- }
-
@VisibleForTesting
static class Config {
boolean showAtLeast3G = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java
new file mode 100644
index 0000000..83a7d3d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalCallbackAdapter.java
@@ -0,0 +1,64 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.telephony.SubscriptionInfo;
+
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+
+import java.util.List;
+
+
+/**
+ * Provides empty implementations of SignalCallback for those that only want some of
+ * the callbacks.
+ */
+public class SignalCallbackAdapter implements SignalCallback {
+
+ @Override
+ public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
+ boolean activityIn, boolean activityOut, String description) {
+ }
+
+ @Override
+ public void setMobileDataIndicators(IconState statusIcon, IconState qsIcon,
+ int darkStatusIcon, int statusType, int qsType, boolean activityIn,
+ boolean activityOut, String typeContentDescription, String description,
+ boolean isWide, int subId) {
+ }
+
+ @Override
+ public void setSubs(List<SubscriptionInfo> subs) {
+ }
+
+ @Override
+ public void setNoSims(boolean show) {
+ }
+
+ @Override
+ public void setEthernetIndicators(IconState icon) {
+ }
+
+ @Override
+ public void setIsAirplaneMode(IconState icon) {
+ }
+
+ @Override
+ public void setMobileDataEnabled(boolean enabled) {
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
index f3322a1..97b530c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SignalController.java
@@ -21,11 +21,7 @@
import android.text.format.DateFormat;
import android.util.Log;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
-
import java.io.PrintWriter;
-import java.util.List;
/**
@@ -49,24 +45,22 @@
// The owner of the SignalController (i.e. NetworkController will maintain the following
// lists and call notifyListeners whenever the list has changed to ensure everyone
// is aware of current state.
- protected final List<NetworkSignalChangedCallback> mSignalsChangedCallbacks;
- protected final List<SignalCluster> mSignalClusters;
protected final NetworkControllerImpl mNetworkController;
+ protected final CallbackHandler mCallbackHandler;
+
// Save the previous HISTORY_SIZE states for logging.
private final State[] mHistory;
// Where to copy the next state into.
private int mHistoryIndex;
- public SignalController(String tag, Context context, int type,
- List<NetworkSignalChangedCallback> signalCallbacks,
- List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+ public SignalController(String tag, Context context, int type, CallbackHandler callbackHandler,
+ NetworkControllerImpl networkController) {
mTag = TAG + "." + tag;
mNetworkController = networkController;
mTransportType = type;
mContext = context;
- mSignalsChangedCallbacks = signalCallbacks;
- mSignalClusters = signalClusters;
+ mCallbackHandler = callbackHandler;
mCurrentState = cleanState();
mLastState = cleanState();
if (RECORD_HISTORY) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index a97ca50..9b1e72a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -29,8 +29,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
+import com.android.systemui.statusbar.policy.NetworkController.IconState;
import java.util.List;
import java.util.Objects;
@@ -43,10 +42,9 @@
private final boolean mHasMobileData;
public WifiSignalController(Context context, boolean hasMobileData,
- List<NetworkSignalChangedCallback> signalCallbacks,
- List<SignalCluster> signalClusters, NetworkControllerImpl networkController) {
+ CallbackHandler callbackHandler, NetworkControllerImpl networkController) {
super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
- signalCallbacks, signalClusters, networkController);
+ callbackHandler, networkController);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mHasMobileData = hasMobileData;
Handler handler = new WifiHandler();
@@ -82,19 +80,13 @@
String wifiDesc = wifiVisible ? mCurrentState.ssid : null;
boolean ssidPresent = wifiVisible && mCurrentState.ssid != null;
String contentDescription = getStringIfExists(getContentDescription());
- int length = mSignalsChangedCallbacks.size();
- for (int i = 0; i < length; i++) {
- mSignalsChangedCallbacks.get(i).onWifiSignalChanged(mCurrentState.enabled,
- mCurrentState.connected, getQsCurrentIconId(),
- ssidPresent && mCurrentState.activityIn,
- ssidPresent && mCurrentState.activityOut, contentDescription, wifiDesc);
- }
- int signalClustersLength = mSignalClusters.size();
- for (int i = 0; i < signalClustersLength; i++) {
- mSignalClusters.get(i).setWifiIndicators(wifiVisible, getCurrentIconId(),
- contentDescription);
- }
+ IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
+ IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
+ contentDescription);
+ mCallbackHandler.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
+ ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
+ wifiDesc);
}
/**
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 a1b0cae..bd3b9ebb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -485,7 +485,7 @@
int minStackHeight = getMinStackHeight();
int stackHeight;
float paddingOffset;
- boolean trackingHeadsUp = mTrackingHeadsUp;
+ boolean trackingHeadsUp = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp();
int normalUnfoldPositionStart = trackingHeadsUp ? mHeadsUpManager.getTopHeadsUpHeight()
: minStackHeight;
if (newStackHeight - mTopPadding - mTopPaddingOverflow >= normalUnfoldPositionStart
@@ -608,7 +608,7 @@
@Override
public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) {
- if (isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) {
+ if (!mIsExpanded && isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) {
mScrimController.setTopHeadsUpDragAmount(animView,
Math.min(Math.abs(swipeProgress - 1.0f), 1.0f));
}
@@ -618,7 +618,7 @@
public void onBeginDrag(View v) {
setSwipingInProgress(true);
mAmbientState.onBeginDrag(v);
- if (mAnimationsEnabled && !isPinnedHeadsUp(v)) {
+ if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
mDragAnimPendingChildren.add(v);
mNeedsAnimation = true;
}
@@ -710,7 +710,7 @@
if (touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
if (slidingChild instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) slidingChild;
- if (row.isHeadsUp() && row.isPinned()
+ if (!mIsExpanded && row.isHeadsUp() && row.isPinned()
&& mHeadsUpManager.getTopEntry().entry.row != row) {
continue;
}
@@ -1871,17 +1871,18 @@
boolean isHeadsUp = eventPair.second;
int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER;
boolean onBottom = false;
+ boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
if (!mIsExpanded && !isHeadsUp) {
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
- } else if (mAddedHeadsUpChildren.contains(row) || (row.isPinned() && !mIsExpanded)) {
- if (row.isPinned() || shouldHunAppearFromBottom(row)) {
+ } else if (isHeadsUp && (mAddedHeadsUpChildren.contains(row) || pinnedAndClosed)) {
+ if (pinnedAndClosed || shouldHunAppearFromBottom(row)) {
// Our custom add animation
type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_APPEAR;
} else {
// Normal add animation
type = AnimationEvent.ANIMATION_TYPE_ADD;
}
- onBottom = !row.isPinned();
+ onBottom = !pinnedAndClosed;
}
AnimationEvent event = new AnimationEvent(row, type);
event.headsUpFromBottom = onBottom;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index de28ac7..081a9c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -311,8 +311,7 @@
StackViewState viewState = resultState.getViewStateForView(
nextChild);
// The child below the dragged one must be fully visible
- if (!NotificationStackScrollLayout.isPinnedHeadsUp(draggedView)
- || NotificationStackScrollLayout.isPinnedHeadsUp(nextChild)) {
+ if (ambientState.isShadeExpanded()) {
viewState.alpha = 1;
}
}
@@ -508,8 +507,18 @@
}
StackViewState childState = resultState.getViewStateForView(row);
boolean isTopEntry = topHeadsUpEntry == row;
+ if (mIsExpanded) {
+ if (isTopEntry) {
+ childState.height += row.getHeadsUpHeight() - mCollapsedSize;
+ }
+ childState.height = Math.max(childState.height, row.getHeadsUpHeight());
+ // Ensure that the heads up is always visible even when scrolled off from the bottom
+ float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height;
+ childState.yTranslation = Math.min(childState.yTranslation,
+ bottomPosition);
+ }
if (row.isPinned()) {
- childState.yTranslation = 0;
+ childState.yTranslation = Math.max(childState.yTranslation, 0);
childState.height = row.getHeadsUpHeight();
if (!isTopEntry) {
// Ensure that a headsUp doesn't vertically extend further than the heads-up at
@@ -519,15 +528,6 @@
childState.yTranslation = topState.yTranslation + topState.height
- childState.height;
}
- } else if (mIsExpanded) {
- if (isTopEntry) {
- childState.height += row.getHeadsUpHeight() - mCollapsedSize;
- }
- childState.height = Math.max(childState.height, row.getHeadsUpHeight());
- // Ensure that the heads up is always visible even when scrolled of from the bottom
- float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height;
- childState.yTranslation = Math.min(childState.yTranslation,
- bottomPosition);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index b9466d4..eac5e79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -163,7 +163,7 @@
// This is a heads up animation
return false;
}
- if (mHostLayout.isPinnedHeadsUp(child)) {
+ if (NotificationStackScrollLayout.isPinnedHeadsUp(child)) {
// This is another headsUp which might move. Let's animate!
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/AutoScrollView.java b/packages/SystemUI/src/com/android/systemui/tuner/AutoScrollView.java
new file mode 100644
index 0000000..6aea2cb
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/AutoScrollView.java
@@ -0,0 +1,46 @@
+/*
+ * 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.systemui.tuner;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.DragEvent;
+import android.widget.ScrollView;
+
+public class AutoScrollView extends ScrollView {
+
+ private static final float SCROLL_PERCENT = .10f;
+
+ public AutoScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public boolean onDragEvent(DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_LOCATION:
+ int y = (int) event.getY();
+ int height = getHeight();
+ int scrollPadding = (int) (height * SCROLL_PERCENT);
+ if (y < scrollPadding) {
+ scrollBy(0, y - scrollPadding);
+ } else if (y > height - scrollPadding) {
+ scrollBy(0, y - height + scrollPadding);
+ }
+ break;
+ }
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
new file mode 100644
index 0000000..5cf0813
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/QsTuner.java
@@ -0,0 +1,451 @@
+/*
+ * 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.systemui.tuner;
+
+import android.app.AlertDialog;
+import android.app.Fragment;
+import android.content.ClipData;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.provider.Settings.Secure;
+import android.util.Log;
+import android.view.DragEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnDragListener;
+import android.view.View.OnLongClickListener;
+import android.view.View.OnTouchListener;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.ScrollView;
+
+import com.android.systemui.R;
+import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.qs.QSTile.Host.Callback;
+import com.android.systemui.qs.QSTile.ResourceIcon;
+import com.android.systemui.qs.QSTileView;
+import com.android.systemui.qs.tiles.IntentTile;
+import com.android.systemui.statusbar.phone.QSTileHost;
+
+import java.util.List;
+
+public class QsTuner extends Fragment implements Callback {
+
+ private static final String TAG = "QsTuner";
+
+ private static final int MENU_RESET = Menu.FIRST;
+
+ private DraggableQsPanel mQsPanel;
+ private CustomHost mTileHost;
+
+ private FrameLayout mDropTarget;
+
+ private ScrollView mScrollRoot;
+
+ private FrameLayout mAddTarget;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setHasOptionsMenu(true);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.add(0, MENU_RESET, 0, com.android.internal.R.string.reset);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_RESET:
+ mTileHost.reset();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ mScrollRoot = (ScrollView) inflater.inflate(R.layout.tuner_qs, container, false);
+
+ mQsPanel = new DraggableQsPanel(getContext());
+ mTileHost = new CustomHost(getContext());
+ mTileHost.setCallback(this);
+ mQsPanel.setTiles(mTileHost.getTiles());
+ mQsPanel.setHost(mTileHost);
+ mQsPanel.refreshAllTiles();
+ ((ViewGroup) mScrollRoot.findViewById(R.id.all_details)).addView(mQsPanel, 0);
+
+ mDropTarget = (FrameLayout) mScrollRoot.findViewById(R.id.remove_target);
+ setupDropTarget();
+ mAddTarget = (FrameLayout) mScrollRoot.findViewById(R.id.add_target);
+ setupAddTarget();
+ return mScrollRoot;
+ }
+
+ private void setupDropTarget() {
+ QSTileView tileView = new QSTileView(getContext());
+ QSTile.State state = new QSTile.State();
+ state.visible = true;
+ state.icon = ResourceIcon.get(R.drawable.ic_delete);
+ state.label = getString(com.android.internal.R.string.delete);
+ tileView.onStateChanged(state);
+ mDropTarget.addView(tileView);
+ mDropTarget.setVisibility(View.GONE);
+ new DragHelper(tileView, new DropListener() {
+ @Override
+ public void onDrop(String sourceText) {
+ mTileHost.remove(sourceText);
+ }
+ });
+ }
+
+ private void setupAddTarget() {
+ QSTileView tileView = new QSTileView(getContext());
+ QSTile.State state = new QSTile.State();
+ state.visible = true;
+ state.icon = ResourceIcon.get(R.drawable.ic_add_circle_qs);
+ state.label = getString(R.string.add_tile);
+ tileView.onStateChanged(state);
+ mAddTarget.addView(tileView);
+ tileView.setClickable(true);
+ tileView.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mTileHost.showAddDialog();
+ }
+ });
+ }
+
+ public void onStartDrag() {
+ mDropTarget.setVisibility(View.VISIBLE);
+ mAddTarget.setVisibility(View.GONE);
+ }
+
+ public void stopDrag() {
+ mDropTarget.setVisibility(View.GONE);
+ mAddTarget.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onTilesChanged() {
+ mQsPanel.setTiles(mTileHost.getTiles());
+ }
+
+ private static int getLabelResource(String spec) {
+ if (spec.equals("wifi")) return R.string.quick_settings_wifi_label;
+ else if (spec.equals("bt")) return R.string.quick_settings_bluetooth_label;
+ else if (spec.equals("inversion")) return R.string.quick_settings_inversion_label;
+ else if (spec.equals("cell")) return R.string.quick_settings_cellular_detail_title;
+ else if (spec.equals("airplane")) return R.string.quick_settings_airplane_mode_label;
+ else if (spec.equals("dnd")) return R.string.quick_settings_dnd_label;
+ else if (spec.equals("rotation")) return R.string.quick_settings_rotation_locked_label;
+ else if (spec.equals("flashlight")) return R.string.quick_settings_flashlight_label;
+ else if (spec.equals("location")) return R.string.quick_settings_location_label;
+ else if (spec.equals("cast")) return R.string.quick_settings_cast_title;
+ else if (spec.equals("hotspot")) return R.string.quick_settings_hotspot_label;
+ return 0;
+ }
+
+ private static class CustomHost extends QSTileHost {
+
+ public CustomHost(Context context) {
+ super(context, null, null, null, null, null, null, null, null, null,
+ null, null, null);
+ }
+
+ @Override
+ protected QSTile<?> createTile(String tileSpec) {
+ return new DraggableTile(this, tileSpec);
+ }
+
+ public void replace(String oldTile, String newTile) {
+ if (oldTile.equals(newTile)) {
+ return;
+ }
+ List<String> order = loadTileSpecs();
+ int index = order.indexOf(oldTile);
+ if (index < 0) {
+ Log.e(TAG, "Can't find " + oldTile);
+ return;
+ }
+ order.remove(newTile);
+ order.add(index, newTile);
+ setTiles(order);
+ }
+
+ public void remove(String tile) {
+ List<String> tiles = loadTileSpecs();
+ tiles.remove(tile);
+ setTiles(tiles);
+ }
+
+ public void add(String tile) {
+ List<String> tiles = loadTileSpecs();
+ tiles.add(tile);
+ setTiles(tiles);
+ }
+
+ public void reset() {
+ Secure.putStringForUser(getContext().getContentResolver(),
+ TILES_SETTING, "default", mUserTracker.getCurrentUserId());
+ }
+
+ private void setTiles(List<String> tiles) {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < tiles.size(); i++) {
+ if (builder.length() != 0) {
+ builder.append(',');
+ }
+ builder.append(tiles.get(i));
+ }
+ Secure.putStringForUser(getContext().getContentResolver(),
+ TILES_SETTING, builder.toString(), mUserTracker.getCurrentUserId());
+ }
+
+ public void showAddDialog() {
+ List<String> tiles = loadTileSpecs();
+ String[] defaults =
+ getContext().getString(R.string.quick_settings_tiles_default).split(",");
+ final String[] available = new String[defaults.length + 1 - tiles.size()];
+ int index = 0;
+ for (int i = 0; i < defaults.length; i++) {
+ if (tiles.contains(defaults[i])) {
+ continue;
+ }
+ int resource = getLabelResource(defaults[i]);
+ if (resource != 0) {
+ available[index++] = getContext().getString(resource);
+ } else {
+ available[index++] = defaults[i];
+ }
+ }
+ available[index++] = getContext().getString(R.string.broadcast_tile);
+ new AlertDialog.Builder(getContext())
+ .setTitle(R.string.add_tile)
+ .setItems(available, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ if (which < available.length - 1) {
+ add(available[which]);
+ } else {
+ showBroadcastTileDialog();
+ }
+ }
+ }).show();
+ }
+
+ public void showBroadcastTileDialog() {
+ final EditText editText = new EditText(getContext());
+ new AlertDialog.Builder(getContext())
+ .setTitle(R.string.broadcast_tile)
+ .setView(editText)
+ .setNegativeButton(android.R.string.cancel, null)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ String action = editText.getText().toString();
+ if (isValid(action)) {
+ add(IntentTile.PREFIX + action + ')');
+ }
+ }
+ }).show();
+ }
+
+ private boolean isValid(String action) {
+ for (int i = 0; i < action.length(); i++) {
+ char c = action.charAt(i);
+ if (!Character.isAlphabetic(c) && !Character.isDigit(c) && c != '.') {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
+ private static class DraggableTile extends QSTile<QSTile.State>
+ implements DropListener {
+ private String mSpec;
+ private QSTileView mView;
+
+ protected DraggableTile(QSTile.Host host, String tileSpec) {
+ super(host);
+ Log.d(TAG, "Creating tile " + tileSpec);
+ mSpec = tileSpec;
+ }
+
+ @Override
+ public QSTileView createTileView(Context context) {
+ mView = super.createTileView(context);
+ return mView;
+ }
+
+ @Override
+ public boolean supportsDualTargets() {
+ return "wifi".equals(mSpec) || "bt".equals(mSpec);
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ }
+
+ @Override
+ protected QSTile.State newTileState() {
+ return new QSTile.State();
+ }
+
+ @Override
+ protected void handleClick() {
+ }
+
+ @Override
+ protected void handleUpdateState(QSTile.State state, Object arg) {
+ state.visible = true;
+ state.icon = ResourceIcon.get(getIcon());
+ state.label = getLabel();
+ }
+
+ private String getLabel() {
+ int resource = getLabelResource(mSpec);
+ if (resource != 0) {
+ return mContext.getString(resource);
+ }
+ if (mSpec.startsWith(IntentTile.PREFIX)) {
+ int lastDot = mSpec.lastIndexOf('.');
+ if (lastDot >= 0) {
+ return mSpec.substring(lastDot + 1, mSpec.length() - 1);
+ } else {
+ return mSpec.substring(IntentTile.PREFIX.length(), mSpec.length() - 1);
+ }
+ }
+ return mSpec;
+ }
+
+ private int getIcon() {
+ if (mSpec.equals("wifi")) return R.drawable.ic_qs_wifi_full_3;
+ else if (mSpec.equals("bt")) return R.drawable.ic_qs_bluetooth_connected;
+ else if (mSpec.equals("inversion")) return R.drawable.ic_invert_colors_enable;
+ else if (mSpec.equals("cell")) return R.drawable.ic_qs_signal_full_3;
+ else if (mSpec.equals("airplane")) return R.drawable.ic_signal_airplane_enable;
+ else if (mSpec.equals("dnd")) return R.drawable.ic_qs_dnd_on;
+ else if (mSpec.equals("rotation")) return R.drawable.ic_portrait_from_auto_rotate;
+ else if (mSpec.equals("flashlight")) return R.drawable.ic_signal_flashlight_enable;
+ else if (mSpec.equals("location")) return R.drawable.ic_signal_location_enable;
+ else if (mSpec.equals("cast")) return R.drawable.ic_qs_cast_on;
+ else if (mSpec.equals("hotspot")) return R.drawable.ic_hotspot_enable;
+ return R.drawable.android;
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return 20000;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof DraggableTile) {
+ return mSpec.equals(((DraggableTile) o).mSpec);
+ }
+ return false;
+ }
+
+ @Override
+ public void onDrop(String sourceText) {
+ ((CustomHost) mHost).replace(mSpec, sourceText);
+ }
+
+ }
+
+ private class DragHelper implements OnDragListener {
+
+ private final View mView;
+ private final DropListener mListener;
+
+ public DragHelper(View view, DropListener dropListener) {
+ mView = view;
+ mListener = dropListener;
+ mView.setOnDragListener(this);
+ }
+
+ @Override
+ public boolean onDrag(View v, DragEvent event) {
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_ENTERED:
+ mView.setBackgroundColor(0x77ffffff);
+ break;
+ case DragEvent.ACTION_DRAG_ENDED:
+ stopDrag();
+ case DragEvent.ACTION_DRAG_EXITED:
+ mView.setBackgroundColor(0x0);
+ break;
+ case DragEvent.ACTION_DROP:
+ stopDrag();
+ String text = event.getClipData().getItemAt(0).getText().toString();
+ mListener.onDrop(text);
+ break;
+ }
+ return true;
+ }
+
+ }
+
+ public interface DropListener {
+ void onDrop(String sourceText);
+ }
+
+ private class DraggableQsPanel extends QSPanel implements OnTouchListener {
+ public DraggableQsPanel(Context context) {
+ super(context);
+ mBrightnessView.setVisibility(View.GONE);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ for (TileRecord r : mRecords) {
+ new DragHelper(r.tileView, (DraggableTile) r.tile);
+ r.tileView.setTag(r.tile);
+ r.tileView.setOnTouchListener(this);
+
+ for (int i = 0; i < r.tileView.getChildCount(); i++) {
+ r.tileView.getChildAt(i).setClickable(false);
+ }
+ }
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ String tileSpec = (String) ((DraggableTile) v.getTag()).mSpec;
+ ClipData data = ClipData.newPlainText(tileSpec, tileSpec);
+ v.startDrag(data, new View.DragShadowBuilder(v), null, 0);
+ onStartDrag();
+ return true;
+ }
+ return false;
+ }
+ }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index df1b0d0..457bade 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -15,7 +15,10 @@
*/
package com.android.systemui.tuner;
+import android.app.FragmentTransaction;
import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.view.MenuItem;
@@ -23,12 +26,25 @@
public class TunerFragment extends PreferenceFragment {
+ private static final String KEY_QS_TUNER = "qs_tuner";
+
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.tuner_prefs);
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
setHasOptionsMenu(true);
+
+ findPreference(KEY_QS_TUNER).setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ ft.replace(android.R.id.content, new QsTuner(), "QsTuner");
+ ft.addToBackStack(null);
+ ft.commit();
+ return false;
+ }
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index e6c95b5..23813d1 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -176,7 +176,7 @@
final CharSequence text = mContext.getString(R.string.ext_media_missing_message);
final Notification notif = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
@@ -313,9 +313,10 @@
final PendingIntent initIntent = buildInitPendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
- .addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
- initIntent))
- .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
+ .addAction(new Action(R.drawable.ic_settings_24dp,
+ mContext.getString(R.string.ext_media_init_action), initIntent))
+ .addAction(new Action(R.drawable.ic_eject_24dp,
+ mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(initIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
@@ -329,9 +330,11 @@
final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
- .addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
+ .addAction(new Action(R.drawable.ic_folder_24dp,
+ mContext.getString(R.string.ext_media_browse_action),
browseIntent))
- .addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
+ .addAction(new Action(R.drawable.ic_eject_24dp,
+ mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
@@ -430,7 +433,7 @@
}
final Notification notif = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
@@ -477,7 +480,7 @@
}
final Notification notif = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.stat_notify_sdcard)
+ .setSmallIcon(R.drawable.ic_sd_card_48dp)
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
@@ -498,14 +501,14 @@
switch (state) {
case VolumeInfo.STATE_CHECKING:
case VolumeInfo.STATE_EJECTING:
- return R.drawable.stat_notify_sdcard_prepare;
+ return R.drawable.ic_sd_card_48dp;
default:
- return R.drawable.stat_notify_sdcard;
+ return R.drawable.ic_sd_card_48dp;
}
} else if (disk.isUsb()) {
- return R.drawable.stat_sys_data_usb;
+ return R.drawable.ic_usb_48dp;
} else {
- return R.drawable.stat_notify_sdcard;
+ return R.drawable.ic_sd_card_48dp;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index 4bc45df..6e0ca3c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -533,8 +533,7 @@
}
Util.setVisOrInvis(row.settingsButton, false);
row.header.setAlpha(mExpanded && isActive ? 1 : 0.5f);
- row.slider.setProgressTintList(isActive ? mActiveSliderTint : mInactiveSliderTint);
- row.slider.setThumbTintList(isActive ? mActiveSliderTint : mInactiveSliderTint);
+ updateVolumeRowSliderTintH(row, isActive);
}
}
@@ -666,8 +665,18 @@
updateVolumeRowSliderH(row, zenMuted);
}
+ private void updateVolumeRowSliderTintH(VolumeRow row, boolean isActive) {
+ final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveSliderTint
+ : mInactiveSliderTint;
+ if (tint == row.cachedSliderTint) return;
+ row.cachedSliderTint = tint;
+ row.slider.setProgressTintList(tint);
+ row.slider.setThumbTintList(tint);
+ }
+
private void updateVolumeRowSliderH(VolumeRow row, boolean zenMuted) {
row.slider.setEnabled(!zenMuted);
+ updateVolumeRowSliderTintH(row, row.stream == mActiveStream);
if (row.tracking) {
return; // don't update if user is sliding
}
@@ -1027,6 +1036,7 @@
private int iconMuteRes;
private boolean important;
private int cachedIconRes;
+ private ColorStateList cachedSliderTint;
private int iconState; // from Events
private boolean cachedShowHeaders = VolumePrefs.DEFAULT_SHOW_HEADERS;
private int cachedExpandButtonRes;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 66c4993..6d67d11 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -127,7 +127,7 @@
Util.setText(mSummaryLine1, line1);
final String line2 = ZenModeConfig.getConditionSummary(mContext, mConfig,
- mController.getCurrentUser());
+ mController.getCurrentUser(), true /*shortVersion*/);
Util.setText(mSummaryLine2, line2);
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index b3b6725..ec24d75 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -23,6 +23,7 @@
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Configuration;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
@@ -175,7 +176,14 @@
});
mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
+ }
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (mZenButtons != null) {
+ mZenButtons.updateLocale();
+ }
}
private void confirmZenIntroduction() {
@@ -438,7 +446,8 @@
final long span = time - now;
if (span <= 0 || span > MAX_BUCKET_MINUTES * MINUTES_MS) return null;
return ZenModeConfig.toTimeCondition(context,
- time, Math.round(span / (float) MINUTES_MS), now, ActivityManager.getCurrentUser());
+ time, Math.round(span / (float) MINUTES_MS), now, ActivityManager.getCurrentUser(),
+ false /*shortVersion*/);
}
private void handleUpdateConditions(Condition[] conditions) {
@@ -717,7 +726,8 @@
if (up && bucketTime > time || !up && bucketTime < time) {
mBucketIndex = j;
newCondition = ZenModeConfig.toTimeCondition(mContext,
- bucketTime, bucketMinutes, now, ActivityManager.getCurrentUser());
+ bucketTime, bucketMinutes, now, ActivityManager.getCurrentUser(),
+ false /*shortVersion*/);
break;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
new file mode 100644
index 0000000..1cc6fa8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.systemui.statusbar.policy;
+
+import android.os.HandlerThread;
+import android.telephony.SubscriptionInfo;
+import android.test.AndroidTestCase;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.IconState;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CallbackHandlerTest extends AndroidTestCase {
+
+ private CallbackHandler mHandler;
+ private HandlerThread mHandlerThread;
+
+ @Mock
+ private EmergencyListener mEmengencyListener;
+ @Mock
+ private SignalCallback mSignalCallback;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mHandlerThread = new HandlerThread("TestThread");
+ mHandlerThread.start();
+ mHandler = new CallbackHandler(mHandlerThread.getLooper());
+
+ MockitoAnnotations.initMocks(this);
+ mHandler.setListening(mEmengencyListener, true);
+ mHandler.setListening(mSignalCallback, true);
+ }
+
+ public void testEmergencyListener() {
+ mHandler.setEmergencyCallsOnly(true);
+ waitForCallbacks();
+
+ ArgumentCaptor<Boolean> captor = ArgumentCaptor.forClass(Boolean.class);
+ Mockito.verify(mEmengencyListener).setEmergencyCallsOnly(captor.capture());
+ assertTrue(captor.getValue());
+ }
+
+ public void testSignalCallback_setWifiIndicators() {
+ boolean enabled = true;
+ IconState status = new IconState(true, 0, "");
+ IconState qs = new IconState(true, 1, "");
+ boolean in = true;
+ boolean out = true;
+ String description = "Test";
+ mHandler.setWifiIndicators(enabled, status, qs, in, out, description);
+ waitForCallbacks();
+
+ ArgumentCaptor<Boolean> enableArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class);
+ ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class);
+ ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+ Mockito.verify(mSignalCallback).setWifiIndicators(enableArg.capture(),
+ statusArg.capture(), qsArg.capture(), inArg.capture(), outArg.capture(),
+ descArg.capture());
+ assertEquals(enabled, (boolean) enableArg.getValue());
+ assertEquals(status, statusArg.getValue());
+ assertEquals(qs, qsArg.getValue());
+ assertEquals(in, (boolean) inArg.getValue());
+ assertEquals(out, (boolean) outArg.getValue());
+ assertEquals(description, descArg.getValue());
+ }
+
+ public void testSignalCallback_setMobileDataIndicators() {
+ IconState status = new IconState(true, 0, "");
+ IconState qs = new IconState(true, 1, "");
+ int dark = 2;
+ boolean in = true;
+ boolean out = true;
+ String typeDescription = "Test 1";
+ String description = "Test 2";
+ int type = R.drawable.stat_sys_data_fully_connected_1x;
+ int qsType = R.drawable.ic_qs_signal_1x;
+ boolean wide = true;
+ int subId = 5;
+ mHandler.setMobileDataIndicators(status, qs, dark, type, qsType, in, out, typeDescription,
+ description, wide, subId);
+ waitForCallbacks();
+
+ ArgumentCaptor<IconState> statusArg = ArgumentCaptor.forClass(IconState.class);
+ ArgumentCaptor<IconState> qsArg = ArgumentCaptor.forClass(IconState.class);
+ ArgumentCaptor<Integer> darkStrengthArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Integer> qsTypeIconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<String> typeContentArg = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor<Boolean> wideArg = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> subIdArg = ArgumentCaptor.forClass(Integer.class);
+ Mockito.verify(mSignalCallback).setMobileDataIndicators(statusArg.capture(), qsArg.capture(),
+ darkStrengthArg.capture(), typeIconArg.capture(), qsTypeIconArg.capture(),
+ inArg.capture(), outArg.capture(), typeContentArg.capture(), descArg.capture(),
+ wideArg.capture(), subIdArg.capture());
+ assertEquals(status, statusArg.getValue());
+ assertEquals(qs, qsArg.getValue());
+ assertEquals(dark, (int) darkStrengthArg.getValue());
+ assertEquals(type, (int) typeIconArg.getValue());
+ assertEquals(qsType, (int) qsTypeIconArg.getValue());
+ assertEquals(in, (boolean) inArg.getValue());
+ assertEquals(out, (boolean) outArg.getValue());
+ assertEquals(typeDescription, typeContentArg.getValue());
+ assertEquals(description, descArg.getValue());
+ assertEquals(wide, (boolean) wideArg.getValue());
+ assertEquals(subId, (int) subIdArg.getValue());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testSignalCallback_setSubs() {
+ List<SubscriptionInfo> subs = new ArrayList<>();
+ mHandler.setSubs(subs);
+ waitForCallbacks();
+
+ ArgumentCaptor<ArrayList> subsArg = ArgumentCaptor.forClass(ArrayList.class);
+ Mockito.verify(mSignalCallback).setSubs(subsArg.capture());
+ assertTrue(subs == subsArg.getValue());
+ }
+
+ public void testSignalCallback_setNoSims() {
+ boolean noSims = true;
+ mHandler.setNoSims(noSims);
+ waitForCallbacks();
+
+ ArgumentCaptor<Boolean> noSimsArg = ArgumentCaptor.forClass(Boolean.class);
+ Mockito.verify(mSignalCallback).setNoSims(noSimsArg.capture());
+ assertEquals(noSims, (boolean) noSimsArg.getValue());
+ }
+
+ public void testSignalCallback_setEthernetIndicators() {
+ IconState state = new IconState(true, R.drawable.stat_sys_ethernet, "Test Description");
+ mHandler.setEthernetIndicators(state);
+ waitForCallbacks();
+
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
+ Mockito.verify(mSignalCallback).setEthernetIndicators(iconArg.capture());
+ assertEquals(state, iconArg.getValue());
+ }
+
+ public void testSignalCallback_setIsAirplaneMode() {
+ IconState state = new IconState(true, R.drawable.stat_sys_airplane_mode, "Test Description");
+ mHandler.setIsAirplaneMode(state);
+ waitForCallbacks();
+
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
+ Mockito.verify(mSignalCallback).setIsAirplaneMode(iconArg.capture());
+ assertEquals(state, iconArg.getValue());
+ }
+
+ private void waitForCallbacks() {
+ mHandlerThread.quitSafely();
+ try {
+ mHandlerThread.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 29f461e..3d5f045 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -23,6 +23,7 @@
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiManager;
+import android.os.Looper;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
@@ -31,12 +32,10 @@
import android.telephony.TelephonyManager;
import android.util.Log;
-import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.cdma.EriInfo;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.policy.NetworkController.NetworkSignalChangedCallback;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.Config;
-import com.android.systemui.statusbar.policy.NetworkControllerImpl.SignalCluster;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.IconState;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -59,8 +58,6 @@
protected NetworkControllerImpl mNetworkController;
protected MobileSignalController mMobileSignalController;
protected PhoneStateListener mPhoneStateListener;
- protected SignalCluster mSignalCluster;
- protected NetworkSignalChangedCallback mNetworkSignalChangedCallback;
private SignalStrength mSignalStrength;
private ServiceState mServiceState;
protected ConnectivityManager mMockCm;
@@ -68,6 +65,7 @@
protected SubscriptionManager mMockSm;
protected TelephonyManager mMockTm;
protected Config mConfig;
+ protected CallbackHandler mCallbackHandler;
protected int mSubId;
@@ -91,33 +89,36 @@
mConfig = new Config();
mConfig.hspaDataDistinguishable = true;
+ mCallbackHandler = mock(CallbackHandler.class);
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
- mConfig, mock(AccessPointControllerImpl.class),
- mock(MobileDataControllerImpl.class));
+ mConfig, Looper.getMainLooper(), mCallbackHandler,
+ mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
setupNetworkController();
}
protected void setupNetworkController() {
// For now just pretend to be the data sim, so we can test that too.
- mSubId = SubscriptionManager.getDefaultDataSubId();
+ mSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
SubscriptionInfo subscription = mock(SubscriptionInfo.class);
List<SubscriptionInfo> subs = new ArrayList<SubscriptionInfo>();
when(subscription.getSubscriptionId()).thenReturn(mSubId);
subs.add(subscription);
mNetworkController.setCurrentSubscriptions(subs);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
+ mMobileSignalController.getState().dataSim = true;
mPhoneStateListener = mMobileSignalController.mPhoneStateListener;
- mSignalCluster = mock(SignalCluster.class);
- mNetworkSignalChangedCallback = mock(NetworkSignalChangedCallback.class);
- mNetworkController.addSignalCluster(mSignalCluster);
- mNetworkController.addNetworkSignalChangedCallback(mNetworkSignalChangedCallback);
+
+ // Trigger blank callbacks to always get the current state (some tests don't trigger
+ // changes from default state).
+ mNetworkController.addSignalCallback(null);
}
protected NetworkControllerImpl setUpNoMobileData() {
when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
NetworkControllerImpl networkControllerNoMobile
= new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
- mConfig, mock(AccessPointControllerImpl.class),
+ mConfig, Looper.getMainLooper(), mCallbackHandler,
+ mock(AccessPointControllerImpl.class),
mock(MobileDataControllerImpl.class));
setupNetworkController();
@@ -242,34 +243,30 @@
protected void verifyHasNoSims(boolean hasNoSimsVisible) {
ArgumentCaptor<Boolean> hasNoSimsArg = ArgumentCaptor.forClass(Boolean.class);
- Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setNoSims(hasNoSimsArg.capture());
- assertEquals("No sims in status bar", hasNoSimsVisible, (boolean) hasNoSimsArg.getValue());
-
- Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce())
- .onNoSimVisibleChanged(hasNoSimsArg.capture());
- assertEquals("No sims in quick settings", hasNoSimsVisible,
- (boolean) hasNoSimsArg.getValue());
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setNoSims(hasNoSimsArg.capture());
+ assertEquals("No sims", hasNoSimsVisible, (boolean) hasNoSimsArg.getValue());
}
protected void verifyLastQsMobileDataIndicators(boolean visible, int icon, int typeIcon,
boolean dataIn, boolean dataOut) {
- ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
- ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Boolean> dataInArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Boolean> dataOutArg = ArgumentCaptor.forClass(Boolean.class);
- Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce())
- .onMobileDataSignalChanged(visibleArg.capture(), iconArg.capture(),
- ArgumentCaptor.forClass(String.class).capture(),
- typeIconArg.capture(),
- dataInArg.capture(),
- dataOutArg.capture(),
- ArgumentCaptor.forClass(String.class).capture(),
- ArgumentCaptor.forClass(String.class).capture(),
- ArgumentCaptor.forClass(Boolean.class).capture());
- assertEquals("Visibility in, quick settings", visible, (boolean) visibleArg.getValue());
- assertEquals("Signal icon in, quick settings", icon, (int) iconArg.getValue());
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
+ ArgumentCaptor.forClass(IconState.class).capture(),
+ iconArg.capture(),
+ ArgumentCaptor.forClass(Integer.class).capture(),
+ ArgumentCaptor.forClass(Integer.class).capture(),
+ typeIconArg.capture(), dataInArg.capture(), dataOutArg.capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ ArgumentCaptor.forClass(String.class).capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(Integer.class).capture());
+ IconState iconState = iconArg.getValue();
+ assertEquals("Visibility in, quick settings", visible, iconState.visible);
+ assertEquals("Signal icon in, quick settings", icon, iconState.icon);
assertEquals("Data icon in, quick settings", typeIcon, (int) typeIconArg.getValue());
assertEquals("Data direction in, in quick settings", dataIn,
(boolean) dataInArg.getValue());
@@ -283,29 +280,32 @@
protected void verifyLastMobileDataIndicators(boolean visible, int strengthIcon,
int darkStrengthIcon, int typeIcon) {
- ArgumentCaptor<Integer> strengthIconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
ArgumentCaptor<Integer> darkStrengthIconArg = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);
- ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
// TODO: Verify all fields.
- Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setMobileDataIndicators(
- visibleArg.capture(), strengthIconArg.capture(), darkStrengthIconArg.capture(),
- typeIconArg.capture(),
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
+ iconArg.capture(),
+ ArgumentCaptor.forClass(IconState.class).capture(),
+ darkStrengthIconArg.capture(), typeIconArg.capture(),
+ ArgumentCaptor.forClass(Integer.class).capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
+ ArgumentCaptor.forClass(Boolean.class).capture(),
ArgumentCaptor.forClass(String.class).capture(),
ArgumentCaptor.forClass(String.class).capture(),
ArgumentCaptor.forClass(Boolean.class).capture(),
ArgumentCaptor.forClass(Integer.class).capture());
+ IconState iconState = iconArg.getValue();
- assertEquals("Signal strength icon in status bar", strengthIcon,
- (int) strengthIconArg.getValue());
+ assertEquals("Signal strength icon in status bar", strengthIcon, iconState.icon);
assertEquals("Signal strength icon (dark mode) in status bar", darkStrengthIcon,
(int) darkStrengthIconArg.getValue());
assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
- assertEquals("Visibility in status bar", visible, (boolean) visibleArg.getValue());
+ assertEquals("Visibility in status bar", visible, iconState.visible);
}
protected void assertNetworkNameEquals(String expected) {
- assertEquals("Network name", expected, mNetworkController.getMobileDataNetworkName());
+ assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 3f9312d..015127d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -2,6 +2,7 @@
import org.mockito.Mockito;
+import android.os.Looper;
import android.telephony.TelephonyManager;
public class NetworkControllerDataTest extends NetworkControllerBaseTest {
@@ -74,7 +75,8 @@
// Switch to showing 4g icon and re-initialize the NetworkController.
mConfig.show4gForLte = true;
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
- mConfig, Mockito.mock(AccessPointControllerImpl.class),
+ mConfig, Looper.getMainLooper(), mCallbackHandler,
+ Mockito.mock(AccessPointControllerImpl.class),
Mockito.mock(MobileDataControllerImpl.class));
setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
index 82ced9f..f1d2acb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerEthernetTest.java
@@ -2,6 +2,8 @@
import android.net.NetworkCapabilities;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.IconState;
+
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -28,13 +30,12 @@
}
protected void verifyLastEthernetIcon(boolean visible, int icon) {
- ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
- ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
- Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setEthernetIndicators(
- visibleArg.capture(), iconArg.capture(),
- ArgumentCaptor.forClass(String.class).capture());
- assertEquals("Ethernet visible, in status bar", visible, (boolean) visibleArg.getValue());
- assertEquals("Ethernet icon, in status bar", icon, (int) iconArg.getValue());
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEthernetIndicators(
+ iconArg.capture());
+ IconState iconState = iconArg.getValue();
+ assertEquals("Ethernet visible, in status bar", visible, iconState.visible);
+ assertEquals("Ethernet icon, in status bar", icon, iconState.icon);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 389ad6f..a85bca2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -19,12 +19,12 @@
import android.content.Intent;
import android.net.ConnectivityManager;
+import android.os.Looper;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionInfo;
import android.telephony.TelephonyManager;
-import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.R;
@@ -41,8 +41,8 @@
Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
// Create a new NetworkController as this is currently handled in constructor.
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
- mConfig, mock(AccessPointControllerImpl.class),
- mock(MobileDataControllerImpl.class));
+ mConfig, Looper.getMainLooper(), mCallbackHandler,
+ mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
setupNetworkController();
verifyLastMobileDataIndicators(false, 0, 0);
@@ -61,8 +61,8 @@
Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
// Create a new NetworkController as this is currently handled in constructor.
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
- mConfig, mock(AccessPointControllerImpl.class),
- mock(MobileDataControllerImpl.class));
+ mConfig, Looper.getMainLooper(), mCallbackHandler,
+ mock(AccessPointControllerImpl.class), mock(MobileDataControllerImpl.class));
setupNetworkController();
// No Subscriptions.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index 2e0e9a3..d0c95b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -6,6 +6,8 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import com.android.systemui.statusbar.policy.NetworkControllerImpl.IconState;
+
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -133,46 +135,39 @@
ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
- Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
- ArgumentCaptor.forClass(Boolean.class).capture(),
- ArgumentCaptor.forClass(Boolean.class).capture(),
- ArgumentCaptor.forClass(Integer.class).capture(),
- inArg.capture(), outArg.capture(),
- ArgumentCaptor.forClass(String.class).capture(),
- ArgumentCaptor.forClass(String.class).capture());
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
+ Mockito.anyBoolean(), Mockito.any(IconState.class), Mockito.any(IconState.class),
+ inArg.capture(), outArg.capture(), Mockito.anyString());
assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
}
protected void verifyLastQsWifiIcon(boolean enabled, boolean connected, int icon,
String description) {
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
ArgumentCaptor<Boolean> enabledArg = ArgumentCaptor.forClass(Boolean.class);
- ArgumentCaptor<Boolean> connectedArg = ArgumentCaptor.forClass(Boolean.class);
- ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
- Mockito.verify(mNetworkSignalChangedCallback, Mockito.atLeastOnce()).onWifiSignalChanged(
- enabledArg.capture(), connectedArg.capture(), iconArg.capture(),
- ArgumentCaptor.forClass(Boolean.class).capture(),
- ArgumentCaptor.forClass(Boolean.class).capture(),
- ArgumentCaptor.forClass(String.class).capture(),
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
+ enabledArg.capture(), Mockito.any(IconState.class),
+ iconArg.capture(), Mockito.anyBoolean(),
+ Mockito.anyBoolean(),
descArg.capture());
+ IconState iconState = iconArg.getValue();
assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
- assertEquals("WiFi connected, in quick settings", connected,
- (boolean) connectedArg.getValue());
- assertEquals("WiFi signal, in quick settings", icon, (int) iconArg.getValue());
- assertEquals("WiFI desc (ssid), in quick settings", description,
- (String) descArg.getValue());
+ assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
+ assertEquals("WiFi signal, in quick settings", icon, iconState.icon);
+ assertEquals("WiFI desc (ssid), in quick settings", description, descArg.getValue());
}
protected void verifyLastWifiIcon(boolean visible, int icon) {
- ArgumentCaptor<Boolean> visibleArg = ArgumentCaptor.forClass(Boolean.class);
- ArgumentCaptor<Integer> iconArg = ArgumentCaptor.forClass(Integer.class);
+ ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
- Mockito.verify(mSignalCluster, Mockito.atLeastOnce()).setWifiIndicators(
- visibleArg.capture(), iconArg.capture(),
- ArgumentCaptor.forClass(String.class).capture());
- assertEquals("WiFi visible, in status bar", visible, (boolean) visibleArg.getValue());
- assertEquals("WiFi signal, in status bar", icon, (int) iconArg.getValue());
+ Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
+ Mockito.anyBoolean(), iconArg.capture(), Mockito.any(IconState.class),
+ Mockito.anyBoolean(), Mockito.anyBoolean(), Mockito.anyString());
+ IconState iconState = iconArg.getValue();
+ assertEquals("WiFi visible, in status bar", visible, iconState.visible);
+ assertEquals("WiFi signal, in status bar", icon, iconState.icon);
}
}
diff --git a/preloaded-classes b/preloaded-classes
index d2ed762..41a8857 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1152,8 +1152,8 @@
android.provider.Settings$System
android.provider.Telephony$Mms
android.renderscript.RenderScript
-android.security.AndroidKeyStoreBCWorkaroundProvider
-android.security.AndroidKeyStoreProvider
+android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
+android.security.keystore.AndroidKeyStoreProvider
android.speech.tts.TextToSpeechService
android.speech.tts.TextToSpeechService$SpeechItemV1
android.speech.tts.TextToSpeechService$SynthesisSpeechItemV1
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index 4b3e30f..6efb6d6 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -536,8 +536,8 @@
}
public static Element F16_3(RenderScript rs) {
- if(rs.mElement_FLOAT_3 == null) {
- rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_16, 3);
+ if(rs.mElement_HALF_3 == null) {
+ rs.mElement_HALF_3 = createVector(rs, DataType.FLOAT_16, 3);
}
return rs.mElement_HALF_3;
}
@@ -911,6 +911,7 @@
switch (dt) {
// Support only primitive integer/float/boolean types as vectors.
+ case FLOAT_16:
case FLOAT_32:
case FLOAT_64:
case SIGNED_8:
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index 4f10699..8b1a032 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -131,7 +131,21 @@
// this should be a monotonically increasing ID
// used in conjunction with the API version of a device
- static final long sMinorID = 1;
+ static final long sMinorVersion = 1;
+
+ /**
+ * @hide
+ *
+ * Only exist to be compatible with old version RenderScript Support lib.
+ * Will eventually be removed.
+ *
+ * @return Always return 1
+ *
+ */
+ public static long getMinorID() {
+ return 1;
+ }
+
/**
* Returns an identifier that can be used to identify a particular
@@ -140,8 +154,8 @@
* @return The minor RenderScript version number
*
*/
- public static long getMinorID() {
- return sMinorID;
+ public static long getMinorVersion() {
+ return sMinorVersion;
}
/**
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index be8b0fd..d1a12f9 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -400,8 +400,10 @@
/**
* Executes a script group
*
- * @param inputs inputs to the script group
- * @return outputs of the script group as an array of objects
+ * @param inputs Values for inputs to the script group, in the order as the
+ * inputs are added via {@link Builder2#addInput}.
+ * @return Outputs of the script group as an array of objects, in the order
+ * as futures are passed to {@link Builder2#create}.
*/
public Object[] execute(Object... inputs) {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 78cbac9..17d7078 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -95,6 +95,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -2494,7 +2495,7 @@
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "gs");
out.attribute(null, "version", String.valueOf(CURRENT_VERSION));
@@ -2557,7 +2558,7 @@
int version = -1;
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int legacyProviderIndex = -1;
int legacyHostIndex = -1;
@@ -3642,7 +3643,7 @@
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "ws"); // widget state
out.attribute(null, "version", String.valueOf(WIDGET_STATE_VERSION));
@@ -3734,7 +3735,7 @@
ArrayList<Host> restoredHosts = new ArrayList<>();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
synchronized (mLock) {
int type;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 745c1906..ad671c6 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -138,6 +138,8 @@
long mLastAlarmDeliveryTime;
long mStartCurrentDelayTime;
long mNextNonWakeupDeliveryTime;
+ long mLastTimeChangeClockTime;
+ long mLastTimeChangeRealtime;
int mNumTimeChanged;
private final SparseArray<AlarmManager.AlarmClockInfo> mNextAlarmClockForUser =
@@ -1024,6 +1026,11 @@
pw.print("="); pw.print(sdf.format(new Date(nowRTC)));
pw.print(" nowELAPSED="); TimeUtils.formatDuration(nowELAPSED, pw);
pw.println();
+ pw.print("mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime);
+ pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
+ pw.print("mLastTimeChangeRealtime=");
+ TimeUtils.formatDuration(mLastTimeChangeRealtime, pw);
+ pw.println();
if (!mInteractive) {
pw.print("Time since non-interactive: ");
TimeUtils.formatDuration(nowELAPSED - mNonInteractiveStartTime, pw);
@@ -1955,77 +1962,102 @@
triggerList.clear();
+ final long nowRTC = System.currentTimeMillis();
+ final long nowELAPSED = SystemClock.elapsedRealtime();
+
if ((result & TIME_CHANGED_MASK) != 0) {
- if (DEBUG_BATCH) {
- Slog.v(TAG, "Time changed notification from kernel; rebatching");
- }
- removeImpl(mTimeTickSender);
- rebatchAllAlarms();
- mClockReceiver.scheduleTimeTickEvent();
+ // The kernel can give us spurious time change notifications due to
+ // small adjustments it makes internally; we want to filter those out.
+ final long lastTimeChangeClockTime;
+ final long expectedClockTime;
synchronized (mLock) {
- mNumTimeChanged++;
+ lastTimeChangeClockTime = mLastTimeChangeClockTime;
+ expectedClockTime = lastTimeChangeClockTime
+ + (nowELAPSED - mLastTimeChangeRealtime);
}
- Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
- | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+ if (lastTimeChangeClockTime == 0 || nowRTC < (expectedClockTime-500)
+ || nowRTC > (expectedClockTime+500)) {
+ // The change is by at least +/- 500 ms (or this is the first change),
+ // let's do it!
+ if (DEBUG_BATCH) {
+ Slog.v(TAG, "Time changed notification from kernel; rebatching");
+ }
+ removeImpl(mTimeTickSender);
+ rebatchAllAlarms();
+ mClockReceiver.scheduleTimeTickEvent();
+ synchronized (mLock) {
+ mNumTimeChanged++;
+ mLastTimeChangeClockTime = nowRTC;
+ mLastTimeChangeRealtime = nowELAPSED;
+ }
+ Intent intent = new Intent(Intent.ACTION_TIME_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
+
+ // The world has changed on us, so we need to re-evaluate alarms
+ // regardless of whether the kernel has told us one went off.
+ result |= IS_WAKEUP_MASK;
+ }
}
-
- synchronized (mLock) {
- final long nowRTC = System.currentTimeMillis();
- final long nowELAPSED = SystemClock.elapsedRealtime();
- if (localLOGV) Slog.v(
- TAG, "Checking for alarms... rtc=" + nowRTC
- + ", elapsed=" + nowELAPSED);
- if (WAKEUP_STATS) {
- if ((result & IS_WAKEUP_MASK) != 0) {
- long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
- int n = 0;
- for (WakeupEvent event : mRecentWakeups) {
- if (event.when > newEarliest) break;
- n++; // number of now-stale entries at the list head
- }
- for (int i = 0; i < n; i++) {
- mRecentWakeups.remove();
- }
+ if (result != TIME_CHANGED_MASK) {
+ // If this was anything besides just a time change, then figure what if
+ // anything to do about alarms.
+ synchronized (mLock) {
+ if (localLOGV) Slog.v(
+ TAG, "Checking for alarms... rtc=" + nowRTC
+ + ", elapsed=" + nowELAPSED);
- recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
- }
- }
+ if (WAKEUP_STATS) {
+ if ((result & IS_WAKEUP_MASK) != 0) {
+ long newEarliest = nowRTC - RECENT_WAKEUP_PERIOD;
+ int n = 0;
+ for (WakeupEvent event : mRecentWakeups) {
+ if (event.when > newEarliest) break;
+ n++; // number of now-stale entries at the list head
+ }
+ for (int i = 0; i < n; i++) {
+ mRecentWakeups.remove();
+ }
- boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
- if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
- // if there are no wakeup alarms and the screen is off, we can
- // delay what we have so far until the future.
- if (mPendingNonWakeupAlarms.size() == 0) {
- mStartCurrentDelayTime = nowELAPSED;
- mNextNonWakeupDeliveryTime = nowELAPSED
- + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
- }
- mPendingNonWakeupAlarms.addAll(triggerList);
- mNumDelayedAlarms += triggerList.size();
- rescheduleKernelAlarmsLocked();
- updateNextAlarmClockLocked();
- } else {
- // now deliver the alarm intents; if there are pending non-wakeup
- // alarms, we need to merge them in to the list. note we don't
- // just deliver them first because we generally want non-wakeup
- // alarms delivered after wakeup alarms.
- rescheduleKernelAlarmsLocked();
- updateNextAlarmClockLocked();
- if (mPendingNonWakeupAlarms.size() > 0) {
- calculateDeliveryPriorities(mPendingNonWakeupAlarms);
- triggerList.addAll(mPendingNonWakeupAlarms);
- Collections.sort(triggerList, mAlarmDispatchComparator);
- final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
- mTotalDelayTime += thisDelayTime;
- if (mMaxDelayTime < thisDelayTime) {
- mMaxDelayTime = thisDelayTime;
+ recordWakeupAlarms(mAlarmBatches, nowELAPSED, nowRTC);
}
- mPendingNonWakeupAlarms.clear();
}
- deliverAlarmsLocked(triggerList, nowELAPSED);
+
+ boolean hasWakeup = triggerAlarmsLocked(triggerList, nowELAPSED, nowRTC);
+ if (!hasWakeup && checkAllowNonWakeupDelayLocked(nowELAPSED)) {
+ // if there are no wakeup alarms and the screen is off, we can
+ // delay what we have so far until the future.
+ if (mPendingNonWakeupAlarms.size() == 0) {
+ mStartCurrentDelayTime = nowELAPSED;
+ mNextNonWakeupDeliveryTime = nowELAPSED
+ + ((currentNonWakeupFuzzLocked(nowELAPSED)*3)/2);
+ }
+ mPendingNonWakeupAlarms.addAll(triggerList);
+ mNumDelayedAlarms += triggerList.size();
+ rescheduleKernelAlarmsLocked();
+ updateNextAlarmClockLocked();
+ } else {
+ // now deliver the alarm intents; if there are pending non-wakeup
+ // alarms, we need to merge them in to the list. note we don't
+ // just deliver them first because we generally want non-wakeup
+ // alarms delivered after wakeup alarms.
+ rescheduleKernelAlarmsLocked();
+ updateNextAlarmClockLocked();
+ if (mPendingNonWakeupAlarms.size() > 0) {
+ calculateDeliveryPriorities(mPendingNonWakeupAlarms);
+ triggerList.addAll(mPendingNonWakeupAlarms);
+ Collections.sort(triggerList, mAlarmDispatchComparator);
+ final long thisDelayTime = nowELAPSED - mStartCurrentDelayTime;
+ mTotalDelayTime += thisDelayTime;
+ if (mMaxDelayTime < thisDelayTime) {
+ mMaxDelayTime = thisDelayTime;
+ }
+ mPendingNonWakeupAlarms.clear();
+ }
+ deliverAlarmsLocked(triggerList, nowELAPSED);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 1366149..7d427d6 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -23,6 +23,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -915,7 +916,7 @@
boolean success = false;
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -1075,7 +1076,7 @@
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "app-ops");
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1dc2d7e71..02bffc4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -23,6 +23,10 @@
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
@@ -463,11 +467,12 @@
}
}
- private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
+ private void maybeLogBroadcast(NetworkAgentInfo nai, boolean connected, int type,
+ boolean isDefaultNetwork) {
if (DBG) {
log("Sending " + (connected ? "connected" : "disconnected") +
" broadcast for type " + type + " " + nai.name() +
- " isDefaultNetwork=" + isDefaultNetwork(nai));
+ " isDefaultNetwork=" + isDefaultNetwork);
}
}
@@ -487,43 +492,45 @@
list.add(nai);
// Send a broadcast if this is the first network of its type or if it's the default.
- if (list.size() == 1 || isDefaultNetwork(nai)) {
- maybeLogBroadcast(nai, true, type);
+ final boolean isDefaultNetwork = isDefaultNetwork(nai);
+ if (list.size() == 1 || isDefaultNetwork) {
+ maybeLogBroadcast(nai, true, type, isDefaultNetwork);
sendLegacyNetworkBroadcast(nai, true, type);
}
}
/** Removes the given network from the specified legacy type list. */
- public void remove(int type, NetworkAgentInfo nai) {
+ public void remove(int type, NetworkAgentInfo nai, boolean wasDefault) {
ArrayList<NetworkAgentInfo> list = mTypeLists[type];
if (list == null || list.isEmpty()) {
return;
}
- boolean wasFirstNetwork = list.get(0).equals(nai);
+ final boolean wasFirstNetwork = list.get(0).equals(nai);
if (!list.remove(nai)) {
return;
}
- if (wasFirstNetwork || isDefaultNetwork(nai)) {
- maybeLogBroadcast(nai, false, type);
+ if (wasFirstNetwork || wasDefault) {
+ maybeLogBroadcast(nai, false, type, wasDefault);
sendLegacyNetworkBroadcast(nai, false, type);
}
if (!list.isEmpty() && wasFirstNetwork) {
if (DBG) log("Other network available for type " + type +
", sending connected broadcast");
- maybeLogBroadcast(list.get(0), false, type);
- sendLegacyNetworkBroadcast(list.get(0), false, type);
+ final NetworkAgentInfo replacement = list.get(0);
+ maybeLogBroadcast(replacement, false, type, isDefaultNetwork(replacement));
+ sendLegacyNetworkBroadcast(replacement, false, type);
}
}
/** Removes the given network from all legacy type lists. */
- public void remove(NetworkAgentInfo nai) {
- if (VDBG) log("Removing agent " + nai);
+ public void remove(NetworkAgentInfo nai, boolean wasDefault) {
+ if (VDBG) log("Removing agent " + nai + " wasDefault=" + wasDefault);
for (int type = 0; type < mTypeLists.length; type++) {
- remove(type, nai);
+ remove(type, nai, wasDefault);
}
}
@@ -713,8 +720,8 @@
private NetworkRequest createInternetRequestForTransport(int transportType) {
NetworkCapabilities netCap = new NetworkCapabilities();
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ netCap.addCapability(NET_CAPABILITY_INTERNET);
+ netCap.addCapability(NET_CAPABILITY_NOT_RESTRICTED);
if (transportType > -1) {
netCap.addTransportType(transportType);
}
@@ -1070,9 +1077,9 @@
if (nai.created) {
NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
if (nai.lastValidated) {
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ nc.addCapability(NET_CAPABILITY_VALIDATED);
} else {
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ nc.removeCapability(NET_CAPABILITY_VALIDATED);
}
return nc;
}
@@ -1185,9 +1192,9 @@
synchronized (nai) {
NetworkCapabilities nc = new NetworkCapabilities(nai.networkCapabilities);
if (nai.lastValidated) {
- nc.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ nc.addCapability(NET_CAPABILITY_VALIDATED);
} else {
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ nc.removeCapability(NET_CAPABILITY_VALIDATED);
}
return nc;
}
@@ -1979,7 +1986,7 @@
if (msg.arg1 == 0) {
setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null);
} else {
- NetworkAgentInfo nai = null;
+ final NetworkAgentInfo nai;
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(msg.arg2);
}
@@ -1987,6 +1994,7 @@
loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor");
break;
}
+ nai.captivePortalDetected = true;
setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(),
nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj);
}
@@ -2036,12 +2044,13 @@
loge("Error connecting NetworkAgent");
NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
if (nai != null) {
+ final boolean wasDefault = isDefaultNetwork(nai);
synchronized (mNetworkForNetId) {
mNetworkForNetId.remove(nai.network.netId);
mNetIdInUse.delete(nai.network.netId);
}
// Just in case.
- mLegacyTypeTracker.remove(nai);
+ mLegacyTypeTracker.remove(nai, wasDefault);
}
}
}
@@ -2071,7 +2080,8 @@
nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
null, null);
}
- if (isDefaultNetwork(nai)) {
+ final boolean wasDefault = isDefaultNetwork(nai);
+ if (wasDefault) {
mDefaultInetConditionPublished = 0;
}
notifyIfacesChanged();
@@ -2079,7 +2089,6 @@
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
- mLegacyTypeTracker.remove(nai);
synchronized (mNetworkForNetId) {
mNetworkForNetId.remove(nai.network.netId);
mNetIdInUse.delete(nai.network.netId);
@@ -2118,6 +2127,7 @@
notifyLockdownVpn(nai);
requestNetworkTransitionWakelock(nai.name());
}
+ mLegacyTypeTracker.remove(nai, wasDefault);
for (NetworkAgentInfo networkToActivate : toActivate) {
unlinger(networkToActivate);
rematchNetworkAndRequests(networkToActivate, NascentState.NOT_JUST_VALIDATED,
@@ -2307,7 +2317,7 @@
}
if (doRemove) {
- mLegacyTypeTracker.remove(nri.request.legacyType, nai);
+ mLegacyTypeTracker.remove(nri.request.legacyType, nai, false);
}
}
@@ -2379,7 +2389,8 @@
// Only prompt if the network is unvalidated and was explicitly selected by the user, and if
// we haven't already been told to switch to it regardless of whether it validated or not.
- if (nai == null || nai.everValidated ||
+ // Also don't prompt on captive portals because we're already prompting the user to sign in.
+ if (nai == null || nai.everValidated || nai.captivePortalDetected ||
!nai.networkMisc.explicitlySelected || nai.networkMisc.acceptUnvalidated) {
return;
}
@@ -3523,7 +3534,7 @@
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
- if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)
== false) {
enforceConnectivityInternalPermission();
} else {
@@ -3551,7 +3562,7 @@
private void enforceMeteredApnPolicy(NetworkCapabilities networkCapabilities) {
// if UID is restricted, don't allow them to bring up metered APNs
- if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED)
== false) {
final int uidRules;
final int uid = Binder.getCallingUid();
@@ -3561,7 +3572,7 @@
if ((uidRules & (RULE_REJECT_METERED | RULE_REJECT_ALL)) != 0) {
// we could silently fail or we can filter the available nets to only give
// them those they have access to. Chose the more useful
- networkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+ networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
}
}
}
@@ -3767,7 +3778,7 @@
// TODO: deprecate and remove mDefaultDns when we can do so safely.
// For now, use it only when the network has Internet access. http://b/18327075
final boolean useDefaultDns = networkAgent.networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ NET_CAPABILITY_INTERNET);
final boolean flushDns = updateRoutes(newLp, oldLp, netId);
updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns);
@@ -4190,7 +4201,7 @@
// the new one connected.
if (oldDefaultNetwork != null) {
mLegacyTypeTracker.remove(oldDefaultNetwork.networkInfo.getType(),
- oldDefaultNetwork);
+ oldDefaultNetwork, true);
}
mDefaultInetConditionPublished = newNetwork.everValidated ? 100 : 0;
mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 0b33812..9b7b2d3 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -45,17 +45,20 @@
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.Xml;
import android.view.Display;
+
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.AtomicFile;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -68,6 +71,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
/**
* Keeps track of device idleness and drives low power mode based on that.
@@ -75,6 +79,8 @@
public class DeviceIdleController extends SystemService {
private static final String TAG = "DeviceIdleController";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
public static final String SERVICE_NAME = "deviceidle";
private static final String ACTION_STEP_IDLE_STATE =
@@ -88,17 +94,20 @@
* immediately after going inactive just because we don't want to be continually running
* the significant motion sensor whenever the screen is off.
*/
- private static final long DEFAULT_INACTIVE_TIMEOUT = 30*60*1000L;
+ private static final long DEFAULT_INACTIVE_TIMEOUT = !DEBUG ? 30*60*1000L
+ : 2 * 60 * 1000L;
/**
* This is the time, after seeing motion, that we wait after becoming inactive from
* that until we start looking for motion again.
*/
- private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT = 10*60*1000L;
+ private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT = !DEBUG ? 10*60*1000L
+ : 60 * 1000L;
/**
* This is the time, after the inactive timeout elapses, that we will wait looking
* for significant motion until we truly consider the device to be idle.
*/
- private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT = 30*60*1000L;
+ private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT = !DEBUG ? 30*60*1000L
+ : 2 * 60 * 1000L;
/**
* This is the initial time, after being idle, that we will allow ourself to be back
* in the IDLE_PENDING state allowing the system to run normally until we return to idle.
@@ -117,11 +126,13 @@
* This is the initial time that we want to sit in the idle state before waking up
* again to return to pending idle and allowing normal work to run.
*/
- private static final long DEFAULT_IDLE_TIMEOUT = 60*60*1000L;
+ private static final long DEFAULT_IDLE_TIMEOUT = !DEBUG ? 60*60*1000L
+ : 5 * 60 * 1000L;
/**
* Maximum idle duration we will be allowed to use.
*/
- private static final long DEFAULT_MAX_IDLE_TIMEOUT = 6*60*60*1000L;
+ private static final long DEFAULT_MAX_IDLE_TIMEOUT = !DEBUG ? 6*60*60*1000L
+ : 10 * 60 * 1000L;
/**
* Scaling factor to apply to current idle timeout each time we cycle through that state.
*/
@@ -130,7 +141,8 @@
* This is the minimum time we will allow until the next upcoming alarm for us to
* actually go in to idle mode.
*/
- private static final long DEFAULT_MIN_TIME_TO_ALARM = 60*60*1000L;
+ private static final long DEFAULT_MIN_TIME_TO_ALARM = !DEBUG ? 60*60*1000L
+ : 5 * 60 * 1000L;
private AlarmManager mAlarmManager;
private IBatteryStats mBatteryStats;
@@ -668,7 +680,7 @@
}
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
readConfigFileLocked(parser);
} catch (XmlPullParserException e) {
} finally {
@@ -745,7 +757,7 @@
try {
synchronized (this) {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(memStream, "utf-8");
+ out.setOutput(memStream, StandardCharsets.UTF_8.name());
writeConfigFileLocked(out);
}
} catch (IOException e) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index e856a93..1f6c473 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -126,6 +126,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -1624,53 +1625,61 @@
}
}
- private boolean needsToShowImeSwitchOngoingNotification() {
+ private boolean shouldShowImeSwitcherLocked() {
if (!mShowOngoingImeSwitcherForPhones) return false;
if (mSwitchingDialog != null) return false;
if (isScreenLocked()) return false;
- synchronized (mMethodMap) {
- List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked();
- final int N = imis.size();
- if (N > 2) return true;
- if (N < 1) return false;
- int nonAuxCount = 0;
- int auxCount = 0;
- InputMethodSubtype nonAuxSubtype = null;
- InputMethodSubtype auxSubtype = null;
- for(int i = 0; i < N; ++i) {
- final InputMethodInfo imi = imis.get(i);
- final List<InputMethodSubtype> subtypes =
- mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
- final int subtypeCount = subtypes.size();
- if (subtypeCount == 0) {
- ++nonAuxCount;
- } else {
- for (int j = 0; j < subtypeCount; ++j) {
- final InputMethodSubtype subtype = subtypes.get(j);
- if (!subtype.isAuxiliary()) {
- ++nonAuxCount;
- nonAuxSubtype = subtype;
- } else {
- ++auxCount;
- auxSubtype = subtype;
- }
+ if ((mImeWindowVis & InputMethodService.IME_ACTIVE) == 0) return false;
+ if (mWindowManagerService.isHardKeyboardAvailable()) {
+ // When physical keyboard is attached, we show the ime switcher (or notification if
+ // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently
+ // exists in the IME switcher dialog. Might be OK to remove this condition once
+ // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live.
+ return true;
+ }
+ if ((mImeWindowVis & InputMethodService.IME_VISIBLE) == 0) return false;
+
+ List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked();
+ final int N = imis.size();
+ if (N > 2) return true;
+ if (N < 1) return false;
+ int nonAuxCount = 0;
+ int auxCount = 0;
+ InputMethodSubtype nonAuxSubtype = null;
+ InputMethodSubtype auxSubtype = null;
+ for(int i = 0; i < N; ++i) {
+ final InputMethodInfo imi = imis.get(i);
+ final List<InputMethodSubtype> subtypes =
+ mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true);
+ final int subtypeCount = subtypes.size();
+ if (subtypeCount == 0) {
+ ++nonAuxCount;
+ } else {
+ for (int j = 0; j < subtypeCount; ++j) {
+ final InputMethodSubtype subtype = subtypes.get(j);
+ if (!subtype.isAuxiliary()) {
+ ++nonAuxCount;
+ nonAuxSubtype = subtype;
+ } else {
+ ++auxCount;
+ auxSubtype = subtype;
}
}
}
- if (nonAuxCount > 1 || auxCount > 1) {
- return true;
- } else if (nonAuxCount == 1 && auxCount == 1) {
- if (nonAuxSubtype != null && auxSubtype != null
- && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
- || auxSubtype.overridesImplicitlyEnabledSubtype()
- || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
- && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
- return false;
- }
- return true;
- }
- return false;
}
+ if (nonAuxCount > 1 || auxCount > 1) {
+ return true;
+ } else if (nonAuxCount == 1 && auxCount == 1) {
+ if (nonAuxSubtype != null && auxSubtype != null
+ && (nonAuxSubtype.getLocale().equals(auxSubtype.getLocale())
+ || auxSubtype.overridesImplicitlyEnabledSubtype()
+ || nonAuxSubtype.overridesImplicitlyEnabledSubtype())
+ && nonAuxSubtype.containsExtraValueKey(TAG_TRY_SUPPRESSING_IME_SWITCHER)) {
+ return false;
+ }
+ return true;
+ }
+ return false;
}
private boolean isKeyguardLocked() {
@@ -1695,13 +1704,9 @@
vis = 0;
}
mImeWindowVis = vis;
- mInputShown = ((mImeWindowVis & InputMethodService.IME_VISIBLE) != 0);
mBackDisposition = backDisposition;
- final boolean iconVisibility = ((vis & (InputMethodService.IME_ACTIVE)) != 0)
- && (mWindowManagerService.isHardKeyboardAvailable()
- || (vis & (InputMethodService.IME_VISIBLE)) != 0);
- final boolean needsToShowImeSwitcher = iconVisibility
- && needsToShowImeSwitchOngoingNotification();
+ // mImeWindowVis should be updated before calling shouldShowImeSwitcherLocked().
+ final boolean needsToShowImeSwitcher = shouldShowImeSwitcherLocked();
if (mStatusBar != null) {
mStatusBar.setImeWindowStatus(token, vis, backDisposition,
needsToShowImeSwitcher);
@@ -3516,7 +3521,7 @@
try {
fos = subtypesFile.startWrite();
final XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, NODE_SUBTYPES);
@@ -3562,7 +3567,7 @@
try {
fis = subtypesFile.openRead();
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type = parser.getEventType();
// Skip parsing until START_TAG
while ((type = parser.next()) != XmlPullParser.START_TAG
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 16834855..c76fc1c 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -60,6 +60,7 @@
import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.Geofence;
+import android.location.IGpsGeofenceHardware;
import android.location.IGpsMeasurementsListener;
import android.location.IGpsNavigationMessageListener;
import android.location.IGpsStatusListener;
@@ -162,6 +163,7 @@
private LocationBlacklist mBlacklist;
private GpsMeasurementsProvider mGpsMeasurementsProvider;
private GpsNavigationMessageProvider mGpsNavigationMessageProvider;
+ private IGpsGeofenceHardware mGpsGeofenceProxy;
// --- fields below are protected by mLock ---
// Set of providers that are explicitly enabled
@@ -401,18 +403,19 @@
addProviderLocked(passiveProvider);
mEnabledProviders.add(passiveProvider.getName());
mPassiveProvider = passiveProvider;
- // Create a gps location provider
- GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
- mLocationHandler.getLooper());
if (GpsLocationProvider.isSupported()) {
+ // Create a gps location provider
+ GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
+ mLocationHandler.getLooper());
mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
addProviderLocked(gpsProvider);
mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
+ mGpsMeasurementsProvider = gpsProvider.getGpsMeasurementsProvider();
+ mGpsNavigationMessageProvider = gpsProvider.getGpsNavigationMessageProvider();
+ mGpsGeofenceProxy = gpsProvider.getGpsGeofenceProxy();
}
- mGpsMeasurementsProvider = gpsProvider.getGpsMeasurementsProvider();
- mGpsNavigationMessageProvider = gpsProvider.getGpsNavigationMessageProvider();
/*
Load package name(s) containing location provider support.
@@ -508,7 +511,7 @@
com.android.internal.R.string.config_geofenceProviderPackageName,
com.android.internal.R.array.config_locationProviderPackageNames,
mLocationHandler,
- gpsProvider.getGpsGeofenceProxy(),
+ mGpsGeofenceProxy,
flpHardwareProvider != null ? flpHardwareProvider.getGeofenceHardware() : null);
if (provider == null) {
Slog.e(TAG, "Unable to bind FLP Geofence proxy.");
@@ -1851,7 +1854,7 @@
Binder.restoreCallingIdentity(identity);
}
- if (!hasLocationAccess) {
+ if (!hasLocationAccess || mGpsMeasurementsProvider == null) {
return false;
}
return mGpsMeasurementsProvider.addListener(listener);
@@ -1859,7 +1862,9 @@
@Override
public void removeGpsMeasurementsListener(IGpsMeasurementsListener listener) {
- mGpsMeasurementsProvider.removeListener(listener);
+ if (mGpsMeasurementsProvider != null) {
+ mGpsMeasurementsProvider.removeListener(listener);
+ }
}
@Override
@@ -1880,7 +1885,7 @@
Binder.restoreCallingIdentity(identity);
}
- if (!hasLocationAccess) {
+ if (!hasLocationAccess || mGpsNavigationMessageProvider == null) {
return false;
}
return mGpsNavigationMessageProvider.addListener(listener);
@@ -1888,7 +1893,9 @@
@Override
public void removeGpsNavigationMessageListener(IGpsNavigationMessageListener listener) {
- mGpsNavigationMessageProvider.removeListener(listener);
+ if (mGpsNavigationMessageProvider != null) {
+ mGpsNavigationMessageProvider.removeListener(listener);
+ }
}
@Override
@@ -2345,22 +2352,16 @@
// Mock Providers
- private void checkMockPermissionsSafe() {
- boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1;
- if (!allowMocks) {
- throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting");
- }
-
- if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
- PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
- }
+ private boolean canCallerAccessMockLocation(String opPackageName) {
+ return mAppOps.noteOp(AppOpsManager.OP_MOCK_LOCATION, Binder.getCallingUid(),
+ opPackageName) == AppOpsManager.MODE_ALLOWED;
}
@Override
- public void addTestProvider(String name, ProviderProperties properties) {
- checkMockPermissionsSafe();
+ public void addTestProvider(String name, ProviderProperties properties, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
if (LocationManager.PASSIVE_PROVIDER.equals(name)) {
throw new IllegalArgumentException("Cannot mock the passive location provider");
@@ -2395,15 +2396,18 @@
}
@Override
- public void removeTestProvider(String provider) {
- checkMockPermissionsSafe();
+ public void removeTestProvider(String provider, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
// These methods can't be called after removing the test provider, so first make sure
// we don't leave anything dangling.
- clearTestProviderEnabled(provider);
- clearTestProviderLocation(provider);
- clearTestProviderStatus(provider);
+ clearTestProviderEnabled(provider, opPackageName);
+ clearTestProviderLocation(provider, opPackageName);
+ clearTestProviderStatus(provider, opPackageName);
MockProvider mockProvider = mMockProviders.remove(provider);
if (mockProvider == null) {
@@ -2425,8 +2429,11 @@
}
@Override
- public void setTestProviderLocation(String provider, Location loc) {
- checkMockPermissionsSafe();
+ public void setTestProviderLocation(String provider, Location loc, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
@@ -2440,8 +2447,11 @@
}
@Override
- public void clearTestProviderLocation(String provider) {
- checkMockPermissionsSafe();
+ public void clearTestProviderLocation(String provider, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
@@ -2452,8 +2462,11 @@
}
@Override
- public void setTestProviderEnabled(String provider, boolean enabled) {
- checkMockPermissionsSafe();
+ public void setTestProviderEnabled(String provider, boolean enabled, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
@@ -2475,8 +2488,11 @@
}
@Override
- public void clearTestProviderEnabled(String provider) {
- checkMockPermissionsSafe();
+ public void clearTestProviderEnabled(String provider, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
@@ -2491,8 +2507,12 @@
}
@Override
- public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
- checkMockPermissionsSafe();
+ public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime,
+ String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
@@ -2503,8 +2523,11 @@
}
@Override
- public void clearTestProviderStatus(String provider) {
- checkMockPermissionsSafe();
+ public void clearTestProviderStatus(String provider, String opPackageName) {
+ if (!canCallerAccessMockLocation(opPackageName)) {
+ return;
+ }
+
synchronized (mLock) {
MockProvider mockProvider = mMockProviders.get(provider);
if (mockProvider == null) {
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index ed2de4a..2df7f79 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -106,20 +106,13 @@
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
+ // Notify keystore that a new user was added.
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
- final int userSysUid = UserHandle.getUid(userHandle, Process.SYSTEM_UID);
final KeyStore ks = KeyStore.getInstance();
-
- // Clear up keystore in case anything was left behind by previous users
- ks.resetUid(userSysUid);
-
- // If this user has a parent, sync with its keystore password
final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE);
final UserInfo parentInfo = um.getProfileParent(userHandle);
- if (parentInfo != null) {
- final int parentSysUid = UserHandle.getUid(parentInfo.id, Process.SYSTEM_UID);
- ks.syncUid(parentSysUid, userSysUid);
- }
+ final int parentHandle = parentInfo != null ? parentInfo.id : -1;
+ ks.onUserAdded(userHandle, parentHandle);
} else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) {
final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
mStorage.prefetchUser(userHandle);
@@ -674,8 +667,7 @@
mStorage.removeUser(userId);
final KeyStore ks = KeyStore.getInstance();
- final int userUid = UserHandle.getUid(userId, Process.SYSTEM_UID);
- ks.resetUid(userUid);
+ ks.onUserRemoved(userId);
}
private static final String[] VALID_SETTINGS = new String[] {
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 93ac51a..e00cf5b 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -16,8 +16,10 @@
package com.android.server;
+import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readStringAttribute;
+import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
import static com.android.internal.util.XmlUtils.writeIntAttribute;
import static com.android.internal.util.XmlUtils.writeStringAttribute;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -37,6 +39,7 @@
import android.mtp.MtpStorage;
import android.net.Uri;
import android.os.Binder;
+import android.os.DropBoxManager;
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.FileUtils;
@@ -174,6 +177,7 @@
private static final boolean WATCHDOG_ENABLE = false;
private static final String TAG = "MountService";
+ private static final String TAG_STORAGE_BENCHMARK = "storage_benchmark";
private static final String VOLD_TAG = "VoldConnector";
@@ -233,6 +237,7 @@
public static final int VOLUME_DESTROYED = 659;
public static final int MOVE_STATUS = 660;
+ public static final int BENCHMARK_RESULT = 661;
/*
* 700 series - fstrim
@@ -247,6 +252,7 @@
private static final String TAG_VOLUMES = "volumes";
private static final String ATTR_VERSION = "version";
private static final String ATTR_PRIMARY_STORAGE_UUID = "primaryStorageUuid";
+ private static final String ATTR_FORCE_ADOPTABLE = "forceAdoptable";
private static final String TAG_VOLUME = "volume";
private static final String ATTR_TYPE = "type";
private static final String ATTR_FS_UUID = "fsUuid";
@@ -276,6 +282,8 @@
private ArrayMap<String, VolumeRecord> mRecords = new ArrayMap<>();
@GuardedBy("mLock")
private String mPrimaryStorageUuid;
+ @GuardedBy("mLock")
+ private boolean mForceAdoptable;
/** Map from disk ID to latches */
@GuardedBy("mLock")
@@ -810,7 +818,8 @@
if (cooked.length != 3) break;
final String id = cooked[1];
int flags = Integer.parseInt(cooked[2]);
- if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)) {
+ if (SystemProperties.getBoolean(StorageManager.PROP_FORCE_ADOPTABLE, false)
+ || mForceAdoptable) {
flags |= DiskInfo.FLAG_ADOPTABLE;
}
mDisks.put(id, new DiskInfo(id, flags));
@@ -927,6 +936,12 @@
break;
}
+ case VoldResponseCode.BENCHMARK_RESULT: {
+ final DropBoxManager dropBox = mContext.getSystemService(DropBoxManager.class);
+ dropBox.addText(TAG_STORAGE_BENCHMARK, raw);
+ break;
+ }
+
case VoldResponseCode.FstrimCompleted: {
EventLogTags.writeFstrimFinish(SystemClock.elapsedRealtime());
break;
@@ -1199,12 +1214,13 @@
private void readSettingsLocked() {
mRecords.clear();
mPrimaryStorageUuid = getDefaultPrimaryStorageUuid();
+ mForceAdoptable = false;
FileInputStream fis = null;
try {
fis = mSettingsFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -1220,6 +1236,7 @@
mPrimaryStorageUuid = readStringAttribute(in,
ATTR_PRIMARY_STORAGE_UUID);
}
+ mForceAdoptable = readBooleanAttribute(in, ATTR_FORCE_ADOPTABLE, false);
} else if (TAG_VOLUME.equals(tag)) {
final VolumeRecord rec = readVolumeRecord(in);
@@ -1244,11 +1261,12 @@
fos = mSettingsFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_VOLUMES);
writeIntAttribute(out, ATTR_VERSION, VERSION_FIX_PRIMARY);
writeStringAttribute(out, ATTR_PRIMARY_STORAGE_UUID, mPrimaryStorageUuid);
+ writeBooleanAttribute(out, ATTR_FORCE_ADOPTABLE, mForceAdoptable);
final int size = mRecords.size();
for (int i = 0; i < size; i++) {
final VolumeRecord rec = mRecords.valueAt(i);
@@ -1406,6 +1424,19 @@
}
@Override
+ public long benchmark(String volId) {
+ enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
+ waitForReady();
+
+ try {
+ final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId);
+ return Long.parseLong(res.getMessage());
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+ @Override
public void partitionPublic(String diskId) {
enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
waitForReady();
@@ -1498,7 +1529,11 @@
}
}
- private void forgetAll() {
+ @Override
+ public void forgetAllVolumes() {
+ enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+ waitForReady();
+
synchronized (mLock) {
for (int i = 0; i < mRecords.size(); i++) {
final String fsUuid = mRecords.keyAt(i);
@@ -1516,6 +1551,21 @@
}
@Override
+ public void setDebugFlags(int flags, int mask) {
+ enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
+ waitForReady();
+
+ synchronized (mLock) {
+ if ((mask & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0) {
+ mForceAdoptable = (flags & StorageManager.DEBUG_FORCE_ADOPTABLE) != 0;
+ }
+
+ writeSettingsLocked();
+ resetIfReadyAndConnected();
+ }
+ }
+
+ @Override
public String getPrimaryStorageUuid() {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
@@ -2979,12 +3029,6 @@
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
- for (String arg : args) {
- if ("--forget-all".equals(arg)) {
- forgetAll();
- }
- }
-
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ", 160);
synchronized (mLock) {
pw.println("Disks:");
@@ -3016,6 +3060,7 @@
pw.println();
pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
+ pw.println("Force adoptable: " + mForceAdoptable);
}
synchronized (mObbMounts) {
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index 0de8c8d..e0e6070 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -216,9 +216,9 @@
mWakeLock.acquire();
- Log.i(TAG, "MSG_NEW_DEVICE_STATE ");
+ Log.i(TAG, "MSG_NEW_DEVICE_STATE");
Message msg = mHandler.obtainMessage(MSG_NEW_DEVICE_STATE, headsetState,
- mHeadsetState, newName);
+ mHeadsetState, "");
mHandler.sendMessage(msg);
mHeadsetState = headsetState;
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index d64e39f..925fae0a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -51,6 +51,7 @@
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
static final boolean DEBUG_LOCKSCREEN = DEBUG_ALL || false;
+ static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
static final boolean DEBUG_LRU = DEBUG_ALL || false;
static final boolean DEBUG_MU = DEBUG_ALL || false;
static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
@@ -82,6 +83,7 @@
static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
static final String POSTFIX_LOCKSCREEN = (APPEND_CATEGORY_NAME) ? "_LOCKSCREEN" : "";
+ static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LOCKTASK" : "";
static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
static final String POSTFIX_MU = "_MU";
static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : "";
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c38fc8d..a8ab667 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -235,6 +235,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -264,6 +265,7 @@
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_LRU = TAG + POSTFIX_LRU;
private static final String TAG_MU = TAG + POSTFIX_MU;
private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
@@ -2439,7 +2441,6 @@
}
}
- long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
synchronized(bstats) {
synchronized(mPidsSelfLocked) {
@@ -2470,7 +2471,7 @@
pr.info.uid, pr.processName);
}
ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime, cpuSpeedTimes);
+ st.rel_stime - otherSTime);
pr.curCpuTime += st.rel_utime + st.rel_stime;
} else {
BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
@@ -2479,7 +2480,7 @@
bstats.mapUid(st.uid), st.name);
}
ps.addCpuTimeLocked(st.rel_utime - otherUTime,
- st.rel_stime - otherSTime, cpuSpeedTimes);
+ st.rel_stime - otherSTime);
}
}
final int userTime = mProcessCpuTracker.getLastUserTime();
@@ -2490,7 +2491,7 @@
final int idleTime = mProcessCpuTracker.getLastIdleTime();
bstats.finishAddingCpuLocked(perc, remainUTime,
remainSTime, totalUTime, totalSTime, userTime, systemTime,
- iowaitTime, irqTime, softIrqTime, idleTime, cpuSpeedTimes);
+ iowaitTime, irqTime, softIrqTime, idleTime);
}
}
}
@@ -2573,7 +2574,7 @@
if (mFocusedActivity.userId != mLastFocusedUserId) {
mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
- mFocusedActivity.userId, 0));
+ mFocusedActivity.userId, 0));
mLastFocusedUserId = mFocusedActivity.userId;
}
}
@@ -5297,7 +5298,7 @@
private final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, String reason) {
- ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
+ ArrayList<ProcessRecord> procs = new ArrayList<>();
// Remove all processes this package may have touched: all with the
// same UID (except for the system or root user), and all whose name
@@ -5444,6 +5445,13 @@
for (int i = providers.size() - 1; i >= 0; i--) {
removeDyingProviderLocked(null, providers.get(i), true);
}
+
+ // Clean-up disabled broadcast receivers.
+ for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
+ mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
+ packageName, disabledClasses, userId, true);
+ }
+
}
private final boolean forceStopPackageLocked(String packageName, int appId,
@@ -5540,6 +5548,13 @@
// Remove transient permissions granted from/to this package/user
removeUriPermissionsForPackageLocked(packageName, userId, false);
+ if (doit) {
+ for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
+ didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
+ packageName, null, userId, doit);
+ }
+ }
+
if (packageName == null || uninstalling) {
// Remove pending intents. For now we only do this when force
// stopping users, because we have some problems when doing this
@@ -5962,7 +5977,7 @@
void postFinishBooting(boolean finishBooting, boolean enableScreen) {
mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
- finishBooting? 1 : 0, enableScreen ? 1 : 0));
+ finishBooting ? 1 : 0, enableScreen ? 1 : 0));
}
void enableScreenAfterBoot() {
@@ -6002,6 +6017,26 @@
}
}
+ @Override
+ public void keyguardGoingAway(boolean disableWindowAnimations,
+ boolean keyguardGoingToNotificationShade) {
+ enforceNotIsolatedCaller("keyguardGoingAway");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ if (DEBUG_LOCKSCREEN) logLockScreen("");
+ mWindowManager.keyguardGoingAway(disableWindowAnimations,
+ keyguardGoingToNotificationShade);
+ if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
+ mLockScreenShown = LOCK_SCREEN_HIDDEN;
+ updateSleepIfNeededLocked();
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
final void finishBooting() {
synchronized (this) {
if (!mBootAnimationComplete) {
@@ -7651,7 +7686,7 @@
fos = mGrantFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_URI_GRANTS);
for (UriPermission.Snapshot perm : persist) {
@@ -7686,7 +7721,7 @@
try {
fis = mGrantFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -8741,6 +8776,7 @@
throw new SecurityException("updateLockTaskPackage called from non-system process");
}
synchronized (this) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" + packages);
mLockTaskPackages.put(userId, packages);
mStackSupervisor.onLockTaskPackagesUpdatedLocked();
}
@@ -8748,6 +8784,7 @@
void startLockTaskModeLocked(TaskRecord task) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
return;
}
@@ -8764,6 +8801,7 @@
task.mLockTaskUid = callingUid;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
// startLockTask() called by app and task mode is lockTaskModeDefault.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
StatusBarManagerInternal statusBarManager =
LocalServices.getService(StatusBarManagerInternal.class);
if (statusBarManager != null) {
@@ -8776,6 +8814,8 @@
throw new IllegalArgumentException("Invalid task, not in foreground");
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
+ "Locking fully");
mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
ActivityManager.LOCK_TASK_MODE_PINNED :
ActivityManager.LOCK_TASK_MODE_LOCKED,
@@ -15062,7 +15102,7 @@
ContentProviderRecord cpr = app.pubProviders.valueAt(i);
final boolean always = app.bad || !allowRestart;
boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
- if ((inLaunching || always) && !cpr.connections.isEmpty()) {
+ if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
// We left the provider in the launching list, need to
// restart it.
restart = true;
@@ -15206,7 +15246,7 @@
for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
ContentProviderRecord cpr = mLaunchingProviders.get(i);
if (cpr.launchingApp == app) {
- if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
+ if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
restart = true;
} else {
removeDyingProviderLocked(app, cpr, true);
@@ -15994,6 +16034,11 @@
// By default broadcasts do not go to stopped apps.
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
+ // If we have not finished booting, don't allow this to launch new processes.
+ if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ }
+
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
(sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
+ " ordered=" + ordered + " userid=" + userId);
@@ -16098,10 +16143,7 @@
final int uid = intentExtras != null
? intentExtras.getInt(Intent.EXTRA_UID) : -1;
if (uid >= 0) {
- BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
- synchronized (bs) {
- bs.removeUidStatsLocked(uid);
- }
+ mBatteryStatsService.removeUid(uid);
mAppOpsService.uidRemoved(uid);
}
break;
@@ -16455,8 +16497,7 @@
// if the caller really truly claims to know what they're doing, go
// ahead and allow the broadcast without launching any receivers
if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
- intent = new Intent(intent);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
} else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
+ " before boot completion");
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index a86df2d..6574538 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -748,6 +748,14 @@
return true;
}
+ if (hasVisibleBehindActivity()) {
+ // Stop visible behind activity before going to sleep.
+ final ActivityRecord r = mActivityContainer.mActivityDisplay.mVisibleBehindActivity;
+ mStackSupervisor.mStoppingActivities.add(r);
+ if (DEBUG_STATES) Slog.v(TAG, "Sleep still waiting to stop visible behind " + r);
+ return true;
+ }
+
return false;
}
@@ -1007,7 +1015,7 @@
// the current instance before starting the new one.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Destroying after pause: " + prev);
destroyActivityLocked(prev, true, "pause-config");
- } else if (!hasVisibleBehindActivity()) {
+ } else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
// If we were visible then resumeTopActivities will release resources before
// stopping.
mStackSupervisor.mStoppingActivities.add(prev);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index cb5ba8e..f304828 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -117,6 +117,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -124,6 +125,7 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -1183,7 +1185,7 @@
final TaskRecord task = r.task;
if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
- setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "lockTaskLaunchMode attribute");
+ setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE");
}
final ActivityStack stack = task.stack;
@@ -2868,6 +2870,9 @@
task.stack.removeTask(task, "moveTaskToStack", false /* notMoving */);
}
stack.addTask(task, toTop, true);
+ // The task might have already been running and its visibility needs to be synchronized with
+ // the visibility of the stack / windows.
+ stack.ensureActivitiesVisibleLocked(null, 0);
resumeTopActivitiesLocked();
}
@@ -3324,6 +3329,18 @@
}
}
+ private String lockTaskModeToString() {
+ switch (mLockTaskModeState) {
+ case LOCK_TASK_MODE_LOCKED:
+ return "LOCKED";
+ case LOCK_TASK_MODE_PINNED:
+ return "PINNED";
+ case LOCK_TASK_MODE_NONE:
+ return "NONE";
+ default: return "unknown=" + mLockTaskModeState;
+ }
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mFocusedStack=" + mFocusedStack);
pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
@@ -3331,7 +3348,16 @@
pw.print(prefix); pw.println("mCurTaskId=" + mCurTaskId);
pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
pw.print(prefix); pw.println("mActivityContainers=" + mActivityContainers);
- pw.print(prefix); pw.println("mLockTaskModeTasks" + mLockTaskModeTasks);
+ pw.print(prefix); pw.print("mLockTaskModeState=" + lockTaskModeToString());
+ final SparseArray<String[]> packages = mService.mLockTaskPackages;
+ if (packages.size() > 0) {
+ pw.println(" mLockTaskPackages (userId:packages)=");
+ for (int i = 0; i < packages.size(); ++i) {
+ pw.print(prefix); pw.print(prefix); pw.print(packages.keyAt(i));
+ pw.print(":"); pw.println(Arrays.toString(packages.valueAt(i)));
+ }
+ }
+ pw.println(" mLockTaskModeTasks" + mLockTaskModeTasks);
}
ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
@@ -3651,6 +3677,8 @@
void removeLockedTaskLocked(final TaskRecord task) {
if (mLockTaskModeTasks.remove(task) && mLockTaskModeTasks.isEmpty()) {
// Last one.
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "removeLockedTask: task=" + task +
+ " last task, reverting locktask mode. Callers=" + Debug.getCallers(3));
final Message lockTaskMsg = Message.obtain();
lockTaskMsg.arg1 = task.userId;
lockTaskMsg.what = LOCK_TASK_END_MSG;
@@ -3676,20 +3704,26 @@
removeLockedTaskLocked(lockedTask);
if (!mLockTaskModeTasks.isEmpty()) {
// There are locked tasks remaining, can only finish this task, not unlock it.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Tasks remaining, can't unlock");
lockedTask.performClearTaskLocked();
resumeTopActivitiesLocked();
return;
}
}
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: No tasks to unlock. Callers=" + Debug.getCallers(4));
return;
}
// Should have already been checked, but do it again.
if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK,
+ "setLockTaskModeLocked: Can't lock due to auth");
return;
}
if (isLockTaskModeViolation(task)) {
- Slog.e(TAG, "setLockTaskMode: Attempt to start an unauthorized lock task.");
+ Slog.e(TAG_LOCKTASK, "setLockTaskMode: Attempt to start an unauthorized lock task.");
return;
}
@@ -3703,6 +3737,8 @@
mHandler.sendMessage(lockTaskMsg);
}
// Add it or move it to the top.
+ if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "setLockTaskModeLocked: Locking to " + task +
+ " Callers=" + Debug.getCallers(4));
mLockTaskModeTasks.remove(task);
mLockTaskModeTasks.add(task);
@@ -3756,6 +3792,13 @@
stack.onLockTaskPackagesUpdatedLocked();
}
}
+ final ActivityRecord r = topRunningActivityLocked();
+ final TaskRecord task = r != null ? r.task : null;
+ if (mLockTaskModeTasks.isEmpty() && task != null
+ && task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE) {
+ // This task must have just been authorized.
+ setLockTaskModeLocked(task, ActivityManager.LOCK_TASK_MODE_LOCKED, "package updated");
+ }
if (didSomething) {
resumeTopActivitiesLocked();
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 58665d7..a61223a 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -64,6 +64,7 @@
implements PowerManagerInternal.LowPowerModeListener {
static final String TAG = "BatteryStatsService";
+ private boolean mFirstExternalStatsUpdate = true;
static IBatteryStats sService;
final BatteryStatsImpl mStats;
final BatteryStatsHandler mHandler;
@@ -177,6 +178,15 @@
// These are for direct use by the activity manager...
+ /**
+ * Remove a UID from the BatteryStats and BatteryStats' external dependencies.
+ */
+ void removeUid(int uid) {
+ synchronized (mStats) {
+ mStats.removeUidStatsLocked(uid);
+ }
+ }
+
void addIsolatedUid(int isolatedUid, int appUid) {
synchronized (mStats) {
mStats.addIsolatedUidLocked(isolatedUid, appUid);
@@ -1150,11 +1160,18 @@
mStats.addHistoryEventLocked(elapsedRealtime, uptime,
BatteryStats.HistoryItem.EVENT_COLLECT_EXTERNAL_STATS, reason, 0);
}
+ mStats.updateCpuTimeLocked(mFirstExternalStatsUpdate);
mStats.updateKernelWakelocksLocked();
mStats.updateMobileRadioStateLocked(SystemClock.elapsedRealtime());
mStats.updateWifiStateLocked(wifiEnergyInfo);
mStats.updateBluetoothStateLocked(bluetoothEnergyInfo);
}
+
+ if (mFirstExternalStatsUpdate) {
+ // We have read the stats for the first time, which means we have a baseline
+ // from which to calculate delta.
+ mFirstExternalStatsUpdate = false;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index e89ef57..745cb7e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -21,6 +21,7 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.Set;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -209,7 +210,7 @@
}
public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
- for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
if (r.intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"***** DROPPING PARALLEL ["
@@ -222,7 +223,7 @@
}
public final boolean replaceOrderedBroadcastLocked(BroadcastRecord r) {
- for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
+ for (int i = mOrderedBroadcasts.size() - 1; i > 0; i--) {
if (r.intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"***** DROPPING ORDERED ["
@@ -1097,6 +1098,28 @@
mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
}
+ boolean cleanupDisabledPackageReceiversLocked(
+ String packageName, Set<String> filterByClasses, int userId, boolean doit) {
+ boolean didSomething = false;
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
+ didSomething |= mParallelBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
+ packageName, filterByClasses, userId, doit);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+
+ for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
+ didSomething |= mOrderedBroadcasts.get(i).cleanupDisabledPackageReceiversLocked(
+ packageName, filterByClasses, userId, doit);
+ if (!doit && didSomething) {
+ return true;
+ }
+ }
+
+ return didSomething;
+ }
+
final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
if (r.nextReceiver > 0) {
Object curReceiver = r.receivers.get(r.nextReceiver-1);
@@ -1130,7 +1153,7 @@
if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
|| mPendingBroadcast != null) {
boolean printed = false;
- for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mParallelBroadcasts.size() - 1; i >= 0; i--) {
BroadcastRecord br = mParallelBroadcasts.get(i);
if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
continue;
@@ -1148,7 +1171,7 @@
}
printed = false;
needSep = true;
- for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
+ for (int i = mOrderedBroadcasts.size() - 1; i >= 0; i--) {
BroadcastRecord br = mOrderedBroadcasts.get(i);
if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
continue;
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index 9a4d7a0..c050d03f 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -26,12 +26,14 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
+import java.util.Set;
/**
* An active intent broadcast.
@@ -164,7 +166,7 @@
final int N = receivers != null ? receivers.size() : 0;
String p2 = prefix + " ";
PrintWriterPrinter printer = new PrintWriterPrinter(pw);
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < N; i++) {
Object o = receivers.get(i);
pw.print(prefix); pw.print("Receiver #"); pw.print(i);
pw.print(": "); pw.println(o);
@@ -205,6 +207,36 @@
state = IDLE;
}
+ boolean cleanupDisabledPackageReceiversLocked(
+ String packageName, Set<String> filterByClasses, int userId, boolean doit) {
+ if ((userId != UserHandle.USER_ALL && this.userId != userId) || receivers == null) {
+ return false;
+ }
+
+ boolean didSomething = false;
+ Object o;
+ for (int i = receivers.size() - 1; i >= 0; i--) {
+ o = receivers.get(i);
+ if (!(o instanceof ResolveInfo)) {
+ continue;
+ }
+ ActivityInfo info = ((ResolveInfo)o).activityInfo;
+
+ final boolean sameComponent = packageName == null
+ || (info.applicationInfo.packageName.equals(packageName)
+ && (filterByClasses == null || filterByClasses.contains(info.name)));
+ if (sameComponent) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ receivers.remove(i);
+ }
+ }
+
+ return didSomething;
+ }
+
public String toString() {
return "BroadcastRecord{"
+ Integer.toHexString(System.identityHashCode(this))
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 0fe9231..814e8b4 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -21,6 +21,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -86,7 +87,7 @@
try {
fis = mFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
@@ -362,7 +363,7 @@
try {
fos = mFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
out.startTag(null, "compat-packages");
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index a37249d..dceadf4 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -139,6 +139,10 @@
return (externalProcessTokenToHandle != null || externalProcessNoHandleCount > 0);
}
+ public boolean hasConnectionOrHandle() {
+ return !connections.isEmpty() || hasExternalProcessHandles();
+ }
+
void dump(PrintWriter pw, String prefix, boolean full) {
if (full) {
pw.print(prefix); pw.print("package=");
diff --git a/services/core/java/com/android/server/am/ProviderMap.java b/services/core/java/com/android/server/am/ProviderMap.java
index a1dc3e3..ed8b1dd 100644
--- a/services/core/java/com/android/server/am/ProviderMap.java
+++ b/services/core/java/com/android/server/am/ProviderMap.java
@@ -210,8 +210,11 @@
boolean collectPackageProvidersLocked(String packageName, Set<String> filterByClasses,
boolean doit, boolean evenPersistent, int userId,
ArrayList<ContentProviderRecord> result) {
- boolean didSomething = collectPackageProvidersLocked(packageName, filterByClasses,
- doit, evenPersistent, mSingletonByClass, result);
+ boolean didSomething = false;
+ if (userId == UserHandle.USER_ALL || userId == UserHandle.USER_OWNER) {
+ didSomething = collectPackageProvidersLocked(packageName, filterByClasses,
+ doit, evenPersistent, mSingletonByClass, result);
+ }
if (!doit && didSomething) {
return true;
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index f7d241e..236af37 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -430,7 +430,7 @@
// avoid deadlocks.
final String localPackageName = packageName;
final int localForegroundId = foregroundId;
- final Notification localForegroundNoti = foregroundNoti;
+ final Notification _foregroundNoti = foregroundNoti;
ams.mHandler.post(new Runnable() {
public void run() {
NotificationManagerInternal nm = LocalServices.getService(
@@ -438,16 +438,14 @@
if (nm == null) {
return;
}
+ Notification localForegroundNoti = _foregroundNoti;
try {
- if (localForegroundNoti.icon == 0) {
+ if (localForegroundNoti.getSmallIcon() == null) {
// It is not correct for the caller to supply a notification
// icon, but this used to be able to slip through, so for
- // those dirty apps give it the app's icon.
- localForegroundNoti.icon = appInfo.icon;
+ // those dirty apps we will create a notification clearly
+ // blaming the app.
- // Do not allow apps to present a sneaky invisible content view either.
- localForegroundNoti.contentView = null;
- localForegroundNoti.bigContentView = null;
CharSequence appName = appInfo.loadLabel(
ams.mContext.getPackageManager());
if (appName == null) {
@@ -457,35 +455,44 @@
try {
ctx = ams.mContext.createPackageContext(
appInfo.packageName, 0);
+
+ Notification.Builder notiBuilder = new Notification.Builder(ctx);
+
+ // it's ugly, but it clearly identifies the app
+ notiBuilder.setSmallIcon(appInfo.icon);
+
Intent runningIntent = new Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
runningIntent.setData(Uri.fromParts("package",
appInfo.packageName, null));
PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- localForegroundNoti.color = ams.mContext.getColor(
+ notiBuilder.setColor(ams.mContext.getColor(
com.android.internal
- .R.color.system_notification_accent_color);
- localForegroundNoti.setLatestEventInfo(ctx,
+ .R.color.system_notification_accent_color));
+ notiBuilder.setContentTitle(
ams.mContext.getString(
com.android.internal.R.string
.app_running_notification_title,
- appName),
+ appName));
+ notiBuilder.setContentText(
ams.mContext.getString(
com.android.internal.R.string
.app_running_notification_text,
- appName),
- pi);
+ appName));
+ notiBuilder.setContentIntent(pi);
+
+ localForegroundNoti = notiBuilder.build();
} catch (PackageManager.NameNotFoundException e) {
- localForegroundNoti.icon = 0;
}
}
- if (localForegroundNoti.icon == 0) {
+ if (localForegroundNoti.getSmallIcon() == null) {
// Notifications whose icon is 0 are defined to not show
// a notification, silently ignoring it. We don't want to
// just ignore it, we want to prevent the service from
// being foreground.
- throw new RuntimeException("icon must be non-zero");
+ throw new RuntimeException("invalid service notification: "
+ + foregroundNoti);
}
int[] outId = new int[1];
nm.enqueueNotification(localPackageName, localPackageName,
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index f3b4516..f653e9e 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -22,6 +22,7 @@
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_DEFAULT;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED;
import static android.content.pm.ActivityInfo.LOCK_TASK_LAUNCH_MODE_NEVER;
+import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
import static com.android.server.am.ActivityManagerDebugConfig.*;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
@@ -62,6 +63,7 @@
final class TaskRecord {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
+ private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
static final String ATTR_TASKID = "task_id";
@@ -90,6 +92,7 @@
private static final String ATTR_CALLING_UID = "calling_uid";
private static final String ATTR_CALLING_PACKAGE = "calling_package";
private static final String ATTR_RESIZEABLE = "resizeable";
+ private static final String ATTR_PRIVILEGED = "privileged";
private static final String TASK_THUMBNAIL_SUFFIX = "_task_thumbnail";
@@ -127,14 +130,16 @@
// the root activity.
int mLockTaskMode; // Which tasklock mode to launch this task in. One of
// ActivityManager.LOCK_TASK_LAUNCH_MODE_*
+ private boolean mPrivileged; // The root activity application of this task holds
+ // privileged permissions.
+
/** Can't be put in lockTask mode. */
final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
- /** Can enter lockTask with user approval if not already in lockTask. */
+ /** Can enter lockTask with user approval. Can never start over existing lockTask task. */
final static int LOCK_TASK_AUTH_PINNABLE = 1;
/** Starts in LOCK_TASK_MODE_LOCKED automatically. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_LAUNCHABLE = 2;
- /** Enters LOCK_TASK_MODE_LOCKED via startLockTask(), enters LOCK_TASK_MODE_PINNED from
- * Overview. Can start over existing lockTask task. */
+ /** Can enter lockTask with user approval. Can start over existing lockTask task. */
final static int LOCK_TASK_AUTH_WHITELISTED = 3;
int mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE;
@@ -245,7 +250,7 @@
long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
- int callingUid, String callingPackage, boolean resizeable) {
+ int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
@@ -281,6 +286,7 @@
mCallingUid = callingUid;
mCallingPackage = callingPackage;
mResizeable = resizeable;
+ mPrivileged = privileged;
}
void touchActiveTime() {
@@ -381,6 +387,7 @@
}
mResizeable = info.resizeable;
mLockTaskMode = info.lockTaskLaunchMode;
+ mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0;
setLockTaskAuth();
}
@@ -734,32 +741,34 @@
performClearTaskAtIndexLocked(0);
}
- private boolean isPrivileged() {
- final ProcessRecord proc = mService.mProcessNames.get(mCallingPackage, mCallingUid);
- if (proc != null) {
- return (proc.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
- }
- return false;
- }
-
void setLockTaskAuth() {
switch (mLockTaskMode) {
case LOCK_TASK_LAUNCH_MODE_DEFAULT:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "WHITELISTED" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_NEVER:
- mLockTaskAuth = isPrivileged() ?
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "DONT_LOCK" : "PINNABLE"));
+ mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_DONT_LOCK : LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_ALWAYS:
- mLockTaskAuth = isPrivileged() ?
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (mPrivileged ? "LAUNCHABLE" : "PINNABLE"));
+ mLockTaskAuth = mPrivileged ?
LOCK_TASK_AUTH_LAUNCHABLE: LOCK_TASK_AUTH_PINNABLE;
break;
case LOCK_TASK_LAUNCH_MODE_IF_WHITELISTED:
+ if (DEBUG_LOCKTASK) Slog.d(TAG_LOCKTASK, "setLockTaskAuth: task=" + this +
+ " mLockTaskAuth=" + (isLockTaskWhitelistedLocked() ?
+ "LAUNCHABLE" : "PINNABLE"));
mLockTaskAuth = isLockTaskWhitelistedLocked() ?
LOCK_TASK_AUTH_LAUNCHABLE : LOCK_TASK_AUTH_PINNABLE;
break;
@@ -930,6 +939,7 @@
out.attribute(null, ATTR_CALLING_UID, String.valueOf(mCallingUid));
out.attribute(null, ATTR_CALLING_PACKAGE, mCallingPackage == null ? "" : mCallingPackage);
out.attribute(null, ATTR_RESIZEABLE, String.valueOf(mResizeable));
+ out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged));
if (affinityIntent != null) {
out.startTag(null, TAG_AFFINITYINTENT);
@@ -993,6 +1003,7 @@
int callingUid = -1;
String callingPackage = "";
boolean resizeable = false;
+ boolean privileged = false;
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
@@ -1048,6 +1059,8 @@
callingPackage = attrValue;
} else if (ATTR_RESIZEABLE.equals(attrName)) {
resizeable = Boolean.valueOf(attrValue);
+ } else if (ATTR_PRIVILEGED.equals(attrName)) {
+ privileged = Boolean.valueOf(attrValue);
} else {
Slog.w(TAG, "TaskRecord: Unknown attribute=" + attrName);
}
@@ -1107,7 +1120,7 @@
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
- callingUid, callingPackage, resizeable);
+ callingUid, callingPackage, resizeable, privileged);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
activities.get(activityNdx).task = task;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2149b7a..6c83192 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -43,7 +43,6 @@
import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -565,8 +564,6 @@
return "card=" + card + ";device=" + device + ";";
}
- private final String DEVICE_NAME_A2DP = "a2dp-device";
-
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
@@ -1106,7 +1103,8 @@
}
// Check if the ringer mode handles this adjustment. If it does we don't
// need to adjust the volume further.
- final int result = checkForRingerModeChange(aliasIndex, direction, step, streamState.mIsMuted);
+ final int result = checkForRingerModeChange(aliasIndex, direction, step,
+ streamState.mIsMuted);
adjustVolume = (result & FLAG_ADJUST_VOLUME) != 0;
// If suppressing a volume adjustment in silent mode, display the UI hint
if ((result & AudioManager.FLAG_SHOW_SILENT_HINT) != 0) {
@@ -1117,6 +1115,11 @@
flags |= AudioManager.FLAG_SHOW_VIBRATE_HINT;
}
}
+ // If the ringermode is suppressing media, prevent changes
+ if (streamTypeAlias == AudioSystem.STREAM_MUSIC
+ && (mRingerModeMutedStreams & (1 << AudioSystem.STREAM_MUSIC)) != 0) {
+ adjustVolume = false;
+ }
int oldIndex = mStreamStates[streamType].getIndex(device);
@@ -1796,20 +1799,14 @@
broadcastRingerMode(AudioManager.RINGER_MODE_CHANGED_ACTION, ringerMode);
}
- private void setRingerModeInt(int ringerMode, boolean persist) {
- final boolean change;
- synchronized(mSettingsLock) {
- change = mRingerMode != ringerMode;
- mRingerMode = ringerMode;
- }
-
+ private void muteRingerModeStreams() {
// Mute stream if not previously muted by ringer mode and ringer mode
// is not RINGER_MODE_NORMAL and stream is affected by ringer mode.
// Unmute stream if previously muted by ringer mode and ringer mode
// is RINGER_MODE_NORMAL or stream is not affected by ringer mode.
int numStreamTypes = AudioSystem.getNumStreamTypes();
- final boolean ringerModeMute = ringerMode == AudioManager.RINGER_MODE_VIBRATE
- || ringerMode == AudioManager.RINGER_MODE_SILENT;
+ final boolean ringerModeMute = mRingerMode == AudioManager.RINGER_MODE_VIBRATE
+ || mRingerMode == AudioManager.RINGER_MODE_SILENT;
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
final boolean isMuted = isStreamMutedByRingerMode(streamType);
final boolean shouldMute = ringerModeMute && isStreamAffectedByRingerMode(streamType);
@@ -1846,6 +1843,16 @@
mRingerModeMutedStreams |= (1 << streamType);
}
}
+ }
+
+ private void setRingerModeInt(int ringerMode, boolean persist) {
+ final boolean change;
+ synchronized(mSettingsLock) {
+ change = mRingerMode != ringerMode;
+ mRingerMode = ringerMode;
+ }
+
+ muteRingerModeStreams();
// Post a persist ringer mode msg
if (persist) {
@@ -3084,30 +3091,19 @@
return (mRingerModeMutedStreams & (1 << streamType)) != 0;
}
- boolean updateRingerModeAffectedStreams() {
- int ringerModeAffectedStreams;
- // make sure settings for ringer mode are consistent with device type: non voice capable
- // devices (tablets) include media stream in silent mode whereas phones don't.
- ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
+ private boolean updateRingerModeAffectedStreams() {
+ int ringerModeAffectedStreams = Settings.System.getIntForUser(mContentResolver,
Settings.System.MODE_RINGER_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_NOTIFICATION)|
(1 << AudioSystem.STREAM_SYSTEM)|(1 << AudioSystem.STREAM_SYSTEM_ENFORCED)),
UserHandle.USER_CURRENT);
- // ringtone, notification and system streams are always affected by ringer mode
- ringerModeAffectedStreams |= (1 << AudioSystem.STREAM_RING)|
- (1 << AudioSystem.STREAM_NOTIFICATION)|
- (1 << AudioSystem.STREAM_SYSTEM);
-
- switch (mPlatformType) {
- case AudioSystem.PLATFORM_TELEVISION:
- ringerModeAffectedStreams = 0;
- break;
- default:
- ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_MUSIC);
- break;
+ if (mPlatformType == AudioSystem.PLATFORM_TELEVISION) {
+ ringerModeAffectedStreams = 0;
+ } else if (mRingerModeDelegate != null) {
+ ringerModeAffectedStreams = mRingerModeDelegate
+ .getRingerModeAffectedStreams(ringerModeAffectedStreams);
}
-
synchronized (mCameraSoundForced) {
if (mCameraSoundForced) {
ringerModeAffectedStreams &= ~(1 << AudioSystem.STREAM_SYSTEM_ENFORCED);
@@ -4389,7 +4385,7 @@
}
// must be called synchronized on mConnectedDevices
- private void makeA2dpDeviceAvailable(String address) {
+ private void makeA2dpDeviceAvailable(String address, String name) {
// enable A2DP before notifying A2DP connection to avoid unecessary processing in
// audio policy manager
VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
@@ -4397,12 +4393,12 @@
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, streamState, 0);
setBluetoothA2dpOnInt(true);
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, name);
// Reset A2DP suspend state each time a new sink is connected
AudioSystem.setParameters("A2dpSuspended=false");
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
- new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_NAME_A2DP,
+ new DeviceListSpec(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, name,
address));
}
@@ -4416,7 +4412,7 @@
mAvrcpAbsVolSupported = false;
}
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
synchronized (mCurAudioRoutes) {
@@ -4446,17 +4442,17 @@
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcAvailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_AVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_AVAILABLE, address, "");
mConnectedDevices.put(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
- new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_NAME_A2DP,
+ new DeviceListSpec(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, "",
address));
}
// must be called synchronized on mConnectedDevices
private void makeA2dpSrcUnavailable(String address) {
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP,
- AudioSystem.DEVICE_STATE_UNAVAILABLE, address, DEVICE_NAME_A2DP);
+ AudioSystem.DEVICE_STATE_UNAVAILABLE, address, "");
mConnectedDevices.remove(
makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
}
@@ -4522,7 +4518,7 @@
makeA2dpDeviceUnavailableNow(mDockAddress);
}
}
- makeA2dpDeviceAvailable(address);
+ makeA2dpDeviceAvailable(address, btDevice.getName());
synchronized (mCurAudioRoutes) {
String name = btDevice.getAliasName();
if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
@@ -4873,7 +4869,7 @@
if (btDevice == null) {
return;
}
-
+
address = btDevice.getAddress();
BluetoothClass btClass = btDevice.getBluetoothClass();
if (btClass != null) {
@@ -4893,9 +4889,11 @@
}
boolean connected = (state == BluetoothProfile.STATE_CONNECTED);
+
+ String btDeviceName = btDevice.getName();
boolean success =
- handleDeviceConnection(connected, outDevice, address, "Bluetooth Headset") &&
- handleDeviceConnection(connected, inDevice, address, "Bluetooth Headset");
+ handleDeviceConnection(connected, outDevice, address, btDeviceName) &&
+ handleDeviceConnection(connected, inDevice, address, btDeviceName);
if (success) {
synchronized (mScoClients) {
if (connected) {
@@ -5541,13 +5539,35 @@
pw.println("\nRinger mode: ");
pw.println("- mode (internal) = " + RINGER_MODE_NAMES[mRingerMode]);
pw.println("- mode (external) = " + RINGER_MODE_NAMES[mRingerModeExternal]);
- pw.print("- ringer mode affected streams = 0x");
- pw.println(Integer.toHexString(mRingerModeAffectedStreams));
- pw.print("- ringer mode muted streams = 0x");
- pw.println(Integer.toHexString(mRingerModeMutedStreams));
+ dumpRingerModeStreams(pw, "affected", mRingerModeAffectedStreams);
+ dumpRingerModeStreams(pw, "muted", mRingerModeMutedStreams);
pw.print("- delegate = "); pw.println(mRingerModeDelegate);
}
+ private void dumpRingerModeStreams(PrintWriter pw, String type, int streams) {
+ pw.print("- ringer mode "); pw.print(type); pw.print(" streams = 0x");
+ pw.print(Integer.toHexString(streams));
+ if (streams != 0) {
+ pw.print(" (");
+ boolean first = true;
+ for (int i = 0; i < AudioSystem.STREAM_NAMES.length; i++) {
+ final int stream = (1 << i);
+ if ((streams & stream) != 0) {
+ if (!first) pw.print(',');
+ pw.print(AudioSystem.STREAM_NAMES[i]);
+ streams &= ~stream;
+ first = false;
+ }
+ }
+ if (streams != 0) {
+ if (!first) pw.print(',');
+ pw.print(streams);
+ }
+ pw.print(')');
+ }
+ pw.println();
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
@@ -5780,6 +5800,7 @@
public void setRingerModeDelegate(RingerModeDelegate delegate) {
mRingerModeDelegate = delegate;
if (mRingerModeDelegate != null) {
+ updateRingerModeAffectedStreams();
setRingerModeInternal(getRingerModeInternal(), TAG + ".setRingerModeDelegate");
}
}
@@ -5820,6 +5841,15 @@
public int getVolumeControllerUid() {
return mControllerService.mUid;
}
+
+ @Override
+ public void updateRingerModeAffectedStreamsInternal() {
+ synchronized (mSettingsLock) {
+ if (updateRingerModeAffectedStreams()) {
+ setRingerModeInt(getRingerModeInternal(), false);
+ }
+ }
+ }
}
//==========================================================================================
diff --git a/services/core/java/com/android/server/camera/CameraService.java b/services/core/java/com/android/server/camera/CameraService.java
index f9b17ed..1d77bc2 100644
--- a/services/core/java/com/android/server/camera/CameraService.java
+++ b/services/core/java/com/android/server/camera/CameraService.java
@@ -15,13 +15,21 @@
*/
package com.android.server.camera;
+import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.UserInfo;
import android.hardware.ICameraService;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserManager;
import com.android.server.SystemService;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
/**
* CameraService is the system_server analog to the camera service running in mediaserver.
*
@@ -38,29 +46,78 @@
public static final int NO_EVENT = 0; // NOOP
public static final int USER_SWITCHED = 1; // User changed, argument is the new user handle
+ private final Context mContext;
+ private UserManager mUserManager;
+ private Set<Integer> mEnabledCameraUsers;
+
public CameraService(Context context) {
super(context);
+ mContext = context;
}
@Override
- public void onStart() {}
+ public void onStart() {
+ mUserManager = UserManager.get(mContext);
+ if (mUserManager == null) {
+ // Should never see this unless someone messes up the SystemServer service boot order.
+ throw new IllegalStateException("UserManagerService must start before CameraService!");
+ }
+ }
+
+ @Override
+ public void onStartUser(int userHandle) {
+ if (mEnabledCameraUsers == null) {
+ // Initialize mediaserver, or update mediaserver if we are recovering from a crash.
+ onSwitchUser(userHandle);
+ }
+ }
@Override
public void onSwitchUser(int userHandle) {
- super.onSwitchUser(userHandle);
+ Set<Integer> currentUserHandles = getEnabledUserHandles(userHandle);
+ if (mEnabledCameraUsers == null || !mEnabledCameraUsers.equals(currentUserHandles)) {
+ // Some user handles have been added or removed, update mediaserver.
+ mEnabledCameraUsers = currentUserHandles;
+ notifyMediaserver(USER_SWITCHED, currentUserHandles);
+ }
+ }
- /**
- * Forward the user switch event to the native camera service running in mediaserver.
- */
+
+ private Set<Integer> getEnabledUserHandles(int currentUserHandle) {
+ List<UserInfo> userProfiles = mUserManager.getEnabledProfiles(currentUserHandle);
+ Set<Integer> handles = new HashSet<>(userProfiles.size());
+
+ for (UserInfo i : userProfiles) {
+ handles.add(i.id);
+ }
+
+ return handles;
+ }
+
+ private void notifyMediaserver(int eventType, Set<Integer> updatedUserHandles) {
+ // Forward the user switch event to the native camera service running in the mediaserver
+ // process.
IBinder cameraServiceBinder = getBinderService(CAMERA_SERVICE_BINDER_NAME);
if (cameraServiceBinder == null) {
- return; // Camera service not active, there is no need to evict user clients.
+ return; // Camera service not active, cannot evict user clients.
}
+
ICameraService cameraServiceRaw = ICameraService.Stub.asInterface(cameraServiceBinder);
+
try {
- cameraServiceRaw.notifySystemEvent(USER_SWITCHED, userHandle);
+ cameraServiceRaw.notifySystemEvent(eventType, toArray(updatedUserHandles));
} catch (RemoteException e) {
- // Do nothing, if camera service is dead, there is no need to evict user clients.
+ // Not much we can do if camera service is dead.
}
}
+
+ private static int[] toArray(Collection<Integer> c) {
+ int len = c.size();
+ int[] ret = new int[len];
+ int idx = 0;
+ for (Integer i : c) {
+ ret[idx++] = i;
+ }
+ return ret;
+ }
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 8a7c902..eac748f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -50,12 +50,11 @@
public final NetworkMisc networkMisc;
// Indicates if netd has been told to create this Network. Once created the appropriate routing
// rules are setup and routes are added so packets can begin flowing over the Network.
- // NOTE: This is a sticky bit; once set it is never cleared.
+ // This is a sticky bit; once set it is never cleared.
public boolean created;
// Set to true if this Network successfully passed validation or if it did not satisfy the
// default NetworkRequest in which case validation will not be attempted.
- // NOTE: This is a sticky bit; once set it is never cleared even if future validation attempts
- // fail.
+ // This is a sticky bit; once set it is never cleared even if future validation attempts fail.
public boolean everValidated;
// The result of the last validation attempt on this network (true if validated, false if not).
@@ -65,6 +64,10 @@
// TODO: Fix the network scoring code, remove this, and rename everValidated to validated.
public boolean lastValidated;
+ // Whether a captive portal was ever detected on this network.
+ // This is a sticky bit; once set it is never cleared.
+ public boolean captivePortalDetected;
+
// This represents the last score received from the NetworkAgent.
private int currentScore;
// Penalty applied to scores of Networks that have not been validated.
@@ -101,9 +104,6 @@
currentScore = score;
networkMonitor = new NetworkMonitor(context, handler, this, defaultRequest);
networkMisc = misc;
- created = false;
- everValidated = false;
- lastValidated = false;
}
public void addRequest(NetworkRequest networkRequest) {
@@ -166,6 +166,7 @@
"created{" + created + "} " +
"explicitlySelected{" + networkMisc.explicitlySelected + "} " +
"acceptUnvalidated{" + networkMisc.acceptUnvalidated + "} " +
+ "captivePortalDetected{" + captivePortalDetected + "} " +
"}";
}
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 4c08960..bb4ff1e 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -608,12 +608,12 @@
tetherUsb(true);
} else {
mUsbTetherRequested = true;
- usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS, false);
+ usbManager.setCurrentFunction(UsbManager.USB_FUNCTION_RNDIS);
}
} else {
tetherUsb(false);
if (mRndisEnabled) {
- usbManager.setCurrentFunction(null, false);
+ usbManager.setCurrentFunction(null);
}
mUsbTetherRequested = false;
}
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index f154c73..d68b615 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -58,6 +58,7 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
@@ -1814,7 +1815,7 @@
Log.v(TAG_FILE, "Reading " + mAccountInfoFile.getBaseFile());
}
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
eventType != XmlPullParser.END_DOCUMENT) {
@@ -2153,7 +2154,7 @@
try {
fos = mAccountInfoFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -2445,7 +2446,7 @@
}
XmlPullParser parser;
parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
@@ -2581,7 +2582,7 @@
}
fos = mPendingFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
for (int i = 0; i < N; i++) {
PendingOperation pop = mPendingOperations.get(i);
@@ -2634,7 +2635,7 @@
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
writePendingOperationLocked(op, out);
out.endDocument();
mPendingFile.finishWrite(fos);
diff --git a/services/core/java/com/android/server/display/DisplayAdapter.java b/services/core/java/com/android/server/display/DisplayAdapter.java
index b411a0d..6ba25a5 100644
--- a/services/core/java/com/android/server/display/DisplayAdapter.java
+++ b/services/core/java/com/android/server/display/DisplayAdapter.java
@@ -18,8 +18,10 @@
import android.content.Context;
import android.os.Handler;
+import android.view.Display;
import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* A display adapter makes zero or more display devices available to the system
@@ -42,6 +44,11 @@
public static final int DISPLAY_DEVICE_EVENT_CHANGED = 2;
public static final int DISPLAY_DEVICE_EVENT_REMOVED = 3;
+ /**
+ * Used to generate globally unique display mode ids.
+ */
+ private static final AtomicInteger NEXT_DISPLAY_MODE_ID = new AtomicInteger(1); // 0 = no mode.
+
// Called with SyncRoot lock held.
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, String name) {
@@ -122,6 +129,11 @@
});
}
+ public static Display.Mode createMode(int width, int height, float refreshRate) {
+ return new Display.Mode(
+ NEXT_DISPLAY_MODE_ID.getAndIncrement(), width, height, refreshRate);
+ }
+
public interface Listener {
public void onDisplayDeviceEvent(DisplayDevice device, int event);
public void onTraversalRequested();
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index ee36972..93bda46 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -19,6 +19,7 @@
import android.graphics.Rect;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
+import android.view.Display;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -132,9 +133,9 @@
}
/**
- * Sets the refresh rate, if supported.
+ * Sets the mode, if supported.
*/
- public void requestRefreshRateLocked(float refreshRate) {
+ public void requestModeInTransactionLocked(int id) {
}
/**
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index ebf6e4e..0db3e3f 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -23,7 +23,6 @@
import java.util.Arrays;
-import libcore.util.EmptyArray;
import libcore.util.Objects;
/**
@@ -137,14 +136,19 @@
public int height;
/**
- * The refresh rate of the display, in frames per second.
+ * The active mode of the display.
*/
- public float refreshRate;
+ public int modeId;
/**
- * The supported refresh rates of the display at the current resolution in frames per second.
+ * The default mode of the display.
*/
- public float[] supportedRefreshRates = EmptyArray.FLOAT;
+ public int defaultModeId;
+
+ /**
+ * The supported modes of the display.
+ */
+ public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
/**
* The nominal apparent density of the display in DPI used for layout calculations.
@@ -264,8 +268,9 @@
|| !Objects.equal(uniqueId, other.uniqueId)
|| width != other.width
|| height != other.height
- || refreshRate != other.refreshRate
- || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
+ || modeId != other.modeId
+ || defaultModeId != other.defaultModeId
+ || !Arrays.equals(supportedModes, other.supportedModes)
|| densityDpi != other.densityDpi
|| xDpi != other.xDpi
|| yDpi != other.yDpi
@@ -293,8 +298,9 @@
uniqueId = other.uniqueId;
width = other.width;
height = other.height;
- refreshRate = other.refreshRate;
- supportedRefreshRates = other.supportedRefreshRates;
+ modeId = other.modeId;
+ defaultModeId = other.defaultModeId;
+ supportedModes = other.supportedModes;
densityDpi = other.densityDpi;
xDpi = other.xDpi;
yDpi = other.yDpi;
@@ -317,8 +323,9 @@
sb.append("DisplayDeviceInfo{\"");
sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
sb.append(width).append(" x ").append(height);
- sb.append(", ").append(refreshRate).append(" fps");
- sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
+ sb.append(", modeId ").append(modeId);
+ sb.append(", defaultModeId ").append(defaultModeId);
+ sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
sb.append(", density ").append(densityDpi);
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 1e87433..7440b8c 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -842,7 +842,7 @@
}
private void setDisplayPropertiesInternal(int displayId, boolean hasContent,
- float requestedRefreshRate, boolean inTraversal) {
+ float requestedRefreshRate, int requestedModeId, boolean inTraversal) {
synchronized (mSyncRoot) {
LogicalDisplay display = mLogicalDisplays.get(displayId);
if (display == null) {
@@ -857,12 +857,17 @@
display.setHasContentLocked(hasContent);
scheduleTraversalLocked(inTraversal);
}
- if (display.getRequestedRefreshRateLocked() != requestedRefreshRate) {
+ if (requestedModeId == 0 && requestedRefreshRate != 0) {
+ // Scan supported modes returned by display.getInfo() to find a mode with the same
+ // size as the default display mode but with the specified refresh rate instead.
+ requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate(
+ requestedRefreshRate);
+ }
+ if (display.getRequestedModeIdLocked() != requestedModeId) {
if (DEBUG) {
- Slog.d(TAG, "Display " + displayId + " has requested a new refresh rate: "
- + requestedRefreshRate + "fps");
+ Slog.d(TAG, "Display " + displayId + " switching to mode " + requestedModeId);
}
- display.setRequestedRefreshRateLocked(requestedRefreshRate);
+ display.setRequestedModeIdLocked(requestedModeId);
scheduleTraversalLocked(inTraversal);
}
}
@@ -1564,8 +1569,9 @@
@Override
public void setDisplayProperties(int displayId, boolean hasContent,
- float requestedRefreshRate, boolean inTraversal) {
- setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, inTraversal);
+ float requestedRefreshRate, int requestedMode, boolean inTraversal) {
+ setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate,
+ requestedMode, inTraversal);
}
@Override
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index e87f265..cc7d848 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -35,7 +35,7 @@
import android.view.SurfaceControl;
import java.io.PrintWriter;
-import java.util.Arrays;
+import java.util.ArrayList;
/**
* A display adapter for the local displays managed by Surface Flinger.
@@ -56,6 +56,7 @@
private final SparseArray<LocalDisplayDevice> mDevices =
new SparseArray<LocalDisplayDevice>();
+ @SuppressWarnings("unused") // Becomes active at instantiation time.
private HotplugDisplayEventReceiver mHotplugReceiver;
// Called with SyncRoot lock held.
@@ -136,28 +137,22 @@
private final class LocalDisplayDevice extends DisplayDevice {
private final int mBuiltInDisplayId;
- private final SurfaceControl.PhysicalDisplayInfo mPhys;
- private final int mDefaultPhysicalDisplayInfo;
private final Light mBacklight;
+ private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
private int mState = Display.STATE_UNKNOWN;
private int mBrightness = PowerManager.BRIGHTNESS_DEFAULT;
- private float[] mSupportedRefreshRates;
- private int[] mRefreshRateConfigIndices;
- private float mLastRequestedRefreshRate;
-
+ private int mDefaultModeId;
+ private int mActiveModeId;
+ private boolean mActiveModeInvalid;
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
mBuiltInDisplayId = builtInDisplayId;
- mPhys = new SurfaceControl.PhysicalDisplayInfo(
- physicalDisplayInfos[activeDisplayInfo]);
- mDefaultPhysicalDisplayInfo = activeDisplayInfo;
- updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
-
+ updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo);
if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
@@ -168,14 +163,73 @@
public boolean updatePhysicalDisplayInfoLocked(
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo) {
- SurfaceControl.PhysicalDisplayInfo newPhys = physicalDisplayInfos[activeDisplayInfo];
- if (!mPhys.equals(newPhys)) {
- mPhys.copyFrom(newPhys);
- updateSupportedRefreshRatesLocked(physicalDisplayInfos, mPhys);
- mHavePendingChanges = true;
- return true;
+ // Build an updated list of all existing modes.
+ boolean modesAdded = false;
+ DisplayModeRecord activeRecord = null;
+ ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
+ for (int i = 0; i < physicalDisplayInfos.length; i++) {
+ SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
+ DisplayModeRecord record = findDisplayModeRecord(info);
+ if (record != null) {
+ record.mPhysIndex = i;
+ } else {
+ record = new DisplayModeRecord(info, i);
+ modesAdded = true;
+ }
+ records.add(record);
+ if (i == activeDisplayInfo) {
+ activeRecord = record;
+ }
}
- return false;
+ // Check whether surface flinger spontaneously changed modes out from under us. Schedule
+ // traversals to ensure that the correct state is reapplied if necessary.
+ if (mActiveModeId != 0
+ && mActiveModeId != activeRecord.mMode.getModeId()) {
+ mActiveModeInvalid = true;
+ sendTraversalRequestLocked();
+ }
+ // If no modes were added and we have the same number of modes as before, then nothing
+ // actually changed except possibly the physical index (which we only care about when
+ // setting the mode) so we're done.
+ if (records.size() == mSupportedModes.size() && !modesAdded) {
+ return false;
+ }
+ // Update the index of modes.
+ mHavePendingChanges = true;
+ mSupportedModes.clear();
+ for (DisplayModeRecord record : records) {
+ mSupportedModes.put(record.mMode.getModeId(), record);
+ }
+ // Update the default mode if needed.
+ if (mSupportedModes.indexOfKey(mDefaultModeId) < 0) {
+ if (mDefaultModeId != 0) {
+ Slog.w(TAG, "Default display mode no longer available, using currently active"
+ + " mode as default.");
+ }
+ mDefaultModeId = activeRecord.mMode.getModeId();
+ }
+ // Determine whether the active mode is still there.
+ if (mSupportedModes.indexOfKey(mActiveModeId) < 0) {
+ if (mActiveModeId != 0) {
+ Slog.w(TAG, "Active display mode no longer available, reverting to default"
+ + " mode.");
+ }
+ mActiveModeId = mDefaultModeId;
+ mActiveModeInvalid = true;
+ }
+ // Schedule traversals so that we apply pending changes.
+ sendTraversalRequestLocked();
+ return true;
+ }
+
+ private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
+ for (int i = 0; i < mSupportedModes.size(); i++) {
+ DisplayModeRecord record = mSupportedModes.valueAt(i);
+ if (record.mPhys.equals(info)) {
+ return record;
+ }
+ }
+ return null;
}
@Override
@@ -189,19 +243,25 @@
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
+ SurfaceControl.PhysicalDisplayInfo phys = mSupportedModes.get(mActiveModeId).mPhys;
mInfo = new DisplayDeviceInfo();
- mInfo.width = mPhys.width;
- mInfo.height = mPhys.height;
- mInfo.refreshRate = mPhys.refreshRate;
- mInfo.supportedRefreshRates = mSupportedRefreshRates;
- mInfo.appVsyncOffsetNanos = mPhys.appVsyncOffsetNanos;
- mInfo.presentationDeadlineNanos = mPhys.presentationDeadlineNanos;
+ mInfo.width = phys.width;
+ mInfo.height = phys.height;
+ mInfo.modeId = mActiveModeId;
+ mInfo.defaultModeId = mDefaultModeId;
+ mInfo.supportedModes = new Display.Mode[mSupportedModes.size()];
+ for (int i = 0; i < mSupportedModes.size(); i++) {
+ DisplayModeRecord record = mSupportedModes.valueAt(i);
+ mInfo.supportedModes[i] = record.mMode;
+ }
+ mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
+ mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
mInfo.state = mState;
mInfo.uniqueId = getUniqueId();
// Assume that all built-in displays that have secure output (eg. HDCP) also
// support compositing from gralloc protected buffers.
- if (mPhys.secure) {
+ if (phys.secure) {
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
| DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
@@ -212,9 +272,9 @@
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
| DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
mInfo.type = Display.TYPE_BUILT_IN;
- mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
- mInfo.xDpi = mPhys.xDpi;
- mInfo.yDpi = mPhys.yDpi;
+ mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
+ mInfo.xDpi = phys.xDpi;
+ mInfo.yDpi = phys.yDpi;
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
} else {
mInfo.type = Display.TYPE_HDMI;
@@ -222,7 +282,7 @@
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_hdmi_display_name);
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
- mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height);
+ mInfo.setAssumedDensityForExternalDisplay(phys.width, phys.height);
// For demonstration purposes, allow rotation of the external display.
// In the future we might allow the user to configure this directly.
@@ -332,30 +392,29 @@
}
@Override
- public void requestRefreshRateLocked(float refreshRate) {
- if (mLastRequestedRefreshRate == refreshRate) {
+ public void requestModeInTransactionLocked(int modeId) {
+ if (modeId == 0) {
+ modeId = mDefaultModeId;
+ } else if (mSupportedModes.indexOfKey(modeId) < 0) {
+ Slog.w(TAG, "Requested mode " + modeId + " is not supported by this display,"
+ + " reverting to default display mode.");
+ modeId = mDefaultModeId;
+ }
+ if (mActiveModeId == modeId && !mActiveModeInvalid) {
return;
}
- mLastRequestedRefreshRate = refreshRate;
- if (refreshRate != 0) {
- final int N = mSupportedRefreshRates.length;
- for (int i = 0; i < N; i++) {
- if (refreshRate == mSupportedRefreshRates[i]) {
- final int configIndex = mRefreshRateConfigIndices[i];
- SurfaceControl.setActiveConfig(getDisplayTokenLocked(), configIndex);
- return;
- }
- }
- Slog.w(TAG, "Requested refresh rate " + refreshRate + " is unsupported.");
- }
- SurfaceControl.setActiveConfig(getDisplayTokenLocked(), mDefaultPhysicalDisplayInfo);
+ DisplayModeRecord record = mSupportedModes.get(modeId);
+ SurfaceControl.setActiveConfig(getDisplayTokenLocked(), record.mPhysIndex);
+ mActiveModeId = modeId;
+ mActiveModeInvalid = false;
+ updateDeviceInfoLocked();
}
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
- pw.println("mPhys=" + mPhys);
+ pw.println("mActiveModeId=" + mActiveModeId);
pw.println("mState=" + Display.stateToString(mState));
pw.println("mBrightness=" + mBrightness);
pw.println("mBacklight=" + mBacklight);
@@ -365,29 +424,20 @@
mInfo = null;
sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
}
+ }
- private void updateSupportedRefreshRatesLocked(
- SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos,
- SurfaceControl.PhysicalDisplayInfo activePhys) {
- final int N = physicalDisplayInfos.length;
- int idx = 0;
- mSupportedRefreshRates = new float[N];
- mRefreshRateConfigIndices = new int[N];
- for (int i = 0; i < N; i++) {
- final SurfaceControl.PhysicalDisplayInfo phys = physicalDisplayInfos[i];
- if (activePhys.width == phys.width
- && activePhys.height == phys.height
- && activePhys.density == phys.density
- && activePhys.xDpi == phys.xDpi
- && activePhys.yDpi == phys.yDpi) {
- mSupportedRefreshRates[idx] = phys.refreshRate;
- mRefreshRateConfigIndices[idx++] = i;
- }
- }
- if (idx != N) {
- mSupportedRefreshRates = Arrays.copyOfRange(mSupportedRefreshRates, 0, idx);
- mRefreshRateConfigIndices = Arrays.copyOfRange(mRefreshRateConfigIndices, 0, idx);
- }
+ /**
+ * Keeps track of a display configuration.
+ */
+ private static final class DisplayModeRecord {
+ public final Display.Mode mMode;
+ public final SurfaceControl.PhysicalDisplayInfo mPhys;
+ public int mPhysIndex;
+
+ public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys, int physIndex) {
+ mMode = createMode(phys.width, phys.height, phys.refreshRate);
+ mPhys = phys;
+ mPhysIndex = physIndex;
}
}
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 65dc72f..424b4a0 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -73,8 +73,7 @@
// True if the logical display has unique content.
private boolean mHasContent;
- // The pending requested refresh rate. 0 if no request is pending.
- private float mRequestedRefreshRate;
+ private int mRequestedModeId;
// The display offsets to apply to the display projection.
private int mDisplayOffsetX;
@@ -118,14 +117,22 @@
public DisplayInfo getDisplayInfoLocked() {
if (mInfo == null) {
mInfo = new DisplayInfo();
+ mInfo.copyFrom(mBaseDisplayInfo);
if (mOverrideDisplayInfo != null) {
- mInfo.copyFrom(mOverrideDisplayInfo);
- mInfo.layerStack = mBaseDisplayInfo.layerStack;
- mInfo.name = mBaseDisplayInfo.name;
- mInfo.uniqueId = mBaseDisplayInfo.uniqueId;
- mInfo.state = mBaseDisplayInfo.state;
- } else {
- mInfo.copyFrom(mBaseDisplayInfo);
+ mInfo.appWidth = mOverrideDisplayInfo.appWidth;
+ mInfo.appHeight = mOverrideDisplayInfo.appHeight;
+ mInfo.smallestNominalAppWidth = mOverrideDisplayInfo.smallestNominalAppWidth;
+ mInfo.smallestNominalAppHeight = mOverrideDisplayInfo.smallestNominalAppHeight;
+ mInfo.largestNominalAppWidth = mOverrideDisplayInfo.largestNominalAppWidth;
+ mInfo.largestNominalAppHeight = mOverrideDisplayInfo.largestNominalAppHeight;
+ mInfo.logicalWidth = mOverrideDisplayInfo.logicalWidth;
+ mInfo.logicalHeight = mOverrideDisplayInfo.logicalHeight;
+ mInfo.overscanLeft = mOverrideDisplayInfo.overscanLeft;
+ mInfo.overscanTop = mOverrideDisplayInfo.overscanTop;
+ mInfo.overscanRight = mOverrideDisplayInfo.overscanRight;
+ mInfo.overscanBottom = mOverrideDisplayInfo.overscanBottom;
+ mInfo.rotation = mOverrideDisplayInfo.rotation;
+ mInfo.logicalDensityDpi = mOverrideDisplayInfo.logicalDensityDpi;
}
}
return mInfo;
@@ -219,9 +226,10 @@
mBaseDisplayInfo.logicalWidth = deviceInfo.width;
mBaseDisplayInfo.logicalHeight = deviceInfo.height;
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
- mBaseDisplayInfo.refreshRate = deviceInfo.refreshRate;
- mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf(
- deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length);
+ mBaseDisplayInfo.modeId = deviceInfo.modeId;
+ mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
+ mBaseDisplayInfo.supportedModes = Arrays.copyOf(
+ deviceInfo.supportedModes, deviceInfo.supportedModes.length);
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
@@ -259,14 +267,19 @@
*/
public void configureDisplayInTransactionLocked(DisplayDevice device,
boolean isBlanked) {
- final DisplayInfo displayInfo = getDisplayInfoLocked();
- final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
-
// Set the layer stack.
device.setLayerStackInTransactionLocked(isBlanked ? BLANK_LAYER_STACK : mLayerStack);
- // Set the refresh rate
- device.requestRefreshRateLocked(mRequestedRefreshRate);
+ // Set the mode.
+ if (device == mPrimaryDisplayDevice) {
+ device.requestModeInTransactionLocked(mRequestedModeId);
+ } else {
+ device.requestModeInTransactionLocked(0); // Revert to default.
+ }
+
+ // Only grab the display info now as it may have been changed based on the requests above.
+ final DisplayInfo displayInfo = getDisplayInfoLocked();
+ final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
// Set the viewport.
// This is the area of the logical display that we intend to show on the
@@ -351,20 +364,17 @@
}
/**
- * Requests the given refresh rate.
- * @param requestedRefreshRate The desired refresh rate.
+ * Requests the given mode.
*/
- public void setRequestedRefreshRateLocked(float requestedRefreshRate) {
- mRequestedRefreshRate = requestedRefreshRate;
+ public void setRequestedModeIdLocked(int modeId) {
+ mRequestedModeId = modeId;
}
/**
- * Gets the pending requested refresh rate.
- *
- * @return The pending refresh rate requested
+ * Returns the pending requested mode.
*/
- public float getRequestedRefreshRateLocked() {
- return mRequestedRefreshRate;
+ public int getRequestedModeIdLocked() {
+ return mRequestedModeId;
}
/**
@@ -393,7 +403,7 @@
pw.println("mDisplayId=" + mDisplayId);
pw.println("mLayerStack=" + mLayerStack);
pw.println("mHasContent=" + mHasContent);
- pw.println("mRequestedRefreshRate=" + mRequestedRefreshRate);
+ pw.println("mRequestedMode=" + mRequestedModeId);
pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")");
pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ?
mPrimaryDisplayDevice.getNameLocked() : "null"));
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index af9f456..0462035 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -34,6 +34,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -47,6 +49,21 @@
* service as usual. The UI handler is only used by the {@link OverlayDisplayWindow}.
* </p><p>
* Display adapters are guarded by the {@link DisplayManagerService.SyncRoot} lock.
+ * </p><p>
+ * This adapter is configured via the
+ * {@link android.provider.Settings.Global#OVERLAY_DISPLAY_DEVICES} setting. This setting should be
+ * formatted as follows:
+ * <pre>
+ * [mode1]|[mode2]|...,[flag1],[flag2],...
+ * </pre>
+ * with each mode specified as:
+ * <pre>
+ * [width]x[height]/[densityDpi]
+ * </pre>
+ * Supported flags:
+ * <ul>
+ * <li><pre>secure</pre>: creates a secure display</li>
+ * </ul>
* </p>
*/
final class OverlayDisplayAdapter extends DisplayAdapter {
@@ -58,8 +75,10 @@
private static final int MAX_WIDTH = 4096;
private static final int MAX_HEIGHT = 4096;
- private static final Pattern SETTING_PATTERN =
- Pattern.compile("(\\d+)x(\\d+)/(\\d+)(,[a-z]+)*");
+ private static final Pattern DISPLAY_PATTERN =
+ Pattern.compile("([^,]+)(,[a-z]+)*");
+ private static final Pattern MODE_PATTERN =
+ Pattern.compile("(\\d+)x(\\d+)/(\\d+)");
// Unique id prefix for overlay displays.
private static final String UNIQUE_ID_PREFIX = "overlay:";
@@ -136,40 +155,49 @@
int count = 0;
for (String part : value.split(";")) {
- Matcher matcher = SETTING_PATTERN.matcher(part);
- if (matcher.matches()) {
+ Matcher displayMatcher = DISPLAY_PATTERN.matcher(part);
+ if (displayMatcher.matches()) {
if (count >= 4) {
Slog.w(TAG, "Too many overlay display devices specified: " + value);
break;
}
- try {
- int width = Integer.parseInt(matcher.group(1), 10);
- int height = Integer.parseInt(matcher.group(2), 10);
- int densityDpi = Integer.parseInt(matcher.group(3), 10);
- String flagString = matcher.group(4);
- if (width >= MIN_WIDTH && width <= MAX_WIDTH
- && height >= MIN_HEIGHT && height <= MAX_HEIGHT
- && densityDpi >= DisplayMetrics.DENSITY_LOW
- && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
- int number = ++count;
- String name = getContext().getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_name,
- number);
- int gravity = chooseOverlayGravity(number);
- boolean secure = flagString != null && flagString.contains(",secure");
-
- Slog.i(TAG, "Showing overlay display device #" + number
- + ": name=" + name + ", width=" + width + ", height=" + height
- + ", densityDpi=" + densityDpi + ", secure=" + secure);
-
- mOverlays.add(new OverlayDisplayHandle(name,
- width, height, densityDpi, gravity, secure, number));
+ String modeString = displayMatcher.group(1);
+ String flagString = displayMatcher.group(2);
+ ArrayList<OverlayMode> modes = new ArrayList<>();
+ for (String mode : modeString.split("\\|")) {
+ Matcher modeMatcher = MODE_PATTERN.matcher(mode);
+ if (modeMatcher.matches()) {
+ try {
+ int width = Integer.parseInt(modeMatcher.group(1), 10);
+ int height = Integer.parseInt(modeMatcher.group(2), 10);
+ int densityDpi = Integer.parseInt(modeMatcher.group(3), 10);
+ if (width >= MIN_WIDTH && width <= MAX_WIDTH
+ && height >= MIN_HEIGHT && height <= MAX_HEIGHT
+ && densityDpi >= DisplayMetrics.DENSITY_LOW
+ && densityDpi <= DisplayMetrics.DENSITY_XXHIGH) {
+ modes.add(new OverlayMode(width, height, densityDpi));
+ continue;
+ }
+ } catch (NumberFormatException ex) {
+ }
+ } else if (mode.isEmpty()) {
continue;
}
- } catch (NumberFormatException ex) {
}
- } else if (part.isEmpty()) {
- continue;
+ if (!modes.isEmpty()) {
+ int number = ++count;
+ String name = getContext().getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_name,
+ number);
+ int gravity = chooseOverlayGravity(number);
+ boolean secure = flagString != null && flagString.contains(",secure");
+
+ Slog.i(TAG, "Showing overlay display device #" + number
+ + ": name=" + name + ", modes=" + Arrays.toString(modes.toArray()));
+
+ mOverlays.add(new OverlayDisplayHandle(name, modes, gravity, secure, number));
+ continue;
+ }
}
Slog.w(TAG, "Malformed overlay display devices setting: " + value);
}
@@ -189,34 +217,41 @@
}
}
- private final class OverlayDisplayDevice extends DisplayDevice {
+ private abstract class OverlayDisplayDevice extends DisplayDevice {
private final String mName;
- private final int mWidth;
- private final int mHeight;
private final float mRefreshRate;
private final long mDisplayPresentationDeadlineNanos;
- private final int mDensityDpi;
private final boolean mSecure;
+ private final List<OverlayMode> mRawModes;
+ private final Display.Mode[] mModes;
+ private final int mDefaultMode;
private int mState;
private SurfaceTexture mSurfaceTexture;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
+ private int mActiveMode;
public OverlayDisplayDevice(IBinder displayToken, String name,
- int width, int height, float refreshRate, long presentationDeadlineNanos,
- int densityDpi, boolean secure, int state,
+ List<OverlayMode> modes, int activeMode, int defaultMode,
+ float refreshRate, long presentationDeadlineNanos,
+ boolean secure, int state,
SurfaceTexture surfaceTexture, int number) {
super(OverlayDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + number);
mName = name;
- mWidth = width;
- mHeight = height;
mRefreshRate = refreshRate;
mDisplayPresentationDeadlineNanos = presentationDeadlineNanos;
- mDensityDpi = densityDpi;
mSecure = secure;
mState = state;
mSurfaceTexture = surfaceTexture;
+ mRawModes = modes;
+ mModes = new Display.Mode[modes.size()];
+ for (int i = 0; i < modes.size(); i++) {
+ OverlayMode mode = modes.get(i);
+ mModes[i] = createMode(mode.mWidth, mode.mHeight, refreshRate);
+ }
+ mActiveMode = activeMode;
+ mDefaultMode = defaultMode;
}
public void destroyLocked() {
@@ -246,16 +281,19 @@
@Override
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
+ Display.Mode mode = mModes[mActiveMode];
+ OverlayMode rawMode = mRawModes.get(mActiveMode);
mInfo = new DisplayDeviceInfo();
mInfo.name = mName;
mInfo.uniqueId = getUniqueId();
- mInfo.width = mWidth;
- mInfo.height = mHeight;
- mInfo.refreshRate = mRefreshRate;
- mInfo.supportedRefreshRates = new float[] { mRefreshRate };
- mInfo.densityDpi = mDensityDpi;
- mInfo.xDpi = mDensityDpi;
- mInfo.yDpi = mDensityDpi;
+ mInfo.width = mode.getPhysicalWidth();
+ mInfo.height = mode.getPhysicalHeight();
+ mInfo.modeId = mode.getModeId();
+ mInfo.defaultModeId = mModes[0].getModeId();
+ mInfo.supportedModes = mModes;
+ mInfo.densityDpi = rawMode.mDensityDpi;
+ mInfo.xDpi = rawMode.mDensityDpi;
+ mInfo.yDpi = rawMode.mDensityDpi;
mInfo.presentationDeadlineNanos = mDisplayPresentationDeadlineNanos +
1000000000L / (int) mRefreshRate; // display's deadline + 1 frame
mInfo.flags = DisplayDeviceInfo.FLAG_PRESENTATION;
@@ -268,6 +306,40 @@
}
return mInfo;
}
+
+ @Override
+ public void requestModeInTransactionLocked(int id) {
+ int index = -1;
+ if (id == 0) {
+ // Use the default.
+ index = 0;
+ } else {
+ for (int i = 0; i < mModes.length; i++) {
+ if (mModes[i].getModeId() == id) {
+ index = i;
+ break;
+ }
+ }
+ }
+ if (index == -1) {
+ Slog.w(TAG, "Unable to locate mode " + id + ", reverting to default.");
+ index = mDefaultMode;
+ }
+ if (mActiveMode == index) {
+ return;
+ }
+ mActiveMode = index;
+ mInfo = null;
+ sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED);
+ onModeChangedLocked(index);
+ }
+
+ /**
+ * Called when the device switched to a new mode.
+ *
+ * @param index index of the mode in the list of modes
+ */
+ public abstract void onModeChangedLocked(int index);
}
/**
@@ -277,27 +349,32 @@
* Guarded by the {@link DisplayManagerService.SyncRoot} lock.
*/
private final class OverlayDisplayHandle implements OverlayDisplayWindow.Listener {
+ private static final int DEFAULT_MODE_INDEX = 0;
+
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private final List<OverlayMode> mModes;
private final int mGravity;
private final boolean mSecure;
private final int mNumber;
private OverlayDisplayWindow mWindow;
private OverlayDisplayDevice mDevice;
+ private int mActiveMode;
- public OverlayDisplayHandle(String name, int width,
- int height, int densityDpi, int gravity, boolean secure, int number) {
+ public OverlayDisplayHandle(String name, List<OverlayMode> modes, int gravity,
+ boolean secure, int number) {
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
+ mModes = modes;
mGravity = gravity;
mSecure = secure;
mNumber = number;
+ mActiveMode = 0;
+
+ showLocked();
+ }
+
+ private void showLocked() {
mUiHandler.post(mShowRunnable);
}
@@ -306,15 +383,28 @@
mUiHandler.post(mDismissRunnable);
}
+ private void onActiveModeChangedLocked(int index) {
+ mUiHandler.removeCallbacks(mResizeRunnable);
+ mActiveMode = index;
+ if (mWindow != null) {
+ mUiHandler.post(mResizeRunnable);
+ }
+ }
+
// Called on the UI thread.
@Override
public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate,
long presentationDeadlineNanos, int state) {
synchronized (getSyncRoot()) {
IBinder displayToken = SurfaceControl.createDisplay(mName, mSecure);
- mDevice = new OverlayDisplayDevice(displayToken, mName,
- mWidth, mHeight, refreshRate, presentationDeadlineNanos,
- mDensityDpi, mSecure, state, surfaceTexture, mNumber);
+ mDevice = new OverlayDisplayDevice(displayToken, mName, mModes, mActiveMode,
+ DEFAULT_MODE_INDEX, refreshRate, presentationDeadlineNanos,
+ mSecure, state, surfaceTexture, mNumber) {
+ @Override
+ public void onModeChangedLocked(int index) {
+ onActiveModeChangedLocked(index);
+ }
+ };
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
}
@@ -344,9 +434,8 @@
public void dumpLocked(PrintWriter pw) {
pw.println(" " + mName + ":");
- pw.println(" mWidth=" + mWidth);
- pw.println(" mHeight=" + mHeight);
- pw.println(" mDensityDpi=" + mDensityDpi);
+ pw.println(" mModes=" + Arrays.toString(mModes.toArray()));
+ pw.println(" mActiveMode=" + mActiveMode);
pw.println(" mGravity=" + mGravity);
pw.println(" mSecure=" + mSecure);
pw.println(" mNumber=" + mNumber);
@@ -363,8 +452,9 @@
private final Runnable mShowRunnable = new Runnable() {
@Override
public void run() {
+ OverlayMode mode = mModes.get(mActiveMode);
OverlayDisplayWindow window = new OverlayDisplayWindow(getContext(),
- mName, mWidth, mHeight, mDensityDpi, mGravity, mSecure,
+ mName, mode.mWidth, mode.mHeight, mode.mDensityDpi, mGravity, mSecure,
OverlayDisplayHandle.this);
window.show();
@@ -389,5 +479,47 @@
}
}
};
+
+ // Runs on the UI thread.
+ private final Runnable mResizeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ OverlayMode mode;
+ OverlayDisplayWindow window;
+ synchronized (getSyncRoot()) {
+ if (mWindow == null) {
+ return;
+ }
+ mode = mModes.get(mActiveMode);
+ window = mWindow;
+ }
+ window.resize(mode.mWidth, mode.mHeight, mode.mDensityDpi);
+ }
+ };
+ }
+
+ /**
+ * A display mode for an overlay display.
+ */
+ private static final class OverlayMode {
+ final int mWidth;
+ final int mHeight;
+ final int mDensityDpi;
+
+ OverlayMode(int width, int height, int densityDpi) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{")
+ .append("width=").append(mWidth)
+ .append(", height=").append(mHeight)
+ .append(", densityDpi=").append(mDensityDpi)
+ .append("}")
+ .toString();
+ }
}
}
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 3f4eab9..f23caf2 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -60,9 +60,9 @@
private final Context mContext;
private final String mName;
- private final int mWidth;
- private final int mHeight;
- private final int mDensityDpi;
+ private int mWidth;
+ private int mHeight;
+ private int mDensityDpi;
private final int mGravity;
private final boolean mSecure;
private final Listener mListener;
@@ -97,19 +97,9 @@
Listener listener) {
mContext = context;
mName = name;
- mWidth = width;
- mHeight = height;
- mDensityDpi = densityDpi;
mGravity = gravity;
mSecure = secure;
mListener = listener;
- mTitle = context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_title,
- mName, mWidth, mHeight, mDensityDpi);
- if (secure) {
- mTitle += context.getResources().getString(
- com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
- }
mDisplayManager = (DisplayManager)context.getSystemService(
Context.DISPLAY_SERVICE);
@@ -119,6 +109,8 @@
mDefaultDisplay = mWindowManager.getDefaultDisplay();
updateDefaultDisplayInfo();
+ resize(width, height, densityDpi, false /* doLayout */);
+
createWindow();
}
@@ -145,6 +137,26 @@
}
}
+ public void resize(int width, int height, int densityDpi) {
+ resize(width, height, densityDpi, true /* doLayout */);
+ }
+
+ private void resize(int width, int height, int densityDpi, boolean doLayout) {
+ mWidth = width;
+ mHeight = height;
+ mDensityDpi = densityDpi;
+ mTitle = mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_title,
+ mName, mWidth, mHeight, mDensityDpi);
+ if (mSecure) {
+ mTitle += mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_overlay_display_secure_suffix);
+ }
+ if (doLayout) {
+ relayout();
+ }
+ }
+
public void relayout() {
if (mWindowVisible) {
updateWindowParams();
@@ -302,7 +314,8 @@
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture,
int width, int height) {
- mListener.onWindowCreated(surfaceTexture, mDefaultDisplayInfo.refreshRate,
+ mListener.onWindowCreated(surfaceTexture,
+ mDefaultDisplayInfo.getMode().getRefreshRate(),
mDefaultDisplayInfo.presentationDeadlineNanos, mDefaultDisplayInfo.state);
}
@@ -377,4 +390,4 @@
public void onWindowDestroyed();
public void onStateChanged(int state);
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/display/PersistentDataStore.java b/services/core/java/com/android/server/display/PersistentDataStore.java
index 67b3695..d676b35 100644
--- a/services/core/java/com/android/server/display/PersistentDataStore.java
+++ b/services/core/java/com/android/server/display/PersistentDataStore.java
@@ -35,6 +35,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import libcore.io.IoUtils;
@@ -195,7 +196,7 @@
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
@@ -215,7 +216,7 @@
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
@@ -284,4 +285,4 @@
serializer.endTag(null, "display-manager-state");
serializer.endDocument();
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 7f961ae..986efd69 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -165,6 +165,8 @@
private static final int PENDING_SURFACE_CHANGE = 0x01;
private static final int PENDING_RESIZE = 0x02;
+ private static final float REFRESH_RATE = 60.0f;
+
private final IBinder mAppToken;
private final int mOwnerUid;
final String mOwnerPackageName;
@@ -181,6 +183,7 @@
private boolean mStopped;
private int mPendingChanges;
private int mUniqueIndex;
+ private Display.Mode mMode;
public VirtualDisplayDevice(IBinder displayToken, IBinder appToken,
int ownerUid, String ownerPackageName,
@@ -193,6 +196,7 @@
mName = name;
mWidth = width;
mHeight = height;
+ mMode = createMode(width, height, REFRESH_RATE);
mDensityDpi = densityDpi;
mSurface = surface;
mFlags = flags;
@@ -262,6 +266,7 @@
sendTraversalRequestLocked();
mWidth = width;
mHeight = height;
+ mMode = createMode(width, height, REFRESH_RATE);
mDensityDpi = densityDpi;
mInfo = null;
mPendingChanges |= PENDING_RESIZE;
@@ -290,12 +295,13 @@
mInfo.uniqueId = getUniqueId();
mInfo.width = mWidth;
mInfo.height = mHeight;
- mInfo.refreshRate = 60;
- mInfo.supportedRefreshRates = new float[] { 60.0f };
+ mInfo.modeId = mMode.getModeId();
+ mInfo.defaultModeId = mMode.getModeId();
+ mInfo.supportedModes = new Display.Mode[] { mMode };
mInfo.densityDpi = mDensityDpi;
mInfo.xDpi = mDensityDpi;
mInfo.yDpi = mDensityDpi;
- mInfo.presentationDeadlineNanos = 1000000000L / (int) mInfo.refreshRate; // 1 frame
+ mInfo.presentationDeadlineNanos = 1000000000L / (int) REFRESH_RATE; // 1 frame
mInfo.flags = 0;
if ((mFlags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) == 0) {
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index f163555..64bc729 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -583,6 +583,7 @@
private final float mRefreshRate;
private final int mFlags;
private final String mAddress;
+ private final Display.Mode mMode;
private Surface mSurface;
private DisplayDeviceInfo mInfo;
@@ -598,6 +599,7 @@
mFlags = flags;
mAddress = address;
mSurface = surface;
+ mMode = createMode(width, height, refreshRate);
}
public void destroyLocked() {
@@ -628,8 +630,9 @@
mInfo.uniqueId = getUniqueId();
mInfo.width = mWidth;
mInfo.height = mHeight;
- mInfo.refreshRate = mRefreshRate;
- mInfo.supportedRefreshRates = new float[] { mRefreshRate };
+ mInfo.modeId = mMode.getModeId();
+ mInfo.defaultModeId = mMode.getModeId();
+ mInfo.supportedModes = new Display.Mode[] { mMode };
mInfo.presentationDeadlineNanos = 1000000000L / (int) mRefreshRate; // 1 frame
mInfo.flags = mFlags;
mInfo.type = Display.TYPE_WIFI;
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 0faccc6..f16fcb0 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -17,13 +17,16 @@
package com.android.server.fingerprint;
import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
+import android.app.IUserSwitchObserver;
import android.content.ContentResolver;
import android.content.Context;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IRemoteCallback;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.RemoteException;
@@ -31,7 +34,6 @@
import com.android.server.SystemService;
-import android.hardware.fingerprint.FingerprintUtils;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintService;
@@ -63,6 +65,7 @@
private final AppOpsManager mAppOps;
private static final int MSG_NOTIFY = 10;
+ private static final int MSG_USER_SWITCHING = 11;
private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
@@ -85,6 +88,10 @@
handleNotify(m.type, m.arg1, m.arg2, m.arg3);
break;
+ case MSG_USER_SWITCHING:
+ handleUserSwitching(msg.arg1);
+ break;
+
default:
Slog.w(TAG, "Unknown message:" + msg.what);
}
@@ -93,6 +100,7 @@
private Context mContext;
private int mHalDeviceId;
private int mFailedAttempts;
+ private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
private final Runnable mLockoutReset = new Runnable() {
@Override
public void run() {
@@ -144,7 +152,7 @@
void handleNotify(int type, int arg1, int arg2, int arg3) {
Slog.v(TAG, "handleNotify(type=" + type + ", arg1=" + arg1 + ", arg2=" + arg2 + ")"
- + ", mAuthClients = " + mAuthClient + ", mEnrollClient = " + mEnrollClient);
+ + ", mAuthClients = " + mAuthClient + ", mEnrollClient = " + mEnrollClient);
if (mEnrollClient != null) {
final IBinder token = mEnrollClient.token;
if (dispatchNotify(mEnrollClient, type, arg1, arg2, arg3)) {
@@ -166,13 +174,16 @@
}
}
+ void handleUserSwitching(int userId) {
+ updateActiveGroup(userId);
+ }
+
/*
* Dispatch notify events to clients.
*
* @return true if the operation is done, i.e. authentication completed
*/
boolean dispatchNotify(ClientMonitor clientMonitor, int type, int arg1, int arg2, int arg3) {
- ContentResolver contentResolver = mContext.getContentResolver();
boolean operationCompleted = false;
int fpId;
int groupId;
@@ -198,7 +209,7 @@
remaining = arg3;
operationCompleted = clientMonitor.sendEnrollResult(fpId, groupId, remaining);
if (remaining == 0) {
- addTemplateForUser(clientMonitor, contentResolver, fpId);
+ addTemplateForUser(clientMonitor, fpId);
operationCompleted = true; // enroll completed
}
break;
@@ -207,7 +218,7 @@
groupId = arg2;
operationCompleted = clientMonitor.sendRemoved(fpId, groupId);
if (fpId != 0) {
- removeTemplateForUser(clientMonitor, contentResolver, fpId);
+ removeTemplateForUser(clientMonitor, fpId);
}
break;
}
@@ -252,16 +263,12 @@
return false;
}
- private void removeTemplateForUser(ClientMonitor clientMonitor, ContentResolver contentResolver,
- final int fingerId) {
- FingerprintUtils.removeFingerprintIdForUser(fingerId, contentResolver,
- clientMonitor.userId);
+ private void removeTemplateForUser(ClientMonitor clientMonitor, int fingerId) {
+ mFingerprintUtils.removeFingerprintIdForUser(mContext, fingerId, clientMonitor.userId);
}
- private void addTemplateForUser(ClientMonitor clientMonitor, ContentResolver contentResolver,
- final int fingerId) {
- FingerprintUtils.addFingerprintIdForUser(contentResolver, fingerId,
- clientMonitor.userId);
+ private void addTemplateForUser(ClientMonitor clientMonitor, int fingerId) {
+ mFingerprintUtils.addFingerprintForUser(mContext, fingerId, clientMonitor.userId);
}
void startEnrollment(IBinder token, byte[] cryptoToken, int groupId,
@@ -345,24 +352,11 @@
}
public List<Fingerprint> getEnrolledFingerprints(int groupId) {
- ContentResolver resolver = mContext.getContentResolver();
- int[] ids = FingerprintUtils.getFingerprintIdsForUser(resolver, groupId);
- List<Fingerprint> result = new ArrayList<Fingerprint>();
- for (int i = 0; i < ids.length; i++) {
- // TODO: persist names in Settings
- CharSequence name = "Finger" + ids[i];
- final int group = 0; // TODO
- final int fingerId = ids[i];
- final long deviceId = 0; // TODO
- Fingerprint item = new Fingerprint(name, 0, ids[i], 0);
- result.add(item);
- }
- return result;
+ return mFingerprintUtils.getFingerprintsForUser(mContext, groupId);
}
public boolean hasEnrolledFingerprints(int groupId) {
- ContentResolver resolver = mContext.getContentResolver();
- return FingerprintUtils.getFingerprintIdsForUser(resolver, groupId).length > 0;
+ return mFingerprintUtils.getFingerprintsForUser(mContext, groupId).size() > 0;
}
void checkPermission(String permission) {
@@ -596,7 +590,7 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- Slog.w(TAG, "rename id=" + fingerId + ",gid=" + groupId + ",name=" + name);
+ mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, groupId, name);
}
});
}
@@ -633,11 +627,37 @@
publishBinderService(Context.FINGERPRINT_SERVICE, new FingerprintServiceWrapper());
mHalDeviceId = nativeOpenHal();
if (mHalDeviceId != 0) {
- int userId = ActivityManager.getCurrentUser();
- File path = Environment.getUserSystemDirectory(userId);
- nativeSetActiveGroup(0, path.getAbsolutePath().getBytes());
+ updateActiveGroup(ActivityManager.getCurrentUser());
}
if (DEBUG) Slog.v(TAG, "Fingerprint HAL id: " + mHalDeviceId);
+ listenForUserSwitches();
}
+ private void updateActiveGroup(int userId) {
+ File path = Environment.getUserSystemDirectory(userId);
+ nativeSetActiveGroup(userId, path.getAbsolutePath().getBytes());
+ }
+
+ private void listenForUserSwitches() {
+ try {
+ ActivityManagerNative.getDefault().registerUserSwitchObserver(
+ new IUserSwitchObserver.Stub() {
+ @Override
+ public void onUserSwitching(int newUserId, IRemoteCallback reply) {
+ mHandler.obtainMessage(MSG_USER_SWITCHING, newUserId, 0 /* unused */)
+ .sendToTarget();
+ }
+ @Override
+ public void onUserSwitchComplete(int newUserId) throws RemoteException {
+ // Ignore.
+ }
+ @Override
+ public void onForegroundProfileSwitch(int newProfileId) {
+ // Ignore.
+ }
+ });
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to listen for user switching event" ,e);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
new file mode 100644
index 0000000..1e6e105
--- /dev/null
+++ b/services/core/java/com/android/server/fingerprint/FingerprintUtils.java
@@ -0,0 +1,95 @@
+/**
+ * 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.server.fingerprint;
+
+import android.content.Context;
+import android.hardware.fingerprint.Fingerprint;
+import android.os.Vibrator;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+
+/**
+ * Utility class for dealing with fingerprints and fingerprint settings.
+ */
+public class FingerprintUtils {
+
+ private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
+ private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};
+
+ private static final Object sInstanceLock = new Object();
+ private static FingerprintUtils sInstance;
+
+ @GuardedBy("this")
+ private final SparseArray<FingerprintsUserState> mUsers = new SparseArray<>();
+
+ public static FingerprintUtils getInstance() {
+ synchronized (sInstanceLock) {
+ if (sInstance == null) {
+ sInstance = new FingerprintUtils();
+ }
+ }
+ return sInstance;
+ }
+
+ private FingerprintUtils() {
+ }
+
+ public List<Fingerprint> getFingerprintsForUser(Context ctx, int userId) {
+ return getStateForUser(ctx, userId).getFingerprints();
+ }
+
+ public void addFingerprintForUser(Context ctx, int fingerId, int userId) {
+ getStateForUser(ctx, userId).addFingerprint(fingerId);
+ }
+
+ public void removeFingerprintIdForUser(Context ctx, int fingerId, int userId) {
+ getStateForUser(ctx, userId).removeFingerprint(fingerId);
+ }
+
+ public void renameFingerprintForUser(Context ctx, int fingerId, int userId, CharSequence name) {
+ getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
+ }
+
+ public static void vibrateFingerprintError(Context context) {
+ Vibrator vibrator = context.getSystemService(Vibrator.class);
+ if (vibrator != null) {
+ vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
+ }
+ }
+
+ public static void vibrateFingerprintSuccess(Context context) {
+ Vibrator vibrator = context.getSystemService(Vibrator.class);
+ if (vibrator != null) {
+ vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
+ }
+ }
+
+ private FingerprintsUserState getStateForUser(Context ctx, int userId) {
+ synchronized (this) {
+ FingerprintsUserState state = mUsers.get(userId);
+ if (state == null) {
+ state = new FingerprintsUserState(ctx, userId);
+ mUsers.put(userId, state);
+ }
+ return state;
+ }
+ }
+}
+
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintsUserState.java b/services/core/java/com/android/server/fingerprint/FingerprintsUserState.java
new file mode 100644
index 0000000..33177b4
--- /dev/null
+++ b/services/core/java/com/android/server/fingerprint/FingerprintsUserState.java
@@ -0,0 +1,247 @@
+/*
+ * 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.server.fingerprint;
+
+import android.content.Context;
+import android.hardware.fingerprint.Fingerprint;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.GuardedBy;
+
+import libcore.io.IoUtils;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Class managing the set of fingerprint per user across device reboots.
+ */
+class FingerprintsUserState {
+
+ private static final String TAG = "FingerprintState";
+ private static final String FINGERPRINT_FILE = "settings_fingerprint.xml";
+
+ private static final String TAG_FINGERPRINTS = "fingerprints";
+ private static final String TAG_FINGERPRINT = "fingerprint";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_GROUP_ID = "groupId";
+ private static final String ATTR_FINGER_ID = "fingerId";
+ private static final String ATTR_DEVICE_ID = "deviceId";
+
+ private final File mFile;
+
+ @GuardedBy("this")
+ private final ArrayList<Fingerprint> mFingerprints = new ArrayList<>();
+ private final Context mCtx;
+
+ public FingerprintsUserState(Context ctx, int userId) {
+ mFile = getFileForUser(userId);
+ mCtx = ctx;
+ synchronized (this) {
+ readStateSyncLocked();
+ }
+ }
+
+ public void addFingerprint(int fingerId) {
+ synchronized (this) {
+ mFingerprints.add(new Fingerprint(getDefaultFingerprintName(fingerId), 0, fingerId, 0));
+ scheduleWriteStateLocked();
+ }
+ }
+
+ public void removeFingerprint(int fingerId) {
+ synchronized (this) {
+ for (int i = 0; i < mFingerprints.size(); i++) {
+ if (mFingerprints.get(i).getFingerId() == fingerId) {
+ mFingerprints.remove(i);
+ scheduleWriteStateLocked();
+ break;
+ }
+ }
+ }
+ }
+
+ public void renameFingerprint(int fingerId, CharSequence name) {
+ synchronized (this) {
+ for (int i = 0; i < mFingerprints.size(); i++) {
+ if (mFingerprints.get(i).getFingerId() == fingerId) {
+ Fingerprint old = mFingerprints.get(i);
+ mFingerprints.set(i, new Fingerprint(name, old.getGroupId(), old.getFingerId(),
+ old.getDeviceId()));
+ scheduleWriteStateLocked();
+ break;
+ }
+ }
+ }
+ }
+
+ public List<Fingerprint> getFingerprints() {
+ synchronized (this) {
+ return getCopy(mFingerprints);
+ }
+ }
+
+ private String getDefaultFingerprintName(int fingerId) {
+ return mCtx.getString(com.android.internal.R.string.fingerprint_name_template, fingerId);
+ }
+
+ private static File getFileForUser(int userId) {
+ return new File(Environment.getUserSystemDirectory(userId), FINGERPRINT_FILE);
+ }
+
+ private final Runnable mWriteStateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ doWriteState();
+ }
+ };
+
+ private void scheduleWriteStateLocked() {
+ AsyncTask.execute(mWriteStateRunnable);
+ }
+
+ private ArrayList<Fingerprint> getCopy(ArrayList<Fingerprint> array) {
+ ArrayList<Fingerprint> result = new ArrayList<>(array.size());
+ for (int i = 0; i < array.size(); i++) {
+ Fingerprint fp = array.get(i);
+ result.add(new Fingerprint(fp.getName(), fp.getGroupId(), fp.getFingerId(),
+ fp.getDeviceId()));
+ }
+ return result;
+ }
+
+ private void doWriteState() {
+ AtomicFile destination = new AtomicFile(mFile);
+
+ ArrayList<Fingerprint> fingerprints;
+
+ synchronized (this) {
+ fingerprints = getCopy(mFingerprints);
+ }
+
+ FileOutputStream out = null;
+ try {
+ out = destination.startWrite();
+
+ XmlSerializer serializer = Xml.newSerializer();
+ serializer.setOutput(out, "utf-8");
+ serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ serializer.startDocument(null, true);
+ serializer.startTag(null, TAG_FINGERPRINTS);
+
+ final int count = fingerprints.size();
+ for (int i = 0; i < count; i++) {
+ Fingerprint fp = fingerprints.get(i);
+ serializer.startTag(null, TAG_FINGERPRINT);
+ serializer.attribute(null, ATTR_FINGER_ID, Integer.toString(fp.getFingerId()));
+ serializer.attribute(null, ATTR_NAME, fp.getName().toString());
+ serializer.attribute(null, ATTR_GROUP_ID, Integer.toString(fp.getGroupId()));
+ serializer.attribute(null, ATTR_DEVICE_ID, Long.toString(fp.getDeviceId()));
+ serializer.endTag(null, TAG_FINGERPRINT);
+ }
+
+ serializer.endTag(null, TAG_FINGERPRINTS);
+ serializer.endDocument();
+ destination.finishWrite(out);
+
+ // Any error while writing is fatal.
+ } catch (Throwable t) {
+ Slog.wtf(TAG, "Failed to write settings, restoring backup", t);
+ destination.failWrite(out);
+ throw new IllegalStateException("Failed to write fingerprints", t);
+ } finally {
+ IoUtils.closeQuietly(out);
+ }
+ }
+
+ private void readStateSyncLocked() {
+ FileInputStream in;
+ if (!mFile.exists()) {
+ return;
+ }
+ try {
+ in = new FileInputStream(mFile);
+ } catch (FileNotFoundException fnfe) {
+ Slog.i(TAG, "No fingerprint state");
+ return;
+ }
+ try {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(in, null);
+ parseStateLocked(parser);
+
+ } catch (XmlPullParserException | IOException e) {
+ throw new IllegalStateException("Failed parsing settings file: "
+ + mFile , e);
+ } finally {
+ IoUtils.closeQuietly(in);
+ }
+ }
+
+ private void parseStateLocked(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_FINGERPRINTS)) {
+ parseFingerprintsLocked(parser);
+ }
+ }
+ }
+
+ private void parseFingerprintsLocked(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_FINGERPRINT)) {
+ String name = parser.getAttributeValue(null, ATTR_NAME);
+ String groupId = parser.getAttributeValue(null, ATTR_GROUP_ID);
+ String fingerId = parser.getAttributeValue(null, ATTR_FINGER_ID);
+ String deviceId = parser.getAttributeValue(null, ATTR_DEVICE_ID);
+ mFingerprints.add(new Fingerprint(name, Integer.parseInt(groupId),
+ Integer.parseInt(fingerId), Integer.parseInt(deviceId)));
+ }
+ }
+ }
+
+}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 8031c05..77b800e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -737,6 +737,9 @@
}
}
+ void setAutoDeviceOff(boolean enabled) {
+ }
+
/**
* Called when a hot-plug event issued.
*
@@ -829,8 +832,11 @@
*
* @param initiatedByCec true if this power sequence is initiated
* by the reception the CEC messages like <Standby>
+ * @param standbyAction Intent action that drives the standby process,
+ * either {@link HdmiControlService#STANDBY_SCREEN_OFF} or
+ * {@link HdmiControlService#STANDBY_SHUTDOWN}
*/
- protected void onStandby(boolean initiatedByCec) {}
+ protected void onStandby(boolean initiatedByCec, int standbyAction) {}
/**
* Disable device. {@code callback} is used to get notified when all pending
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index fd3364a..30a9b43 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -23,6 +23,7 @@
import android.os.PowerManager.WakeLock;
import android.os.RemoteException;
import android.os.SystemProperties;
+import android.provider.Settings.Global;
import android.util.Slog;
import com.android.internal.util.IndentingPrintWriter;
@@ -47,8 +48,17 @@
// Lazily initialized - should call getWakeLock() to get the instance.
private ActiveWakeLock mWakeLock;
+ // If true, turn off TV upon standby. False by default.
+ private boolean mAutoTvOff;
+
HdmiCecLocalDevicePlayback(HdmiControlService service) {
super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);
+
+ mAutoTvOff = mService.readBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, false);
+
+ // The option is false by default. Update settings db as well to have the right
+ // initial setting on UI.
+ mService.writeBooleanSetting(Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED, mAutoTvOff);
}
@Override
@@ -141,6 +151,35 @@
}
}
+ @Override
+ @ServiceThreadOnly
+ protected void onStandby(boolean initiatedByCec, int standbyAction) {
+ assertRunOnServiceThread();
+ if (!mService.isControlEnabled() || initiatedByCec) {
+ return;
+ }
+ switch (standbyAction) {
+ case HdmiControlService.STANDBY_SCREEN_OFF:
+ if (mAutoTvOff) {
+ mService.sendCecCommand(
+ HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV));
+ }
+ break;
+ case HdmiControlService.STANDBY_SHUTDOWN:
+ // ACTION_SHUTDOWN is taken as a signal to power off all the devices.
+ mService.sendCecCommand(
+ HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_BROADCAST));
+ break;
+ }
+ }
+
+ @Override
+ @ServiceThreadOnly
+ void setAutoDeviceOff(boolean enabled) {
+ assertRunOnServiceThread();
+ mAutoTvOff = enabled;
+ }
+
@ServiceThreadOnly
void setActiveSource(boolean on) {
assertRunOnServiceThread();
@@ -295,6 +334,7 @@
protected void dump(final IndentingPrintWriter pw) {
super.dump(pw);
pw.println("mIsActiveSource: " + mIsActiveSource);
+ pw.println("mAutoTvOff:" + mAutoTvOff);
}
// Wrapper interface over PowerManager.WakeLock
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 51ba32d..96cb51c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1583,6 +1583,7 @@
}
}
+ @Override
@ServiceThreadOnly
void setAutoDeviceOff(boolean enabled) {
assertRunOnServiceThread();
@@ -1659,7 +1660,7 @@
@Override
@ServiceThreadOnly
- protected void onStandby(boolean initiatedByCec) {
+ protected void onStandby(boolean initiatedByCec, int standbyAction) {
assertRunOnServiceThread();
// Seq #11
if (!mService.isControlEnabled()) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 2cbc1b9..c37f619 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -106,6 +106,12 @@
static final int INITIATED_BY_WAKE_UP_MESSAGE = 3;
static final int INITIATED_BY_HOTPLUG = 4;
+ // The reason code representing the intent action that drives the standby
+ // procedure. The procedure starts either by Intent.ACTION_SCREEN_OFF or
+ // Intent.ACTION_SHUTDOWN.
+ static final int STANDBY_SCREEN_OFF = 0;
+ static final int STANDBY_SHUTDOWN = 1;
+
/**
* Interface to report send result.
*/
@@ -143,7 +149,7 @@
switch (intent.getAction()) {
case Intent.ACTION_SCREEN_OFF:
if (isPowerOnOrTransient()) {
- onStandby();
+ onStandby(STANDBY_SCREEN_OFF);
}
break;
case Intent.ACTION_SCREEN_ON:
@@ -157,6 +163,11 @@
onLanguageChanged(language);
}
break;
+ case Intent.ACTION_SHUTDOWN:
+ if (isPowerOnOrTransient()) {
+ onStandby(STANDBY_SHUTDOWN);
+ }
+ break;
}
}
@@ -381,10 +392,6 @@
mCecController = HdmiCecController.create(this);
if (mCecController != null) {
- // TODO: Remove this as soon as OEM's HAL implementation is corrected.
- mCecController.setOption(OPTION_CEC_ENABLE, ENABLED);
-
- // TODO: load value for mHdmiControlEnabled from preference.
if (mHdmiControlEnabled) {
initializeCec(INITIATED_BY_BOOT_UP);
}
@@ -510,8 +517,9 @@
setCecOption(OPTION_CEC_AUTO_WAKEUP, toInt(enabled));
break;
case Global.HDMI_CONTROL_AUTO_DEVICE_OFF_ENABLED:
- if (isTvDeviceEnabled()) {
- tv().setAutoDeviceOff(enabled);
+ for (int type : mLocalDevices) {
+ HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type);
+ localDevice.setAutoDeviceOff(enabled);
}
// No need to propagate to HAL.
break;
@@ -1994,7 +2002,7 @@
}
@ServiceThreadOnly
- private void onStandby() {
+ private void onStandby(final int standbyAction) {
assertRunOnServiceThread();
if (!canGoToStandby()) return;
mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY;
@@ -2008,7 +2016,7 @@
Slog.v(TAG, "On standby-action cleared:" + device.mDeviceType);
devices.remove(device);
if (devices.isEmpty()) {
- onStandbyCompleted();
+ onStandbyCompleted(standbyAction);
// We will not clear local devices here, since some OEM/SOC will keep passing
// the received packets until the application processor enters to the sleep
// actually.
@@ -2062,7 +2070,7 @@
}
@ServiceThreadOnly
- private void onStandbyCompleted() {
+ private void onStandbyCompleted(int standbyAction) {
assertRunOnServiceThread();
Slog.v(TAG, "onStandbyCompleted");
@@ -2071,7 +2079,7 @@
}
mPowerStatus = HdmiControlManager.POWER_STATUS_STANDBY;
for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.onStandby(mStandbyMessageReceived);
+ device.onStandby(mStandbyMessageReceived, standbyAction);
}
mStandbyMessageReceived = false;
mAddressAllocated = false;
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index 92fa813..f6d7244 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -37,6 +37,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -214,7 +215,7 @@
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(InputManagerService.TAG, "Failed to load input manager persistent store data.", ex);
@@ -234,7 +235,7 @@
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index b066d6b..bb4e388 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -154,7 +154,8 @@
mRunningJob = job;
final boolean isDeadlineExpired =
- job.getLatestRunTimeElapsed() >= SystemClock.elapsedRealtime();
+ job.hasDeadlineConstraint() &&
+ (job.getLatestRunTimeElapsed() < SystemClock.elapsedRealtime());
mParams = new JobParameters(this, job.getJobId(), job.getExtras(), isDeadlineExpired);
mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index b64c677..24d4f15 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -41,6 +41,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -292,7 +293,7 @@
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(baos, "utf-8");
+ out.setOutput(baos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -450,7 +451,7 @@
private List<JobStatus> readJobMapImpl(FileInputStream fis)
throws XmlPullParserException, IOException {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int eventType = parser.getEventType();
while (eventType != XmlPullParser.START_TAG &&
diff --git a/services/core/java/com/android/server/location/FlpHardwareProvider.java b/services/core/java/com/android/server/location/FlpHardwareProvider.java
index 1fb22be..259ff1d 100644
--- a/services/core/java/com/android/server/location/FlpHardwareProvider.java
+++ b/services/core/java/com/android/server/location/FlpHardwareProvider.java
@@ -48,7 +48,7 @@
// Capabilities provided by FlpCallbacks
private boolean mHaveBatchingCapabilities;
private int mBatchingCapabilities;
- private int mVersion;
+ private int mVersion = 1;
private static FlpHardwareProvider sSingletonInstance = null;
@@ -154,7 +154,9 @@
private void setVersion(int version) {
mVersion = version;
- getGeofenceHardwareSink().setVersion(version);
+ if (mGeofenceHardwareSink != null) {
+ mGeofenceHardwareSink.setVersion(version);
+ }
}
private void maybeSendCapabilities() {
@@ -480,6 +482,7 @@
private GeofenceHardwareImpl getGeofenceHardwareSink() {
if (mGeofenceHardwareSink == null) {
mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext);
+ mGeofenceHardwareSink.setVersion(mVersion);
}
return mGeofenceHardwareSink;
diff --git a/services/core/java/com/android/server/location/GeofenceProxy.java b/services/core/java/com/android/server/location/GeofenceProxy.java
index b886eef..d1bb8db 100644
--- a/services/core/java/com/android/server/location/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/GeofenceProxy.java
@@ -129,7 +129,9 @@
private void setGpsGeofenceLocked() {
try {
- mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
+ if (mGpsGeofenceHardware != null) {
+ mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
+ }
} catch (RemoteException e) {
Log.e(TAG, "Error while connecting to GeofenceHardwareService");
}
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 6bd646d..d338d91 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -446,13 +446,12 @@
int networkState;
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false) ||
- !info.isConnected()) {
+ !info.isConnected()) {
networkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
} else {
networkState = LocationProvider.AVAILABLE;
}
-
updateNetworkState(networkState, info);
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 0ae6735..24ab3b8 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -170,6 +170,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -1290,7 +1291,7 @@
try {
fis = mPolicyFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
int version = VERSION_INIT;
@@ -1425,7 +1426,7 @@
fos = mPolicyFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_POLICY_LIST);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 791c1de..311ca65 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -120,6 +120,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
@@ -391,7 +392,7 @@
try {
infile = mPolicyFile.openRead();
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(infile, null);
+ parser.setInput(infile, StandardCharsets.UTF_8.name());
int type;
String tag;
@@ -449,7 +450,7 @@
try {
final XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_BODY);
out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
@@ -908,11 +909,6 @@
void onPolicyChanged() {
sendRegisteredOnlyBroadcast(NotificationManager.ACTION_NOTIFICATION_POLICY_CHANGED);
}
-
- private void sendRegisteredOnlyBroadcast(String action) {
- getContext().sendBroadcast(new Intent(action)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
- }
});
final File systemDir = new File(Environment.getDataDirectory(), "system");
mPolicyFile = new AtomicFile(new File(systemDir, "notification_policy.xml"));
@@ -995,6 +991,11 @@
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
+ private void sendRegisteredOnlyBroadcast(String action) {
+ getContext().sendBroadcastAsUser(new Intent(action)
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY), UserHandle.ALL, null);
+ }
+
/**
* Read the old XML-based app block database and import those blockages into the AppOps system.
*/
@@ -1061,8 +1062,7 @@
ZenLog.traceEffectsSuppressorChanged(mEffectsSuppressor, suppressor);
mEffectsSuppressor = suppressor;
mZenModeHelper.setEffectsSuppressed(suppressor != null);
- getContext().sendBroadcast(new Intent(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY));
+ sendRegisteredOnlyBroadcast(NotificationManager.ACTION_EFFECTS_SUPPRESSOR_CHANGED);
}
private void updateInterruptionFilterLocked() {
@@ -1623,16 +1623,16 @@
}
@Override
- public void notifyConditions(String pkg, IConditionProvider provider,
- Condition[] conditions) {
+ public void notifyConditions(final String pkg, IConditionProvider provider,
+ final Condition[] conditions) {
final ManagedServiceInfo info = mConditionProviders.checkServiceToken(provider);
checkCallerIsSystemOrSameApp(pkg);
- final long identity = Binder.clearCallingIdentity();
- try {
- mConditionProviders.notifyConditions(pkg, info, conditions);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mConditionProviders.notifyConditions(pkg, info, conditions);
+ }
+ });
}
@Override
@@ -2018,7 +2018,8 @@
throw new IllegalArgumentException("null not allowed: pkg=" + pkg
+ " id=" + id + " notification=" + notification);
}
- if (notification.icon != 0) {
+
+ if (notification.getSmallIcon() != null) {
if (!notification.isValid()) {
throw new IllegalArgumentException("Invalid notification (): pkg=" + pkg
+ " id=" + id + " notification=" + notification);
@@ -2139,11 +2140,11 @@
applyZenModeLocked(r);
mRankingHelper.sort(mNotificationList);
- if (notification.icon != 0) {
+ if (notification.getSmallIcon() != null) {
StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
mListeners.notifyPostedLocked(n, oldSbn);
} else {
- Slog.e(TAG, "Not posting notification with icon==0: " + notification);
+ Slog.e(TAG, "Not posting notification without small icon: " + notification);
if (old != null && !old.isCanceled) {
mListeners.notifyRemovedLocked(n);
}
@@ -2716,7 +2717,7 @@
}
// status bar
- if (r.getNotification().icon != 0) {
+ if (r.getNotification().getSmallIcon() != null) {
r.isCanceled = true;
mListeners.notifyRemovedLocked(r.sbn);
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index c9f5bdf..02cc840 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -20,6 +20,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.drawable.Icon;
import android.media.AudioAttributes;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
@@ -106,10 +107,14 @@
void dump(PrintWriter pw, String prefix, Context baseContext) {
final Notification notification = sbn.getNotification();
+ final Icon icon = notification.getSmallIcon();
+ String iconStr = String.valueOf(icon);
+ if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) {
+ iconStr += " / " + idDebugString(baseContext, icon.getResPackage(), icon.getResId());
+ }
pw.println(prefix + this);
pw.println(prefix + " uid=" + sbn.getUid() + " userId=" + sbn.getUserId());
- pw.println(prefix + " icon=0x" + Integer.toHexString(notification.icon)
- + " / " + idDebugString(baseContext, sbn.getPackageName(), notification.icon));
+ pw.println(prefix + " icon=" + iconStr);
pw.println(prefix + " pri=" + notification.priority + " score=" + sbn.getScore());
pw.println(prefix + " key=" + sbn.getKey());
pw.println(prefix + " seen=" + mIsSeen);
diff --git a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
index bca13c2..f06f54c 100644
--- a/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
+++ b/services/core/java/com/android/server/notification/ScheduleConditionProvider.java
@@ -57,6 +57,7 @@
private boolean mConnected;
private boolean mRegistered;
+ private long mNextAlarmTime;
public ScheduleConditionProvider() {
if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()");
@@ -84,6 +85,12 @@
pw.print(meetsSchedule(conditionId, now) ? "* " : " ");
pw.println(conditionId);
}
+ pw.print(" mNextAlarmTime="); pw.print(mNextAlarmTime);
+ if (mNextAlarmTime > 0) {
+ pw.printf(" (%s, in %s, now=%s)", ts(mNextAlarmTime),
+ formatDuration(mNextAlarmTime - now), ts(now));
+ }
+ pw.println();
}
@Override
@@ -141,7 +148,7 @@
private void evaluateSubscriptions() {
setRegistered(!mSubscriptions.isEmpty());
final long now = System.currentTimeMillis();
- long nextAlarmTime = 0;
+ mNextAlarmTime = 0;
for (Uri conditionId : mSubscriptions) {
final ScheduleCalendar cal = toScheduleCalendar(conditionId);
if (cal != null && cal.isInSchedule(now)) {
@@ -152,13 +159,13 @@
if (cal != null) {
final long nextChangeTime = cal.getNextChangeTime(now);
if (nextChangeTime > 0 && nextChangeTime > now) {
- if (nextAlarmTime == 0 || nextChangeTime < nextAlarmTime) {
- nextAlarmTime = nextChangeTime;
+ if (mNextAlarmTime == 0 || nextChangeTime < mNextAlarmTime) {
+ mNextAlarmTime = nextChangeTime;
}
}
}
}
- updateAlarm(now, nextAlarmTime);
+ updateAlarm(now, mNextAlarmTime);
}
private void updateAlarm(long now, long time) {
@@ -209,7 +216,8 @@
}
private void notifyCondition(Uri conditionId, int state, String reason) {
- if (DEBUG) Slog.d(TAG, "notifyCondition " + Condition.stateToString(state)
+ if (DEBUG) Slog.d(TAG, "notifyCondition " + conditionId
+ + " " + Condition.stateToString(state)
+ " reason=" + reason);
notifyCondition(createCondition(conditionId, state));
}
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index fa314de..f1c58bd 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -63,7 +63,7 @@
mConditionProviders.requestConditions(callback, relevance);
}
- public void evaluateConfig(ZenModeConfig config) {
+ public void evaluateConfig(ZenModeConfig config, boolean processSubscriptione) {
if (config == null) return;
if (config.manualRule != null && config.manualRule.condition != null
&& !config.manualRule.isTrueOrUnknown()) {
@@ -71,18 +71,20 @@
config.manualRule = null;
}
final ArraySet<Uri> current = new ArraySet<>();
- evaluateRule(config.manualRule, current);
+ evaluateRule(config.manualRule, current, processSubscriptione);
for (ZenRule automaticRule : config.automaticRules.values()) {
- evaluateRule(automaticRule, current);
+ evaluateRule(automaticRule, current, processSubscriptione);
updateSnoozing(automaticRule);
}
final int N = mSubscriptions.size();
for (int i = N - 1; i >= 0; i--) {
final Uri id = mSubscriptions.keyAt(i);
final ComponentName component = mSubscriptions.valueAt(i);
- if (!current.contains(id)) {
- mConditionProviders.unsubscribeIfNecessary(component, id);
- mSubscriptions.removeAt(i);
+ if (processSubscriptione) {
+ if (!current.contains(id)) {
+ mConditionProviders.unsubscribeIfNecessary(component, id);
+ mSubscriptions.removeAt(i);
+ }
}
}
mFirstEvaluation = false;
@@ -122,7 +124,7 @@
}
}
- private void evaluateRule(ZenRule rule, ArraySet<Uri> current) {
+ private void evaluateRule(ZenRule rule, ArraySet<Uri> current, boolean processSubscriptions) {
if (rule == null || rule.conditionId == null) return;
final Uri id = rule.conditionId;
boolean isSystemCondition = false;
@@ -148,10 +150,12 @@
if (current != null) {
current.add(id);
}
- if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) {
- mSubscriptions.put(rule.conditionId, rule.component);
- } else {
- if (DEBUG) Log.d(TAG, "zmc failed to subscribe");
+ if (processSubscriptions) {
+ if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) {
+ mSubscriptions.put(rule.conditionId, rule.component);
+ } else {
+ if (DEBUG) Log.d(TAG, "zmc failed to subscribe");
+ }
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index aeb6b78..a3c36ed 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -16,8 +16,6 @@
package com.android.server.notification;
-import static android.media.AudioAttributes.USAGE_ALARM;
-import static android.media.AudioAttributes.USAGE_MEDIA;
import static android.media.AudioAttributes.USAGE_NOTIFICATION;
import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
@@ -32,6 +30,7 @@
import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
+import android.media.AudioSystem;
import android.media.VolumePolicy;
import android.net.Uri;
import android.os.Bundle;
@@ -41,7 +40,6 @@
import android.os.UserHandle;
import android.provider.Settings.Global;
import android.service.notification.IConditionListener;
-import android.service.notification.NotificationListenerService;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.EventInfo;
import android.service.notification.ZenModeConfig.ScheduleInfo;
@@ -266,7 +264,7 @@
Log.w(TAG, "Invalid config in setConfig; " + config);
return false;
}
- mConditions.evaluateConfig(config); // may modify config
+ mConditions.evaluateConfig(config, false /*processSubscriptions*/); // may modify config
if (config.equals(mConfig)) return true;
if (DEBUG) Log.d(TAG, "setConfig reason=" + reason, new Throwable());
ZenLog.traceConfig(reason, config);
@@ -282,6 +280,7 @@
if (!evaluateZenMode(reason, setRingerMode)) {
applyRestrictions(); // evaluateZenMode will also apply restrictions if changed
}
+ mConditions.evaluateConfig(config, true /*processSubscriptions*/);
return true;
}
@@ -300,6 +299,7 @@
if (zen == mZenMode) return false;
ZenLog.traceSetZenMode(zen, reason);
mZenMode = zen;
+ updateRingerModeAffectedStreams();
setZenModeSetting(mZenMode);
if (setRingerMode) {
applyZenToRingerMode();
@@ -309,6 +309,12 @@
return true;
}
+ private void updateRingerModeAffectedStreams() {
+ if (mAudioManager != null) {
+ mAudioManager.updateRingerModeAffectedStreamsInternal();
+ }
+ }
+
private int computeZenMode(ArraySet<ZenRule> automaticRulesOut) {
if (mConfig == null) return Global.ZEN_MODE_OFF;
if (mConfig.manualRule != null) return mConfig.manualRule.zenMode;
@@ -334,11 +340,6 @@
final boolean muteCalls = zen && !mConfig.allowCalls && !mConfig.allowRepeatCallers
|| mEffectsSuppressed;
applyRestrictions(muteCalls, USAGE_NOTIFICATION_RINGTONE);
-
- // alarm/media restrictions
- final boolean zenNone = mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS;
- applyRestrictions(zenNone, USAGE_ALARM);
- applyRestrictions(zenNone, USAGE_MEDIA);
}
private void applyRestrictions(boolean mute, int usage) {
@@ -523,6 +524,7 @@
&& mZenMode != Global.ZEN_MODE_ALARMS) {
newZen = Global.ZEN_MODE_ALARMS;
}
+ mPreviousRingerMode = ringerModeOld;
}
break;
case AudioManager.RINGER_MODE_VIBRATE:
@@ -559,10 +561,10 @@
case AudioManager.RINGER_MODE_SILENT:
if (isChange) {
if (mZenMode == Global.ZEN_MODE_OFF) {
- newZen = Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ newZen = Global.ZEN_MODE_ALARMS;
}
ringerModeInternalOut = isVibrate ? AudioManager.RINGER_MODE_VIBRATE
- : AudioManager.RINGER_MODE_NORMAL;
+ : AudioManager.RINGER_MODE_SILENT;
} else {
ringerModeInternalOut = ringerModeInternal;
}
@@ -587,6 +589,24 @@
public boolean canVolumeDownEnterSilent() {
return mZenMode == Global.ZEN_MODE_OFF;
}
+
+ @Override
+ public int getRingerModeAffectedStreams(int streams) {
+ // ringtone, notification and system streams are always affected by ringer mode
+ streams |= (1 << AudioSystem.STREAM_RING) |
+ (1 << AudioSystem.STREAM_NOTIFICATION) |
+ (1 << AudioSystem.STREAM_SYSTEM);
+
+ // alarm and music streams are only affected by ringer mode when in total silence
+ if (mZenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
+ streams |= (1 << AudioSystem.STREAM_ALARM) |
+ (1 << AudioSystem.STREAM_MUSIC);
+ } else {
+ streams &= ~((1 << AudioSystem.STREAM_ALARM) |
+ (1 << AudioSystem.STREAM_MUSIC));
+ }
+ return streams;
+ }
}
private final class SettingsObserver extends ContentObserver {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index b505f7e..7024ec8 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -17,9 +17,12 @@
package com.android.server.pm;
import android.annotation.Nullable;
+import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageParser;
+import android.os.PowerManager;
import android.os.UserHandle;
+import android.os.WorkSource;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
@@ -50,8 +53,14 @@
private final PackageManagerService mPackageManagerService;
private ArraySet<PackageParser.Package> mDeferredDexOpt;
+ private final PowerManager.WakeLock mDexoptWakeLock;
+ private volatile boolean mSystemReady;
+
PackageDexOptimizer(PackageManagerService packageManagerService) {
this.mPackageManagerService = packageManagerService;
+ PowerManager powerManager = (PowerManager)packageManagerService.mContext.getSystemService(
+ Context.POWER_SERVICE);
+ mDexoptWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*dexopt*");
}
/**
@@ -71,7 +80,18 @@
done = null;
}
synchronized (mPackageManagerService.mInstallLock) {
- return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
+ final boolean useLock = mSystemReady;
+ if (useLock) {
+ mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid));
+ mDexoptWakeLock.acquire();
+ }
+ try {
+ return performDexOptLI(pkg, instructionSets, forceDex, defer, done);
+ } finally {
+ if (useLock) {
+ mDexoptWakeLock.release();
+ }
+ }
}
}
@@ -242,4 +262,8 @@
}
mDeferredDexOpt.add(pkg);
}
+
+ void systemReady() {
+ mSystemReady = true;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 09096ff..a1738a2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -105,6 +105,7 @@
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
@@ -323,7 +324,7 @@
try {
fis = mSessionsFile.openRead();
final XmlPullParser in = Xml.newPullParser();
- in.setInput(fis, null);
+ in.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = in.next()) != END_DOCUMENT) {
@@ -410,7 +411,7 @@
fos = mSessionsFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(fos, "utf-8");
+ out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_SESSIONS);
final int size = mSessions.size();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 89ca00e..dcf668d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -127,6 +127,8 @@
@GuardedBy("mLock")
private boolean mPermissionsAccepted = false;
@GuardedBy("mLock")
+ private boolean mRelinquished = false;
+ @GuardedBy("mLock")
private boolean mDestroyed = false;
private int mFinalStatus;
@@ -557,6 +559,7 @@
user = new UserHandle(userId);
}
+ mRelinquished = true;
mPm.installStage(mPackageName, stageDir, stageCid, localObserver, params,
installerPackageName, installerUid, user);
}
@@ -928,6 +931,10 @@
@Override
public void abandon() {
+ if (mRelinquished) {
+ Slog.d(TAG, "Ignoring abandon after commit relinquished control");
+ return;
+ }
destroyInternal();
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
}
@@ -958,8 +965,7 @@
}
}
if (stageDir != null) {
- FileUtils.deleteContents(stageDir);
- stageDir.delete();
+ mPm.mInstaller.rmPackageDir(stageDir.getAbsolutePath());
}
if (stageCid != null) {
PackageHelper.destroySdDir(stageCid);
@@ -990,6 +996,7 @@
pw.printPair("mProgress", mProgress);
pw.printPair("mSealed", mSealed);
pw.printPair("mPermissionsAccepted", mPermissionsAccepted);
+ pw.printPair("mRelinquished", mRelinquished);
pw.printPair("mDestroyed", mDestroyed);
pw.printPair("mBridges", mBridges.size());
pw.printPair("mFinalStatus", mFinalStatus);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 477af72..509289b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -55,6 +55,7 @@
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
import static android.content.pm.PackageParser.isApkFile;
+import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.O_CREAT;
@@ -3142,17 +3143,10 @@
}
}
- private static void enforceOnlySystemUpdatesPermissionPolicyFlags(int flagMask, int flagValues) {
- if (((flagMask & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0
- || (flagValues & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0)
- && getCallingUid() != Process.SYSTEM_UID) {
- throw new SecurityException("Only the system can modify policy flags");
- }
- }
-
@Override
public void grantRuntimePermission(String packageName, String name, int userId) {
if (!sUserManager.exists(userId)) {
+ Log.e(TAG, "No such user:" + userId);
return;
}
@@ -3210,6 +3204,7 @@
@Override
public void revokeRuntimePermission(String packageName, String name, int userId) {
if (!sUserManager.exists(userId)) {
+ Log.e(TAG, "No such user:" + userId);
return;
}
@@ -3302,7 +3297,15 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false,
"updatePermissionFlags");
- enforceOnlySystemUpdatesPermissionPolicyFlags(flagMask, flagValues);
+ // Only the system can change policy flags.
+ if (getCallingUid() != Process.SYSTEM_UID) {
+ flagMask &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+ flagValues &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
+ }
+
+ // Only the package manager can change system flags.
+ flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
+ flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
@@ -3322,6 +3325,12 @@
PermissionsState permissionsState = sb.getPermissionsState();
+ // Only the package manager can change flags for system component permissions.
+ final int flags = permissionsState.getPermissionFlags(bp.name, userId);
+ if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
+ return;
+ }
+
if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
// Install and runtime permissions are stored in different places,
// so figure out what permission changed and persist the change.
@@ -4130,7 +4139,9 @@
synchronized (mPackages) {
final int count = candidates.size();
- // First, try to use the domain prefered App
+ // First, try to use the domain prefered App. Partition the candidates into four lists:
+ // one for the final results, one for the "do not use ever", one for "undefined status"
+ // and finally one for "Browser App type".
for (int n=0; n<count; n++) {
ResolveInfo info = candidates.get(n);
String packageName = info.activityInfo.packageName;
@@ -4152,10 +4163,12 @@
}
}
}
+ // Add all undefined Apps as we want them to appear in the Disambiguation dialog.
+ result.addAll(undefinedList);
// If there is nothing selected, add all candidates and remove the ones that the User
// has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and
- // also remove any Browser Apps ones.
- // If there is still none after this pass, add all undefined one and Browser Apps and
+ // also remove Browser Apps ones.
+ // If there is still none after this pass, add all Browser Apps and
// let the User decide with the Disambiguation dialog if there are several ones.
if (result.size() == 0) {
result.addAll(candidates);
@@ -4163,7 +4176,6 @@
result.removeAll(neverList);
result.removeAll(matchAllList);
if (result.size() == 0) {
- result.addAll(undefinedList);
if ((flags & MATCH_ALL) != 0) {
result.addAll(matchAllList);
} else {
@@ -7757,9 +7769,14 @@
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
} else {
+ // System components not only get the permissions but
+ // they are also fixed, so nothing can change that.
+ final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
+ ? flags
+ : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
// Propagate the permission flags.
permissionsState.updatePermissionFlags(bp, userId,
- flags, flags);
+ newFlags, newFlags);
}
}
}
@@ -7782,9 +7799,14 @@
for (int userId : upgradeUserIds) {
if (permissionsState.grantRuntimePermission(bp, userId) !=
PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ // System components not only get the permissions but
+ // they are also fixed so nothing can change that.
+ final int newFlags = !isSystemComponentOrPersistentPrivApp(pkg)
+ ? flags
+ : flags | PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
// Transfer the permission flags.
permissionsState.updatePermissionFlags(bp, userId,
- flags, flags);
+ newFlags, newFlags);
// If we granted the permission, we have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
@@ -11441,6 +11463,21 @@
replace = true;
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
}
+
+ // Prevent apps opting out from runtime permissions
+ if (replace) {
+ PackageParser.Package oldPackage = mPackages.get(pkgName);
+ final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
+ final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
+ if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
+ && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
+ res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
+ "Package " + pkg.packageName + " new target SDK " + newTargetSdk
+ + " doesn't support runtime permissions but the old"
+ + " target SDK " + oldTargetSdk + " does.");
+ return;
+ }
+ }
}
PackageSetting ps = mSettings.mPackages.get(pkgName);
@@ -11666,6 +11703,13 @@
}
}
+ private boolean isSystemComponentOrPersistentPrivApp(PackageParser.Package pkg) {
+ return UserHandle.getAppId(pkg.applicationInfo.uid) < FIRST_APPLICATION_UID
+ || ((pkg.applicationInfo.privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0
+ && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0);
+ }
+
private static boolean isMultiArch(PackageSetting ps) {
return (ps.pkgFlags & ApplicationInfo.FLAG_MULTIARCH) != 0;
}
@@ -13012,7 +13056,7 @@
ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
try {
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(dataStream, "utf-8");
+ serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.startTag(null, TAG_PREFERRED_BACKUP);
@@ -13041,7 +13085,7 @@
try {
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(new ByteArrayInputStream(backup), null);
+ parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -13442,6 +13486,7 @@
storage.registerListener(mStorageListener);
mInstallerService.systemReady();
+ mPackageDexOptimizer.systemReady();
}
@Override
@@ -13823,7 +13868,7 @@
BufferedOutputStream str = new BufferedOutputStream(fout);
XmlSerializer serializer = new FastXmlSerializer();
try {
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index 171a50d..8942325 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -49,14 +49,14 @@
*/
public final class PermissionsState {
+ /** The permission operation failed. */
+ public static final int PERMISSION_OPERATION_FAILURE = -1;
+
/** The permission operation succeeded and no gids changed. */
- public static final int PERMISSION_OPERATION_SUCCESS = 1;
+ public static final int PERMISSION_OPERATION_SUCCESS = 0;
/** The permission operation succeeded and gids changed. */
- public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 2;
-
- /** The permission operation failed. */
- public static final int PERMISSION_OPERATION_FAILURE = 3;
+ public static final int PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED = 1;
private static final int[] NO_GIDS = {};
@@ -167,8 +167,6 @@
* @return The operation result which is either {@link #PERMISSION_OPERATION_SUCCESS},
* or {@link #PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED}, or {@link
* #PERMISSION_OPERATION_FAILURE}.
- *
- * @see android.content.pm.PackageManager.PermissionFlags
*/
public int revokeRuntimePermission(BasePermission permission, int userId) {
enforceValidUserId(userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 2e9656a..76ef19f 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -94,6 +94,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -1346,7 +1347,7 @@
str = new FileInputStream(userPackagesStateFile);
}
final XmlPullParser parser = Xml.newPullParser();
- parser.setInput(str, null);
+ parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
while ((type=parser.next()) != XmlPullParser.START_TAG
@@ -1598,7 +1599,7 @@
final BufferedOutputStream str = new BufferedOutputStream(fstr);
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -1922,7 +1923,7 @@
//XmlSerializer serializer = XmlUtils.serializerInstance();
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(str, "utf-8");
+ serializer.setOutput(str, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -2339,7 +2340,7 @@
str = new FileInputStream(mSettingsFilename);
}
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(str, null);
+ parser.setInput(str, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -4288,7 +4289,7 @@
out = destination.startWrite();
XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(out, "utf-8");
+ serializer.setOutput(out, StandardCharsets.UTF_8.name());
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument(null, true);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index e463fad..40c8ca3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -70,6 +70,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -670,7 +671,7 @@
try {
fis = userListFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -823,7 +824,7 @@
// XmlSerializer serializer = XmlUtils.serializerInstance();
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -882,7 +883,7 @@
// XmlSerializer serializer = XmlUtils.serializerInstance();
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
@@ -964,7 +965,7 @@
new AtomicFile(new File(mUsersDir, Integer.toString(id) + XML_SUFFIX));
fis = userFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -1569,7 +1570,7 @@
try {
fis = restrictionsFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
XmlUtils.nextElement(parser);
if (parser.getEventType() != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read restrictions file "
@@ -1658,7 +1659,7 @@
final BufferedOutputStream bos = new BufferedOutputStream(fos);
final XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(bos, "utf-8");
+ serializer.setOutput(bos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
diff --git a/services/core/java/com/android/server/tv/PersistentDataStore.java b/services/core/java/com/android/server/tv/PersistentDataStore.java
index fcfaaea..f9b5b9a 100644
--- a/services/core/java/com/android/server/tv/PersistentDataStore.java
+++ b/services/core/java/com/android/server/tv/PersistentDataStore.java
@@ -44,6 +44,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -167,7 +168,7 @@
XmlPullParser parser;
try {
parser = Xml.newPullParser();
- parser.setInput(new BufferedInputStream(is), null);
+ parser.setInput(new BufferedInputStream(is), StandardCharsets.UTF_8.name());
loadFromXml(parser);
} catch (IOException | XmlPullParserException ex) {
Slog.w(TAG, "Failed to load tv input manager persistent store data.", ex);
@@ -200,7 +201,7 @@
boolean success = false;
try {
XmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(new BufferedOutputStream(os), "utf-8");
+ serializer.setOutput(new BufferedOutputStream(os), StandardCharsets.UTF_8.name());
saveToXml(serializer);
serializer.flush();
success = true;
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e649e48..a869c20 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -39,6 +39,7 @@
import android.graphics.Rect;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.tv.DvbDeviceInfo;
import android.media.tv.ITvInputClient;
import android.media.tv.ITvInputHardware;
import android.media.tv.ITvInputHardwareCallback;
@@ -64,6 +65,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -80,23 +82,34 @@
import org.xmlpull.v1.XmlPullParserException;
+import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.IllegalArgumentException;
+import java.lang.Integer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/** This class provides a system service that manages television inputs. */
public final class TvInputManagerService extends SystemService {
private static final boolean DEBUG = false;
private static final String TAG = "TvInputManagerService";
+ // Pattern for selecting the DVB frontend devices from the list of files in the /dev directory.
+ private static final Pattern sFrontEndDevicePattern =
+ Pattern.compile("^dvb([0-9]+)\\.frontend([0-9]+)$");
+
private final Context mContext;
private final TvInputHardwareManager mTvInputHardwareManager;
@@ -1507,6 +1520,74 @@
}
@Override
+ public List<DvbDeviceInfo> getDvbDeviceList() throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ ArrayList<DvbDeviceInfo> deviceInfos = new ArrayList<>();
+ File devDirectory = new File("/dev");
+ for (String fileName : devDirectory.list()) {
+ Matcher matcher = sFrontEndDevicePattern.matcher(fileName);
+ if (matcher.find()) {
+ int adapterId = Integer.parseInt(matcher.group(1));
+ int deviceId = Integer.parseInt(matcher.group(2));
+ deviceInfos.add(new DvbDeviceInfo(adapterId, deviceId));
+ }
+ }
+ return Collections.unmodifiableList(deviceInfos);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public ParcelFileDescriptor openDvbDevice(DvbDeviceInfo info, int device)
+ throws RemoteException {
+ if (mContext.checkCallingPermission(android.Manifest.permission.DVB_DEVICE)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires DVB_DEVICE permission");
+ }
+
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ String deviceFileName;
+ switch (device) {
+ case TvInputManager.DVB_DEVICE_DEMUX:
+ deviceFileName = String.format("/dev/dvb%d.demux%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_DVR:
+ deviceFileName = String.format("/dev/dvb%d.dvr%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ case TvInputManager.DVB_DEVICE_FRONTEND:
+ deviceFileName = String.format("/dev/dvb%d.frontend%d", info.getAdapterId(),
+ info.getDeviceId());
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid DVB device: " + device);
+ }
+ try {
+ // The DVB frontend device only needs to be opened in read/write mode, which
+ // allows performing tuning operations. The DVB demux and DVR device are enough
+ // to be opened in read only mode.
+ return ParcelFileDescriptor.open(new File(deviceFileName),
+ TvInputManager.DVB_DEVICE_FRONTEND == device
+ ? ParcelFileDescriptor.MODE_READ_WRITE
+ : ParcelFileDescriptor.MODE_READ_ONLY);
+ } catch (FileNotFoundException e) {
+ return null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId, int userId)
throws RemoteException {
if (mContext.checkCallingPermission(
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 755c414..7784884 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -79,6 +79,7 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
@@ -589,12 +590,7 @@
void switchUser(int userId, IRemoteCallback reply) {
synchronized (mLock) {
mCurrentUserId = userId;
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- wallpaper = new WallpaperData(userId);
- mWallpaperMap.put(userId, wallpaper);
- loadSettingsLocked(userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
// Not started watching yet, in case wallpaper data was loaded for other reasons.
if (wallpaper.wallpaperObserver == null) {
wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
@@ -717,10 +713,7 @@
}
synchronized (mLock) {
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("width and height must be > 0");
}
@@ -782,10 +775,7 @@
}
synchronized (mLock) {
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
if (padding.left < 0 || padding.top < 0 || padding.right < 0 || padding.bottom < 0) {
throw new IllegalArgumentException("padding must be positive: " + padding);
}
@@ -866,10 +856,7 @@
synchronized (mLock) {
if (DEBUG) Slog.v(TAG, "setWallpaper");
int userId = UserHandle.getCallingUserId();
- WallpaperData wallpaper = mWallpaperMap.get(userId);
- if (wallpaper == null) {
- throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
- }
+ WallpaperData wallpaper = getWallpaperSafeLocked(userId);
final long ident = Binder.clearCallingIdentity();
try {
ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
@@ -1165,7 +1152,7 @@
try {
stream = new FileOutputStream(journal.chooseForWrite(), false);
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "wp");
@@ -1229,6 +1216,22 @@
return Integer.parseInt(value);
}
+ /**
+ * Sometimes it is expected the wallpaper map may not have a user's data. E.g. This could
+ * happen during user switch. The async user switch observer may not have received
+ * the event yet. We use this safe method when we don't care about this ordering and just
+ * want to update the data. The data is going to be applied when the user switch observer
+ * is eventually executed.
+ */
+ private WallpaperData getWallpaperSafeLocked(int userId) {
+ WallpaperData wallpaper = mWallpaperMap.get(userId);
+ if (wallpaper == null) {
+ loadSettingsLocked(userId);
+ wallpaper = mWallpaperMap.get(userId);
+ }
+ return wallpaper;
+ }
+
private void loadSettingsLocked(int userId) {
if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
@@ -1248,7 +1251,7 @@
try {
stream = new FileInputStream(file);
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
do {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 9033c9c..0357de2 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -289,11 +289,13 @@
return mNextAppTransitionStartY;
}
- void prepare() {
+ boolean prepare() {
if (!isRunning()) {
mAppTransitionState = APP_STATE_IDLE;
notifyAppTransitionPendingLocked();
+ return true;
}
+ return false;
}
void goodToGo(AppWindowAnimator openingAppAnimator, AppWindowAnimator closingAppAnimator) {
@@ -953,8 +955,8 @@
: com.android.internal.R.anim.voice_activity_open_exit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation voice:"
- + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " transit=" + appTransitionToString(transit)
+ + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
} else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE
|| transit == TRANSIT_TASK_CLOSE
|| transit == TRANSIT_TASK_TO_BACK)) {
@@ -963,22 +965,23 @@
: com.android.internal.R.anim.voice_activity_close_exit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation voice:"
- + " anim=" + a + " transit=" + transit + " isEntrance=" + enter
- + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " transit=" + appTransitionToString(transit)
+ + " isEntrance=" + enter + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
a = loadAnimationRes(mNextAppTransitionPackage, enter ?
mNextAppTransitionEnter : mNextAppTransitionExit);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM"
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE) {
a = loadAnimationRes(mNextAppTransitionPackage, mNextAppTransitionInPlace);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
- + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
- + " transit=" + transit + " Callers=" + Debug.getCallers(3));
+ + " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
+ + " transit=" + appTransitionToString(transit)
+ + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
a = createClipRevealAnimationLocked(transit, enter, appFrame);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
@@ -990,7 +993,7 @@
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP ||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
@@ -1003,7 +1006,7 @@
"ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
Slog.v(TAG, "applyAnimation:"
+ " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP ||
@@ -1018,7 +1021,7 @@
"ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
Slog.v(TAG, "applyAnimation:"
+ " anim=" + a + " nextAppTransition=" + animName
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
} else {
@@ -1084,7 +1087,7 @@
"applyAnimation:"
+ " anim=" + a
+ " animAttr=0x" + Integer.toHexString(animAttr)
- + " transit=" + transit + " isEntrance=" + enter
+ + " transit=" + appTransitionToString(transit) + " isEntrance=" + enter
+ " Callers=" + Debug.getCallers(3));
}
return a;
@@ -1188,7 +1191,7 @@
@Override
public String toString() {
- return "mNextAppTransition=0x" + Integer.toHexString(mNextAppTransition);
+ return "mNextAppTransition=" + appTransitionToString(mNextAppTransition);
}
/**
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index 55ec9fc..3feec82 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -16,6 +16,11 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+
import android.graphics.Matrix;
import android.util.Slog;
import android.util.TimeUtils;
@@ -36,6 +41,7 @@
final WindowAnimator mAnimator;
boolean animating;
+ boolean wasAnimating;
Animation animation;
boolean hasTransformation;
final Transformation transformation = new Transformation();
@@ -77,7 +83,11 @@
boolean deferFinalFrameCleanup;
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
- ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
+ ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<>();
+
+ /** True if the current animation was transferred from another AppWindowAnimator.
+ * See {@link #transferCurrentAnimation}*/
+ boolean usingTransferredAnimation = false;
static final Animation sDummyAnimation = new DummyAnimation();
@@ -101,9 +111,9 @@
int zorder = anim.getZAdjustment();
int adj = 0;
if (zorder == Animation.ZORDER_TOP) {
- adj = WindowManagerService.TYPE_LAYER_OFFSET;
+ adj = TYPE_LAYER_OFFSET;
} else if (zorder == Animation.ZORDER_BOTTOM) {
- adj = -WindowManagerService.TYPE_LAYER_OFFSET;
+ adj = -TYPE_LAYER_OFFSET;
}
if (animLayerAdjustment != adj) {
@@ -139,6 +149,7 @@
mAppToken.allDrawn = false;
mAppToken.deferClearAllDrawn = false;
}
+ usingTransferredAnimation = false;
}
public boolean isAnimating() {
@@ -153,19 +164,38 @@
deferThumbnailDestruction = false;
}
+ void transferCurrentAnimation(
+ AppWindowAnimator toAppAnimator, WindowStateAnimator transferWinAnimator) {
+
+ if (animation != null) {
+ toAppAnimator.animation = animation;
+ animation = null;
+ toAppAnimator.animating = animating;
+ toAppAnimator.animLayerAdjustment = animLayerAdjustment;
+ animLayerAdjustment = 0;
+ toAppAnimator.updateLayers();
+ updateLayers();
+ toAppAnimator.usingTransferredAnimation = true;
+ }
+ if (transferWinAnimator != null) {
+ mAllAppWinAnimators.remove(transferWinAnimator);
+ toAppAnimator.mAllAppWinAnimators.add(transferWinAnimator);
+ transferWinAnimator.mAppAnimator = toAppAnimator;
+ }
+ }
+
void updateLayers() {
- final int N = mAppToken.allAppWindows.size();
+ final int windowCount = mAppToken.allAppWindows.size();
final int adj = animLayerAdjustment;
thumbnailLayer = -1;
- for (int i=0; i<N; i++) {
+ for (int i = 0; i < windowCount; i++) {
final WindowState w = mAppToken.allAppWindows.get(i);
final WindowStateAnimator winAnimator = w.mWinAnimator;
winAnimator.mAnimLayer = w.mLayer + adj;
if (winAnimator.mAnimLayer > thumbnailLayer) {
thumbnailLayer = winAnimator.mAnimLayer;
}
- if (WindowManagerService.DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": "
- + winAnimator.mAnimLayer);
+ if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
mService.setInputMethodAnimLayerAdjustment(adj);
}
@@ -190,11 +220,11 @@
// cache often used attributes locally
final float tmpFloats[] = mService.mTmpFloats;
thumbnailTransformation.getMatrix().getValues(tmpFloats);
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
+ if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "POS " + tmpFloats[Matrix.MTRANS_X]
+ ", " + tmpFloats[Matrix.MTRANS_Y], null);
thumbnail.setPosition(tmpFloats[Matrix.MTRANS_X], tmpFloats[Matrix.MTRANS_Y]);
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
+ if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(thumbnail,
"thumbnail", "alpha=" + thumbnailTransformation.getAlpha()
+ " layer=" + thumbnailLayer
+ " matrix=[" + tmpFloats[Matrix.MSCALE_X]
@@ -227,14 +257,14 @@
deferFinalFrameCleanup = true;
hasMoreFrames = true;
} else {
- if (false && WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
- ", xform=" + transformation);
+ if (false && DEBUG_ANIM) Slog.v(TAG,
+ "Stepped animation in " + mAppToken + ": more=" + hasMoreFrames +
+ ", xform=" + transformation);
deferFinalFrameCleanup = false;
animation = null;
clearThumbnail();
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Finished animation in " + mAppToken + " @ " + currentTime);
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Finished animation in " + mAppToken + " @ " + currentTime);
}
}
hasTransformation = hasMoreFrames;
@@ -257,8 +287,8 @@
if ((mAppToken.allDrawn || animating || mAppToken.startingDisplayed)
&& animation != null) {
if (!animating) {
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Starting animation in " + mAppToken +
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Starting animation in " + mAppToken +
" @ " + currentTime + " scale="
+ mService.getTransitionAnimationScaleLocked()
+ " allDrawn=" + mAppToken.allDrawn + " animating=" + animating);
@@ -305,8 +335,8 @@
mService.moveInputMethodWindowsIfNeededLocked(true);
}
- if (WindowManagerService.DEBUG_ANIM) Slog.v(
- TAG, "Animation done in " + mAppToken
+ if (DEBUG_ANIM) Slog.v(TAG,
+ "Animation done in " + mAppToken
+ ": reportedVisible=" + mAppToken.reportedVisible);
transformation.clear();
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index ba995f2..01f878c 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -32,6 +32,7 @@
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
/**
@@ -108,7 +109,7 @@
boolean success = false;
try {
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
@@ -193,7 +194,7 @@
try {
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "display-settings");
diff --git a/services/core/java/com/android/server/wm/Watermark.java b/services/core/java/com/android/server/wm/Watermark.java
index ba3ce36..e226e3d 100644
--- a/services/core/java/com/android/server/wm/Watermark.java
+++ b/services/core/java/com/android/server/wm/Watermark.java
@@ -84,7 +84,7 @@
int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
TypedValue.COMPLEX_UNIT_DIP, 20, dm);
- mTextPaint = new Paint();
+ mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(fontSize);
mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 52071cc..9169351 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -30,9 +30,9 @@
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
import android.content.Context;
+import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.view.Display;
import android.view.SurfaceControl;
@@ -98,15 +98,13 @@
// forceHiding states.
static final int KEYGUARD_NOT_SHOWN = 0;
- static final int KEYGUARD_ANIMATING_IN = 1;
- static final int KEYGUARD_SHOWN = 2;
- static final int KEYGUARD_ANIMATING_OUT = 3;
+ static final int KEYGUARD_SHOWN = 1;
+ static final int KEYGUARD_ANIMATING_OUT = 2;
int mForceHiding = KEYGUARD_NOT_SHOWN;
private String forceHidingToString() {
switch (mForceHiding) {
case KEYGUARD_NOT_SHOWN: return "KEYGUARD_NOT_SHOWN";
- case KEYGUARD_ANIMATING_IN: return "KEYGUARD_ANIMATING_IN";
case KEYGUARD_SHOWN: return "KEYGUARD_SHOWN";
case KEYGUARD_ANIMATING_OUT:return "KEYGUARD_ANIMATING_OUT";
default: return "KEYGUARD STATE UNKNOWN " + mForceHiding;
@@ -157,11 +155,11 @@
final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator;
- final boolean wasAnimating = appAnimator.animation != null
- && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
+ appAnimator.wasAnimating = appAnimator.animating;
if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
+ appAnimator.animating = true;
mAnimating = mAppWindowAnimating = true;
- } else if (wasAnimating) {
+ } else if (appAnimator.wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator,
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
@@ -173,14 +171,13 @@
}
final AppTokenList exitingAppTokens = stack.mExitingAppTokens;
- final int NEAT = exitingAppTokens.size();
- for (int i = 0; i < NEAT; i++) {
+ final int exitingCount = exitingAppTokens.size();
+ for (int i = 0; i < exitingCount; i++) {
final AppWindowAnimator appAnimator = exitingAppTokens.get(i).mAppAnimator;
- final boolean wasAnimating = appAnimator.animation != null
- && appAnimator.animation != AppWindowAnimator.sDummyAnimation;
+ appAnimator.wasAnimating = appAnimator.animating;
if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) {
mAnimating = mAppWindowAnimating = true;
- } else if (wasAnimating) {
+ } else if (appAnimator.wasAnimating) {
// stopped animating, do one more pass through the layout
setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER,
"exiting appToken " + appAnimator.mAppToken + " done", displayId);
@@ -206,9 +203,7 @@
|| (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw()
// Show error dialogs over apps that dismiss keyguard.
|| (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0)));
- return ((mForceHiding == KEYGUARD_ANIMATING_IN)
- && (!win.mWinAnimator.isAnimating() || hideWhenLocked))
- || ((mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked);
+ return (mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked;
}
private void updateWindowsLocked(final int displayId) {
@@ -259,8 +254,27 @@
if (winAnimator.mSurfaceControl != null) {
final boolean wasAnimating = winAnimator.mWasAnimating;
final boolean nowAnimating = winAnimator.stepAnimationLocked(mCurrentTime);
+ winAnimator.mWasAnimating = nowAnimating;
mAnimating |= nowAnimating;
+ boolean appWindowAnimating = winAnimator.mAppAnimator != null
+ && winAnimator.mAppAnimator.animating;
+ boolean wasAppWindowAnimating = winAnimator.mAppAnimator != null
+ && winAnimator.mAppAnimator.wasAnimating;
+ boolean anyAnimating = appWindowAnimating || nowAnimating;
+ boolean anyWasAnimating = wasAppWindowAnimating || wasAnimating;
+
+ try {
+ if (anyAnimating && !anyWasAnimating) {
+ win.mClient.onAnimationStarted(
+ winAnimator.mKeyguardGoingAwayAnimation ? 1 : 0);
+ } else if (!anyAnimating && anyWasAnimating) {
+ win.mClient.onAnimationStopped();
+ }
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to dispatch window animation state change.", e);
+ }
+
if (WindowManagerService.DEBUG_WALLPAPER) {
Slog.v(TAG, win + ": wasAnimating=" + wasAnimating +
", nowAnimating=" + nowAnimating);
@@ -297,11 +311,7 @@
}
if (win.isReadyForDisplay()) {
if (nowAnimating) {
- if (winAnimator.mAnimationIsEntrance) {
- mForceHiding = KEYGUARD_ANIMATING_IN;
- } else {
- mForceHiding = KEYGUARD_ANIMATING_OUT;
- }
+ mForceHiding = KEYGUARD_ANIMATING_OUT;
} else {
mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6bf68e8..4972ce4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,44 +16,13 @@
package com.android.server.wm;
-import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
-import static android.view.WindowManager.LayoutParams.*;
-
-import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import android.app.AppOpsManager;
-import android.os.Build;
-import android.os.SystemService;
-import android.util.ArraySet;
-import android.util.TimeUtils;
-import android.view.IWindowId;
-
-import android.view.IWindowSessionCallback;
-import android.view.WindowContentFrameStats;
-import com.android.internal.app.IAssistScreenshotReceiver;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.FastPrintWriter;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-import com.android.internal.view.IInputMethodManager;
-import com.android.internal.view.WindowManagerPolicyThread;
-import com.android.server.AttributeCache;
-import com.android.server.DisplayThread;
-import com.android.server.EventLogTags;
-import com.android.server.FgThread;
-import com.android.server.LocalServices;
-import com.android.server.UiThread;
-import com.android.server.Watchdog;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.input.InputManagerService;
-import com.android.server.power.ShutdownThread;
-import com.android.server.policy.PhoneWindowManager;
-
import android.Manifest;
+import android.animation.ValueAnimator;
import android.app.ActivityManagerNative;
+import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.app.admin.DevicePolicyManager;
-import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
@@ -75,6 +44,7 @@
import android.hardware.display.DisplayManagerInternal;
import android.net.Uri;
import android.os.Binder;
+import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
@@ -92,17 +62,20 @@
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.os.SystemService;
import android.os.Trace;
import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
+import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
-import android.util.SparseArray;
import android.util.Pair;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
+import android.util.TimeUtils;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
@@ -113,8 +86,10 @@
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
import android.view.IWindow;
+import android.view.IWindowId;
import android.view.IWindowManager;
import android.view.IWindowSession;
+import android.view.IWindowSessionCallback;
import android.view.InputChannel;
import android.view.InputDevice;
import android.view.InputEvent;
@@ -122,21 +97,41 @@
import android.view.KeyEvent;
import android.view.MagnificationSpec;
import android.view.MotionEvent;
-import android.view.WindowManagerInternal;
-import android.view.Surface.OutOfResourcesException;
import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
+import android.view.WindowContentFrameStats;
import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerGlobal;
+import android.view.WindowManagerInternal;
+import android.view.WindowManagerPolicy;
import android.view.WindowManagerPolicy.FakeWindow;
import android.view.WindowManagerPolicy.PointerEventListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.FastPrintWriter;
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
+import com.android.internal.view.IInputMethodManager;
+import com.android.internal.view.WindowManagerPolicyThread;
+import com.android.server.AttributeCache;
+import com.android.server.DisplayThread;
+import com.android.server.EventLogTags;
+import com.android.server.FgThread;
+import com.android.server.LocalServices;
+import com.android.server.UiThread;
+import com.android.server.Watchdog;
+import com.android.server.am.BatteryStatsService;
+import com.android.server.input.InputManagerService;
+import com.android.server.policy.PhoneWindowManager;
+import com.android.server.power.ShutdownThread;
+
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
@@ -157,6 +152,41 @@
import java.util.Iterator;
import java.util.List;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
+import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
+
/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub
implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
@@ -426,12 +456,6 @@
Runnable mWaitingForDrawnCallback;
/**
- * Windows that have called relayout() while we were running animations,
- * so we need to tell when the animation is done.
- */
- final ArrayList<WindowState> mRelayoutWhileAnimating = new ArrayList<WindowState>();
-
- /**
* Used when rebuilding window list to keep track of windows that have
* been removed.
*/
@@ -471,7 +495,7 @@
String mLastANRState;
/** All DisplayContents in the world, kept here */
- SparseArray<DisplayContent> mDisplayContents = new SparseArray<DisplayContent>(2);
+ SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
int mRotation = 0;
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -487,7 +511,7 @@
deathRecipient = d;
}
}
- ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>();
+ ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<>();
int mDeferredRotationPauseCount;
int mSystemDecorLayer = 0;
@@ -512,7 +536,10 @@
int mLayoutSeq = 0;
+ // Last systemUiVisibility we received from status bar.
int mLastStatusBarVisibility = 0;
+ // Last systemUiVisibility we dispatched to windows.
+ int mLastDispatchedSystemUiVisibility = 0;
// State while inside of layoutAndPlaceSurfacesLocked().
boolean mFocusMayChange;
@@ -525,11 +552,10 @@
private final PowerManager.WakeLock mScreenFrozenLock;
final AppTransition mAppTransition;
- boolean mStartingIconInTransition = false;
boolean mSkipAppTransitionAnimation = false;
- final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<AppWindowToken>();
- final ArraySet<AppWindowToken> mClosingApps = new ArraySet<AppWindowToken>();
+ final ArraySet<AppWindowToken> mOpeningApps = new ArraySet<>();
+ final ArraySet<AppWindowToken> mClosingApps = new ArraySet<>();
boolean mIsTouchDevice;
@@ -554,7 +580,7 @@
int mInputMethodAnimLayerAdjustment;
WindowState mInputMethodWindow = null;
- final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
+ final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<>();
/** Temporary list for comparison. Always clear this after use so we don't end up with
* orphaned windows references */
@@ -691,6 +717,8 @@
boolean mObscureApplicationContentOnSecondaryDisplays = false;
float mPreferredRefreshRate = 0;
+
+ int mPreferredModeId = 0;
}
final LayoutFields mInnerFields = new LayoutFields();
@@ -3335,10 +3363,6 @@
TAG, "Relayout of " + win + ": focusMayChange=" + focusMayChange);
inTouchMode = mInTouchMode;
- animating = mAnimator.mAnimating && win.mWinAnimator.isAnimating();
- if (animating && !mRelayoutWhileAnimating.contains(win)) {
- mRelayoutWhileAnimating.add(win);
- }
mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -3355,8 +3379,7 @@
return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
| (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
- | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
- | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
+ | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0);
}
public void performDeferredDestroyWindow(Session session, IWindow client) {
@@ -4122,8 +4145,8 @@
}
synchronized(mWindowMap) {
- if (DEBUG_APP_TRANSITIONS) Slog.v(
- TAG, "Prepare app transition: transit=" + transit
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Prepare app transition:"
+ + " transit=" + AppTransition.appTransitionToString(transit)
+ " " + mAppTransition
+ " alwaysKeepCurrent=" + alwaysKeepCurrent
+ " Callers=" + Debug.getCallers(3));
@@ -4142,9 +4165,7 @@
mAppTransition.setAppTransition(transit);
}
}
- if (okToDisplay()) {
- mAppTransition.prepare();
- mStartingIconInTransition = false;
+ if (okToDisplay() && mAppTransition.prepare()) {
mSkipAppTransitionAnimation = false;
}
if (mAppTransition.isTransitionSet()) {
@@ -4271,19 +4292,16 @@
if (ttoken != null) {
WindowState startingWindow = ttoken.startingWindow;
if (startingWindow != null) {
- if (mStartingIconInTransition) {
- // In this case, the starting icon has already
- // been displayed, so start letting windows get
- // shown immediately without any more transitions.
- mSkipAppTransitionAnimation = true;
- }
+ // In this case, the starting icon has already been displayed, so start
+ // letting windows get shown immediately without any more transitions.
+ mSkipAppTransitionAnimation = true;
+
if (DEBUG_STARTING_WINDOW) Slog.v(TAG,
"Moving existing starting " + startingWindow + " from " + ttoken
+ " to " + wtoken);
final long origId = Binder.clearCallingIdentity();
- // Transfer the starting window over to the new
- // token.
+ // Transfer the starting window over to the new token.
wtoken.startingData = ttoken.startingData;
wtoken.startingView = ttoken.startingView;
wtoken.startingDisplayed = ttoken.startingDisplayed;
@@ -4297,7 +4315,6 @@
startingWindow.mToken = wtoken;
startingWindow.mRootToken = wtoken;
startingWindow.mAppToken = wtoken;
- startingWindow.mWinAnimator.mAppAnimator = wtoken.mAppAnimator;
if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
Slog.v(TAG, "Removing starting window: " + startingWindow);
@@ -4331,17 +4348,8 @@
wtoken.clientHidden = ttoken.clientHidden;
wtoken.sendAppVisibilityToClients();
}
- final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
- final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
- if (tAppAnimator.animation != null) {
- wAppAnimator.animation = tAppAnimator.animation;
- wAppAnimator.animating = tAppAnimator.animating;
- wAppAnimator.animLayerAdjustment = tAppAnimator.animLayerAdjustment;
- tAppAnimator.animation = null;
- tAppAnimator.animLayerAdjustment = 0;
- wAppAnimator.updateLayers();
- tAppAnimator.updateLayers();
- }
+ ttoken.mAppAnimator.transferCurrentAnimation(
+ wtoken.mAppAnimator, startingWindow.mWinAnimator);
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
true /*updateInputWindows*/);
@@ -4441,7 +4449,6 @@
}
if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Creating StartingData");
- mStartingIconInTransition = true;
wtoken.startingData = new StartingData(pkg, theme, compatInfo, nonLocalizedLabel,
labelRes, icon, logo, windowFlags);
Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
@@ -4542,8 +4549,8 @@
changed = true;
}
- final int N = wtoken.allAppWindows.size();
- for (int i=0; i<N; i++) {
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int i = 0; i < windowsCount; i++) {
WindowState win = wtoken.allAppWindows.get(i);
if (win == wtoken.startingWindow) {
continue;
@@ -4672,7 +4679,7 @@
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
if (okToDisplay() && mAppTransition.isTransitionSet()) {
- if (!wtoken.startingDisplayed) {
+ if (!wtoken.startingDisplayed || mSkipAppTransitionAnimation) {
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Setting dummy animation on: " + wtoken);
wtoken.mAppAnimator.setDummyAnimation();
@@ -9154,14 +9161,14 @@
public int handleAppTransitionReadyLocked(WindowList windows) {
int changes = 0;
int i;
- int NN = mOpeningApps.size();
+ int appsCount = mOpeningApps.size();
boolean goodToGo = true;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "Checking " + NN + " opening apps (frozen="
+ "Checking " + appsCount + " opening apps (frozen="
+ mDisplayFrozen + " timeout="
+ mAppTransition.isTimeout() + ")...");
if (!mAppTransition.isTimeout()) {
- for (i=0; i<NN && goodToGo; i++) {
+ for (i = 0; i < appsCount && goodToGo; i++) {
AppWindowToken wtoken = mOpeningApps.valueAt(i);
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
"Check opening app=" + wtoken + ": allDrawn="
@@ -9214,7 +9221,6 @@
if (mSkipAppTransitionAnimation) {
transit = AppTransition.TRANSIT_UNSET;
}
- mStartingIconInTransition = false;
mSkipAppTransitionAnimation = false;
mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
@@ -9263,17 +9269,17 @@
// (2) Find the layout params of the top-most
// application window in the tokens, which is
// what will control the animation theme.
- final int NC = mClosingApps.size();
- NN = NC + mOpeningApps.size();
- for (i=0; i<NN; i++) {
+ final int closingAppsCount = mClosingApps.size();
+ appsCount = closingAppsCount + mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
final AppWindowToken wtoken;
- if (i < NC) {
+ if (i < closingAppsCount) {
wtoken = mClosingApps.valueAt(i);
if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
closingAppHasWallpaper = true;
}
} else {
- wtoken = mOpeningApps.valueAt(i - NC);
+ wtoken = mOpeningApps.valueAt(i - closingAppsCount);
if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
openingAppHasWallpaper = true;
}
@@ -9314,20 +9320,23 @@
transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
break;
}
- if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit: " + transit);
+ if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
+ "New transit: " + AppTransition.appTransitionToString(transit));
} else if ((oldWallpaper != null) && !mOpeningApps.isEmpty()
&& !mOpeningApps.contains(oldWallpaper.mAppToken)) {
// We are transitioning from an activity with
// a wallpaper to one without.
transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit away from wallpaper: " + transit);
+ "New transit away from wallpaper: "
+ + AppTransition.appTransitionToString(transit));
} else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
// We are transitioning from an activity without
// a wallpaper to now showing the wallpaper
transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
- "New transit into wallpaper: " + transit);
+ "New transit into wallpaper: "
+ + AppTransition.appTransitionToString(transit));
} else {
mAnimateWallpaperWithTarget = true;
}
@@ -9371,21 +9380,24 @@
}
}
- NN = mOpeningApps.size();
- for (i=0; i<NN; i++) {
+ appsCount = mOpeningApps.size();
+ for (i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mOpeningApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
- appAnimator.clearThumbnail();
- appAnimator.animation = null;
+
+ if (!appAnimator.usingTransferredAnimation) {
+ appAnimator.clearThumbnail();
+ appAnimator.animation = null;
+ }
wtoken.inPendingTransaction = false;
setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
appAnimator.mAllAppWinAnimators.clear();
- final int N = wtoken.allAppWindows.size();
- for (int j = 0; j < N; j++) {
+ final int windowsCount = wtoken.allAppWindows.size();
+ for (int j = 0; j < windowsCount; j++) {
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
}
mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
@@ -9393,7 +9405,7 @@
if (animLp != null) {
int layer = -1;
- for (int j=0; j<wtoken.windows.size(); j++) {
+ for (int j = 0; j < wtoken.windows.size(); j++) {
WindowState win = wtoken.windows.get(j);
if (win.mWinAnimator.mAnimLayer > layer) {
layer = win.mWinAnimator.mAnimLayer;
@@ -9405,8 +9417,8 @@
}
}
}
- NN = mClosingApps.size();
- for (i=0; i<NN; i++) {
+ appsCount = mClosingApps.size();
+ for (i = 0; i < appsCount; i++) {
AppWindowToken wtoken = mClosingApps.valueAt(i);
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
@@ -9430,7 +9442,7 @@
if (animLp != null) {
int layer = -1;
- for (int j=0; j<wtoken.windows.size(); j++) {
+ for (int j = 0; j < wtoken.windows.size(); j++) {
WindowState win = wtoken.windows.get(j);
if (win.mWinAnimator.mAnimLayer > layer) {
layer = win.mWinAnimator.mAnimLayer;
@@ -9713,6 +9725,10 @@
&& w.mAttrs.preferredRefreshRate != 0) {
mInnerFields.mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
}
+ if (mInnerFields.mPreferredModeId == 0
+ && w.mAttrs.preferredDisplayModeId != 0) {
+ mInnerFields.mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+ }
}
}
}
@@ -9846,6 +9862,7 @@
// Reset for each display.
mInnerFields.mDisplayHasContent = false;
mInnerFields.mPreferredRefreshRate = 0;
+ mInnerFields.mPreferredModeId = 0;
int repeats = 0;
do {
@@ -10066,6 +10083,7 @@
mDisplayManagerInternal.setDisplayProperties(displayId,
mInnerFields.mDisplayHasContent, mInnerFields.mPreferredRefreshRate,
+ mInnerFields.mPreferredModeId,
true /* inTraversal, must call performTraversalInTrans... below */);
getDisplayContentLocked(displayId).stopDimmingIfNeeded();
@@ -10228,16 +10246,6 @@
}
}
- if (!mAnimator.mAnimating && mRelayoutWhileAnimating.size() > 0) {
- for (int j=mRelayoutWhileAnimating.size()-1; j>=0; j--) {
- try {
- mRelayoutWhileAnimating.get(j).mClient.doneAnimating();
- } catch (RemoteException e) {
- }
- }
- mRelayoutWhileAnimating.clear();
- }
-
if (wallpaperDestroyed) {
defaultDisplay.pendingLayoutChanges |=
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -10947,6 +10955,10 @@
// TOOD(multidisplay): StatusBar on multiple screens?
void updateStatusBarVisibilityLocked(int visibility) {
+ if (mLastDispatchedSystemUiVisibility == visibility) {
+ return;
+ }
+ mLastDispatchedSystemUiVisibility = visibility;
mInputManager.setSystemUiVisibility(visibility);
final WindowList windows = getDefaultWindowListLocked();
final int N = windows.size();
@@ -11383,8 +11395,7 @@
pw.print(" transition="); pw.print(mTransitionAnimationScaleSetting);
pw.print(" animator="); pw.println(mAnimatorDurationScaleSetting);
pw.print(" mTraversalScheduled="); pw.println(mTraversalScheduled);
- pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
- pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
+ pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
mAppTransition.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index d6726c1..ec89b37 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -276,9 +276,6 @@
// This must be called while inside a transaction. Returns true if
// there is more animation to run.
boolean stepAnimationLocked(long currentTime) {
- // Save the animation state as it was before this step so WindowManagerService can tell if
- // we just started or just stopped animating by comparing mWasAnimating with isAnimating().
- mWasAnimating = mAnimating;
final DisplayContent displayContent = mWin.getDisplayContent();
if (displayContent != null && mService.okToDisplay()) {
// We will run animations as long as the display isn't frozen.
@@ -1218,6 +1215,10 @@
mDtDx = 0;
mDsDy = 0;
mDtDy = mWin.mGlobalScale;
+ if (appTransformation == null) {
+ mHasClipRect = false;
+ mClipRect.setEmpty();
+ }
}
}
@@ -1301,7 +1302,10 @@
clipRect.bottom += attrs.surfaceInsets.bottom;
// If we have an animated clip rect, intersect it with the clip rect.
- if (mHasClipRect) {
+ // However, the clip rect animation effect should be applied on app windows that inset
+ // decor only. If applying on non-inset decor one, the top region of this window will
+ // be clipped on the end of animation, e.g. dialog activities.
+ if (mHasClipRect && (w.mAttrs.flags & LayoutParams.FLAG_LAYOUT_INSET_DECOR) != 0) {
// NOTE: We are adding a temporary workaround due to the status bar
// not always reporting the correct system decor rect. In such
// cases, we take into account the specified content insets as well.
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
index 88bf54e..7bd27f2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -42,6 +42,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -116,9 +117,9 @@
/**
* Creates an instance of the device owner object with the device initializer set.
*/
- static DeviceOwner createWithDeviceInitializer(ComponentName admin, String ownerName) {
+ static DeviceOwner createWithDeviceInitializer(ComponentName admin) {
DeviceOwner owner = new DeviceOwner();
- owner.mDeviceInitializer = new OwnerInfo(ownerName, admin);
+ owner.mDeviceInitializer = new OwnerInfo(null, admin);
return owner;
}
@@ -155,12 +156,8 @@
return mDeviceInitializer != null ? mDeviceInitializer.packageName : null;
}
- String getDeviceInitializerName() {
- return mDeviceInitializer != null ? mDeviceInitializer.name : null;
- }
-
- void setDeviceInitializer(ComponentName admin, String ownerName) {
- mDeviceInitializer = new OwnerInfo(ownerName, admin);
+ void setDeviceInitializer(ComponentName admin) {
+ mDeviceInitializer = new OwnerInfo(null, admin);
}
void clearDeviceInitializer() {
@@ -242,7 +239,7 @@
try {
InputStream input = openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(input, null);
+ parser.setInput(input, StandardCharsets.UTF_8.name());
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type!=XmlPullParser.START_TAG) {
@@ -255,16 +252,15 @@
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
mDeviceOwner = new OwnerInfo(name, packageName);
} else if (tag.equals(TAG_DEVICE_INITIALIZER)) {
- String name = parser.getAttributeValue(null, ATTR_NAME);
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE);
String initializerComponentStr =
parser.getAttributeValue(null, ATTR_COMPONENT_NAME);
ComponentName admin =
ComponentName.unflattenFromString(initializerComponentStr);
if (admin != null) {
- mDeviceInitializer = new OwnerInfo(name, admin);
+ mDeviceInitializer = new OwnerInfo(null, admin);
} else {
- mDeviceInitializer = new OwnerInfo(name, packageName);
+ mDeviceInitializer = new OwnerInfo(null, packageName);
Slog.e(TAG, "Error parsing device-owner file. Bad component name " +
initializerComponentStr);
}
@@ -317,7 +313,7 @@
try {
OutputStream outputStream = startWrite();
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(outputStream, "utf-8");
+ out.setOutput(outputStream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
// Write device owner tag
@@ -334,9 +330,6 @@
if (mDeviceInitializer != null) {
out.startTag(null, TAG_DEVICE_INITIALIZER);
out.attribute(null, ATTR_PACKAGE, mDeviceInitializer.packageName);
- if (mDeviceInitializer.name != null) {
- out.attribute(null, ATTR_NAME, mDeviceInitializer.name);
- }
if (mDeviceInitializer.admin != null) {
out.attribute(
null, ATTR_COMPONENT_NAME, mDeviceInitializer.admin.flattenToString());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index ba5d666..9ad7e11 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -133,6 +133,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -246,6 +247,17 @@
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
}
+ // Keyguard features that when set of a profile will affect the profiles
+ // parent user.
+ private static final int PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER =
+ DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS
+ | DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
+
+ // Keyguard features that are allowed to be set on a managed profile
+ private static final int PROFILE_KEYGUARD_FEATURES =
+ PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER
+ | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+
final Context mContext;
final UserManager mUserManager;
final PowerManager.WakeLock mWakeLock;
@@ -1403,7 +1415,7 @@
try {
stream = new FileOutputStream(journal.chooseForWrite(), false);
XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
+ out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "policies");
@@ -1526,7 +1538,7 @@
try {
stream = new FileInputStream(file);
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -3187,8 +3199,8 @@
}
@Override
- public void choosePrivateKeyAlias(final int uid, final String host, int port, final String url,
- final String alias, final IBinder response) {
+ public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias,
+ final IBinder response) {
// Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers.
if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID) {
return;
@@ -3205,9 +3217,7 @@
Intent intent = new Intent(DeviceAdminReceiver.ACTION_CHOOSE_PRIVATE_KEY_ALIAS);
intent.setComponent(profileOwner);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_SENDER_UID, uid);
- intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_HOST, host);
- intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_PORT, port);
- intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URL, url);
+ intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_URI, uri);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_ALIAS, alias);
intent.putExtra(DeviceAdminReceiver.EXTRA_CHOOSE_PRIVATE_KEY_RESPONSE, response);
@@ -3957,7 +3967,9 @@
}
Preconditions.checkNotNull(who, "ComponentName is null");
final int userHandle = UserHandle.getCallingUserId();
- enforceNotManagedProfile(userHandle, "disable keyguard features");
+ if (isManagedProfile(userHandle)) {
+ which = which & PROFILE_KEYGUARD_FEATURES;
+ }
synchronized (this) {
ActiveAdmin ap = getActiveAdminForCallerLocked(who,
DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
@@ -3978,21 +3990,50 @@
return 0;
}
enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return (admin != null) ? admin.disabledKeyguardFeatures : 0;
- }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ if (who != null) {
+ ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
+ return (admin != null) ? admin.disabledKeyguardFeatures : 0;
+ }
- // Determine which keyguard features are disabled for any active admins.
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- int which = 0;
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- which |= admin.disabledKeyguardFeatures;
+ UserInfo user = mUserManager.getUserInfo(userHandle);
+ final List<UserInfo> profiles;
+ if (user.isManagedProfile()) {
+ // If we are being asked about a managed profile just return
+ // keyguard features disabled by admins in the profile.
+ profiles = new ArrayList<UserInfo>(1);
+ profiles.add(user);
+ } else {
+ // Otherwise return those set by admins in the user
+ // and its profiles.
+ profiles = mUserManager.getProfiles(userHandle);
+ }
+
+ // Determine which keyguard features are disabled by any active admin.
+ int which = 0;
+ for (UserInfo userInfo : profiles) {
+ DevicePolicyData policy = getUserData(userInfo.id);
+ final int N = policy.mAdminList.size();
+ for (int i = 0; i < N; i++) {
+ ActiveAdmin admin = policy.mAdminList.get(i);
+ if (userInfo.id == userHandle || !userInfo.isManagedProfile()) {
+ // If we are being asked explictly about this user
+ // return all disabled features even if its a managed profile.
+ which |= admin.disabledKeyguardFeatures;
+ } else {
+ // Otherwise a managed profile is only allowed to disable
+ // some features on the parent user.
+ which |= (admin.disabledKeyguardFeatures
+ & PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER);
+ }
+ }
+ }
+ return which;
}
- return which;
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
@@ -4122,8 +4163,7 @@
}
@Override
- public boolean setDeviceInitializer(ComponentName who, ComponentName initializer,
- String ownerName) {
+ public boolean setDeviceInitializer(ComponentName who, ComponentName initializer) {
if (!mHasFeature) {
return false;
}
@@ -4142,10 +4182,10 @@
if (mDeviceOwner == null) {
// Device owner state does not exist, create it.
- mDeviceOwner = DeviceOwner.createWithDeviceInitializer(initializer, ownerName);
+ mDeviceOwner = DeviceOwner.createWithDeviceInitializer(initializer);
} else {
// Device owner already exists, update it.
- mDeviceOwner.setDeviceInitializer(initializer, ownerName);
+ mDeviceOwner.setDeviceInitializer(initializer);
}
addDeviceInitializerToLockTaskPackagesLocked(UserHandle.USER_OWNER);
@@ -5362,7 +5402,7 @@
} else if (UserManager.DISALLOW_USB_FILE_TRANSFER.equals(key)) {
UsbManager manager =
(UsbManager) mContext.getSystemService(Context.USB_SERVICE);
- manager.setCurrentFunction("none", false);
+ manager.setCurrentFunction("none");
} else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF,
@@ -6305,10 +6345,16 @@
return;
}
+ ActivityInfo[] receivers = null;
try {
- ActivityInfo[] receivers = mContext.getPackageManager().getPackageInfo(
+ receivers = mContext.getPackageManager().getPackageInfo(
deviceOwnerPackage, PackageManager.GET_RECEIVERS).receivers;
- if (receivers != null) {
+ } catch (NameNotFoundException e) {
+ Log.e(LOG_TAG, "Cannot find device owner package", e);
+ }
+ if (receivers != null) {
+ long ident = Binder.clearCallingIdentity();
+ try {
for (int i = 0; i < receivers.length; i++) {
if (permission.BIND_DEVICE_ADMIN.equals(receivers[i].permission)) {
intent.setComponent(new ComponentName(deviceOwnerPackage,
@@ -6316,9 +6362,9 @@
mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
}
}
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
- } catch (NameNotFoundException e) {
- Log.e(LOG_TAG, "Cannot find device owner package", e);
}
}
}
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 176f54b1..370f125 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -339,7 +339,7 @@
private static final MidiDeviceInfo[] EMPTY_DEVICE_INFO_ARRAY = new MidiDeviceInfo[0];
- public MidiDeviceInfo[] getDeviceList() {
+ public MidiDeviceInfo[] getDevices() {
ArrayList<MidiDeviceInfo> deviceInfos = new ArrayList<MidiDeviceInfo>();
int uid = Binder.getCallingUid();
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
new file mode 100644
index 0000000..9d3db16
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -0,0 +1,95 @@
+/**
+ * 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.server.usage;
+
+import android.util.ArrayMap;
+import android.util.SparseArray;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+/**
+ * Keeps track of recent active state changes in apps.
+ * Access should be guarded by a lock by the caller.
+ */
+public class AppIdleHistory {
+
+ private SparseArray<ArrayMap<String,byte[]>> idleHistory = new SparseArray<>();
+ private long lastPeriod = 0;
+ private static final long ONE_MINUTE = 60 * 1000;
+ private static final int HISTORY_SIZE = 100;
+ private static final int FLAG_LAST_STATE = 2;
+ private static final int FLAG_PARTIAL_ACTIVE = 1;
+ private static final long PERIOD_DURATION = UsageStatsService.DEBUG ? ONE_MINUTE
+ : 60 * ONE_MINUTE;
+
+ public void addEntry(String packageName, int userId, boolean idle, long timeNow) {
+ ArrayMap<String, byte[]> userHistory = idleHistory.get(userId);
+ if (userHistory == null) {
+ userHistory = new ArrayMap<>();
+ idleHistory.put(userId, userHistory);
+ }
+ byte[] packageHistory = userHistory.get(packageName);
+ if (packageHistory == null) {
+ packageHistory = new byte[HISTORY_SIZE];
+ userHistory.put(packageName, packageHistory);
+ }
+ long thisPeriod = timeNow / PERIOD_DURATION;
+ // Has the period switched over? Slide all users' package histories
+ if (lastPeriod != 0 && lastPeriod < thisPeriod
+ && (thisPeriod - lastPeriod) < HISTORY_SIZE - 1) {
+ int diff = (int) (thisPeriod - lastPeriod);
+ final int NUSERS = idleHistory.size();
+ for (int u = 0; u < NUSERS; u++) {
+ userHistory = idleHistory.valueAt(u);
+ for (byte[] history : userHistory.values()) {
+ // Shift left
+ System.arraycopy(history, diff, history, 0, HISTORY_SIZE - diff);
+ // Replicate last state across the diff
+ for (int i = 0; i < diff; i++) {
+ history[HISTORY_SIZE - i - 1] =
+ (byte) (history[HISTORY_SIZE - diff - 1] & FLAG_LAST_STATE);
+ }
+ }
+ }
+ }
+ lastPeriod = thisPeriod;
+ if (!idle) {
+ packageHistory[HISTORY_SIZE - 1] = FLAG_LAST_STATE | FLAG_PARTIAL_ACTIVE;
+ } else {
+ packageHistory[HISTORY_SIZE - 1] &= ~FLAG_LAST_STATE;
+ }
+ }
+
+ public void removeUser(int userId) {
+ idleHistory.remove(userId);
+ }
+
+ public void dump(IndentingPrintWriter idpw, int userId) {
+ ArrayMap<String, byte[]> userHistory = idleHistory.get(userId);
+ if (userHistory == null) return;
+ final int P = userHistory.size();
+ for (int p = 0; p < P; p++) {
+ final String packageName = userHistory.keyAt(p);
+ final byte[] history = userHistory.valueAt(p);
+ for (int i = 0; i < HISTORY_SIZE; i++) {
+ idpw.print(history[i] == 0 ? '.' : 'A');
+ }
+ idpw.print(" " + packageName);
+ idpw.println();
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 197daed..f7bcf2a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -49,6 +49,7 @@
import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
+import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -58,10 +59,12 @@
import android.provider.Settings;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.DeviceIdleController;
@@ -87,13 +90,22 @@
static final String TAG = "UsageStatsService";
- static final boolean DEBUG = false;
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
private static final long TEN_SECONDS = 10 * 1000;
+ private static final long ONE_MINUTE = 60 * 1000;
private static final long TWENTY_MINUTES = 20 * 60 * 1000;
private static final long FLUSH_INTERVAL = DEBUG ? TEN_SECONDS : TWENTY_MINUTES;
private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
- static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = 2L * 24 * 60 * 60 * 1000; // 1 day
- static final long DEFAULT_CHECK_IDLE_INTERVAL = 8 * 3600 * 1000; // 8 hours
+
+ static final long DEFAULT_APP_IDLE_THRESHOLD_MILLIS = DEBUG ? ONE_MINUTE * 4
+ : 1L * 24 * 60 * ONE_MINUTE; // 1 day
+ static final long DEFAULT_CHECK_IDLE_INTERVAL = DEBUG ? ONE_MINUTE
+ : 8 * 60 * ONE_MINUTE; // 8 hours
+ static final long DEFAULT_PAROLE_INTERVAL = DEBUG ? ONE_MINUTE * 10
+ : 24 * 60 * ONE_MINUTE; // 24 hours between paroles
+ static final long DEFAULT_PAROLE_DURATION = DEBUG ? ONE_MINUTE
+ : 10 * ONE_MINUTE; // 10 minutes
// Handler message types.
static final int MSG_REPORT_EVENT = 0;
@@ -102,6 +114,8 @@
static final int MSG_INFORM_LISTENERS = 3;
static final int MSG_FORCE_IDLE_STATE = 4;
static final int MSG_CHECK_IDLE_STATES = 5;
+ static final int MSG_CHECK_PAROLE_TIMEOUT = 6;
+ static final int MSG_PAROLE_END_TIMEOUT = 7;
private final Object mLock = new Object();
Handler mHandler;
@@ -110,19 +124,24 @@
AppWidgetManager mAppWidgetManager;
IDeviceIdleController mDeviceIdleController;
private DisplayManager mDisplayManager;
+ private PowerManager mPowerManager;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
private File mUsageStatsDir;
long mRealTimeSnapshot;
long mSystemTimeSnapshot;
+
boolean mAppIdleParoled;
private boolean mScreenOn;
-
+ private long mLastAppIdleParoledTime;
long mAppIdleDurationMillis;
long mCheckIdleIntervalMillis = DEFAULT_CHECK_IDLE_INTERVAL;
long mScreenOnTime;
long mScreenOnSystemTimeSnapshot;
+ @GuardedBy("mLock")
+ private AppIdleHistory mAppIdleHistory = new AppIdleHistory();
+
private ArrayList<UsageStatsManagerInternal.AppIdleStateChangeListener>
mPackageAccessListeners = new ArrayList<>();
@@ -152,6 +171,7 @@
IntentFilter deviceStates = new IntentFilter(BatteryManager.ACTION_CHARGING);
deviceStates.addAction(BatteryManager.ACTION_DISCHARGING);
+ deviceStates.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
getContext().registerReceiver(new DeviceStateReceiver(), deviceStates);
synchronized (mLock) {
cleanUpRemovedUsersLocked();
@@ -179,6 +199,8 @@
ServiceManager.getService(DeviceIdleController.SERVICE_NAME));
mDisplayManager = (DisplayManager) getContext().getSystemService(
Context.DISPLAY_SERVICE);
+ mPowerManager = getContext().getSystemService(PowerManager.class);
+
mScreenOnSystemTimeSnapshot = System.currentTimeMillis();
synchronized (this) {
mScreenOnTime = readScreenOnTimeLocked();
@@ -216,6 +238,8 @@
if (BatteryManager.ACTION_CHARGING.equals(action)
|| BatteryManager.ACTION_DISCHARGING.equals(action)) {
setAppIdleParoled(BatteryManager.ACTION_CHARGING.equals(action));
+ } else if (PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
+ onDeviceIdleModeChanged();
}
}
}
@@ -270,15 +294,41 @@
}
}
+ /** Paroled here means temporary pardon from being inactive */
void setAppIdleParoled(boolean paroled) {
synchronized (mLock) {
if (mAppIdleParoled != paroled) {
mAppIdleParoled = paroled;
+ if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
+ if (paroled) {
+ mLastAppIdleParoledTime = checkAndGetTimeLocked();
+ postNextParoleTimeout();
+ }
postCheckIdleStates();
}
}
}
+ private void postNextParoleTimeout() {
+ if (DEBUG) Slog.d(TAG, "Posting MSG_CHECK_PAROLE_TIMEOUT");
+ mHandler.removeMessages(MSG_CHECK_PAROLE_TIMEOUT);
+ // Compute when the next parole needs to happen. We check more frequently than necessary
+ // since the message handler delays are based on elapsedRealTime and not wallclock time.
+ // The comparison is done in wallclock time.
+ long timeLeft = (mLastAppIdleParoledTime + DEFAULT_PAROLE_INTERVAL)
+ - checkAndGetTimeLocked();
+ if (timeLeft < 0) {
+ timeLeft = 0;
+ }
+ mHandler.sendEmptyMessageDelayed(MSG_CHECK_PAROLE_TIMEOUT, timeLeft / 10);
+ }
+
+ private void postParoleEndTimeout() {
+ if (DEBUG) Slog.d(TAG, "Posting MSG_PAROLE_END_TIMEOUT");
+ mHandler.removeMessages(MSG_PAROLE_END_TIMEOUT);
+ mHandler.sendEmptyMessageDelayed(MSG_PAROLE_END_TIMEOUT, DEFAULT_PAROLE_DURATION);
+ }
+
void postCheckIdleStates() {
mHandler.removeMessages(MSG_CHECK_IDLE_STATES);
mHandler.sendEmptyMessage(MSG_CHECK_IDLE_STATES);
@@ -286,6 +336,7 @@
/** Check all running users' apps to see if they enter an idle state. */
void checkIdleStates() {
+ if (DEBUG) Slog.d(TAG, "Checking idle state");
final int[] runningUsers;
try {
runningUsers = ActivityManagerNative.getDefault().getRunningUserIds();
@@ -301,18 +352,38 @@
| PackageManager.GET_UNINSTALLED_PACKAGES,
userId);
synchronized (mLock) {
+ final long timeNow = checkAndGetTimeLocked();
final int packageCount = packages.size();
for (int p = 0; p < packageCount; p++) {
final String packageName = packages.get(p).packageName;
final boolean isIdle = isAppIdleFiltered(packageName, userId);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS,
userId, isIdle ? 1 : 0, packageName));
+ mAppIdleHistory.addEntry(packageName, userId, isIdle, timeNow);
}
}
}
mHandler.sendEmptyMessageDelayed(MSG_CHECK_IDLE_STATES, mCheckIdleIntervalMillis);
}
+ /** Check if it's been a while since last parole and let idle apps do some work */
+ void checkParoleTimeout() {
+ synchronized (mLock) {
+ if (!mAppIdleParoled) {
+ final long timeSinceLastParole = checkAndGetTimeLocked() - mLastAppIdleParoledTime;
+ if (timeSinceLastParole > DEFAULT_PAROLE_INTERVAL) {
+ if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
+ setAppIdleParoled(true);
+ // Make sure it ends at some point
+ postParoleEndTimeout();
+ } else {
+ if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
+ postNextParoleTimeout();
+ }
+ }
+ }
+ }
+
void updateDisplayLocked() {
boolean screenOn = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY).getState()
!= Display.STATE_OFF;
@@ -368,6 +439,23 @@
}
}
+ void onDeviceIdleModeChanged() {
+ final boolean deviceIdle = mPowerManager.isDeviceIdleMode();
+ if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle);
+ synchronized (mLock) {
+ final long timeSinceLastParole = checkAndGetTimeLocked() - mLastAppIdleParoledTime;
+ if (!deviceIdle
+ && timeSinceLastParole >= DEFAULT_PAROLE_INTERVAL) {
+ if (DEBUG) Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false");
+ postNextParoleTimeout();
+ setAppIdleParoled(true);
+ } else if (deviceIdle) {
+ if (DEBUG) Slog.i(TAG, "Device idle, back to prison");
+ setAppIdleParoled(false);
+ }
+ }
+ }
+
private static void deleteRecursively(File f) {
File[] files = f.listFiles();
if (files != null) {
@@ -400,12 +488,20 @@
final long actualSystemTime = System.currentTimeMillis();
final long actualRealtime = SystemClock.elapsedRealtime();
final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
+ boolean resetBeginIdleTime = false;
if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
// The time has changed.
+
+ // Check if it's severe enough a change to reset screenOnTime
+ if (Math.abs(actualSystemTime - expectedSystemTime) > mAppIdleDurationMillis) {
+ mScreenOnSystemTimeSnapshot = actualSystemTime;
+ mScreenOnTime = 0;
+ resetBeginIdleTime = true;
+ }
final int userCount = mUserState.size();
for (int i = 0; i < userCount; i++) {
final UserUsageStatsService service = mUserState.valueAt(i);
- service.onTimeChanged(expectedSystemTime, actualSystemTime);
+ service.onTimeChanged(expectedSystemTime, actualSystemTime, resetBeginIdleTime);
}
mRealTimeSnapshot = actualRealtime;
mSystemTimeSnapshot = actualSystemTime;
@@ -453,6 +549,7 @@
// Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ 0, event.mPackage));
+ mAppIdleHistory.addEntry(event.mPackage, userId, false, timeNow);
}
}
}
@@ -479,6 +576,7 @@
// Slog.d(TAG, "Informing listeners of out-of-idle " + event.mPackage);
mHandler.sendMessage(mHandler.obtainMessage(MSG_INFORM_LISTENERS, userId,
/* idle = */ idle ? 1 : 0, packageName));
+ mAppIdleHistory.addEntry(packageName, userId, idle, timeNow);
}
}
}
@@ -680,10 +778,14 @@
mUserState.valueAt(i).checkin(idpw, screenOnTime);
} else {
mUserState.valueAt(i).dump(idpw, screenOnTime);
+ idpw.println();
+ if (args.length > 0 && "history".equals(args[0])) {
+ mAppIdleHistory.dump(idpw, mUserState.keyAt(i));
+ }
}
idpw.decreaseIndent();
}
- pw.write("Screen On Timestamp:" + mScreenOnTime + "\n");
+ pw.write("Screen On Timebase:" + mScreenOnTime + "\n");
}
}
@@ -718,6 +820,16 @@
case MSG_CHECK_IDLE_STATES:
checkIdleStates();
break;
+
+ case MSG_CHECK_PAROLE_TIMEOUT:
+ checkParoleTimeout();
+ break;
+
+ case MSG_PAROLE_END_TIMEOUT:
+ if (DEBUG) Slog.d(TAG, "Ending parole");
+ setAppIdleParoled(false);
+ break;
+
default:
super.handleMessage(msg);
break;
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index b638c8e..b7e1c22 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -104,7 +104,7 @@
// By calling loadActiveStats, we will
// generate new stats for each bucket.
- loadActiveStats(currentTimeMillis, false);
+ loadActiveStats(currentTimeMillis,/*force=*/ false, /*resetBeginIdleTime=*/ false);
} else {
// Set up the expiry date to be one day from the latest daily stat.
// This may actually be today and we will rollover on the first event
@@ -167,10 +167,10 @@
persistActiveStats();
}
- void onTimeChanged(long oldTime, long newTime) {
+ void onTimeChanged(long oldTime, long newTime, boolean resetBeginIdleTime) {
persistActiveStats();
mDatabase.onTimeChanged(newTime - oldTime);
- loadActiveStats(newTime, true);
+ loadActiveStats(newTime, /* force= */ true, resetBeginIdleTime);
}
void reportEvent(UsageEvents.Event event, long deviceUsageTime) {
@@ -431,7 +431,7 @@
persistActiveStats();
mDatabase.prune(currentTimeMillis);
- loadActiveStats(currentTimeMillis, false);
+ loadActiveStats(currentTimeMillis, /*force=*/ false, /*resetBeginIdleTime=*/ false);
final int continueCount = continuePreviousDay.size();
for (int i = 0; i < continueCount; i++) {
@@ -460,7 +460,8 @@
/**
* @param force To force all in-memory stats to be reloaded.
*/
- private void loadActiveStats(final long currentTimeMillis, boolean force) {
+ private void loadActiveStats(final long currentTimeMillis, boolean force,
+ boolean resetBeginIdleTime) {
final UnixCalendar tempCal = mDailyExpiryDate;
for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) {
tempCal.setTimeInMillis(currentTimeMillis);
@@ -496,6 +497,12 @@
mCurrentStats[intervalType].beginTime = tempCal.getTimeInMillis();
mCurrentStats[intervalType].endTime = currentTimeMillis;
}
+
+ if (resetBeginIdleTime) {
+ for (UsageStats usageStats : mCurrentStats[intervalType].packageStats.values()) {
+ usageStats.mBeginIdleTime = 0;
+ }
+ }
}
mStatsChanged = false;
mDailyExpiryDate.setTimeInMillis(currentTimeMillis);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index f84beb6..cb8f938 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -92,7 +92,6 @@
private static final int MSG_BOOT_COMPLETED = 4;
private static final int MSG_USER_SWITCHED = 5;
- private static final int AUDIO_MODE_NONE = 0;
private static final int AUDIO_MODE_SOURCE = 1;
// Delay for debouncing USB disconnects.
@@ -107,8 +106,6 @@
// Request is cancelled if host does not configure device within 10 seconds.
private static final int ACCESSORY_REQUEST_TIMEOUT = 10 * 1000;
- private static final String BOOT_MODE_PROPERTY = "ro.bootmode";
-
private UsbHandler mHandler;
private boolean mBootCompleted;
@@ -245,7 +242,7 @@
if (functions != null) {
mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
- setCurrentFunctions(functions, false);
+ setCurrentFunctions(functions);
}
}
@@ -318,7 +315,6 @@
private boolean mConnected;
private boolean mConfigured;
private String mCurrentFunctions;
- private String mDefaultFunctions;
private UsbAccessory mCurrentAccessory;
private int mUsbNotificationId;
private boolean mAdbNotificationShown;
@@ -343,25 +339,20 @@
public UsbHandler(Looper looper) {
super(looper);
try {
+ // Special note about persist.sys.usb.config: We only ever look at the adb value
+ // from that property. Other values are ignored. persist.sys.usb.config is now
+ // only used to determine if adb is enabled or not.
+ // TODO: rename persist.sys.usb.config to something more descriptive.
// persist.sys.usb.config should never be unset. But if it is, set it to "adb"
// so we have a chance of debugging what happened.
- mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb");
- // Check if USB mode needs to be overridden depending on OEM specific bootmode.
- mDefaultFunctions = processOemUsbOverride(mDefaultFunctions);
+ mAdbEnabled = containsFunction(
+ SystemProperties.get(UsbManager.ADB_PERSISTENT_PROPERTY, "adb"),
+ UsbManager.USB_FUNCTION_ADB);
- // sanity check the sys.usb.config system property
- // this may be necessary if we crashed while switching USB configurations
- String config = SystemProperties.get("sys.usb.config", "none");
- if (!config.equals(mDefaultFunctions)) {
- Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions);
- SystemProperties.set("sys.usb.config", mDefaultFunctions);
- }
-
- mCurrentFunctions = getDefaultFunctions();
+ mCurrentFunctions = mAdbEnabled ? "adb" : "none";
String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
updateState(state);
- mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB);
// register observer to listen for settings changes
mContentResolver.registerContentObserver(
@@ -396,14 +387,6 @@
sendMessage(m);
}
- public void sendMessage(int what, Object arg0, boolean arg1) {
- removeMessages(what);
- Message m = Message.obtain(this, what);
- m.obj = arg0;
- m.arg1 = (arg1 ? 1 : 0);
- sendMessage(m);
- }
-
public void updateState(String state) {
int connected, configured;
@@ -443,7 +426,7 @@
private boolean setUsbConfig(String config) {
if (DEBUG) Slog.d(TAG, "setUsbConfig(" + config + ")");
// set the new configuration
- SystemProperties.set("sys.usb.config", config);
+ SystemProperties.set(UsbManager.USB_SETTINGS_PROPERTY, config);
return waitForState(config);
}
@@ -453,9 +436,9 @@
mAdbEnabled = enable;
// Due to the persist.sys.usb.config property trigger, changing adb state requires
// persisting default function
- setEnabledFunctions(mDefaultFunctions, true);
+ SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none");
// After persisting them use the lock-down aware function set
- setEnabledFunctions(getDefaultFunctions(), false);
+ setEnabledFunctions(getDefaultFunctions());
updateAdbNotification();
}
if (mDebuggingManager != null) {
@@ -463,65 +446,31 @@
}
}
- private void setEnabledFunctions(String functions, boolean makeDefault) {
- if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions
- + " makeDefault: " + makeDefault);
+ private void setEnabledFunctions(String functions) {
+ if (DEBUG) Slog.d(TAG, "setEnabledFunctions " + functions);
- // Do not update persystent.sys.usb.config if the device is booted up
- // with OEM specific mode.
- if (functions != null && makeDefault && !needsOemUsbOverride()) {
+ if (functions == null) {
+ functions = "none";
+ }
- if (mAdbEnabled) {
- functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
- } else {
- functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
- }
- if (!mDefaultFunctions.equals(functions)) {
- if (!setUsbConfig("none")) {
- Slog.e(TAG, "Failed to disable USB");
- // revert to previous configuration if we fail
- setUsbConfig(mCurrentFunctions);
- return;
- }
- // setting this property will also change the current USB state
- // via a property trigger
- SystemProperties.set("persist.sys.usb.config", functions);
- if (waitForState(functions)) {
- mCurrentFunctions = functions;
- mDefaultFunctions = functions;
- } else {
- Slog.e(TAG, "Failed to switch persistent USB config to " + functions);
- // revert to previous configuration if we fail
- SystemProperties.set("persist.sys.usb.config", mDefaultFunctions);
- }
- }
+ if (mAdbEnabled) {
+ functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
} else {
- if (functions == null) {
- functions = mDefaultFunctions;
+ functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ }
+ if (!mCurrentFunctions.equals(functions)) {
+ if (!setUsbConfig("none")) {
+ Slog.e(TAG, "Failed to disable USB");
+ // revert to previous configuration if we fail
+ setUsbConfig(mCurrentFunctions);
+ return;
}
-
- // Override with bootmode specific usb mode if needed
- functions = processOemUsbOverride(functions);
-
- if (mAdbEnabled) {
- functions = addFunction(functions, UsbManager.USB_FUNCTION_ADB);
+ if (setUsbConfig(functions)) {
+ mCurrentFunctions = functions;
} else {
- functions = removeFunction(functions, UsbManager.USB_FUNCTION_ADB);
- }
- if (!mCurrentFunctions.equals(functions)) {
- if (!setUsbConfig("none")) {
- Slog.e(TAG, "Failed to disable USB");
- // revert to previous configuration if we fail
- setUsbConfig(mCurrentFunctions);
- return;
- }
- if (setUsbConfig(functions)) {
- mCurrentFunctions = functions;
- } else {
- Slog.e(TAG, "Failed to switch USB config to " + functions);
- // revert to previous configuration if we fail
- setUsbConfig(mCurrentFunctions);
- }
+ Slog.e(TAG, "Failed to switch USB config to " + functions);
+ // revert to previous configuration if we fail
+ setUsbConfig(mCurrentFunctions);
}
}
}
@@ -551,7 +500,7 @@
// make sure accessory mode is off
// and restore default functions
Slog.d(TAG, "exited USB accessory mode");
- setEnabledFunctions(getDefaultFunctions(), false);
+ setEnabledFunctions(getDefaultFunctions());
if (mCurrentAccessory != null) {
if (mBootCompleted) {
@@ -644,7 +593,7 @@
updateCurrentAccessory();
} else if (!mConnected) {
// restore defaults when USB is disconnected
- setEnabledFunctions(getDefaultFunctions(), false);
+ setEnabledFunctions(getDefaultFunctions());
}
if (mBootCompleted) {
updateUsbState();
@@ -657,10 +606,11 @@
break;
case MSG_SET_CURRENT_FUNCTIONS:
String functions = (String)msg.obj;
- boolean makeDefault = (msg.arg1 == 1);
- setEnabledFunctions(functions, makeDefault);
+ setEnabledFunctions(functions);
break;
case MSG_SYSTEM_READY:
+ setUsbConfig(mCurrentFunctions);
+ SystemProperties.set(UsbManager.ADB_PERSISTENT_PROPERTY, mAdbEnabled ? "adb" : "none");
updateUsbNotification();
updateAdbNotification();
updateUsbState();
@@ -669,6 +619,7 @@
break;
case MSG_BOOT_COMPLETED:
mBootCompleted = true;
+ setUsbConfig(mCurrentFunctions);
if (mCurrentAccessory != null) {
getCurrentSettings().accessoryAttached(mCurrentAccessory);
}
@@ -724,10 +675,7 @@
} else if (containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ACCESSORY)) {
id = com.android.internal.R.string.usb_accessory_notification_title;
} else {
- // There is a different notification for USB tethering so we don't need one here
- //if (!containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_RNDIS)) {
- // Slog.e(TAG, "No known USB function in updateUsbNotification");
- //}
+ id = com.android.internal.R.string.usb_charging_notification_title;
}
}
if (id != mUsbNotificationId) {
@@ -754,7 +702,7 @@
Intent intent = Intent.makeRestartActivityTask(
new ComponentName("com.android.settings",
- "com.android.settings.UsbSettings"));
+ "com.android.settings.deviceinfo.UsbModeChooserActivity"));
PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
intent, 0, null, UserHandle.CURRENT);
notification.color = mContext.getColor(
@@ -810,18 +758,12 @@
}
private String getDefaultFunctions() {
- UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER,
- new UserHandle(mCurrentUser))) {
- return "none";
- }
- return mDefaultFunctions;
+ return "none";
}
public void dump(FileDescriptor fd, PrintWriter pw) {
pw.println(" USB Device State:");
pw.println(" Current Functions: " + mCurrentFunctions);
- pw.println(" Default Functions: " + mDefaultFunctions);
pw.println(" mConnected: " + mConnected);
pw.println(" mConfigured: " + mConfigured);
pw.println(" mCurrentAccessory: " + mCurrentAccessory);
@@ -857,9 +799,9 @@
return nativeOpenAccessory();
}
- public void setCurrentFunctions(String functions, boolean makeDefault) {
- if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ") default: " + makeDefault);
- mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, makeDefault);
+ public void setCurrentFunctions(String functions) {
+ if (DEBUG) Slog.d(TAG, "setCurrentFunctions(" + functions + ")");
+ mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
}
private void readOemUsbOverrideConfig() {
@@ -884,31 +826,6 @@
}
}
- private boolean needsOemUsbOverride() {
- if (mOemModeMap == null) return false;
-
- String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
- return (mOemModeMap.get(bootMode) != null) ? true : false;
- }
-
- private String processOemUsbOverride(String usbFunctions) {
- if ((usbFunctions == null) || (mOemModeMap == null)) return usbFunctions;
-
- String bootMode = SystemProperties.get(BOOT_MODE_PROPERTY, "unknown");
-
- List<Pair<String, String>> overrides = mOemModeMap.get(bootMode);
- if (overrides != null) {
- for (Pair<String, String> pair: overrides) {
- if (pair.first.equals(usbFunctions)) {
- Slog.d(TAG, "OEM USB override: " + pair.first + " ==> " + pair.second);
- return pair.second;
- }
- }
- }
- // return passed in functions as is.
- return usbFunctions;
- }
-
public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
if (mDebuggingManager != null) {
mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey);
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index e03884f..51281a2 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -252,19 +252,19 @@
}
@Override
- public void setCurrentFunction(String function, boolean makeDefault) {
+ public void setCurrentFunction(String function) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
// If attempt to change USB function while file transfer is restricted, ensure that
// the current function is set to "none", and return.
UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
if (userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
- if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none", false);
+ if (mDeviceManager != null) mDeviceManager.setCurrentFunctions("none");
return;
}
if (mDeviceManager != null) {
- mDeviceManager.setCurrentFunctions(function, makeDefault);
+ mDeviceManager.setCurrentFunctions(function);
} else {
throw new IllegalStateException("USB device mode not supported");
}
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index bfd1f13..2331a8b 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -57,6 +57,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -558,7 +559,7 @@
try {
fis = new FileInputStream(sSingleUserSettingsFile);
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(fis, null);
+ parser.setInput(fis, StandardCharsets.UTF_8.name());
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
@@ -594,7 +595,7 @@
try {
stream = mSettingsFile.openRead();
XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
XmlUtils.nextElement(parser);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
@@ -623,7 +624,7 @@
fos = mSettingsFile.startWrite();
FastXmlSerializer serializer = new FastXmlSerializer();
- serializer.setOutput(fos, "utf-8");
+ serializer.setOutput(fos, StandardCharsets.UTF_8.name());
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "settings");
diff --git a/telecomm/java/android/telecom/AudioState.java b/telecomm/java/android/telecom/AudioState.java
index 465c5f4..33013ac 100644
--- a/telecomm/java/android/telecom/AudioState.java
+++ b/telecomm/java/android/telecom/AudioState.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -24,8 +25,12 @@
/**
* Encapsulates the telecom audio state, including the current audio routing, supported audio
* routing and mute.
+ * @deprecated - use {@link CallAudioState} instead.
+ * @hide
*/
-public final class AudioState implements Parcelable {
+@Deprecated
+@SystemApi
+public class AudioState implements Parcelable {
/** Direct the audio stream through the device's earpiece. */
public static final int ROUTE_EARPIECE = 0x00000001;
@@ -64,6 +69,12 @@
supportedRouteMask = state.getSupportedRouteMask();
}
+ public AudioState(CallAudioState state) {
+ isMuted = state.isMuted();
+ route = state.getRoute();
+ supportedRouteMask = state.getSupportedRouteMask();
+ }
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index adab00b..d74c61c 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -202,7 +202,7 @@
/**
* For video calls, indicates whether the outgoing video for the call can be paused using
- * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState.
+ * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
*/
public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
diff --git a/telecomm/java/android/telecom/CameraCapabilities.aidl b/telecomm/java/android/telecom/CallAudioState.aidl
similarity index 75%
rename from telecomm/java/android/telecom/CameraCapabilities.aidl
rename to telecomm/java/android/telecom/CallAudioState.aidl
index c8e0c5e..90dbbe5 100644
--- a/telecomm/java/android/telecom/CameraCapabilities.aidl
+++ b/telecomm/java/android/telecom/CallAudioState.aidl
@@ -1,17 +1,17 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright 2014, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* 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
+ * limitations under the License.
*/
package android.telecom;
@@ -19,4 +19,4 @@
/**
* {@hide}
*/
-parcelable CameraCapabilities;
+parcelable CallAudioState;
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
new file mode 100644
index 0000000..2b16722
--- /dev/null
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Encapsulates the telecom audio state, including the current audio routing, supported audio
+ * routing and mute.
+ */
+public final class CallAudioState implements Parcelable {
+ /** Direct the audio stream through the device's earpiece. */
+ public static final int ROUTE_EARPIECE = 0x00000001;
+
+ /** Direct the audio stream through Bluetooth. */
+ public static final int ROUTE_BLUETOOTH = 0x00000002;
+
+ /** Direct the audio stream through a wired headset. */
+ public static final int ROUTE_WIRED_HEADSET = 0x00000004;
+
+ /** Direct the audio stream through the device's speakerphone. */
+ public static final int ROUTE_SPEAKER = 0x00000008;
+
+ /**
+ * Direct the audio stream through the device's earpiece or wired headset if one is
+ * connected.
+ */
+ public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;
+
+ /** Bit mask of all possible audio routes. */
+ private static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
+ ROUTE_SPEAKER;
+
+ private final boolean isMuted;
+ private final int route;
+ private final int supportedRouteMask;
+
+ /**
+ * Constructor for a {@link CallAudioState} object.
+ *
+ * @param muted {@code true} if the call is muted, {@code false} otherwise.
+ * @param route The current audio route being used.
+ * Allowed values:
+ * {@link #ROUTE_EARPIECE}
+ * {@link #ROUTE_BLUETOOTH}
+ * {@link #ROUTE_WIRED_HEADSET}
+ * {@link #ROUTE_SPEAKER}
+ * @param supportedRouteMask Bit mask of all routes supported by this call. This should be a
+ * bitwise combination of the following values:
+ * {@link #ROUTE_EARPIECE}
+ * {@link #ROUTE_BLUETOOTH}
+ * {@link #ROUTE_WIRED_HEADSET}
+ * {@link #ROUTE_SPEAKER}
+ */
+ public CallAudioState(boolean muted, int route, int supportedRouteMask) {
+ this.isMuted = muted;
+ this.route = route;
+ this.supportedRouteMask = supportedRouteMask;
+ }
+
+ /** @hide */
+ public CallAudioState(CallAudioState state) {
+ isMuted = state.isMuted();
+ route = state.getRoute();
+ supportedRouteMask = state.getSupportedRouteMask();
+ }
+
+ /** @hide */
+ @SuppressWarnings("deprecation")
+ public CallAudioState(AudioState state) {
+ isMuted = state.isMuted();
+ route = state.getRoute();
+ supportedRouteMask = state.getSupportedRouteMask();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof CallAudioState)) {
+ return false;
+ }
+ CallAudioState state = (CallAudioState) obj;
+ return isMuted() == state.isMuted() && getRoute() == state.getRoute() &&
+ getSupportedRouteMask() == state.getSupportedRouteMask();
+ }
+
+ @Override
+ public String toString() {
+ return String.format(Locale.US,
+ "[AudioState isMuted: %b, route: %s, supportedRouteMask: %s]",
+ isMuted,
+ audioRouteToString(route),
+ audioRouteToString(supportedRouteMask));
+ }
+
+ /**
+ * @return {@code true} if the call is muted, {@code false} otherwise.
+ */
+ public boolean isMuted() {
+ return isMuted;
+ }
+
+ /**
+ * @return The current audio route being used.
+ */
+ public int getRoute() {
+ return route;
+ }
+
+ /**
+ * @return Bit mask of all routes supported by this call.
+ */
+ public int getSupportedRouteMask() {
+ return supportedRouteMask;
+ }
+
+ /**
+ * Converts the provided audio route into a human readable string representation.
+ *
+ * @param route to convert into a string.
+ *
+ * @return String representation of the provided audio route.
+ */
+ public static String audioRouteToString(int route) {
+ if (route == 0 || (route & ~ROUTE_ALL) != 0x0) {
+ return "UNKNOWN";
+ }
+
+ StringBuffer buffer = new StringBuffer();
+ if ((route & ROUTE_EARPIECE) == ROUTE_EARPIECE) {
+ listAppend(buffer, "EARPIECE");
+ }
+ if ((route & ROUTE_BLUETOOTH) == ROUTE_BLUETOOTH) {
+ listAppend(buffer, "BLUETOOTH");
+ }
+ if ((route & ROUTE_WIRED_HEADSET) == ROUTE_WIRED_HEADSET) {
+ listAppend(buffer, "WIRED_HEADSET");
+ }
+ if ((route & ROUTE_SPEAKER) == ROUTE_SPEAKER) {
+ listAppend(buffer, "SPEAKER");
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Responsible for creating AudioState objects for deserialized Parcels.
+ */
+ public static final Parcelable.Creator<CallAudioState> CREATOR =
+ new Parcelable.Creator<CallAudioState> () {
+
+ @Override
+ public CallAudioState createFromParcel(Parcel source) {
+ boolean isMuted = source.readByte() == 0 ? false : true;
+ int route = source.readInt();
+ int supportedRouteMask = source.readInt();
+ return new CallAudioState(isMuted, route, supportedRouteMask);
+ }
+
+ @Override
+ public CallAudioState[] newArray(int size) {
+ return new CallAudioState[size];
+ }
+ };
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Writes AudioState object into a serializeable Parcel.
+ */
+ @Override
+ public void writeToParcel(Parcel destination, int flags) {
+ destination.writeByte((byte) (isMuted ? 1 : 0));
+ destination.writeInt(route);
+ destination.writeInt(supportedRouteMask);
+ }
+
+ private static void listAppend(StringBuffer buffer, String str) {
+ if (buffer.length() > 0) {
+ buffer.append(", ");
+ }
+ buffer.append(str);
+ }
+}
diff --git a/telecomm/java/android/telecom/CameraCapabilities.java b/telecomm/java/android/telecom/CameraCapabilities.java
deleted file mode 100644
index 6242956..0000000
--- a/telecomm/java/android/telecom/CameraCapabilities.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telecom;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Represents the camera capabilities important to a Video Telephony provider.
- */
-public final class CameraCapabilities implements Parcelable {
-
- /**
- * The width of the camera video in pixels.
- */
- private final int mWidth;
-
- /**
- * The height of the camera video in pixels.
- */
- private final int mHeight;
-
- /**
- * Whether the camera supports zoom.
- */
- private final boolean mZoomSupported;
-
- /**
- * The maximum zoom supported by the camera.
- */
- private final float mMaxZoom;
-
- /**
- * Create a call camera capabilities instance.
- *
- * @param width The width of the camera video (in pixels).
- * @param height The height of the camera video (in pixels).
- */
- public CameraCapabilities(int width, int height) {
- this(width, height, false, 1.0f);
- }
-
- /**
- * Create a call camera capabilities instance that optionally
- * supports zoom.
- *
- * @param width The width of the camera video (in pixels).
- * @param height The height of the camera video (in pixels).
- * @param zoomSupported True when camera supports zoom.
- * @param maxZoom Maximum zoom supported by camera.
- * @hide
- */
- public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) {
- mWidth = width;
- mHeight = height;
- mZoomSupported = zoomSupported;
- mMaxZoom = maxZoom;
- }
-
- /**
- * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
- **/
- public static final Parcelable.Creator<CameraCapabilities> CREATOR =
- new Parcelable.Creator<CameraCapabilities> () {
- /**
- * Creates a CallCameraCapabilities instances from a parcel.
- *
- * @param source The parcel.
- * @return The CallCameraCapabilities.
- */
- @Override
- public CameraCapabilities createFromParcel(Parcel source) {
- int width = source.readInt();
- int height = source.readInt();
- boolean supportsZoom = source.readByte() != 0;
- float maxZoom = source.readFloat();
-
- return new CameraCapabilities(width, height, supportsZoom, maxZoom);
- }
-
- @Override
- public CameraCapabilities[] newArray(int size) {
- return new CameraCapabilities[size];
- }
- };
-
- /**
- * Describe the kinds of special objects contained in this Parcelable's
- * marshalled representation.
- *
- * @return a bitmask indicating the set of special object types marshalled
- * by the Parcelable.
- */
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * Flatten this object in to a Parcel.
- *
- * @param dest The Parcel in which the object should be written.
- * @param flags Additional flags about how the object should be written.
- * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
- */
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(getWidth());
- dest.writeInt(getHeight());
- dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
- dest.writeFloat(getMaxZoom());
- }
-
- /**
- * The width of the camera video in pixels.
- */
- public int getWidth() {
- return mWidth;
- }
-
- /**
- * The height of the camera video in pixels.
- */
- public int getHeight() {
- return mHeight;
- }
-
- /**
- * Whether the camera supports zoom.
- * @hide
- */
- public boolean isZoomSupported() {
- return mZoomSupported;
- }
-
- /**
- * The maximum zoom supported by the camera.
- * @hide
- */
- public float getMaxZoom() {
- return mMaxZoom;
- }
-}
diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java
index e682697..dfbb67a 100644
--- a/telecomm/java/android/telecom/Conference.java
+++ b/telecomm/java/android/telecom/Conference.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.annotation.SystemApi;
import android.telecom.Connection.VideoProvider;
import java.util.ArrayList;
@@ -29,7 +30,7 @@
/**
* Represents a conference call which can contain any number of {@link Connection} objects.
*/
-public abstract class Conference implements Conferenceable {
+public abstract class Conference extends Conferenceable {
/**
* Used to indicate that the conference connection time is not specified. If not specified,
@@ -62,7 +63,7 @@
Collections.unmodifiableList(mConferenceableConnections);
private PhoneAccountHandle mPhoneAccount;
- private AudioState mAudioState;
+ private CallAudioState mCallAudioState;
private int mState = Connection.STATE_NEW;
private DisconnectCause mDisconnectCause;
private int mConnectionCapabilities;
@@ -116,7 +117,7 @@
}
/**
- * Returns the capabilities of a conference. See {@code CAPABILITY_*} constants in class
+ * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
* {@link Connection} for valid values.
*
* @return A bitmask of the capabilities of the conference call.
@@ -172,9 +173,22 @@
* @return The audio state of the conference, describing how its audio is currently
* being routed by the system. This is {@code null} if this Conference
* does not directly know about its audio state.
+ * @deprecated Use {@link #getCallAudioState()} instead.
+ * @hide
*/
+ @Deprecated
+ @SystemApi
public final AudioState getAudioState() {
- return mAudioState;
+ return new AudioState(mCallAudioState);
+ }
+
+ /**
+ * @return The audio state of the conference, describing how its audio is currently
+ * being routed by the system. This is {@code null} if this Conference
+ * does not directly know about its audio state.
+ */
+ public final CallAudioState getCallAudioState() {
+ return mCallAudioState;
}
/**
@@ -248,10 +262,21 @@
* Notifies this conference that the {@link #getAudioState()} property has a new value.
*
* @param state The new call audio state.
+ * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
+ * @hide
*/
+ @SystemApi
+ @Deprecated
public void onAudioStateChanged(AudioState state) {}
/**
+ * Notifies this conference that the {@link #getCallAudioState()} property has a new value.
+ *
+ * @param state The new call audio state.
+ */
+ public void onCallAudioStateChanged(CallAudioState state) {}
+
+ /**
* Notifies this conference that a connection has been added to it.
*
* @param connection The newly added connection.
@@ -365,10 +390,10 @@
/**
* Set the video state for the conference.
- * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#TX_ENABLED},
- * {@link VideoProfile.VideoState#RX_ENABLED}.
+ * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_TX_ENABLED},
+ * {@link VideoProfile#STATE_RX_ENABLED}.
*
* @param videoState The new video state.
*/
@@ -458,7 +483,9 @@
* the connection from which the conference will retrieve its current state.
*
* @return The primary connection.
+ * @hide
*/
+ @SystemApi
public Connection getPrimaryConnection() {
if (mUnmodifiableChildConnections == null || mUnmodifiableChildConnections.isEmpty()) {
return null;
@@ -467,22 +494,42 @@
}
/**
- * Sets the connect time of the {@code Conference}.
- *
- * @param connectTimeMillis The connection time, in milliseconds.
+ * @hide
+ * @deprecated Use {@link #setConnectionTime}.
*/
- public void setConnectTimeMillis(long connectTimeMillis) {
- mConnectTimeMillis = connectTimeMillis;
+ @Deprecated
+ @SystemApi
+ public final void setConnectTimeMillis(long connectTimeMillis) {
+ setConnectionTime(connectTimeMillis);
}
/**
- * Retrieves the connect time of the {@code Conference}, if specified. A value of
+ * Sets the connection start time of the {@code Conference}.
+ *
+ * @param connectionTimeMillis The connection time, in milliseconds.
+ */
+ public final void setConnectionTime(long connectionTimeMillis) {
+ mConnectTimeMillis = connectionTimeMillis;
+ }
+
+ /**
+ * @hide
+ * @deprecated Use {@link #getConnectionTime}.
+ */
+ @Deprecated
+ @SystemApi
+ public final long getConnectTimeMillis() {
+ return getConnectionTime();
+ }
+
+ /**
+ * Retrieves the connection start time of the {@code Conference}, if specified. A value of
* {@link #CONNECT_TIME_NOT_SPECIFIED} indicates that Telecom should determine the start time
* of the conference.
*
- * @return The time the {@code Conference} has been connected.
+ * @return The time at which the {@code Conference} was connected.
*/
- public final long getConnectTimeMillis() {
+ public final long getConnectionTime() {
return mConnectTimeMillis;
}
@@ -492,10 +539,11 @@
* @param state The new audio state.
* @hide
*/
- final void setAudioState(AudioState state) {
- Log.d(this, "setAudioState %s", state);
- mAudioState = state;
- onAudioStateChanged(state);
+ final void setCallAudioState(CallAudioState state) {
+ Log.d(this, "setCallAudioState %s", state);
+ mCallAudioState = state;
+ onAudioStateChanged(getAudioState());
+ onCallAudioStateChanged(state);
}
private void setState(int newState) {
diff --git a/telecomm/java/android/telecom/Conferenceable.java b/telecomm/java/android/telecom/Conferenceable.java
index 5c4cbc5..bb6f2b8 100644
--- a/telecomm/java/android/telecom/Conferenceable.java
+++ b/telecomm/java/android/telecom/Conferenceable.java
@@ -21,6 +21,6 @@
* call with. The {@link ConnectionService} implementation will only recognize
* {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s.
*/
-public interface Conferenceable {
-
+public abstract class Conferenceable {
+ Conferenceable() {}
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 0bf9118..fba4e6a 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -20,6 +20,7 @@
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import android.annotation.SystemApi;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
@@ -46,7 +47,7 @@
* must call {@link #destroy()} to signal to the framework that the {@code Connection} is no
* longer used and associated resources may be recovered.
*/
-public abstract class Connection implements Conferenceable {
+public abstract class Connection extends Conferenceable {
public static final int STATE_INITIALIZING = 0;
@@ -186,7 +187,7 @@
/**
* For video calls, indicates whether the outgoing video for the call can be paused using
- * the {@link android.telecom.VideoProfile.VideoState#PAUSED} VideoState.
+ * the {@link android.telecom.VideoProfile#STATE_PAUSED} VideoState.
*/
public static final int CAPABILITY_CAN_PAUSE_VIDEO = 0x00100000;
@@ -484,7 +485,7 @@
onRequestConnectionDataUsage();
break;
case MSG_SET_PAUSE_IMAGE:
- onSetPauseImage((String) msg.obj);
+ onSetPauseImage((Uri) msg.obj);
break;
default:
break;
@@ -547,7 +548,7 @@
mMessageHandler.obtainMessage(MSG_REQUEST_CONNECTION_DATA_USAGE).sendToTarget();
}
- public void setPauseImage(String uri) {
+ public void setPauseImage(Uri uri) {
mMessageHandler.obtainMessage(MSG_SET_PAUSE_IMAGE, uri).sendToTarget();
}
}
@@ -642,7 +643,7 @@
*
* @param uri URI of image to display.
*/
- public abstract void onSetPauseImage(String uri);
+ public abstract void onSetPauseImage(Uri uri);
/**
* Invokes callback method defined in listening {@link InCallService} implementations.
@@ -726,7 +727,7 @@
*
* @param dataUsage The updated data usage.
*/
- public void changeCallDataUsage(long dataUsage) {
+ public void setCallDataUsage(long dataUsage) {
if (mVideoCallbacks != null) {
try {
for (IVideoCallback callback : mVideoCallbacks.values()) {
@@ -740,9 +741,20 @@
/**
* Invokes callback method defined in listening {@link InCallService} implementations.
*
+ * @param dataUsage The updated data usage.
+ * @deprecated - Use {@link #setCallDataUsage(long)} instead.
+ * @hide
+ */
+ public void changeCallDataUsage(long dataUsage) {
+ setCallDataUsage(dataUsage);
+ }
+
+ /**
+ * Invokes callback method defined in listening {@link InCallService} implementations.
+ *
* @param cameraCapabilities The changed camera capabilities.
*/
- public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
+ public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
if (mVideoCallbacks != null) {
try {
for (IVideoCallback callback : mVideoCallbacks.values()) {
@@ -756,6 +768,12 @@
/**
* Invokes callback method defined in listening {@link InCallService} implementations.
*
+ * Allowed values:
+ * {@link VideoProfile#QUALITY_HIGH},
+ * {@link VideoProfile#QUALITY_MEDIUM},
+ * {@link VideoProfile#QUALITY_LOW},
+ * {@link VideoProfile#QUALITY_DEFAULT}.
+ *
* @param videoQuality The updated video quality.
*/
public void changeVideoQuality(int videoQuality) {
@@ -800,7 +818,7 @@
Collections.unmodifiableList(mConferenceables);
private int mState = STATE_NEW;
- private AudioState mAudioState;
+ private CallAudioState mCallAudioState;
private Uri mAddress;
private int mAddressPresentation;
private String mCallerDisplayName;
@@ -859,10 +877,10 @@
/**
* Returns the video state of the connection.
- * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#TX_ENABLED},
- * {@link VideoProfile.VideoState#RX_ENABLED}.
+ * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_TX_ENABLED},
+ * {@link VideoProfile#STATE_RX_ENABLED}.
*
* @return The video state of the connection.
* @hide
@@ -875,9 +893,22 @@
* @return The audio state of the connection, describing how its audio is currently
* being routed by the system. This is {@code null} if this Connection
* does not directly know about its audio state.
+ * @deprecated Use {@link #getCallAudioState()} instead.
+ * @hide
*/
+ @SystemApi
+ @Deprecated
public final AudioState getAudioState() {
- return mAudioState;
+ return new AudioState(mCallAudioState);
+ }
+
+ /**
+ * @return The audio state of the connection, describing how its audio is currently
+ * being routed by the system. This is {@code null} if this Connection
+ * does not directly know about its audio state.
+ */
+ public final CallAudioState getCallAudioState() {
+ return mCallAudioState;
}
/**
@@ -951,11 +982,12 @@
* @param state The new audio state.
* @hide
*/
- final void setAudioState(AudioState state) {
+ final void setCallAudioState(CallAudioState state) {
checkImmutable();
Log.d(this, "setAudioState %s", state);
- mAudioState = state;
- onAudioStateChanged(state);
+ mCallAudioState = state;
+ onAudioStateChanged(getAudioState());
+ onCallAudioStateChanged(state);
}
/**
@@ -1027,10 +1059,10 @@
/**
* Set the video state for the connection.
- * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#TX_ENABLED},
- * {@link VideoProfile.VideoState#RX_ENABLED}.
+ * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_TX_ENABLED},
+ * {@link VideoProfile#STATE_RX_ENABLED}.
*
* @param videoState The new video state.
*/
@@ -1342,10 +1374,21 @@
* Notifies this Connection that the {@link #getAudioState()} property has a new value.
*
* @param state The new connection audio state.
+ * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState)} instead.
+ * @hide
*/
+ @SystemApi
+ @Deprecated
public void onAudioStateChanged(AudioState state) {}
/**
+ * Notifies this Connection that the {@link #getCallAudioState()} property has a new value.
+ *
+ * @param state The new connection audio state.
+ */
+ public void onCallAudioStateChanged(CallAudioState state) {}
+
+ /**
* Notifies this Connection of an internal state change. This method is called after the
* state is changed.
*
diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java
index f5cceea..975df5d 100644
--- a/telecomm/java/android/telecom/ConnectionRequest.java
+++ b/telecomm/java/android/telecom/ConnectionRequest.java
@@ -88,10 +88,10 @@
/**
* Describes the video states supported by the client requesting the connection.
- * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#TX_ENABLED},
- * {@link VideoProfile.VideoState#RX_ENABLED}.
+ * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_TX_ENABLED},
+ * {@link VideoProfile#STATE_RX_ENABLED}.
*
* @return The video state for the connection.
*/
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 13eb016..199100b 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -50,7 +50,7 @@
* <pre>
* <service android:name="com.example.package.MyConnectionService"
* android:label="@string/some_label_for_my_connection_service"
- * android:permission="android.permission.BIND_CONNECTION_SERVICE">
+ * android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
* <intent-filter>
* <action android:name="android.telecom.ConnectionService" />
* </intent-filter>
@@ -90,7 +90,7 @@
private static final int MSG_DISCONNECT = 6;
private static final int MSG_HOLD = 7;
private static final int MSG_UNHOLD = 8;
- private static final int MSG_ON_AUDIO_STATE_CHANGED = 9;
+ private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 9;
private static final int MSG_PLAY_DTMF_TONE = 10;
private static final int MSG_STOP_DTMF_TONE = 11;
private static final int MSG_CONFERENCE = 12;
@@ -180,11 +180,11 @@
}
@Override
- public void onAudioStateChanged(String callId, AudioState audioState) {
+ public void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = callId;
- args.arg2 = audioState;
- mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, args).sendToTarget();
+ args.arg2 = callAudioState;
+ mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, args).sendToTarget();
}
@Override
@@ -304,12 +304,12 @@
case MSG_UNHOLD:
unhold((String) msg.obj);
break;
- case MSG_ON_AUDIO_STATE_CHANGED: {
+ case MSG_ON_CALL_AUDIO_STATE_CHANGED: {
SomeArgs args = (SomeArgs) msg.obj;
try {
String callId = (String) args.arg1;
- AudioState audioState = (AudioState) args.arg2;
- onAudioStateChanged(callId, audioState);
+ CallAudioState audioState = (CallAudioState) args.arg2;
+ onCallAudioStateChanged(callId, new CallAudioState(audioState));
} finally {
args.recycle();
}
@@ -688,12 +688,14 @@
}
}
- private void onAudioStateChanged(String callId, AudioState audioState) {
- Log.d(this, "onAudioStateChanged %s %s", callId, audioState);
+ private void onCallAudioStateChanged(String callId, CallAudioState callAudioState) {
+ Log.d(this, "onAudioStateChanged %s %s", callId, callAudioState);
if (mConnectionById.containsKey(callId)) {
- findConnectionForAction(callId, "onAudioStateChanged").setAudioState(audioState);
+ findConnectionForAction(callId, "onCallAudioStateChanged").setCallAudioState(
+ callAudioState);
} else {
- findConferenceForAction(callId, "onAudioStateChanged").setAudioState(audioState);
+ findConferenceForAction(callId, "onCallAudioStateChanged").setCallAudioState(
+ callAudioState);
}
}
diff --git a/telecomm/java/android/telecom/IConferenceable.java b/telecomm/java/android/telecom/IConferenceable.java
deleted file mode 100644
index a664baa..0000000
--- a/telecomm/java/android/telecom/IConferenceable.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package android.telecom;
-
-/**
- * Interface used to identify entities with which another entity can participate in a conference
- * call with. The {@link ConnectionService} implementation will only recognize
- * {@link Conferenceable}s which are {@link Connection}s or {@link Conference}s.
- * <p>
- * @deprecated use {@link Conferenceable} instead.
- * @hide
- */
-public interface IConferenceable extends Conferenceable {
-}
diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java
index 62b8dea..0cf7212b 100644
--- a/telecomm/java/android/telecom/InCallAdapter.java
+++ b/telecomm/java/android/telecom/InCallAdapter.java
@@ -119,7 +119,7 @@
}
/**
- * Sets the audio route (speaker, bluetooth, etc...). See {@link AudioState}.
+ * Sets the audio route (speaker, bluetooth, etc...). See {@link CallAudioState}.
*
* @param route The audio route to use.
*/
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 3cb4e87..e37cff7 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -20,6 +20,7 @@
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
+import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -51,7 +52,7 @@
private static final int MSG_ADD_CALL = 2;
private static final int MSG_UPDATE_CALL = 3;
private static final int MSG_SET_POST_DIAL_WAIT = 4;
- private static final int MSG_ON_AUDIO_STATE_CHANGED = 5;
+ private static final int MSG_ON_CALL_AUDIO_STATE_CHANGED = 5;
private static final int MSG_BRING_TO_FOREGROUND = 6;
private static final int MSG_ON_CAN_ADD_CALL_CHANGED = 7;
@@ -86,8 +87,8 @@
}
break;
}
- case MSG_ON_AUDIO_STATE_CHANGED:
- mPhone.internalAudioStateChanged((AudioState) msg.obj);
+ case MSG_ON_CALL_AUDIO_STATE_CHANGED:
+ mPhone.internalCallAudioStateChanged((CallAudioState) msg.obj);
break;
case MSG_BRING_TO_FOREGROUND:
mPhone.internalBringToForeground(msg.arg1 == 1);
@@ -132,8 +133,8 @@
}
@Override
- public void onAudioStateChanged(AudioState audioState) {
- mHandler.obtainMessage(MSG_ON_AUDIO_STATE_CHANGED, audioState).sendToTarget();
+ public void onCallAudioStateChanged(CallAudioState callAudioState) {
+ mHandler.obtainMessage(MSG_ON_CALL_AUDIO_STATE_CHANGED, callAudioState).sendToTarget();
}
@Override
@@ -155,6 +156,10 @@
InCallService.this.onAudioStateChanged(audioState);
}
+ public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) {
+ InCallService.this.onCallAudioStateChanged(callAudioState);
+ };
+
/** ${inheritDoc} */
@Override
public void onBringToForeground(Phone phone, boolean showDialpad) {
@@ -247,14 +252,27 @@
*
* @return An object encapsulating the audio state. Returns null if the service is not
* fully initialized.
+ * @deprecated Use {@link #getCallAudioState()} instead.
+ * @hide
*/
+ @Deprecated
public final AudioState getAudioState() {
return mPhone == null ? null : mPhone.getAudioState();
}
/**
+ * Obtains the current phone call audio state.
+ *
+ * @return An object encapsulating the audio state. Returns null if the service is not
+ * fully initialized.
+ */
+ public final CallAudioState getCallAudioState() {
+ return mPhone == null ? null : mPhone.getCallAudioState();
+ }
+
+ /**
* Sets the microphone mute state. When this request is honored, there will be change to
- * the {@link #getAudioState()}.
+ * the {@link #getCallAudioState()}.
*
* @param state {@code true} if the microphone should be muted; {@code false} otherwise.
*/
@@ -266,7 +284,7 @@
/**
* Sets the audio route (speaker, bluetooth, etc...). When this request is honored, there will
- * be change to the {@link #getAudioState()}.
+ * be change to the {@link #getCallAudioState()}.
*
* @param route The audio route to use.
*/
@@ -310,11 +328,22 @@
* Called when the audio state changes.
*
* @param audioState The new {@link AudioState}.
+ * @deprecated Use {@link #onCallAudioStateChanged(CallAudioState) instead}.
+ * @hide
*/
+ @Deprecated
public void onAudioStateChanged(AudioState audioState) {
}
/**
+ * Called when the audio state changes.
+ *
+ * @param audioState The new {@link CallAudioState}.
+ */
+ public void onCallAudioStateChanged(CallAudioState audioState) {
+ }
+
+ /**
* Called to bring the in-call screen to the foreground. The in-call experience should
* respond immediately by coming to the foreground to inform the user of the state of
* ongoing {@code Call}s.
@@ -466,7 +495,7 @@
*
* @param uri URI of image to display.
*/
- public abstract void setPauseImage(String uri);
+ public abstract void setPauseImage(Uri uri);
/**
* Callback class which invokes callbacks after video call actions occur.
@@ -546,7 +575,8 @@
*
* @param cameraCapabilities The changed camera capabilities.
*/
- public abstract void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities);
+ public abstract void onCameraCapabilitiesChanged(
+ VideoProfile.CameraCapabilities cameraCapabilities);
}
}
}
diff --git a/telecomm/java/android/telecom/Phone.java b/telecomm/java/android/telecom/Phone.java
index 4cdfd2e..8eb091b 100644
--- a/telecomm/java/android/telecom/Phone.java
+++ b/telecomm/java/android/telecom/Phone.java
@@ -41,10 +41,21 @@
*
* @param phone The {@code Phone} calling this method.
* @param audioState The new {@link AudioState}.
+ *
+ * @deprecated Use {@link #onCallAudioStateChanged(Phone, CallAudioState)} instead.
*/
+ @Deprecated
public void onAudioStateChanged(Phone phone, AudioState audioState) { }
/**
+ * Called when the audio state changes.
+ *
+ * @param phone The {@code Phone} calling this method.
+ * @param callAudioState The new {@link CallAudioState}.
+ */
+ public void onCallAudioStateChanged(Phone phone, CallAudioState callAudioState) { }
+
+ /**
* Called to bring the in-call screen to the foreground. The in-call experience should
* respond immediately by coming to the foreground to inform the user of the state of
* ongoing {@code Call}s.
@@ -100,7 +111,7 @@
private final InCallAdapter mInCallAdapter;
- private AudioState mAudioState;
+ private CallAudioState mCallAudioState;
private final List<Listener> mListeners = new CopyOnWriteArrayList<>();
@@ -145,10 +156,10 @@
}
}
- final void internalAudioStateChanged(AudioState audioState) {
- if (!Objects.equals(mAudioState, audioState)) {
- mAudioState = audioState;
- fireAudioStateChanged(audioState);
+ final void internalCallAudioStateChanged(CallAudioState callAudioState) {
+ if (!Objects.equals(mCallAudioState, callAudioState)) {
+ mCallAudioState = callAudioState;
+ fireCallAudioStateChanged(callAudioState);
}
}
@@ -271,9 +282,20 @@
* Obtains the current phone call audio state of the {@code Phone}.
*
* @return An object encapsulating the audio state.
+ * @deprecated Use {@link #getCallAudioState()} instead.
*/
+ @Deprecated
public final AudioState getAudioState() {
- return mAudioState;
+ return new AudioState(mCallAudioState);
+ }
+
+ /**
+ * Obtains the current phone call audio state of the {@code Phone}.
+ *
+ * @return An object encapsulating the audio state.
+ */
+ public final CallAudioState getCallAudioState() {
+ return mCallAudioState;
}
private void fireCallAdded(Call call) {
@@ -288,9 +310,10 @@
}
}
- private void fireAudioStateChanged(AudioState audioState) {
+ private void fireCallAudioStateChanged(CallAudioState audioState) {
for (Listener listener : mListeners) {
- listener.onAudioStateChanged(this, audioState);
+ listener.onCallAudioStateChanged(this, audioState);
+ listener.onAudioStateChanged(this, new AudioState(audioState));
}
}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index bab460d..f05a1ef 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -26,6 +26,7 @@
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -47,7 +48,7 @@
* should supply a valid {@link PhoneAccountHandle} that references the connection service
* implementation Telecom will use to interact with the app.
*/
-public class PhoneAccount implements Parcelable {
+public final class PhoneAccount implements Parcelable {
/**
* Flag indicating that this {@code PhoneAccount} can act as a connection manager for
@@ -127,6 +128,7 @@
/**
* Indicating no icon tint is set.
+ * @hide
*/
public static final int NO_ICON_TINT = 0;
@@ -144,14 +146,11 @@
private final Uri mAddress;
private final Uri mSubscriptionAddress;
private final int mCapabilities;
- private final int mIconResId;
- private final String mIconPackageName;
- private final Bitmap mIconBitmap;
- private final int mIconTint;
private final int mHighlightColor;
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
+ private final Icon mIcon;
/**
* Helper class for creating a {@link PhoneAccount}.
@@ -161,14 +160,11 @@
private Uri mAddress;
private Uri mSubscriptionAddress;
private int mCapabilities;
- private int mIconResId;
- private String mIconPackageName;
- private Bitmap mIconBitmap;
- private int mIconTint = NO_ICON_TINT;
private int mHighlightColor = NO_HIGHLIGHT_COLOR;
private CharSequence mLabel;
private CharSequence mShortDescription;
private List<String> mSupportedUriSchemes = new ArrayList<String>();
+ private Icon mIcon;
/**
* Creates a builder with the specified {@link PhoneAccountHandle} and label.
@@ -189,14 +185,11 @@
mAddress = phoneAccount.getAddress();
mSubscriptionAddress = phoneAccount.getSubscriptionAddress();
mCapabilities = phoneAccount.getCapabilities();
- mIconResId = phoneAccount.getIconResId();
- mIconPackageName = phoneAccount.getIconPackageName();
- mIconBitmap = phoneAccount.getIconBitmap();
- mIconTint = phoneAccount.getIconTint();
mHighlightColor = phoneAccount.getHighlightColor();
mLabel = phoneAccount.getLabel();
mShortDescription = phoneAccount.getShortDescription();
mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
+ mIcon = phoneAccount.getIcon();
}
/**
@@ -233,65 +226,12 @@
}
/**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
+ * Sets the icon. See {@link PhoneAccount#getIcon}.
*
- * @param packageContext The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @return The builder.
+ * @param icon The icon to set.
*/
- public Builder setIcon(Context packageContext, int iconResId) {
- return setIcon(packageContext.getPackageName(), iconResId);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconPackageName The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @return The builder.
- */
- public Builder setIcon(String iconPackageName, int iconResId) {
- return setIcon(iconPackageName, iconResId, NO_ICON_TINT);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param packageContext The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @param iconTint A color with which to tint this icon.
- * @return The builder.
- */
- public Builder setIcon(Context packageContext, int iconResId, int iconTint) {
- return setIcon(packageContext.getPackageName(), iconResId, iconTint);
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconPackageName The package from which to load an icon.
- * @param iconResId The resource in {@code iconPackageName} representing the icon.
- * @param iconTint A color with which to tint this icon.
- * @return The builder.
- */
- public Builder setIcon(String iconPackageName, int iconResId, int iconTint) {
- this.mIconPackageName = iconPackageName;
- this.mIconResId = iconResId;
- this.mIconTint = iconTint;
- return this;
- }
-
- /**
- * Sets the icon. See {@link PhoneAccount#createIconDrawable}.
- *
- * @param iconBitmap The icon bitmap.
- * @return The builder.
- */
- public Builder setIcon(Bitmap iconBitmap) {
- this.mIconBitmap = iconBitmap;
- this.mIconPackageName = null;
- this.mIconResId = NO_RESOURCE_ID;
- this.mIconTint = NO_ICON_TINT;
+ public Builder setIcon(Icon icon) {
+ mIcon = icon;
return this;
}
@@ -363,10 +303,7 @@
mAddress,
mSubscriptionAddress,
mCapabilities,
- mIconResId,
- mIconPackageName,
- mIconBitmap,
- mIconTint,
+ mIcon,
mHighlightColor,
mLabel,
mShortDescription,
@@ -379,10 +316,7 @@
Uri address,
Uri subscriptionAddress,
int capabilities,
- int iconResId,
- String iconPackageName,
- Bitmap iconBitmap,
- int iconTint,
+ Icon icon,
int highlightColor,
CharSequence label,
CharSequence shortDescription,
@@ -391,10 +325,7 @@
mAddress = address;
mSubscriptionAddress = subscriptionAddress;
mCapabilities = capabilities;
- mIconResId = iconResId;
- mIconPackageName = iconPackageName;
- mIconBitmap = iconBitmap;
- mIconTint = iconTint;
+ mIcon = icon;
mHighlightColor = highlightColor;
mLabel = label;
mShortDescription = shortDescription;
@@ -497,6 +428,15 @@
}
/**
+ * The icon to represent this {@code PhoneAccount}.
+ *
+ * @return The icon.
+ */
+ public Icon getIcon() {
+ return mIcon;
+ }
+
+ /**
* Determines if the {@link PhoneAccount} supports calls to/from addresses with a specified URI
* scheme.
*
@@ -518,59 +458,6 @@
}
/**
- * The icon resource ID for the icon of this {@code PhoneAccount}.
- * <p>
- * Creators of a {@code PhoneAccount} who possess the icon in static resources should prefer
- * this method of indicating the icon rather than using {@link #getIconBitmap()}, since it
- * leads to less resource usage.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
- *
- * @return A resource ID.
- */
- public int getIconResId() {
- return mIconResId;
- }
-
- /**
- * The package name from which to load the icon of this {@code PhoneAccount}.
- * <p>
- * If this property is {@code null}, the resource {@link #getIconResId()} will be loaded from
- * the package in the {@link ComponentName} of the {@link #getAccountHandle()}.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use {@link #createIconDrawable(Context)}.
- *
- * @return A package name.
- */
- public String getIconPackageName() {
- return mIconPackageName;
- }
-
- /**
- * A tint to apply to the icon of this {@code PhoneAccount}.
- *
- * @return A hexadecimal color value.
- */
- public int getIconTint() {
- return mIconTint;
- }
-
- /**
- * A literal icon bitmap to represent this {@code PhoneAccount} in a user interface.
- * <p>
- * If this property is specified, it is to be considered the preferred icon. Otherwise, the
- * resource specified by {@link #getIconResId()} should be used.
- * <p>
- * Clients wishing to display a {@code PhoneAccount} should use
- * {@link #createIconDrawable(Context)}.
- *
- * @return A bitmap.
- */
- public Bitmap getIconBitmap() {
- return mIconBitmap;
- }
-
- /**
* A highlight color to use in displaying information about this {@code PhoneAccount}.
*
* @return A hexadecimal color value.
@@ -579,41 +466,6 @@
return mHighlightColor;
}
- /**
- * Builds and returns an icon {@code Drawable} to represent this {@code PhoneAccount} in a user
- * interface. Uses the properties {@link #getIconResId()}, {@link #getIconPackageName()}, and
- * {@link #getIconBitmap()} as necessary.
- *
- * @param context A {@code Context} to use for loading {@code Drawable}s.
- *
- * @return An icon for this {@code PhoneAccount}.
- */
- public Drawable createIconDrawable(Context context) {
- if (mIconBitmap != null) {
- return new BitmapDrawable(context.getResources(), mIconBitmap);
- }
-
- if (mIconResId != 0) {
- try {
- Context packageContext = context.createPackageContext(mIconPackageName, 0);
- try {
- Drawable iconDrawable = packageContext.getDrawable(mIconResId);
- if (mIconTint != NO_ICON_TINT) {
- iconDrawable.setTint(mIconTint);
- }
- return iconDrawable;
- } catch (NotFoundException | MissingResourceException e) {
- Log.e(this, e, "Cannot find icon %d in package %s",
- mIconResId, mIconPackageName);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(this, "Cannot find package %s", mIconPackageName);
- }
- }
-
- return new ColorDrawable(Color.TRANSPARENT);
- }
-
//
// Parcelable implementation
//
@@ -644,19 +496,16 @@
mSubscriptionAddress.writeToParcel(out, flags);
}
out.writeInt(mCapabilities);
- out.writeInt(mIconResId);
- out.writeString(mIconPackageName);
- if (mIconBitmap == null) {
- out.writeInt(0);
- } else {
- out.writeInt(1);
- mIconBitmap.writeToParcel(out, flags);
- }
- out.writeInt(mIconTint);
out.writeInt(mHighlightColor);
out.writeCharSequence(mLabel);
out.writeCharSequence(mShortDescription);
out.writeStringList(mSupportedUriSchemes);
+ if (mIcon == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ mIcon.writeToParcel(out, flags);
+ }
}
public static final Creator<PhoneAccount> CREATOR
@@ -689,18 +538,15 @@
mSubscriptionAddress = null;
}
mCapabilities = in.readInt();
- mIconResId = in.readInt();
- mIconPackageName = in.readString();
- if (in.readInt() > 0) {
- mIconBitmap = Bitmap.CREATOR.createFromParcel(in);
- } else {
- mIconBitmap = null;
- }
- mIconTint = in.readInt();
mHighlightColor = in.readInt();
mLabel = in.readCharSequence();
mShortDescription = in.readCharSequence();
mSupportedUriSchemes = Collections.unmodifiableList(in.createStringArrayList());
+ if (in.readInt() > 0) {
+ mIcon = Icon.CREATOR.createFromParcel(in);
+ } else {
+ mIcon = null;
+ }
}
@Override
diff --git a/telecomm/java/android/telecom/PhoneAccountHandle.java b/telecomm/java/android/telecom/PhoneAccountHandle.java
index 60917b2..6dc6e9c 100644
--- a/telecomm/java/android/telecom/PhoneAccountHandle.java
+++ b/telecomm/java/android/telecom/PhoneAccountHandle.java
@@ -35,7 +35,7 @@
*
* See {@link PhoneAccount}, {@link TelecomManager}.
*/
-public class PhoneAccountHandle implements Parcelable {
+public final class PhoneAccountHandle implements Parcelable {
private final ComponentName mComponentName;
private final String mId;
private final UserHandle mUserHandle;
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index a76bf59..095a88f 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -18,6 +18,7 @@
import com.android.internal.telecom.IConnectionService;
+import android.annotation.SystemApi;
import android.os.Handler;
import android.os.RemoteException;
@@ -29,7 +30,10 @@
import java.util.concurrent.CopyOnWriteArraySet;
/**
- * Represents a conference call which can contain any number of {@link Connection} objects.
+ * A conference provided to a {@link ConnectionService} by another {@code ConnectionService}
+ * running in a different process.
+ *
+ * @see ConnectionService#onRemoteConferenceAdded
*/
public final class RemoteConference {
@@ -62,18 +66,18 @@
private DisconnectCause mDisconnectCause;
private int mConnectionCapabilities;
- /** {@hide} */
+ /** @hide */
RemoteConference(String id, IConnectionService connectionService) {
mId = id;
mConnectionService = connectionService;
}
- /** {@hide} */
+ /** @hide */
String getId() {
return mId;
}
- /** {@hide} */
+ /** @hide */
void setDestroyed() {
for (RemoteConnection connection : mChildConnections) {
connection.setConference(null);
@@ -90,7 +94,7 @@
}
}
- /** {@hide} */
+ /** @hide */
void setState(final int newState) {
if (newState != Connection.STATE_ACTIVE &&
newState != Connection.STATE_HOLDING &&
@@ -116,7 +120,7 @@
}
}
- /** {@hide} */
+ /** @hide */
void addConnection(final RemoteConnection connection) {
if (!mChildConnections.contains(connection)) {
mChildConnections.add(connection);
@@ -134,7 +138,7 @@
}
}
- /** {@hide} */
+ /** @hide */
void removeConnection(final RemoteConnection connection) {
if (mChildConnections.contains(connection)) {
mChildConnections.remove(connection);
@@ -152,7 +156,7 @@
}
}
- /** {@hide} */
+ /** @hide */
void setConnectionCapabilities(final int connectionCapabilities) {
if (mConnectionCapabilities != connectionCapabilities) {
mConnectionCapabilities = connectionCapabilities;
@@ -187,7 +191,7 @@
}
}
- /** {@hide} */
+ /** @hide */
void setDisconnected(final DisconnectCause disconnectCause) {
if (mState != Connection.STATE_DISCONNECTED) {
mDisconnectCause = disconnectCause;
@@ -205,18 +209,37 @@
}
}
+ /**
+ * Returns the list of {@link RemoteConnection}s contained in this conference.
+ *
+ * @return A list of child connections.
+ */
public final List<RemoteConnection> getConnections() {
return mUnmodifiableChildConnections;
}
+ /**
+ * Gets the state of the conference call. See {@link Connection} for valid values.
+ *
+ * @return A constant representing the state the conference call is currently in.
+ */
public final int getState() {
return mState;
}
+ /**
+ * Returns the capabilities of the conference. See {@code CAPABILITY_*} constants in class
+ * {@link Connection} for valid values.
+ *
+ * @return A bitmask of the capabilities of the conference call.
+ */
public final int getConnectionCapabilities() {
return mConnectionCapabilities;
}
+ /**
+ * Disconnects the conference call as well as the child {@link RemoteConnection}s.
+ */
public void disconnect() {
try {
mConnectionService.disconnect(mId);
@@ -224,6 +247,13 @@
}
}
+ /**
+ * Removes the specified {@link RemoteConnection} from the conference. This causes the
+ * {@link RemoteConnection} to become a standalone connection. This is a no-op if the
+ * {@link RemoteConnection} does not belong to this conference.
+ *
+ * @param connection The remote-connection to remove.
+ */
public void separate(RemoteConnection connection) {
if (mChildConnections.contains(connection)) {
try {
@@ -233,6 +263,16 @@
}
}
+ /**
+ * Merges all {@link RemoteConnection}s of this conference into a single call. This should be
+ * invoked only if the conference contains the capability
+ * {@link Connection#CAPABILITY_MERGE_CONFERENCE}, otherwise it is a no-op. The presence of said
+ * capability indicates that the connections of this conference, despite being part of the
+ * same conference object, are yet to have their audio streams merged; this is a common pattern
+ * for CDMA conference calls, but the capability is not used for GSM and SIP conference calls.
+ * Invoking this method will cause the unmerged child connections to merge their audio
+ * streams.
+ */
public void merge() {
try {
mConnectionService.mergeConference(mId);
@@ -240,6 +280,15 @@
}
}
+ /**
+ * Swaps the active audio stream between the conference's child {@link RemoteConnection}s.
+ * This should be invoked only if the conference contains the capability
+ * {@link Connection#CAPABILITY_SWAP_CONFERENCE}, otherwise it is a no-op. This is only used by
+ * {@link ConnectionService}s that create conferences for connections that do not yet have
+ * their audio streams merged; this is a common pattern for CDMA conference calls, but the
+ * capability is not used for GSM and SIP conference calls. Invoking this method will change the
+ * active audio stream to a different child connection.
+ */
public void swap() {
try {
mConnectionService.swapConference(mId);
@@ -247,6 +296,9 @@
}
}
+ /**
+ * Puts the conference on hold.
+ */
public void hold() {
try {
mConnectionService.hold(mId);
@@ -254,6 +306,9 @@
}
}
+ /**
+ * Unholds the conference call.
+ */
public void unhold() {
try {
mConnectionService.unhold(mId);
@@ -261,10 +316,22 @@
}
}
+ /**
+ * Returns the {@link DisconnectCause} for the conference if it is in the state
+ * {@link Connection#STATE_DISCONNECTED}. If the conference is not disconnected, this will
+ * return null.
+ *
+ * @return The disconnect cause.
+ */
public DisconnectCause getDisconnectCause() {
return mDisconnectCause;
}
+ /**
+ * Requests that the conference start playing the specified DTMF tone.
+ *
+ * @param digit The digit for which to play a DTMF tone.
+ */
public void playDtmfTone(char digit) {
try {
mConnectionService.playDtmfTone(mId, digit);
@@ -272,6 +339,11 @@
}
}
+ /**
+ * Stops the most recent request to play a DTMF tone.
+ *
+ * @see #playDtmfTone
+ */
public void stopDtmfTone() {
try {
mConnectionService.stopDtmfTone(mId);
@@ -279,21 +351,57 @@
}
}
+ /**
+ * Request to change the conference's audio routing to the specified state. The specified state
+ * can include audio routing (Bluetooth, Speaker, etc) and muting state.
+ *
+ * @see android.telecom.AudioState
+ * @deprecated Use {@link #setCallAudioState(CallAudioState)} instead.
+ * @hide
+ */
+ @SystemApi
+ @Deprecated
public void setAudioState(AudioState state) {
+ setCallAudioState(new CallAudioState(state));
+ }
+
+ /**
+ * Request to change the conference's audio routing to the specified state. The specified state
+ * can include audio routing (Bluetooth, Speaker, etc) and muting state.
+ */
+ public void setCallAudioState(CallAudioState state) {
try {
- mConnectionService.onAudioStateChanged(mId, state);
+ mConnectionService.onCallAudioStateChanged(mId, state);
} catch (RemoteException e) {
}
}
+
+ /**
+ * Returns a list of independent connections that can me merged with this conference.
+ *
+ * @return A list of conferenceable connections.
+ */
public List<RemoteConnection> getConferenceableConnections() {
return mUnmodifiableConferenceableConnections;
}
+ /**
+ * Register a callback through which to receive state updates for this conference.
+ *
+ * @param callback The callback to notify of state changes.
+ */
public final void registerCallback(Callback callback) {
registerCallback(callback, new Handler());
}
+ /**
+ * Registers a callback through which to receive state updates for this conference.
+ * Callbacks will be notified using the specified handler, if provided.
+ *
+ * @param callback The callback to notify of state changes.
+ * @param handler The handler on which to execute the callbacks.
+ */
public final void registerCallback(Callback callback, Handler handler) {
unregisterCallback(callback);
if (callback != null && handler != null) {
@@ -301,6 +409,13 @@
}
}
+ /**
+ * Unregisters a previously registered callback.
+ *
+ * @see #registerCallback
+ *
+ * @param callback The callback to unregister.
+ */
public final void unregisterCallback(Callback callback) {
if (callback != null) {
for (CallbackRecord<Callback> record : mCallbackRecords) {
diff --git a/telecomm/java/android/telecom/RemoteConnection.java b/telecomm/java/android/telecom/RemoteConnection.java
index 9ca9f316..1d6e15c 100644
--- a/telecomm/java/android/telecom/RemoteConnection.java
+++ b/telecomm/java/android/telecom/RemoteConnection.java
@@ -20,6 +20,7 @@
import com.android.internal.telecom.IVideoCallback;
import com.android.internal.telecom.IVideoProvider;
+import android.annotation.SystemApi;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
@@ -220,7 +221,7 @@
public void onCameraCapabilitiesChanged(
VideoProvider videoProvider,
- CameraCapabilities cameraCapabilities) {}
+ VideoProfile.CameraCapabilities cameraCapabilities) {}
public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {}
}
@@ -267,7 +268,8 @@
}
@Override
- public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
+ public void changeCameraCapabilities(
+ VideoProfile.CameraCapabilities cameraCapabilities) {
for (Listener l : mListeners) {
l.onCameraCapabilitiesChanged(VideoProvider.this, cameraCapabilities);
}
@@ -378,7 +380,7 @@
}
}
- public void setPauseImage(String uri) {
+ public void setPauseImage(Uri uri) {
try {
mVideoProviderBinder.setPauseImage(uri);
} catch (RemoteException e) {
@@ -775,11 +777,24 @@
* Set the audio state of this {@code RemoteConnection}.
*
* @param state The audio state of this {@code RemoteConnection}.
+ * @hide
+ * @deprecated Use {@link #setCallAudioState(CallAudioState) instead.
*/
+ @SystemApi
+ @Deprecated
public void setAudioState(AudioState state) {
+ setCallAudioState(new CallAudioState(state));
+ }
+
+ /**
+ * Set the audio state of this {@code RemoteConnection}.
+ *
+ * @param state The audio state of this {@code RemoteConnection}.
+ */
+ public void setCallAudioState(CallAudioState state) {
try {
if (mConnected) {
- mConnectionService.onAudioStateChanged(mConnectionId, state);
+ mConnectionService.onCallAudioStateChanged(mConnectionId, state);
}
} catch (RemoteException ignored) {
}
@@ -945,7 +960,7 @@
record.getHandler().post(new Runnable() {
@Override
public void run() {
- callback.onPostDialWait(connection, String.valueOf(nextChar));
+ callback.onPostDialChar(connection, nextChar);
}
});
}
diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java
index a32eae7..453f408 100644
--- a/telecomm/java/android/telecom/StatusHints.java
+++ b/telecomm/java/android/telecom/StatusHints.java
@@ -16,15 +16,15 @@
package android.telecom;
+import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
-import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.MissingResourceException;
import java.util.Objects;
/**
@@ -32,24 +32,35 @@
*/
public final class StatusHints implements Parcelable {
- private final ComponentName mPackageName;
private final CharSequence mLabel;
- private final int mIconResId;
+ private final Icon mIcon;
private final Bundle mExtras;
+ /**
+ * @hide
+ */
+ @SystemApi @Deprecated
public StatusHints(ComponentName packageName, CharSequence label, int iconResId,
Bundle extras) {
- mPackageName = packageName;
+ this(label, iconResId == 0 ? null : Icon.createWithResource(packageName.getPackageName(),
+ iconResId), extras);
+ }
+
+ public StatusHints(CharSequence label, Icon icon, Bundle extras) {
mLabel = label;
- mIconResId = iconResId;
+ mIcon = icon;
mExtras = extras;
}
/**
* @return A package used to load the icon.
+ *
+ * @hide
*/
+ @SystemApi @Deprecated
public ComponentName getPackageName() {
- return mPackageName;
+ // Minimal compatibility shim for legacy apps' tests
+ return new ComponentName("", "");
}
/**
@@ -63,16 +74,30 @@
* The icon resource ID for the icon to show.
*
* @return A resource ID.
+ *
+ * @hide
*/
+ @SystemApi @Deprecated
public int getIconResId() {
- return mIconResId;
+ // Minimal compatibility shim for legacy apps' tests
+ return 0;
}
/**
* @return An icon displayed in the in-call UI.
+ *
+ * @hide
*/
+ @SystemApi @Deprecated
public Drawable getIcon(Context context) {
- return getIcon(context, mIconResId);
+ return mIcon.loadDrawable(context);
+ }
+
+ /**
+ * @return An icon depicting the status.
+ */
+ public Icon getIcon() {
+ return mIcon;
}
/**
@@ -89,9 +114,8 @@
@Override
public void writeToParcel(Parcel out, int flags) {
- out.writeParcelable(mPackageName, flags);
out.writeCharSequence(mLabel);
- out.writeInt(mIconResId);
+ out.writeParcelable(mIcon, 0);
out.writeParcelable(mExtras, 0);
}
@@ -107,36 +131,17 @@
};
private StatusHints(Parcel in) {
- mPackageName = in.readParcelable(getClass().getClassLoader());
mLabel = in.readCharSequence();
- mIconResId = in.readInt();
+ mIcon = in.readParcelable(getClass().getClassLoader());
mExtras = in.readParcelable(getClass().getClassLoader());
}
- private Drawable getIcon(Context context, int resId) {
- Context packageContext;
- try {
- packageContext = context.createPackageContext(mPackageName.getPackageName(), 0);
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(this, e, "Cannot find package %s", mPackageName.getPackageName());
- return null;
- }
- try {
- return packageContext.getDrawable(resId);
- } catch (MissingResourceException e) {
- Log.e(this, e, "Cannot find icon %d in package %s",
- resId, mPackageName.getPackageName());
- return null;
- }
- }
-
@Override
public boolean equals(Object other) {
if (other != null && other instanceof StatusHints) {
StatusHints otherHints = (StatusHints) other;
- return Objects.equals(otherHints.getPackageName(), getPackageName()) &&
- Objects.equals(otherHints.getLabel(), getLabel()) &&
- otherHints.getIconResId() == getIconResId() &&
+ return Objects.equals(otherHints.getLabel(), getLabel()) &&
+ Objects.equals(otherHints.getIcon(), getIcon()) &&
Objects.equals(otherHints.getExtras(), getExtras());
}
return false;
@@ -144,7 +149,6 @@
@Override
public int hashCode() {
- return Objects.hashCode(mPackageName) + Objects.hashCode(mLabel) + mIconResId +
- Objects.hashCode(mExtras);
+ return Objects.hashCode(mLabel) + Objects.hashCode(mIcon) + Objects.hashCode(mExtras);
}
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index ebd3f12..c8ed2b0 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -142,10 +142,10 @@
* Optional extra for {@link android.content.Intent#ACTION_CALL} containing an integer that
* determines the desired video state for an outgoing call.
* Valid options:
- * {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#RX_ENABLED},
- * {@link VideoProfile.VideoState#TX_ENABLED}.
+ * {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_RX_ENABLED},
+ * {@link VideoProfile#STATE_TX_ENABLED}.
*/
public static final String EXTRA_START_CALL_WITH_VIDEO_STATE =
"android.telecom.extra.START_CALL_WITH_VIDEO_STATE";
@@ -333,16 +333,24 @@
* displayed to the user.
*/
- /** Property is displayed normally. */
+ /**
+ * Indicates that the address or number of a call is allowed to be displayed for caller ID.
+ */
public static final int PRESENTATION_ALLOWED = 1;
- /** Property was blocked. */
+ /**
+ * Indicates that the address or number of a call is blocked by the other party.
+ */
public static final int PRESENTATION_RESTRICTED = 2;
- /** Presentation was not specified or is unknown. */
+ /**
+ * Indicates that the address or number of a call is not specified or known by the carrier.
+ */
public static final int PRESENTATION_UNKNOWN = 3;
- /** Property should be displayed as a pay phone. */
+ /**
+ * Indicates that the address or number of a call belongs to a pay phone.
+ */
public static final int PRESENTATION_PAYPHONE = 4;
private static final String TAG = "TelecomManager";
diff --git a/telecomm/java/android/telecom/VideoCallImpl.java b/telecomm/java/android/telecom/VideoCallImpl.java
index 331f57e..c8072d1 100644
--- a/telecomm/java/android/telecom/VideoCallImpl.java
+++ b/telecomm/java/android/telecom/VideoCallImpl.java
@@ -16,6 +16,7 @@
package android.telecom;
+import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -98,7 +99,7 @@
}
@Override
- public void changeCameraCapabilities(CameraCapabilities cameraCapabilities) {
+ public void changeCameraCapabilities(VideoProfile.CameraCapabilities cameraCapabilities) {
mHandler.obtainMessage(MessageHandler.MSG_CHANGE_CAMERA_CAPABILITIES,
cameraCapabilities).sendToTarget();
}
@@ -160,7 +161,7 @@
break;
case MSG_CHANGE_CAMERA_CAPABILITIES:
mCallback.onCameraCapabilitiesChanged(
- (CameraCapabilities) msg.obj);
+ (VideoProfile.CameraCapabilities) msg.obj);
break;
case MSG_CHANGE_VIDEO_QUALITY:
mVideoQuality = msg.arg1;
@@ -302,7 +303,7 @@
}
/** {@inheritDoc} */
- public void setPauseImage(String uri) {
+ public void setPauseImage(Uri uri) {
try {
mVideoProvider.setPauseImage(uri);
} catch (RemoteException e) {
diff --git a/telecomm/java/android/telecom/VideoCallbackServant.java b/telecomm/java/android/telecom/VideoCallbackServant.java
index 1123621..1fbad224 100644
--- a/telecomm/java/android/telecom/VideoCallbackServant.java
+++ b/telecomm/java/android/telecom/VideoCallbackServant.java
@@ -98,7 +98,7 @@
break;
}
case MSG_CHANGE_CAMERA_CAPABILITIES: {
- mDelegate.changeCameraCapabilities((CameraCapabilities) msg.obj);
+ mDelegate.changeCameraCapabilities((VideoProfile.CameraCapabilities) msg.obj);
break;
}
case MSG_CHANGE_VIDEO_QUALITY: {
@@ -148,7 +148,8 @@
}
@Override
- public void changeCameraCapabilities(CameraCapabilities cameraCapabilities)
+ public void changeCameraCapabilities(
+ VideoProfile.CameraCapabilities cameraCapabilities)
throws RemoteException {
mHandler.obtainMessage(MSG_CHANGE_CAMERA_CAPABILITIES, cameraCapabilities)
.sendToTarget();
diff --git a/telecomm/java/android/telecom/VideoProfile.aidl b/telecomm/java/android/telecom/VideoProfile.aidl
index 091b569..0b32721 100644
--- a/telecomm/java/android/telecom/VideoProfile.aidl
+++ b/telecomm/java/android/telecom/VideoProfile.aidl
@@ -21,3 +21,4 @@
* {@hide}
*/
parcelable VideoProfile;
+parcelable VideoProfile.CameraCapabilities;
diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java
index 902fddb..71de505 100644
--- a/telecomm/java/android/telecom/VideoProfile.java
+++ b/telecomm/java/android/telecom/VideoProfile.java
@@ -48,6 +48,31 @@
*/
public static final int QUALITY_DEFAULT = 4;
+ /**
+ * Call is currently in an audio-only mode with no video transmission or receipt.
+ */
+ public static final int STATE_AUDIO_ONLY = 0x0;
+
+ /**
+ * Video transmission is enabled.
+ */
+ public static final int STATE_TX_ENABLED = 0x1;
+
+ /**
+ * Video reception is enabled.
+ */
+ public static final int STATE_RX_ENABLED = 0x2;
+
+ /**
+ * Video signal is bi-directional.
+ */
+ public static final int STATE_BIDIRECTIONAL = STATE_TX_ENABLED | STATE_RX_ENABLED;
+
+ /**
+ * Video is paused.
+ */
+ public static final int STATE_PAUSED = 0x4;
+
private final int mVideoState;
private final int mQuality;
@@ -74,11 +99,11 @@
/**
* The video state of the call.
- * Valid values: {@link VideoProfile.VideoState#AUDIO_ONLY},
- * {@link VideoProfile.VideoState#BIDIRECTIONAL},
- * {@link VideoProfile.VideoState#TX_ENABLED},
- * {@link VideoProfile.VideoState#RX_ENABLED},
- * {@link VideoProfile.VideoState#PAUSED}.
+ * Valid values: {@link VideoProfile#STATE_AUDIO_ONLY},
+ * {@link VideoProfile#STATE_BIDIRECTIONAL},
+ * {@link VideoProfile#STATE_TX_ENABLED},
+ * {@link VideoProfile#STATE_RX_ENABLED},
+ * {@link VideoProfile#STATE_PAUSED}.
*/
public int getVideoState() {
return mVideoState;
@@ -162,28 +187,41 @@
public static class VideoState {
/**
* Call is currently in an audio-only mode with no video transmission or receipt.
+ * @deprecated Use {@link VideoProfile#STATE_AUDIO_ONLY} instead
+ * @hide
*/
- public static final int AUDIO_ONLY = 0x0;
+ public static final int AUDIO_ONLY = VideoProfile.STATE_AUDIO_ONLY;
/**
* Video transmission is enabled.
+ * @deprecated Use {@link VideoProfile#STATE_TX_ENABLED} instead
+ * @hide
*/
- public static final int TX_ENABLED = 0x1;
+ public static final int TX_ENABLED = VideoProfile.STATE_TX_ENABLED;
/**
* Video reception is enabled.
+ * @deprecated Use {@link VideoProfile#STATE_RX_ENABLED} instead
+ * @hide
*/
- public static final int RX_ENABLED = 0x2;
+ public static final int RX_ENABLED = VideoProfile.STATE_RX_ENABLED;
/**
* Video signal is bi-directional.
+ * @deprecated Use {@link VideoProfile#STATE_BIDIRECTIONAL} instead
+ * @hide
*/
- public static final int BIDIRECTIONAL = TX_ENABLED | RX_ENABLED;
+ public static final int BIDIRECTIONAL = VideoProfile.STATE_BIDIRECTIONAL;
/**
* Video is paused.
+ * @deprecated Use {@link VideoProfile#STATE_PAUSED} instead
+ * @hide
*/
- public static final int PAUSED = 0x4;
+ public static final int PAUSED = VideoProfile.STATE_PAUSED;
+
+ /** @hide */
+ private VideoState() {}
/**
* Whether the video state is audio only.
@@ -191,7 +229,8 @@
* @return Returns true if the video state is audio only.
*/
public static boolean isAudioOnly(int videoState) {
- return !hasState(videoState, TX_ENABLED) && !hasState(videoState, RX_ENABLED);
+ return !hasState(videoState, VideoProfile.STATE_TX_ENABLED)
+ && !hasState(videoState, VideoProfile.STATE_RX_ENABLED);
}
/**
@@ -201,8 +240,9 @@
* @return Returns true if the video state TX or RX or Bidirectional
*/
public static boolean isVideo(int videoState) {
- return hasState(videoState, TX_ENABLED) || hasState(videoState, RX_ENABLED)
- || hasState(videoState, BIDIRECTIONAL);
+ return hasState(videoState, VideoProfile.STATE_TX_ENABLED)
+ || hasState(videoState, VideoProfile.STATE_RX_ENABLED)
+ || hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
}
/**
@@ -211,7 +251,7 @@
* @return Returns true if the video transmission is enabled.
*/
public static boolean isTransmissionEnabled(int videoState) {
- return hasState(videoState, TX_ENABLED);
+ return hasState(videoState, VideoProfile.STATE_TX_ENABLED);
}
/**
@@ -220,7 +260,7 @@
* @return Returns true if the video transmission is enabled.
*/
public static boolean isReceptionEnabled(int videoState) {
- return hasState(videoState, RX_ENABLED);
+ return hasState(videoState, VideoProfile.STATE_RX_ENABLED);
}
/**
@@ -229,7 +269,7 @@
* @return Returns true if the video signal is bi-directional.
*/
public static boolean isBidirectional(int videoState) {
- return hasState(videoState, BIDIRECTIONAL);
+ return hasState(videoState, VideoProfile.STATE_BIDIRECTIONAL);
}
/**
@@ -238,7 +278,7 @@
* @return Returns true if the video is paused.
*/
public static boolean isPaused(int videoState) {
- return hasState(videoState, PAUSED);
+ return hasState(videoState, VideoProfile.STATE_PAUSED);
}
/**
@@ -278,4 +318,142 @@
return sb.toString();
}
}
+
+ /**
+ * Represents the camera capabilities important to a Video Telephony provider.
+ */
+ public static final class CameraCapabilities implements Parcelable {
+
+ /**
+ * The width of the camera video in pixels.
+ */
+ private final int mWidth;
+
+ /**
+ * The height of the camera video in pixels.
+ */
+ private final int mHeight;
+
+ /**
+ * Whether the camera supports zoom.
+ */
+ private final boolean mZoomSupported;
+
+ /**
+ * The maximum zoom supported by the camera.
+ */
+ private final float mMaxZoom;
+
+ /**
+ * Create a call camera capabilities instance.
+ *
+ * @param width The width of the camera video (in pixels).
+ * @param height The height of the camera video (in pixels).
+ */
+ public CameraCapabilities(int width, int height) {
+ this(width, height, false, 1.0f);
+ }
+
+ /**
+ * Create a call camera capabilities instance that optionally
+ * supports zoom.
+ *
+ * @param width The width of the camera video (in pixels).
+ * @param height The height of the camera video (in pixels).
+ * @param zoomSupported True when camera supports zoom.
+ * @param maxZoom Maximum zoom supported by camera.
+ * @hide
+ */
+ public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) {
+ mWidth = width;
+ mHeight = height;
+ mZoomSupported = zoomSupported;
+ mMaxZoom = maxZoom;
+ }
+
+ /**
+ * Responsible for creating CallCameraCapabilities objects from deserialized Parcels.
+ **/
+ public static final Parcelable.Creator<CameraCapabilities> CREATOR =
+ new Parcelable.Creator<CameraCapabilities> () {
+ /**
+ * Creates a CallCameraCapabilities instances from a parcel.
+ *
+ * @param source The parcel.
+ * @return The CallCameraCapabilities.
+ */
+ @Override
+ public CameraCapabilities createFromParcel(Parcel source) {
+ int width = source.readInt();
+ int height = source.readInt();
+ boolean supportsZoom = source.readByte() != 0;
+ float maxZoom = source.readFloat();
+
+ return new CameraCapabilities(width, height, supportsZoom, maxZoom);
+ }
+
+ @Override
+ public CameraCapabilities[] newArray(int size) {
+ return new CameraCapabilities[size];
+ }
+ };
+
+ /**
+ * Describe the kinds of special objects contained in this Parcelable's
+ * marshalled representation.
+ *
+ * @return a bitmask indicating the set of special object types marshalled
+ * by the Parcelable.
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Flatten this object in to a Parcel.
+ *
+ * @param dest The Parcel in which the object should be written.
+ * @param flags Additional flags about how the object should be written.
+ * May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(getWidth());
+ dest.writeInt(getHeight());
+ dest.writeByte((byte) (isZoomSupported() ? 1 : 0));
+ dest.writeFloat(getMaxZoom());
+ }
+
+ /**
+ * The width of the camera video in pixels.
+ */
+ public int getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * The height of the camera video in pixels.
+ */
+ public int getHeight() {
+ return mHeight;
+ }
+
+ /**
+ * Whether the camera supports zoom.
+ * @hide
+ */
+ public boolean isZoomSupported() {
+ return mZoomSupported;
+ }
+
+ /**
+ * The maximum zoom supported by the camera.
+ * @hide
+ */
+ public float getMaxZoom() {
+ return mMaxZoom;
+ }
+ }
+
}
diff --git a/telecomm/java/android/telecom/Voicemail.java b/telecomm/java/android/telecom/Voicemail.java
index f5b8052..151917e 100644
--- a/telecomm/java/android/telecom/Voicemail.java
+++ b/telecomm/java/android/telecom/Voicemail.java
@@ -28,6 +28,7 @@
public class Voicemail implements Parcelable {
private final Long mTimestamp;
private final String mNumber;
+ private final PhoneAccountHandle mPhoneAccount;
private final Long mId;
private final Long mDuration;
private final String mSource;
@@ -36,10 +37,12 @@
private final Boolean mIsRead;
private final Boolean mHasContent;
- private Voicemail(Long timestamp, String number, Long id, Long duration, String source,
- String providerData, Uri uri, Boolean isRead, Boolean hasContent) {
+ private Voicemail(Long timestamp, String number, PhoneAccountHandle phoneAccountHandle, Long id,
+ Long duration, String source, String providerData, Uri uri, Boolean isRead,
+ Boolean hasContent) {
mTimestamp = timestamp;
mNumber = number;
+ mPhoneAccount = phoneAccountHandle;
mId = id;
mDuration = duration;
mSource = source;
@@ -77,6 +80,7 @@
public static class Builder {
private Long mBuilderTimestamp;
private String mBuilderNumber;
+ private PhoneAccountHandle mBuilderPhoneAccount;
private Long mBuilderId;
private Long mBuilderDuration;
private String mBuilderSourcePackage;
@@ -99,6 +103,11 @@
return this;
}
+ public Builder setPhoneAccount(PhoneAccountHandle phoneAccount) {
+ mBuilderPhoneAccount = phoneAccount;
+ return this;
+ }
+
public Builder setId(long id) {
mBuilderId = id;
return this;
@@ -139,9 +148,9 @@
mBuilderTimestamp = mBuilderTimestamp == null ? 0 : mBuilderTimestamp;
mBuilderDuration = mBuilderDuration == null ? 0: mBuilderDuration;
mBuilderIsRead = mBuilderIsRead == null ? false : mBuilderIsRead;
- return new Voicemail(mBuilderTimestamp, mBuilderNumber, mBuilderId, mBuilderDuration,
- mBuilderSourcePackage, mBuilderSourceData, mBuilderUri, mBuilderIsRead,
- mBuilderHasContent);
+ return new Voicemail(mBuilderTimestamp, mBuilderNumber, mBuilderPhoneAccount,
+ mBuilderId, mBuilderDuration, mBuilderSourcePackage, mBuilderSourceData,
+ mBuilderUri, mBuilderIsRead, mBuilderHasContent);
}
}
@@ -161,6 +170,11 @@
return mNumber;
}
+ /** The phone account associated with the voicemail, null if not set. */
+ public PhoneAccountHandle getPhoneAccount() {
+ return mPhoneAccount;
+ }
+
/** The timestamp the voicemail was received, in millis since the epoch, zero if not set. */
public long getTimestampMillis() {
return mTimestamp;
@@ -225,6 +239,12 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mTimestamp);
dest.writeCharSequence(mNumber);
+ if (mPhoneAccount == null) {
+ dest.writeInt(0);
+ } else {
+ dest.writeInt(1);
+ mPhoneAccount.writeToParcel(dest, flags);
+ }
dest.writeLong(mId);
dest.writeLong(mDuration);
dest.writeCharSequence(mSource);
@@ -263,6 +283,11 @@
private Voicemail(Parcel in) {
mTimestamp = in.readLong();
mNumber = (String) in.readCharSequence();
+ if (in.readInt() > 0) {
+ mPhoneAccount = PhoneAccountHandle.CREATOR.createFromParcel(in);
+ } else {
+ mPhoneAccount = null;
+ }
mId = in.readLong();
mDuration = in.readLong();
mSource = (String) in.readCharSequence();
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
index 339a982..c2e8530 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionService.aidl
@@ -17,7 +17,7 @@
package com.android.internal.telecom;
import android.os.Bundle;
-import android.telecom.AudioState;
+import android.telecom.CallAudioState;
import android.telecom.ConnectionRequest;
import android.telecom.PhoneAccountHandle;
@@ -56,7 +56,7 @@
void unhold(String callId);
- void onAudioStateChanged(String activeCallId, in AudioState audioState);
+ void onCallAudioStateChanged(String activeCallId, in CallAudioState callAudioState);
void playDtmfTone(String callId, char digit);
diff --git a/telecomm/java/com/android/internal/telecom/IInCallService.aidl b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
index d26f6cb..ded47d5 100644
--- a/telecomm/java/com/android/internal/telecom/IInCallService.aidl
+++ b/telecomm/java/com/android/internal/telecom/IInCallService.aidl
@@ -17,7 +17,7 @@
package com.android.internal.telecom;
import android.app.PendingIntent;
-import android.telecom.AudioState;
+import android.telecom.CallAudioState;
import android.telecom.ParcelableCall;
import com.android.internal.telecom.IInCallAdapter;
@@ -40,7 +40,7 @@
void setPostDialWait(String callId, String remaining);
- void onAudioStateChanged(in AudioState audioState);
+ void onCallAudioStateChanged(in CallAudioState callAudioState);
void bringToForeground(boolean showDialpad);
diff --git a/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl b/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl
index 59f8f0c..cdfad02 100644
--- a/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl
+++ b/telecomm/java/com/android/internal/telecom/IVideoCallback.aidl
@@ -16,7 +16,6 @@
package com.android.internal.telecom;
-import android.telecom.CameraCapabilities;
import android.telecom.VideoProfile;
/**
@@ -41,7 +40,7 @@
void changeCallDataUsage(long dataUsage);
- void changeCameraCapabilities(in CameraCapabilities cameraCapabilities);
+ void changeCameraCapabilities(in VideoProfile.CameraCapabilities cameraCapabilities);
void changeVideoQuality(int videoQuality);
}
diff --git a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
index d095744..68e5fd4 100644
--- a/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
+++ b/telecomm/java/com/android/internal/telecom/IVideoProvider.aidl
@@ -16,6 +16,7 @@
package com.android.internal.telecom;
+import android.net.Uri;
import android.view.Surface;
import android.telecom.VideoProfile;
@@ -47,5 +48,5 @@
void requestCallDataUsage();
- void setPauseImage(String uri);
+ void setPauseImage(in Uri uri);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 299c7c4..b3beaf9 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -18,9 +18,11 @@
import com.android.internal.telephony.ICarrierConfigLoader;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.Context;
-import android.os.Bundle;
+import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -131,8 +133,8 @@
/** Used in Cellular Network Settings for preferred network type. */
public static final String BOOL_PREFER_2G = "bool_prefer_2g";
- /** Show cdma auto network mode in (glabal) roaming */
- public static final String BOOL_SHOW_CDMA = "bool_show_cdma";
+ /** Show cdma network mode choices 1x, 3G, global etc. */
+ public static final String BOOL_SHOW_CDMA_CHOICES = "bool_show_cdma_choices";
/** CDMA activation goes through HFA */
public static final String BOOL_USE_HFA_FOR_PROVISIONING = "bool_use_hfa_for_provisioning";
@@ -232,10 +234,10 @@
private final static String TAG = "CarrierConfigManager";
/** The default value for every variable. */
- private final static Bundle sDefaults;
+ private final static PersistableBundle sDefaults;
static {
- sDefaults = new Bundle();
+ sDefaults = new PersistableBundle();
sDefaults.putBoolean(BOOL_ADDITIONAL_CALL_SETTING, true);
sDefaults.putBoolean(BOOL_ALLOW_EMERGENCY_NUMBERS_IN_CALL_LOG, false);
sDefaults.putBoolean(BOOL_ALLOW_LOCAL_DTMF_TONES, true);
@@ -254,7 +256,7 @@
sDefaults.putBoolean(BOOL_OPERATOR_SELECTION_EXPAND, true);
sDefaults.putBoolean(BOOL_PREFER_2G, true);
sDefaults.putBoolean(BOOL_SHOW_APN_SETTING_CDMA, false);
- sDefaults.putBoolean(BOOL_SHOW_CDMA, false);
+ sDefaults.putBoolean(BOOL_SHOW_CDMA_CHOICES, false);
sDefaults.putBoolean(BOOL_SHOW_ONSCREEN_DIAL_BUTTON, true);
sDefaults.putBoolean(BOOL_SIM_NETWORK_UNLOCK_ALLOW_DISMISS, true);
sDefaults.putBoolean(BOOL_SUPPORT_PAUSE_IMS_VIDEO_CALLS, true);
@@ -276,10 +278,11 @@
* values.
*
* @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
- * @return A {@link Bundle} containing the config for the given subId, or default values for an
- * invalid subId.
+ * @return A {@link PersistableBundle} containing the config for the given subId, or default
+ * values for an invalid subId.
*/
- public Bundle getConfigForSubId(int subId) {
+ @Nullable
+ public PersistableBundle getConfigForSubId(int subId) {
try {
return getICarrierConfigLoader().getConfigForSubId(subId);
} catch (RemoteException ex) {
@@ -297,7 +300,8 @@
*
* @see #getConfigForSubId
*/
- public Bundle getConfig() {
+ @Nullable
+ public PersistableBundle getConfig() {
return getConfigForSubId(SubscriptionManager.getDefaultSubId());
}
@@ -348,9 +352,10 @@
*
* @hide
*/
+ @NonNull
@SystemApi
- public static Bundle getDefaultConfig() {
- return new Bundle(sDefaults);
+ public static PersistableBundle getDefaultConfig() {
+ return new PersistableBundle(sDefaults);
}
/** @hide */
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 9fea418..0c5c557 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -255,5 +255,43 @@
return type;
}
-}
+ public static int singleRafTypeFromString(String rafString) {
+ switch (rafString) {
+ case "GPRS": return RAF_GPRS;
+ case "EDGE": return RAF_EDGE;
+ case "UMTS": return RAF_UMTS;
+ case "IS95A": return RAF_IS95A;
+ case "IS95B": return RAF_IS95B;
+ case "1XRTT": return RAF_1xRTT;
+ case "EVDO_0": return RAF_EVDO_0;
+ case "EVDO_A": return RAF_EVDO_A;
+ case "HSDPA": return RAF_HSDPA;
+ case "HSUPA": return RAF_HSUPA;
+ case "HSPA": return RAF_HSPA;
+ case "EVDO_B": return RAF_EVDO_B;
+ case "EHRPD": return RAF_EHRPD;
+ case "LTE": return RAF_LTE;
+ case "HSPAP": return RAF_HSPAP;
+ case "GSM": return RAF_GSM;
+ case "TD_SCDMA":return RAF_TD_SCDMA;
+ case "HS": return HS;
+ case "CDMA": return CDMA;
+ case "EVDO": return EVDO;
+ case "WCDMA": return WCDMA;
+ default: return RAF_UNKNOWN;
+ }
+ }
+
+ public static int rafTypeFromString(String rafList) {
+ rafList = rafList.toUpperCase();
+ String[] rafs = rafList.split("\\|");
+ int result = 0;
+ for(String raf : rafs) {
+ int rafType = singleRafTypeFromString(raf.trim());
+ if (rafType == RAF_UNKNOWN) return rafType;
+ result |= rafType;
+ }
+ return result;
+ }
+}
diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl
index be8751b..9499c9f 100644
--- a/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl
+++ b/telephony/java/com/android/ims/internal/IImsVideoCallCallback.aidl
@@ -16,7 +16,6 @@
package com.android.ims.internal;
-import android.telecom.CameraCapabilities;
import android.telecom.VideoProfile;
/**
@@ -43,7 +42,7 @@
void changeCallDataUsage(long dataUsage);
- void changeCameraCapabilities(in CameraCapabilities cameraCapabilities);
+ void changeCameraCapabilities(in VideoProfile.CameraCapabilities cameraCapabilities);
void changeVideoQuality(int videoQuality);
}
diff --git a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl
index 4ff0b4367..39e83c6 100644
--- a/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl
+++ b/telephony/java/com/android/ims/internal/IImsVideoCallProvider.aidl
@@ -16,6 +16,7 @@
package com.android.ims.internal;
+import android.net.Uri;
import android.view.Surface;
import android.telecom.VideoProfile;
@@ -60,5 +61,5 @@
void requestCallDataUsage();
- void setPauseImage(String uri);
+ void setPauseImage(in Uri uri);
}
diff --git a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
index b5cdd9a2..cb53f51 100644
--- a/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
+++ b/telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl
@@ -16,14 +16,14 @@
package com.android.internal.telephony;
-import android.os.Bundle;
+import android.os.PersistableBundle;
/**
* Interface used to interact with the CarrierConfigLoader
*/
interface ICarrierConfigLoader {
- Bundle getConfigForSubId(int subId);
+ PersistableBundle getConfigForSubId(int subId);
void reloadCarrierConfigForSubId(int subId);
diff --git a/tests/LockTaskTests/AndroidManifest.xml b/tests/LockTaskTests/AndroidManifest.xml
index f88744e..e349c92 100644
--- a/tests/LockTaskTests/AndroidManifest.xml
+++ b/tests/LockTaskTests/AndroidManifest.xml
@@ -29,28 +29,28 @@
android:label="@string/title_activity_default"
android:taskAffinity=""
android:documentLaunchMode="always"
- android:lockTaskMode="lockTaskModeDefault" >
+ android:lockTaskMode="normal" >
</activity>
<activity
android:name="com.google.android.example.locktasktests.LockTaskNeverActivity"
android:label="@string/title_activity_never"
android:taskAffinity=""
android:documentLaunchMode="always"
- android:lockTaskMode="lockTaskModeNever" >
+ android:lockTaskMode="never" >
</activity>
<activity
android:name="com.google.android.example.locktasktests.LockWhitelistedActivity"
android:label="@string/title_activity_whitelist"
android:taskAffinity=""
android:documentLaunchMode="always"
- android:lockTaskMode="lockTaskModeIfWhitelisted" >
+ android:lockTaskMode="if_whitelisted" >
</activity>
<activity
android:name="com.google.android.example.locktasktests.LockAtLaunchActivity"
android:label="@string/title_activity_always"
android:taskAffinity=""
android:documentLaunchMode="always"
- android:lockTaskMode="lockTaskModeAlways" >
+ android:lockTaskMode="always" >
</activity>
</application>
diff --git a/tests/LockTaskTests/res/values/strings.xml b/tests/LockTaskTests/res/values/strings.xml
index 61c029f..3bcae80 100644
--- a/tests/LockTaskTests/res/values/strings.xml
+++ b/tests/LockTaskTests/res/values/strings.xml
@@ -7,16 +7,17 @@
<string name="title_activity_whitelist">LockWhitelistedActivity</string>
<string name="title_activity_always">LockAtLaunchActivity</string>
<string name="launch_default">android:lockTaskMode=\n
- \"lockTaskModeDefault\"\n
+ \"default\"\n
Pinnable from Overview.</string>
<string name="launch_never">android:lockTaskMode=\n
- \"lockTaskModeNever\"\n
+ \"never\"\n
Not Lockable or Pinnable.</string>
- <string name="launch_whitelist">android:lockTaskMode=\n\"lockTaskModeIfWhitelisted\"\n
+ <string name="launch_whitelist">android:lockTaskMode=\n
+ \"if_whitelisted\"\n
Lockable if whitelisted, Pinnable.\n
Use SampleDeviceOwner app to set whitelist.</string>
<string name="launch_always">android:lockTaskMode=\n
- \"lockTaskModeAlways\"\n
+ \"always\"\n
Launches into lock mode.</string>
<string name="launch_main">launch MainActivity (as activity)"</string>
<string name="try_lock">Call startLockMode()</string>
diff --git a/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java b/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java
index c2275c8..3e4f8ee 100644
--- a/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java
+++ b/tests/LockTaskTests/src/com/google/android/example/locktasktests/MainActivity.java
@@ -6,26 +6,50 @@
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.view.View;
public class MainActivity extends Activity {
private final static String TAG = "LockTaskTests";
+ Runnable mBackgroundPolling;
+ boolean mRunning;
+ Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ mBackgroundPolling = new Runnable() {
+ // Poll lock task state and set background pink if locked, otherwise white.
+ @Override
+ public void run() {
+ if (!mRunning) {
+ return;
+ }
+ ActivityManager activityManager =
+ (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
+ final int color = activityManager.getLockTaskModeState() !=
+ ActivityManager.LOCK_TASK_MODE_NONE ? 0xFFFFC0C0 : 0xFFFFFFFF;
+ findViewById(R.id.root_launch).setBackgroundColor(color);
+ mHandler.postDelayed(this, 500);
+ }
+ };
+ mHandler = new Handler(Looper.getMainLooper());
}
@Override
public void onResume() {
super.onResume();
- ActivityManager activityManager =
- (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- final int color = activityManager.getLockTaskModeState() !=
- ActivityManager.LOCK_TASK_MODE_NONE ? 0xFFFFC0C0 : 0xFFFFFFFF;
- findViewById(R.id.root_launch).setBackgroundColor(color);
+ mRunning = true;
+ mBackgroundPolling.run();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mRunning = false;
}
public void onButtonPressed(View v) {
diff --git a/tests/notification/Android.mk b/tests/notification/Android.mk
new file mode 100644
index 0000000..0669553
--- /dev/null
+++ b/tests/notification/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_PACKAGE_NAME := NotificationTests
+
+LOCAL_SDK_VERSION := 21
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/notification/AndroidManifest.xml b/tests/notification/AndroidManifest.xml
new file mode 100644
index 0000000..7cee00a7
--- /dev/null
+++ b/tests/notification/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworks.tests.notification"
+ >
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.frameworks.tests.notification"
+ android:label="Frameworks Notification Tests" />
+</manifest>
diff --git a/tests/notification/res/drawable-nodpi/arubin_hed.jpeg b/tests/notification/res/drawable-nodpi/arubin_hed.jpeg
new file mode 100644
index 0000000..c6d8ae9
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/arubin_hed.jpeg
Binary files differ
diff --git a/tests/notification/res/drawable-nodpi/bucket.png b/tests/notification/res/drawable-nodpi/bucket.png
new file mode 100644
index 0000000..c865649
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/bucket.png
Binary files differ
diff --git a/tests/notification/res/drawable-nodpi/matias_hed.jpg b/tests/notification/res/drawable-nodpi/matias_hed.jpg
new file mode 100644
index 0000000..8cc3081
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/matias_hed.jpg
Binary files differ
diff --git a/tests/notification/res/drawable-nodpi/page_hed.jpg b/tests/notification/res/drawable-nodpi/page_hed.jpg
new file mode 100644
index 0000000..ea950c8
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/page_hed.jpg
Binary files differ
diff --git a/tests/notification/res/drawable-nodpi/romainguy_hed.jpg b/tests/notification/res/drawable-nodpi/romainguy_hed.jpg
new file mode 100644
index 0000000..5b7643e
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/romainguy_hed.jpg
Binary files differ
diff --git a/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg b/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg
new file mode 100644
index 0000000..68473ba
--- /dev/null
+++ b/tests/notification/res/drawable-nodpi/romainguy_rockaway.jpg
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/add.png b/tests/notification/res/drawable-xhdpi/add.png
new file mode 100644
index 0000000..7226b3d
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/add.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png b/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png
new file mode 100644
index 0000000..ca20a91
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/ic_dial_action_call.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/ic_end_call.png b/tests/notification/res/drawable-xhdpi/ic_end_call.png
new file mode 100644
index 0000000..c464a6d
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/ic_end_call.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/ic_media_next.png b/tests/notification/res/drawable-xhdpi/ic_media_next.png
new file mode 100644
index 0000000..4def965
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/ic_media_next.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/ic_menu_upload.png b/tests/notification/res/drawable-xhdpi/ic_menu_upload.png
new file mode 100644
index 0000000..f1438ed
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/ic_menu_upload.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/icon.png b/tests/notification/res/drawable-xhdpi/icon.png
new file mode 100644
index 0000000..189e85b
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/icon.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png b/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png
new file mode 100644
index 0000000..658d04f
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_alarm.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png b/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png
new file mode 100644
index 0000000..5ae7782
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_calendar.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_email.png b/tests/notification/res/drawable-xhdpi/stat_notify_email.png
new file mode 100644
index 0000000..23c4672
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_email.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png b/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png
new file mode 100644
index 0000000..8719eff
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_missed_call.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_sms.png b/tests/notification/res/drawable-xhdpi/stat_notify_sms.png
new file mode 100644
index 0000000..323cb3d
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_sms.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png b/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png
new file mode 100644
index 0000000..26dcda35
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_snooze.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png b/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png
new file mode 100644
index 0000000..b8b2f8a
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_snooze_longer.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png b/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png
new file mode 100644
index 0000000..12cae9f
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_notify_talk_text.png
Binary files differ
diff --git a/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png b/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png
new file mode 100644
index 0000000..db42b7c
--- /dev/null
+++ b/tests/notification/res/drawable-xhdpi/stat_sys_phone_call.png
Binary files differ
diff --git a/tests/notification/res/layout/full_screen.xml b/tests/notification/res/layout/full_screen.xml
new file mode 100644
index 0000000..6ff7552
--- /dev/null
+++ b/tests/notification/res/layout/full_screen.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:src="@drawable/page_hed"
+ android:onClick="dismiss"
+ />
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/notification/res/layout/main.xml b/tests/notification/res/layout/main.xml
new file mode 100644
index 0000000..f5a740f
--- /dev/null
+++ b/tests/notification/res/layout/main.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+ <LinearLayout android:id="@+id/linearLayout1" android:orientation="vertical" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_width="match_parent" android:layout_margin="35dp">
+ <Button android:id="@+id/button1" android:text="@string/post_button_label" android:layout_height="wrap_content" android:layout_width="match_parent" android:onClick="doPost"></Button>
+ <Button android:id="@+id/button2" android:text="@string/remove_button_label" android:layout_height="wrap_content" android:layout_width="match_parent" android:onClick="doRemove"></Button>
+ </LinearLayout>
+</FrameLayout>
diff --git a/tests/notification/res/values/dimens.xml b/tests/notification/res/values/dimens.xml
new file mode 100644
index 0000000..21e7bc3
--- /dev/null
+++ b/tests/notification/res/values/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2012, 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>
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_width">64dp</dimen>
+ <!-- The width of the big icons in notifications. -->
+ <dimen name="notification_large_icon_height">64dp</dimen>
+</resources>
diff --git a/tests/notification/res/values/strings.xml b/tests/notification/res/values/strings.xml
new file mode 100644
index 0000000..80bf103
--- /dev/null
+++ b/tests/notification/res/values/strings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, NotificationShowcaseActivity!</string>
+ <string name="app_name">NotificationShowcase</string>
+ <string name="post_button_label">Post Notifications</string>
+ <string name="remove_button_label">Remove Notifications</string>
+ <string name="answered">call answered</string>
+ <string name="ignored">call ignored</string>
+ <string name="full_screen_name">Full Screen Activity</string>
+</resources>
diff --git a/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java b/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java
new file mode 100644
index 0000000..7cda977
--- /dev/null
+++ b/tests/notification/src/com/android/frameworks/tests/notification/NotificationTests.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Typeface;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.SystemClock;
+import android.provider.ContactsContract;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.style.StyleSpan;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+import java.lang.reflect.Method;
+import java.lang.InterruptedException;
+import java.lang.NoSuchMethodError;
+import java.lang.NoSuchMethodException;
+import java.util.ArrayList;
+
+import com.android.frameworks.tests.notification.R;
+
+public class NotificationTests extends AndroidTestCase {
+ private static final String TAG = "NOTEST";
+ public static void L(String msg, Object... args) {
+ Log.v(TAG, (args == null || args.length == 0) ? msg : String.format(msg, args));
+ }
+
+ public static final String ACTION_CREATE = "create";
+ public static final int NOTIFICATION_ID = 31338;
+
+ public static final boolean SHOW_PHONE_CALL = false;
+ public static final boolean SHOW_INBOX = true;
+ public static final boolean SHOW_BIG_TEXT = true;
+ public static final boolean SHOW_BIG_PICTURE = true;
+ public static final boolean SHOW_MEDIA = true;
+ public static final boolean SHOW_STOPWATCH = false;
+ public static final boolean SHOW_SOCIAL = false;
+ public static final boolean SHOW_CALENDAR = false;
+ public static final boolean SHOW_PROGRESS = false;
+
+ private static Bitmap getBitmap(Context context, int resId) {
+ int largeIconWidth = (int) context.getResources()
+ .getDimension(R.dimen.notification_large_icon_width);
+ int largeIconHeight = (int) context.getResources()
+ .getDimension(R.dimen.notification_large_icon_height);
+ Drawable d = context.getResources().getDrawable(resId);
+ Bitmap b = Bitmap.createBitmap(largeIconWidth, largeIconHeight, Bitmap.Config.ARGB_8888);
+ Canvas c = new Canvas(b);
+ d.setBounds(0, 0, largeIconWidth, largeIconHeight);
+ d.draw(c);
+ return b;
+ }
+
+ private static PendingIntent makeEmailIntent(Context context, String who) {
+ final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO,
+ Uri.parse("mailto:" + who));
+ return PendingIntent.getActivity(
+ context, 0, intent,
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ }
+
+ static final String[] LINES = new String[] {
+ "Uh oh",
+ "Getting kicked out of this room",
+ "I'll be back in 5-10 minutes.",
+ "And now \u2026 I have to find my shoes. \uD83D\uDC63",
+ "\uD83D\uDC5F \uD83D\uDC5F",
+ "\uD83D\uDC60 \uD83D\uDC60",
+ };
+ static final int MAX_LINES = 5;
+ public static Notification makeBigTextNotification(Context context, int update, int id,
+ long when) {
+ String personUri = null;
+ /*
+ Cursor c = null;
+ try {
+ String[] projection = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.LOOKUP_KEY };
+ String selections = ContactsContract.Contacts.DISPLAY_NAME + " = 'Mike Cleron'";
+ final ContentResolver contentResolver = context.getContentResolver();
+ c = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,
+ projection, selections, null, null);
+ if (c != null && c.getCount() > 0) {
+ c.moveToFirst();
+ int lookupIdx = c.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY);
+ int idIdx = c.getColumnIndex(ContactsContract.Contacts._ID);
+ String lookupKey = c.getString(lookupIdx);
+ long contactId = c.getLong(idIdx);
+ Uri lookupUri = ContactsContract.Contacts.getLookupUri(contactId, lookupKey);
+ personUri = lookupUri.toString();
+ }
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ if (TextUtils.isEmpty(personUri)) {
+ Log.w(TAG, "failed to find contact for Mike Cleron");
+ } else {
+ Log.w(TAG, "Mike Cleron is " + personUri);
+ }
+ */
+
+ StringBuilder longSmsText = new StringBuilder();
+ int end = 2 + update;
+ if (end > LINES.length) {
+ end = LINES.length;
+ }
+ final int start = Math.max(0, end - MAX_LINES);
+ for (int i=start; i<end; i++) {
+ if (i >= LINES.length) break;
+ if (i > start) longSmsText.append("\n");
+ longSmsText.append(LINES[i]);
+ }
+ if (update > 2) {
+ when = System.currentTimeMillis();
+ }
+ Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle()
+ .bigText(longSmsText);
+ Notification bigText = new Notification.Builder(context)
+ .setContentTitle("Mike Cleron")
+ .setContentIntent(ToastService.getPendingIntent(context, "Clicked on bigText"))
+ .setContentText(longSmsText)
+ //.setTicker("Mike Cleron: " + longSmsText)
+ .setWhen(when)
+ .setLargeIcon(getBitmap(context, R.drawable.bucket))
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setNumber(update)
+ .setSmallIcon(R.drawable.stat_notify_talk_text)
+ .setStyle(bigTextStyle)
+ .setDefaults(Notification.DEFAULT_SOUND)
+ .addPerson(personUri)
+ .build();
+ return bigText;
+ }
+
+ public static Notification makeUploadNotification(Context context, int progress, long when) {
+ Notification.Builder uploadNotification = new Notification.Builder(context)
+ .setContentTitle("File Upload")
+ .setContentText("foo.txt")
+ .setPriority(Notification.PRIORITY_MIN)
+ .setContentIntent(ToastService.getPendingIntent(context, "Clicked on Upload"))
+ .setWhen(when)
+ .setSmallIcon(R.drawable.ic_menu_upload)
+ .setProgress(100, Math.min(progress, 100), false);
+ return uploadNotification.build();
+ }
+
+ static SpannableStringBuilder BOLD(CharSequence str) {
+ final SpannableStringBuilder ssb = new SpannableStringBuilder(str);
+ ssb.setSpan(new StyleSpan(Typeface.BOLD), 0, ssb.length(), 0);
+ return ssb;
+ }
+
+ public static class ToastService extends IntentService {
+
+ private static final String TAG = "ToastService";
+
+ private static final String ACTION_TOAST = "toast";
+
+ private Handler handler;
+
+ public ToastService() {
+ super(TAG);
+ }
+ public ToastService(String name) {
+ super(name);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ handler = new Handler();
+ return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+ Log.v(TAG, "clicked a thing! intent=" + intent.toString());
+ if (intent.hasExtra("text")) {
+ final String text = intent.getStringExtra("text");
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ Toast.makeText(ToastService.this, text, Toast.LENGTH_LONG).show();
+ Log.v(TAG, "toast " + text);
+ }
+ });
+ }
+ }
+
+ public static PendingIntent getPendingIntent(Context context, String text) {
+ Intent toastIntent = new Intent(context, ToastService.class);
+ toastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ toastIntent.setAction(ACTION_TOAST + ":" + text); // one per toast message
+ toastIntent.putExtra("text", text);
+ PendingIntent pi = PendingIntent.getService(
+ context, 58, toastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ return pi;
+ }
+ }
+
+ public static void sleepIfYouCan(int ms) {
+ try {
+ Thread.sleep(ms);
+ } catch (InterruptedException e) {}
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ public static String summarize(Notification n) {
+ return String.format("<notif title=\"%s\" icon=0x%08x view=%s>",
+ n.extras.get(Notification.EXTRA_TITLE),
+ n.icon,
+ String.valueOf(n.contentView));
+ }
+
+ public void testCreate() throws Exception {
+ ArrayList<Notification> mNotifications = new ArrayList<Notification>();
+ NotificationManager noMa =
+ (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ L("Constructing notifications...");
+ if (SHOW_BIG_TEXT) {
+ int bigtextId = mNotifications.size();
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = makeBigTextNotification(mContext, 0, bigtextId, System.currentTimeMillis());
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ int uploadId = mNotifications.size();
+ long uploadWhen = System.currentTimeMillis();
+
+ if (SHOW_PROGRESS) {
+ mNotifications.add(makeUploadNotification(mContext, 0, uploadWhen));
+ }
+
+ if (SHOW_PHONE_CALL) {
+ int phoneId = mNotifications.size();
+ final PendingIntent fullscreenIntent
+ = FullScreenActivity.getPendingIntent(mContext, phoneId);
+ final long time = SystemClock.currentThreadTimeMillis();
+ Notification phoneCall = new Notification.Builder(mContext)
+ .setContentTitle("Incoming call")
+ .setContentText("Matias Duarte")
+ .setLargeIcon(getBitmap(mContext, R.drawable.matias_hed))
+ .setSmallIcon(R.drawable.stat_sys_phone_call)
+ .setDefaults(Notification.DEFAULT_SOUND)
+ .setPriority(Notification.PRIORITY_MAX)
+ .setContentIntent(fullscreenIntent)
+ .setFullScreenIntent(fullscreenIntent, true)
+ .addAction(R.drawable.ic_dial_action_call, "Answer",
+ ToastService.getPendingIntent(mContext, "Clicked on Answer"))
+ .addAction(R.drawable.ic_end_call, "Ignore",
+ ToastService.getPendingIntent(mContext, "Clicked on Ignore"))
+ .setOngoing(true)
+ .addPerson(Uri.fromParts("tel", "1 (617) 555-1212", null).toString())
+ .build();
+ L(" %s: create=%dms", phoneCall.toString(), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(phoneCall);
+ }
+
+ if (SHOW_STOPWATCH) {
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = new Notification.Builder(mContext)
+ .setContentTitle("Stopwatch PRO")
+ .setContentText("Counting up")
+ .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Stopwatch"))
+ .setSmallIcon(R.drawable.stat_notify_alarm)
+ .setUsesChronometer(true)
+ .build();
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ if (SHOW_CALENDAR) {
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = new Notification.Builder(mContext)
+ .setContentTitle("J Planning")
+ .setContentText("The Botcave")
+ .setWhen(System.currentTimeMillis())
+ .setSmallIcon(R.drawable.stat_notify_calendar)
+ .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on calendar event"))
+ .setContentInfo("7PM")
+ .addAction(R.drawable.stat_notify_snooze, "+10 min",
+ ToastService.getPendingIntent(mContext, "snoozed 10 min"))
+ .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour",
+ ToastService.getPendingIntent(mContext, "snoozed 1 hr"))
+ .addAction(R.drawable.stat_notify_email, "Email",
+ ToastService.getPendingIntent(mContext,
+ "Congratulations, you just destroyed someone's inbox zero"))
+ .build();
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ if (SHOW_BIG_PICTURE) {
+ BitmapDrawable d =
+ (BitmapDrawable) mContext.getResources().getDrawable(R.drawable.romainguy_rockaway);
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = new Notification.Builder(mContext)
+ .setContentTitle("Romain Guy")
+ .setContentText("I was lucky to find a Canon 5D Mk III at a local Bay Area "
+ + "store last week but I had not been able to try it in the field "
+ + "until tonight. After a few days of rain the sky finally cleared "
+ + "up. Rockaway Beach did not disappoint and I was finally able to "
+ + "see what my new camera feels like when shooting landscapes.")
+ .setSmallIcon(android.R.drawable.stat_notify_chat)
+ .setContentIntent(
+ ToastService.getPendingIntent(mContext, "Clicked picture"))
+ .setLargeIcon(getBitmap(mContext, R.drawable.romainguy_hed))
+ .addAction(R.drawable.add, "Add to Gallery",
+ ToastService.getPendingIntent(mContext, "Added"))
+ .setStyle(new Notification.BigPictureStyle()
+ .bigPicture(d.getBitmap()))
+ .build();
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ if (SHOW_INBOX) {
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = new Notification.Builder(mContext)
+ .setContentTitle("New mail")
+ .setContentText("3 new messages")
+ .setSubText("example@gmail.com")
+ .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Mail"))
+ .setSmallIcon(R.drawable.stat_notify_email)
+ .setStyle(new Notification.InboxStyle()
+ .setSummaryText("example@gmail.com")
+ .addLine(BOLD("Alice:").append(" hey there!"))
+ .addLine(BOLD("Bob:").append(" hi there!"))
+ .addLine(BOLD("Charlie:").append(" Iz IN UR EMAILZ!!"))
+ ).build();
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ if (SHOW_SOCIAL) {
+ final long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = new Notification.Builder(mContext)
+ .setContentTitle("Social Network")
+ .setContentText("You were mentioned in a post")
+ .setContentInfo("example@gmail.com")
+ .setContentIntent(ToastService.getPendingIntent(mContext, "Clicked on Social"))
+ .setSmallIcon(android.R.drawable.stat_notify_chat)
+ .setPriority(Notification.PRIORITY_LOW)
+ .build();
+ L(" %s: create=%dms", summarize(n), SystemClock.currentThreadTimeMillis() - time);
+ mNotifications.add(n);
+ }
+
+ L("Posting notifications...");
+ for (int i=0; i<mNotifications.size(); i++) {
+ final int count = 4;
+ for (int j=0; j<count; j++) {
+ long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = mNotifications.get(i);
+ noMa.notify(NOTIFICATION_ID + i, n);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: notify=%dms (%d/%d)", summarize(n), time,
+ j + 1, count);
+ sleepIfYouCan(150);
+ }
+ }
+
+ sleepIfYouCan(1000);
+
+ L("Canceling notifications...");
+ for (int i=0; i<mNotifications.size(); i++) {
+ final Notification n = mNotifications.get(i);
+ long time = SystemClock.currentThreadTimeMillis();
+ noMa.cancel(NOTIFICATION_ID + i);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: cancel=%dms", summarize(n), time);
+ }
+
+ sleepIfYouCan(500);
+
+ L("Parceling notifications...");
+ // we want to be able to use this test on older OSes that do not have getBlobAshmemSize
+ Method getBlobAshmemSize = null;
+ try {
+ getBlobAshmemSize = Parcel.class.getMethod("getBlobAshmemSize");
+ } catch (NoSuchMethodException ex) {
+ }
+ for (int i=0; i<mNotifications.size(); i++) {
+ Parcel p = Parcel.obtain();
+ {
+ final Notification n = mNotifications.get(i);
+ long time = SystemClock.currentThreadTimeMillis();
+ n.writeToParcel(p, 0);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: write parcel=%dms size=%d ashmem=%s",
+ summarize(n), time, p.dataPosition(),
+ (getBlobAshmemSize != null)
+ ? getBlobAshmemSize.invoke(p)
+ : "???");
+ p.setDataPosition(0);
+ }
+
+ long time = SystemClock.currentThreadTimeMillis();
+ final Notification n2 = Notification.CREATOR.createFromParcel(p);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: parcel read=%dms", summarize(n2), time);
+
+ time = SystemClock.currentThreadTimeMillis();
+ noMa.notify(NOTIFICATION_ID + i, n2);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: notify=%dms", summarize(n2), time);
+ }
+
+ sleepIfYouCan(500);
+
+ L("Canceling notifications...");
+ for (int i=0; i<mNotifications.size(); i++) {
+ long time = SystemClock.currentThreadTimeMillis();
+ final Notification n = mNotifications.get(i);
+ noMa.cancel(NOTIFICATION_ID + i);
+ time = SystemClock.currentThreadTimeMillis() - time;
+ L(" %s: cancel=%dms", summarize(n), time);
+ }
+
+
+// if (SHOW_PROGRESS) {
+// ProgressService.startProgressUpdater(this, uploadId, uploadWhen, 0);
+// }
+ }
+
+ public static class FullScreenActivity extends Activity {
+ public static final String EXTRA_ID = "id";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.full_screen);
+ final Intent intent = getIntent();
+ if (intent != null && intent.hasExtra(EXTRA_ID)) {
+ final int id = intent.getIntExtra(EXTRA_ID, -1);
+ if (id >= 0) {
+ NotificationManager noMa =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+ noMa.cancel(NOTIFICATION_ID + id);
+ }
+ }
+ }
+
+ public void dismiss(View v) {
+ finish();
+ }
+
+ public static PendingIntent getPendingIntent(Context context, int id) {
+ Intent fullScreenIntent = new Intent(context, FullScreenActivity.class);
+ fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ fullScreenIntent.putExtra(EXTRA_ID, id);
+ PendingIntent pi = PendingIntent.getActivity(
+ context, 22, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ return pi;
+ }
+ }
+}
+
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index 5ef4311..23d679d 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -30,6 +30,7 @@
BinaryXmlPullParser.cpp \
BindingXmlPullParser.cpp \
ConfigDescription.cpp \
+ Debug.cpp \
Files.cpp \
Flag.cpp \
JavaClassGenerator.cpp \
diff --git a/tools/aapt2/BinaryResourceParser.cpp b/tools/aapt2/BinaryResourceParser.cpp
index d16f63b..3559f43 100644
--- a/tools/aapt2/BinaryResourceParser.cpp
+++ b/tools/aapt2/BinaryResourceParser.cpp
@@ -475,10 +475,17 @@
source.line = entry->sourceLine;
}
- if (!mTable->markPublic(name, resId, source)) {
+ if (!mTable->markPublicAllowMangled(name, resId, source)) {
return false;
}
+ // Add this resource name->id mapping to the index so
+ // that we can resolve all ID references to name references.
+ auto cacheIter = mIdIndex.find(resId);
+ if (cacheIter == mIdIndex.end()) {
+ mIdIndex.insert({ resId, name });
+ }
+
entry++;
}
return true;
@@ -611,12 +618,12 @@
source.line = sourceBlock->line;
}
- if (!mTable->addResource(name, config, source, std::move(resourceValue))) {
+ if (!mTable->addResourceAllowMangled(name, config, source, std::move(resourceValue))) {
return false;
}
if ((entry->flags & ResTable_entry::FLAG_PUBLIC) != 0) {
- if (!mTable->markPublic(name, resId, mSource.line(0))) {
+ if (!mTable->markPublicAllowMangled(name, resId, mSource.line(0))) {
return false;
}
}
@@ -635,6 +642,10 @@
const ConfigDescription& config,
const Res_value* value,
uint16_t flags) {
+ if (name.type == ResourceType::kId) {
+ return util::make_unique<Id>();
+ }
+
if (value->dataType == Res_value::TYPE_STRING) {
StringPiece16 str = util::getString(mValuePool, value->data);
@@ -686,8 +697,7 @@
// This is not an unresolved symbol, so it must be the magic @null reference.
Res_value nullType = {};
- nullType.dataType = Res_value::TYPE_NULL;
- nullType.data = Res_value::DATA_NULL_UNDEFINED;
+ nullType.dataType = Res_value::TYPE_REFERENCE;
return util::make_unique<BinaryPrimitive>(nullType);
}
@@ -697,13 +707,6 @@
StringPool::Context{ 1, config }));
}
- if (name.type == ResourceType::kId ||
- (value->dataType == Res_value::TYPE_NULL &&
- value->data == Res_value::DATA_NULL_UNDEFINED &&
- (flags & ResTable_entry::FLAG_WEAK) != 0)) {
- return util::make_unique<Id>();
- }
-
// Treat this as a raw binary primitive.
return util::make_unique<BinaryPrimitive>(*value);
}
@@ -731,8 +734,7 @@
std::unique_ptr<Style> BinaryResourceParser::parseStyle(const ResourceNameRef& name,
const ConfigDescription& config,
const ResTable_map_entry* map) {
- const bool isWeak = (map->flags & ResTable_entry::FLAG_WEAK) != 0;
- std::unique_ptr<Style> style = util::make_unique<Style>(isWeak);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
if (map->parent.ident == 0) {
// The parent is either not set or it is an unresolved symbol.
// Check to see if it is a symbol.
@@ -789,10 +791,21 @@
continue;
}
- attr->symbols.push_back(Attribute::Symbol{
- Reference(mapEntry.name.ident),
- mapEntry.value.data
- });
+ Attribute::Symbol symbol;
+ symbol.value = mapEntry.value.data;
+ if (mapEntry.name.ident == 0) {
+ // The map entry's key (id) is not set. This must be
+ // a symbol reference, so resolve it.
+ ResourceNameRef symbolName;
+ bool result = getSymbol(&mapEntry.name.ident, &symbolName);
+ assert(result);
+ symbol.symbol.name = symbolName.toResourceName();
+ } else {
+ // The map entry's key (id) is a regular reference.
+ symbol.symbol.id = mapEntry.name.ident;
+ }
+
+ attr->symbols.push_back(std::move(symbol));
}
}
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
new file mode 100644
index 0000000..cf222c6
--- /dev/null
+++ b/tools/aapt2/Debug.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+#include "Debug.h"
+#include "ResourceTable.h"
+#include "ResourceValues.h"
+#include "Util.h"
+
+#include <algorithm>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <queue>
+#include <set>
+#include <vector>
+
+namespace aapt {
+
+struct PrintVisitor : ConstValueVisitor {
+ void visit(const Attribute& attr, ValueVisitorArgs&) override {
+ std::cout << "(attr) type=";
+ attr.printMask(std::cout);
+ static constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM |
+ android::ResTable_map::TYPE_FLAGS;
+ if (attr.typeMask & kMask) {
+ for (const auto& symbol : attr.symbols) {
+ std::cout << "\n "
+ << symbol.symbol.name.entry << " (" << symbol.symbol.id << ") = "
+ << symbol.value;
+ }
+ }
+ }
+
+ void visit(const Style& style, ValueVisitorArgs&) override {
+ std::cout << "(style)";
+ if (style.parent.name.isValid() || style.parent.id.isValid()) {
+ std::cout << " parent=";
+ if (style.parent.name.isValid()) {
+ std::cout << style.parent.name << " ";
+ }
+
+ if (style.parent.id.isValid()) {
+ std::cout << style.parent.id;
+ }
+ }
+
+ for (const auto& entry : style.entries) {
+ std::cout << "\n ";
+ if (entry.key.name.isValid()) {
+ std::cout << entry.key.name.package << ":" << entry.key.name.entry;
+ }
+
+ if (entry.key.id.isValid()) {
+ std::cout << "(" << entry.key.id << ")";
+ }
+
+ std::cout << "=" << *entry.value;
+ }
+ }
+
+ void visit(const Array& array, ValueVisitorArgs&) override {
+ array.print(std::cout);
+ }
+
+ void visit(const Plural& plural, ValueVisitorArgs&) override {
+ plural.print(std::cout);
+ }
+
+ void visit(const Styleable& styleable, ValueVisitorArgs&) override {
+ styleable.print(std::cout);
+ }
+
+ void visitItem(const Item& item, ValueVisitorArgs& args) override {
+ item.print(std::cout);
+ }
+};
+
+void Debug::printTable(const std::shared_ptr<ResourceTable>& table) {
+ std::cout << "Package name=" << table->getPackage();
+ if (table->getPackageId() != ResourceTable::kUnsetPackageId) {
+ std::cout << " id=" << std::hex << table->getPackageId() << std::dec;
+ }
+ std::cout << std::endl;
+
+ for (const auto& type : *table) {
+ std::cout << " type " << type->type;
+ if (type->typeId != ResourceTableType::kUnsetTypeId) {
+ std::cout << " id=" << std::hex << type->typeId << std::dec;
+ }
+ std::cout << " entryCount=" << type->entries.size() << std::endl;
+
+ std::vector<const ResourceEntry*> sortedEntries;
+ for (const auto& entry : type->entries) {
+ auto iter = std::lower_bound(sortedEntries.begin(), sortedEntries.end(), entry.get(),
+ [](const ResourceEntry* a, const ResourceEntry* b) -> bool {
+ return a->entryId < b->entryId;
+ });
+ sortedEntries.insert(iter, entry.get());
+ }
+
+ for (const ResourceEntry* entry : sortedEntries) {
+ ResourceId id = { table->getPackageId(), type->typeId, entry->entryId };
+ ResourceName name = { table->getPackage(), type->type, entry->name };
+ std::cout << " spec resource " << id << " " << name;
+ if (entry->publicStatus.isPublic) {
+ std::cout << " PUBLIC";
+ }
+ std::cout << std::endl;
+
+ PrintVisitor visitor;
+ for (const auto& value : entry->values) {
+ std::cout << " (" << value.config << ") ";
+ value.value->accept(visitor, {});
+ std::cout << std::endl;
+ }
+ }
+ }
+}
+
+static size_t getNodeIndex(const std::vector<ResourceName>& names, const ResourceName& name) {
+ auto iter = std::lower_bound(names.begin(), names.end(), name);
+ assert(iter != names.end() && *iter == name);
+ return std::distance(names.begin(), iter);
+}
+
+void Debug::printStyleGraph(const std::shared_ptr<ResourceTable>& table,
+ const ResourceName& targetStyle) {
+ std::map<ResourceName, std::set<ResourceName>> graph;
+
+ std::queue<ResourceName> stylesToVisit;
+ stylesToVisit.push(targetStyle);
+ for (; !stylesToVisit.empty(); stylesToVisit.pop()) {
+ const ResourceName& styleName = stylesToVisit.front();
+ std::set<ResourceName>& parents = graph[styleName];
+ if (!parents.empty()) {
+ // We've already visited this style.
+ continue;
+ }
+
+ const ResourceTableType* type;
+ const ResourceEntry* entry;
+ std::tie(type, entry) = table->findResource(styleName);
+ if (entry) {
+ for (const auto& value : entry->values) {
+ visitFunc<Style>(*value.value, [&](const Style& style) {
+ if (style.parent.name.isValid()) {
+ parents.insert(style.parent.name);
+ stylesToVisit.push(style.parent.name);
+ }
+ });
+ }
+ }
+ }
+
+ std::vector<ResourceName> names;
+ for (const auto& entry : graph) {
+ names.push_back(entry.first);
+ }
+
+ std::cout << "digraph styles {\n";
+ for (const auto& name : names) {
+ std::cout << " node_" << getNodeIndex(names, name)
+ << " [label=\"" << name << "\"];\n";
+ }
+
+ for (const auto& entry : graph) {
+ const ResourceName& styleName = entry.first;
+ size_t styleNodeIndex = getNodeIndex(names, styleName);
+
+ for (const auto& parentName : entry.second) {
+ std::cout << " node_" << styleNodeIndex << " -> "
+ << "node_" << getNodeIndex(names, parentName) << ";\n";
+ }
+ }
+
+ std::cout << "}" << std::endl;
+}
+
+} // namespace aapt
diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h
new file mode 100644
index 0000000..cdb3dcb
--- /dev/null
+++ b/tools/aapt2/Debug.h
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT_DEBUG_H
+#define AAPT_DEBUG_H
+
+#include "Resource.h"
+#include "ResourceTable.h"
+
+#include <memory>
+
+namespace aapt {
+
+struct Debug {
+ static void printTable(const std::shared_ptr<ResourceTable>& table);
+ static void printStyleGraph(const std::shared_ptr<ResourceTable>& table,
+ const ResourceName& targetStyle);
+};
+
+} // namespace aapt
+
+#endif // AAPT_DEBUG_H
diff --git a/tools/aapt2/Flag.cpp b/tools/aapt2/Flag.cpp
index 0f63c2c..76985da 100644
--- a/tools/aapt2/Flag.cpp
+++ b/tools/aapt2/Flag.cpp
@@ -13,7 +13,7 @@
struct Flag {
std::string name;
std::string description;
- std::function<void(const StringPiece&)> action;
+ std::function<bool(const StringPiece&, std::string*)> action;
bool required;
bool* flagResult;
bool flagValueWhenSet;
@@ -23,22 +23,38 @@
static std::vector<Flag> sFlags;
static std::vector<std::string> sArgs;
+static std::function<bool(const StringPiece&, std::string*)> wrap(
+ const std::function<void(const StringPiece&)>& action) {
+ return [action](const StringPiece& arg, std::string*) -> bool {
+ action(arg);
+ return true;
+ };
+}
+
void optionalFlag(const StringPiece& name, const StringPiece& description,
std::function<void(const StringPiece&)> action) {
- sFlags.push_back(
- Flag{ name.toString(), description.toString(), action, false, nullptr, false, false });
+ sFlags.push_back(Flag{
+ name.toString(), description.toString(), wrap(action),
+ false, nullptr, false, false });
}
void requiredFlag(const StringPiece& name, const StringPiece& description,
std::function<void(const StringPiece&)> action) {
- sFlags.push_back(
- Flag{ name.toString(), description.toString(), action, true, nullptr, false, false });
+ sFlags.push_back(Flag{ name.toString(), description.toString(), wrap(action),
+ true, nullptr, false, false });
+}
+
+void requiredFlag(const StringPiece& name, const StringPiece& description,
+ std::function<bool(const StringPiece&, std::string*)> action) {
+ sFlags.push_back(Flag{ name.toString(), description.toString(), action,
+ true, nullptr, false, false });
}
void optionalSwitch(const StringPiece& name, const StringPiece& description, bool resultWhenSet,
bool* result) {
sFlags.push_back(Flag{
- name.toString(), description.toString(), {}, false, result, resultWhenSet, false });
+ name.toString(), description.toString(), {},
+ false, result, resultWhenSet, false });
}
void usageAndDie(const StringPiece& command) {
@@ -62,6 +78,7 @@
}
void parse(int argc, char** argv, const StringPiece& command) {
+ std::string errorStr;
for (int i = 0; i < argc; i++) {
const StringPiece arg(argv[i]);
if (*arg.data() != '-') {
@@ -83,7 +100,11 @@
<< std::endl;
usageAndDie(command);
}
- flag.action(argv[i]);
+
+ if (!flag.action(argv[i], &errorStr)) {
+ std::cerr << errorStr << "." << std::endl << std::endl;
+ usageAndDie(command);
+ }
}
break;
}
diff --git a/tools/aapt2/Flag.h b/tools/aapt2/Flag.h
index 4745c35..e863742 100644
--- a/tools/aapt2/Flag.h
+++ b/tools/aapt2/Flag.h
@@ -13,6 +13,9 @@
void requiredFlag(const StringPiece& name, const StringPiece& description,
std::function<void(const StringPiece&)> action);
+void requiredFlag(const StringPiece& name, const StringPiece& description,
+ std::function<bool(const StringPiece&, std::string*)> action);
+
void optionalFlag(const StringPiece& name, const StringPiece& description,
std::function<void(const StringPiece&)> action);
diff --git a/tools/aapt2/JavaClassGenerator.cpp b/tools/aapt2/JavaClassGenerator.cpp
index 2bb0e65..e2ffe79 100644
--- a/tools/aapt2/JavaClassGenerator.cpp
+++ b/tools/aapt2/JavaClassGenerator.cpp
@@ -81,23 +81,28 @@
}
struct GenArgs : ValueVisitorArgs {
- GenArgs(std::ostream* o, std::u16string* e) : out(o), entryName(e) {
+ GenArgs(std::ostream* o, const std::u16string* p, std::u16string* e) :
+ out(o), package(p), entryName(e) {
}
std::ostream* out;
+ const std::u16string* package;
std::u16string* entryName;
};
void JavaClassGenerator::visit(const Styleable& styleable, ValueVisitorArgs& a) {
const StringPiece finalModifier = mOptions.useFinal ? " final" : "";
std::ostream* out = static_cast<GenArgs&>(a).out;
+ const std::u16string* package = static_cast<GenArgs&>(a).package;
std::u16string* entryName = static_cast<GenArgs&>(a).entryName;
// This must be sorted by resource ID.
std::vector<std::pair<ResourceId, ResourceNameRef>> sortedAttributes;
sortedAttributes.reserve(styleable.entries.size());
for (const auto& attr : styleable.entries) {
- assert(attr.id.isValid() && "no ID set for Styleable entry");
+ // If we are not encoding final attributes, the styleable entry may have no ID
+ // if we are building a static library.
+ assert((!mOptions.useFinal || attr.id.isValid()) && "no ID set for Styleable entry");
assert(attr.name.isValid() && "no name set for Styleable entry");
sortedAttributes.emplace_back(attr.id, attr.name);
}
@@ -129,7 +134,7 @@
// We may reference IDs from other packages, so prefix the entry name with
// the package.
const ResourceNameRef& itemName = sortedAttributes[i].second;
- if (itemName.package != mTable->getPackage()) {
+ if (itemName.package != *package) {
*out << "_" << transform(itemName.package);
}
*out << "_" << transform(itemName.entry) << " = " << i << ";" << std::endl;
@@ -172,7 +177,7 @@
if (type.type == ResourceType::kStyleable) {
assert(!entry->values.empty());
- entry->values.front().value->accept(*this, GenArgs{ &out, &unmangledName });
+ entry->values.front().value->accept(*this, GenArgs{ &out, &package, &unmangledName });
} else {
out << " " << "public static" << finalModifier
<< " int " << transform(unmangledName) << " = " << id << ";" << std::endl;
diff --git a/tools/aapt2/JavaClassGenerator_test.cpp b/tools/aapt2/JavaClassGenerator_test.cpp
index d4341b6..b385ff4 100644
--- a/tools/aapt2/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/JavaClassGenerator_test.cpp
@@ -95,8 +95,9 @@
SourceLine{ "lib.xml", 33 }, util::make_unique<Id>()));
ASSERT_TRUE(mTable->merge(std::move(table)));
- Linker linker(mTable, std::make_shared<MockResolver>(mTable,
- std::map<ResourceName, ResourceId>()));
+ Linker linker(mTable,
+ std::make_shared<MockResolver>(mTable, std::map<ResourceName, ResourceId>()),
+ {});
ASSERT_TRUE(linker.linkAndValidate());
JavaClassGenerator generator(mTable, {});
@@ -130,7 +131,7 @@
{ ResourceName{ u"com.lib", ResourceType::kAttr, u"bar" },
ResourceId{ 0x02, 0x01, 0x0000 } }}));
- Linker linker(mTable, resolver);
+ Linker linker(mTable, resolver, {});
ASSERT_TRUE(linker.linkAndValidate());
JavaClassGenerator generator(mTable, {});
diff --git a/tools/aapt2/Linker.cpp b/tools/aapt2/Linker.cpp
index a8b7a14..f3f04a5 100644
--- a/tools/aapt2/Linker.cpp
+++ b/tools/aapt2/Linker.cpp
@@ -40,8 +40,9 @@
Linker::Args::Args(const ResourceNameRef& r, const SourceLine& s) : referrer(r), source(s) {
}
-Linker::Linker(std::shared_ptr<ResourceTable> table, std::shared_ptr<IResolver> resolver) :
- mTable(table), mResolver(resolver), mError(false) {
+Linker::Linker(const std::shared_ptr<ResourceTable>& table,
+ const std::shared_ptr<IResolver>& resolver, const Options& options) :
+ mResolver(resolver), mTable(table), mOptions(options), mError(false) {
}
bool Linker::linkAndValidate() {
@@ -49,7 +50,7 @@
std::array<std::set<uint16_t>, 256> usedIds;
usedTypeIds.set(0);
- // First build the graph of references.
+ // Collect which resource IDs are already taken.
for (auto& type : *mTable) {
if (type->typeId != ResourceTableType::kUnsetTypeId) {
// The ID for this type has already been set. We
@@ -66,29 +67,10 @@
// later.
usedIds[type->typeId].insert(entry->entryId);
}
-
- if (entry->publicStatus.isPublic && entry->values.empty()) {
- // A public resource has no values. It will not be encoded
- // properly without a symbol table. This is a unresolved symbol.
- addUnresolvedSymbol(ResourceNameRef{
- mTable->getPackage(), type->type, entry->name },
- entry->publicStatus.source);
- } else {
- for (auto& valueConfig : entry->values) {
- // Dispatch to the right method of this linker
- // based on the value's type.
- valueConfig.value->accept(*this, Args{
- ResourceNameRef{ mTable->getPackage(), type->type, entry->name },
- valueConfig.source
- });
- }
- }
}
}
- /*
- * Assign resource IDs that are available.
- */
+ // Assign resource IDs that are available.
size_t nextTypeIndex = 0;
for (auto& type : *mTable) {
if (type->typeId == ResourceTableType::kUnsetTypeId) {
@@ -109,29 +91,32 @@
++nextEntryIter;
}
entry->entryId = nextIndex++;
-
- std::u16string unmangledPackage = mTable->getPackage();
- std::u16string unmangledName = entry->name;
- NameMangler::unmangle(&unmangledName, &unmangledPackage);
-
- // Update callers of this resource with the right ID.
- auto callersIter = mGraph.find(ResourceNameRef{
- unmangledPackage,
- type->type,
- unmangledName
- });
-
- if (callersIter != std::end(mGraph)) {
- for (Node& caller : callersIter->second) {
- caller.reference->id = ResourceId(mTable->getPackageId(),
- type->typeId,
- entry->entryId);
- }
- }
}
}
}
+ // Now do reference linking.
+ for (auto& type : *mTable) {
+ for (auto& entry : type->entries) {
+ if (entry->publicStatus.isPublic && entry->values.empty()) {
+ // A public resource has no values. It will not be encoded
+ // properly without a symbol table. This is a unresolved symbol.
+ addUnresolvedSymbol(ResourceNameRef{
+ mTable->getPackage(), type->type, entry->name },
+ entry->publicStatus.source);
+ continue;
+ }
+
+ for (auto& valueConfig : entry->values) {
+ // Dispatch to the right method of this linker
+ // based on the value's type.
+ valueConfig.value->accept(*this, Args{
+ ResourceNameRef{ mTable->getPackage(), type->type, entry->name },
+ valueConfig.source
+ });
+ }
+ }
+ }
return !mError;
}
@@ -139,12 +124,48 @@
return mUnresolvedSymbols;
}
+void Linker::doResolveReference(Reference& reference, const SourceLine& source) {
+ Maybe<ResourceId> result = mResolver->findId(reference.name);
+ if (!result) {
+ addUnresolvedSymbol(reference.name, source);
+ return;
+ }
+ assert(result.value().isValid());
+
+ if (mOptions.linkResourceIds) {
+ reference.id = result.value();
+ } else {
+ reference.id = 0;
+ }
+}
+
+const Attribute* Linker::doResolveAttribute(Reference& attribute, const SourceLine& source) {
+ Maybe<IResolver::Entry> result = mResolver->findAttribute(attribute.name);
+ if (!result || !result.value().attr) {
+ addUnresolvedSymbol(attribute.name, source);
+ return nullptr;
+ }
+
+ const IResolver::Entry& entry = result.value();
+ assert(entry.id.isValid());
+
+ if (mOptions.linkResourceIds) {
+ attribute.id = entry.id;
+ } else {
+ attribute.id = 0;
+ }
+ return entry.attr;
+}
+
void Linker::visit(Reference& reference, ValueVisitorArgs& a) {
Args& args = static_cast<Args&>(a);
if (!reference.name.isValid()) {
// We can't have a completely bad reference.
- assert(reference.id.isValid());
+ if (!reference.id.isValid()) {
+ Logger::error() << "srsly? " << args.referrer << std::endl;
+ assert(reference.id.isValid());
+ }
// This reference has no name but has an ID.
// It is a really bad error to have no name and have the same
@@ -156,25 +177,7 @@
return;
}
- Maybe<ResourceId> result = mResolver->findId(reference.name);
- if (!result) {
- addUnresolvedSymbol(reference.name, args.source);
- return;
- }
-
- const ResourceId& id = result.value();
- if (id.isValid()) {
- reference.id = id;
- } else {
- // We need to update the ID when it is set, so add it
- // to the graph.
- mGraph[reference.name].push_back(Node{
- args.referrer,
- args.source.path,
- args.source.line,
- &reference
- });
- }
+ doResolveReference(reference, args.source);
// TODO(adamlesinski): Verify the referencedType is another reference
// or a compatible primitive.
@@ -192,7 +195,6 @@
// We should never get here. All references would have been
// parsed in the parser phase.
assert(false);
- //mTable->addResource(name, ConfigDescription{}, source, util::make_unique<Id>());
};
convertedValue = ResourceParser::parseItemForAttribute(*str.value, attr,
@@ -240,25 +242,10 @@
}
for (Style::Entry& styleEntry : style.entries) {
- Maybe<IResolver::Entry> result = mResolver->findAttribute(styleEntry.key.name);
- if (!result || !result.value().attr) {
- addUnresolvedSymbol(styleEntry.key.name, args.source);
- continue;
+ const Attribute* attr = doResolveAttribute(styleEntry.key, args.source);
+ if (attr) {
+ processAttributeValue(args.referrer, args.source, *attr, styleEntry.value);
}
-
- const IResolver::Entry& entry = result.value();
- if (entry.id.isValid()) {
- styleEntry.key.id = entry.id;
- } else {
- // Create a dependency for the style on this attribute.
- mGraph[styleEntry.key.name].push_back(Node{
- args.referrer,
- args.source.path,
- args.source.line,
- &styleEntry.key
- });
- }
- processAttributeValue(args.referrer, args.source, *entry.attr, styleEntry.value);
}
}
@@ -300,8 +287,4 @@
mUnresolvedSymbols[name.toResourceName()].push_back(source);
}
-::std::ostream& operator<<(::std::ostream& out, const Linker::Node& node) {
- return out << node.name << "(" << node.source << ":" << node.line << ")";
-}
-
} // namespace aapt
diff --git a/tools/aapt2/Linker.h b/tools/aapt2/Linker.h
index 9db64ab..6f03515 100644
--- a/tools/aapt2/Linker.h
+++ b/tools/aapt2/Linker.h
@@ -50,14 +50,25 @@
*/
class Linker : ValueVisitor {
public:
+ struct Options {
+ /**
+ * Assign resource Ids to references when linking.
+ * When building a static library, set this to false.
+ */
+ bool linkResourceIds = true;
+ };
+
/**
* Create a Linker for the given resource table with the sources available in
* IResolver. IResolver should contain the ResourceTable as a source too.
*/
- Linker(std::shared_ptr<ResourceTable> table, std::shared_ptr<IResolver> resolver);
+ Linker(const std::shared_ptr<ResourceTable>& table,
+ const std::shared_ptr<IResolver>& resolver, const Options& options);
Linker(const Linker&) = delete;
+ virtual ~Linker() = default;
+
/**
* Entry point to the linker. Assigns resource IDs, follows references,
* and validates types. Returns true if all references to defined values
@@ -73,6 +84,12 @@
using ResourceNameToSourceMap = std::map<ResourceName, std::vector<SourceLine>>;
const ResourceNameToSourceMap& getUnresolvedReferences() const;
+protected:
+ virtual void doResolveReference(Reference& reference, const SourceLine& source);
+ virtual const Attribute* doResolveAttribute(Reference& attribute, const SourceLine& source);
+
+ std::shared_ptr<IResolver> mResolver;
+
private:
struct Args : public ValueVisitorArgs {
Args(const ResourceNameRef& r, const SourceLine& s);
@@ -92,33 +109,13 @@
void visit(Plural& plural, ValueVisitorArgs& args) override;
void processAttributeValue(const ResourceNameRef& name, const SourceLine& source,
- const Attribute& attr, std::unique_ptr<Item>& value);
+ const Attribute& attr, std::unique_ptr<Item>& value);
void addUnresolvedSymbol(const ResourceNameRef& name, const SourceLine& source);
- /**
- * Node of the resource table graph.
- */
- struct Node {
- // We use ResourceNameRef and StringPiece, which are safe so long as the ResourceTable
- // that defines the data isn't modified.
- ResourceNameRef name;
- StringPiece source;
- size_t line;
-
- // The reference object that points to name.
- Reference* reference;
-
- bool operator<(const Node& rhs) const;
- bool operator==(const Node& rhs) const;
- bool operator!=(const Node& rhs) const;
- };
- friend ::std::ostream& operator<<(::std::ostream&, const Node&);
-
std::shared_ptr<ResourceTable> mTable;
- std::shared_ptr<IResolver> mResolver;
- std::map<ResourceNameRef, std::vector<Node>> mGraph;
std::map<ResourceName, std::vector<SourceLine>> mUnresolvedSymbols;
+ Options mOptions;
bool mError;
};
diff --git a/tools/aapt2/Linker_test.cpp b/tools/aapt2/Linker_test.cpp
index 3c5b8b4..d897f98 100644
--- a/tools/aapt2/Linker_test.cpp
+++ b/tools/aapt2/Linker_test.cpp
@@ -32,7 +32,8 @@
mTable->setPackage(u"android");
mTable->setPackageId(0x01);
mLinker = std::make_shared<Linker>(mTable, std::make_shared<ResourceTableResolver>(
- mTable, std::make_shared<android::AssetManager>()));
+ mTable, std::vector<std::shared_ptr<const android::AssetManager>>()),
+ Linker::Options{});
// Create a few attributes for use in the tests.
@@ -76,7 +77,7 @@
}
TEST_F(LinkerTest, EscapeAndConvertRawString) {
- std::unique_ptr<Style> style = util::make_unique<Style>(false);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
style->entries.push_back(Style::Entry{
ResourceNameRef{ u"android", ResourceType::kAttr, u"integer" },
util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u" 123"))
@@ -92,7 +93,7 @@
}
TEST_F(LinkerTest, FailToConvertRawString) {
- std::unique_ptr<Style> style = util::make_unique<Style>(false);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
style->entries.push_back(Style::Entry{
ResourceNameRef{ u"android", ResourceType::kAttr, u"integer" },
util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u"yo what is up?"))
@@ -104,7 +105,7 @@
}
TEST_F(LinkerTest, ConvertRawStringToString) {
- std::unique_ptr<Style> style = util::make_unique<Style>(false);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
style->entries.push_back(Style::Entry{
ResourceNameRef{ u"android", ResourceType::kAttr, u"string" },
util::make_unique<RawString>(
@@ -123,7 +124,7 @@
}
TEST_F(LinkerTest, ConvertRawStringToFlags) {
- std::unique_ptr<Style> style = util::make_unique<Style>(false);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
style->entries.push_back(Style::Entry{
ResourceNameRef{ u"android", ResourceType::kAttr, u"flags" },
util::make_unique<RawString>(mTable->getValueStringPool().makeRef(u"banana | apple"))
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 3377f07..91639c5 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -19,6 +19,7 @@
#include "BinaryResourceParser.h"
#include "BinaryXmlPullParser.h"
#include "BindingXmlPullParser.h"
+#include "Debug.h"
#include "Files.h"
#include "Flag.h"
#include "JavaClassGenerator.h"
@@ -55,54 +56,6 @@
using namespace aapt;
-void printTable(const ResourceTable& table) {
- std::cout << "ResourceTable package=" << table.getPackage();
- if (table.getPackageId() != ResourceTable::kUnsetPackageId) {
- std::cout << " id=" << std::hex << table.getPackageId() << std::dec;
- }
- std::cout << std::endl
- << "---------------------------------------------------------" << std::endl;
-
- for (const auto& type : table) {
- std::cout << "Type " << type->type;
- if (type->typeId != ResourceTableType::kUnsetTypeId) {
- std::cout << " [" << type->typeId << "]";
- }
- std::cout << " (" << type->entries.size() << " entries)" << std::endl;
- for (const auto& entry : type->entries) {
- std::cout << " " << entry->name;
- if (entry->entryId != ResourceEntry::kUnsetEntryId) {
- std::cout << " [" << entry->entryId << "]";
- }
- std::cout << " (" << entry->values.size() << " configurations)";
- if (entry->publicStatus.isPublic) {
- std::cout << " PUBLIC";
- }
- std::cout << std::endl;
- for (const auto& value : entry->values) {
- std::cout << " " << value.config << " (" << value.source << ") : ";
- value.value->print(std::cout);
- std::cout << std::endl;
- }
- }
- }
-}
-
-void printStringPool(const StringPool& pool) {
- std::cout << "String pool of length " << pool.size() << std::endl
- << "---------------------------------------------------------" << std::endl;
-
- size_t i = 0;
- for (const auto& entry : pool) {
- std::cout << "[" << i << "]: "
- << entry->value
- << " (Priority " << entry->context.priority
- << ", Config '" << entry->context.config << "')"
- << std::endl;
- i++;
- }
-}
-
/**
* Collect files from 'root', filtering out any files that do not
* match the FileFilter 'filter'.
@@ -144,29 +97,6 @@
return !error;
}
-bool loadResTable(android::ResTable* table, const Source& source) {
- std::ifstream ifs(source.path, std::ifstream::in | std::ifstream::binary);
- if (!ifs) {
- Logger::error(source) << strerror(errno) << std::endl;
- return false;
- }
-
- std::streampos fsize = ifs.tellg();
- ifs.seekg(0, std::ios::end);
- fsize = ifs.tellg() - fsize;
- ifs.seekg(0, std::ios::beg);
-
- assert(fsize >= 0);
- size_t dataSize = static_cast<size_t>(fsize);
- char* buf = new char[dataSize];
- ifs.read(buf, dataSize);
-
- bool result = table->add(buf, dataSize, -1, true) == android::NO_ERROR;
-
- delete [] buf;
- return result;
-}
-
void versionStylesForCompat(const std::shared_ptr<ResourceTable>& table) {
for (auto& type : *table) {
if (type->type != ResourceType::kStyle) {
@@ -228,7 +158,6 @@
};
Style& newStyle = static_cast<Style&>(*value.value);
- newStyle.weak = true;
// Move the recorded stripped attributes into this new style.
std::move(stripped.begin(), stripped.end(),
@@ -260,16 +189,16 @@
}
struct CompileItem {
- Source source;
ResourceName name;
ConfigDescription config;
+ Source source;
std::string extension;
};
struct LinkItem {
- Source source;
ResourceName name;
ConfigDescription config;
+ Source source;
std::string originalPath;
ZipFile* apk;
std::u16string originalPackage;
@@ -285,8 +214,6 @@
return str.substr(offset, str.size() - offset);
}
-
-
std::string buildFileReference(const ResourceNameRef& name, const ConfigDescription& config,
const StringPiece& extension) {
std::stringstream path;
@@ -309,7 +236,8 @@
return buildFileReference(item.name, item.config, getExtension<char>(item.originalPath));
}
-bool addFileReference(const std::shared_ptr<ResourceTable>& table, const CompileItem& item) {
+template <typename T>
+bool addFileReference(const std::shared_ptr<ResourceTable>& table, const T& item) {
StringPool& pool = table->getValueStringPool();
StringPool::Ref ref = pool.makeRef(util::utf8ToUtf16(buildFileReference(item)),
StringPool::Context{ 0, item.config });
@@ -321,6 +249,8 @@
enum class Phase {
Link,
Compile,
+ Dump,
+ DumpStyleGraph,
};
enum class PackageType {
@@ -364,11 +294,14 @@
// referencing attributes defined in a newer SDK
// level than the style or layout is defined for.
bool versionStylesAndLayouts = true;
+
+ // The target style that will have it's style hierarchy dumped
+ // when the phase is DumpStyleGraph.
+ ResourceName dumpStyleTarget;
};
-
bool compileXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
- const CompileItem& item, std::queue<CompileItem>* outQueue, ZipFile* outApk) {
+ const CompileItem& item, ZipFile* outApk) {
std::ifstream in(item.source.path, std::ifstream::binary);
if (!in) {
Logger::error(item.source) << strerror(errno) << std::endl;
@@ -382,6 +315,76 @@
XmlFlattener::Options xmlOptions;
xmlOptions.defaultPackage = table->getPackage();
+ xmlOptions.keepRawValues = true;
+
+ std::shared_ptr<XmlPullParser> parser = std::make_shared<SourceXmlPullParser>(in);
+
+ Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, parser, &outBuffer,
+ xmlOptions);
+ if (!minStrippedSdk) {
+ return false;
+ }
+
+ // Write the resulting compiled XML file to the output APK.
+ if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressStored,
+ nullptr) != android::NO_ERROR) {
+ Logger::error(options.output) << "failed to write compiled '" << item.source
+ << "' to apk." << std::endl;
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Determines if a layout should be auto generated based on SDK level. We do not
+ * generate a layout if there is already a layout defined whose SDK version is greater than
+ * the one we want to generate.
+ */
+bool shouldGenerateVersionedResource(const std::shared_ptr<const ResourceTable>& table,
+ const ResourceName& name, const ConfigDescription& config,
+ int sdkVersionToGenerate) {
+ assert(sdkVersionToGenerate > config.sdkVersion);
+ const ResourceTableType* type;
+ const ResourceEntry* entry;
+ std::tie(type, entry) = table->findResource(name);
+ assert(type && entry);
+
+ auto iter = std::lower_bound(entry->values.begin(), entry->values.end(), config,
+ [](const ResourceConfigValue& lhs, const ConfigDescription& config) -> bool {
+ return lhs.config < config;
+ });
+
+ assert(iter != entry->values.end());
+ ++iter;
+
+ if (iter == entry->values.end()) {
+ return true;
+ }
+
+ ConfigDescription newConfig = config;
+ newConfig.sdkVersion = sdkVersionToGenerate;
+ return newConfig < iter->config;
+}
+
+bool linkXml(const AaptOptions& options, const std::shared_ptr<ResourceTable>& table,
+ const std::shared_ptr<IResolver>& resolver, const LinkItem& item,
+ const void* data, size_t dataLen, ZipFile* outApk, std::queue<LinkItem>* outQueue) {
+ std::shared_ptr<android::ResXMLTree> tree = std::make_shared<android::ResXMLTree>();
+ if (tree->setTo(data, dataLen, false) != android::NO_ERROR) {
+ return false;
+ }
+
+ std::shared_ptr<XmlPullParser> parser = std::make_shared<BinaryXmlPullParser>(tree);
+
+ BigBuffer outBuffer(1024);
+ XmlFlattener flattener({}, resolver);
+
+ XmlFlattener::Options xmlOptions;
+ xmlOptions.defaultPackage = item.originalPackage;
+
+ if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
+ xmlOptions.keepRawValues = true;
+ }
if (options.versionStylesAndLayouts) {
// We strip attributes that do not belong in this version of the resource.
@@ -390,14 +393,14 @@
}
std::shared_ptr<BindingXmlPullParser> binding;
- std::shared_ptr<XmlPullParser> parser = std::make_shared<SourceXmlPullParser>(in);
if (item.name.type == ResourceType::kLayout) {
// Layouts may have defined bindings, so we need to make sure they get processed.
binding = std::make_shared<BindingXmlPullParser>(parser);
parser = binding;
}
- Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, parser, &outBuffer, xmlOptions);
+ Maybe<size_t> minStrippedSdk = flattener.flatten(item.source, parser, &outBuffer,
+ xmlOptions);
if (!minStrippedSdk) {
return false;
}
@@ -405,16 +408,27 @@
if (minStrippedSdk.value() > 0) {
// Something was stripped, so let's generate a new file
// with the version of the smallest SDK version stripped.
- CompileItem newWork = item;
- newWork.config.sdkVersion = minStrippedSdk.value();
- outQueue->push(newWork);
+ // We can only generate a versioned layout if there doesn't exist a layout
+ // with sdk version greater than the current one but less than the one we
+ // want to generate.
+ if (shouldGenerateVersionedResource(table, item.name, item.config,
+ minStrippedSdk.value())) {
+ LinkItem newWork = item;
+ newWork.config.sdkVersion = minStrippedSdk.value();
+ outQueue->push(newWork);
+
+ if (!addFileReference(table, newWork)) {
+ Logger::error(options.output) << "failed to add auto-versioned resource '"
+ << newWork.name << "'." << std::endl;
+ return false;
+ }
+ }
}
- // Write the resulting compiled XML file to the output APK.
- if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressStored,
+ if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressDeflated,
nullptr) != android::NO_ERROR) {
- Logger::error(options.output) << "failed to write compiled '" << item.source << "' to apk."
- << std::endl;
+ Logger::error(options.output) << "failed to write linked file '"
+ << buildFileReference(item) << "' to apk." << std::endl;
return false;
}
@@ -444,33 +458,6 @@
return true;
}
-bool linkXml(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver,
- const LinkItem& item, const void* data, size_t dataLen, ZipFile* outApk) {
- std::shared_ptr<android::ResXMLTree> tree = std::make_shared<android::ResXMLTree>();
- if (tree->setTo(data, dataLen, false) != android::NO_ERROR) {
- return false;
- }
-
- std::shared_ptr<XmlPullParser> xmlParser = std::make_shared<BinaryXmlPullParser>(tree);
-
- BigBuffer outBuffer(1024);
- XmlFlattener flattener({}, resolver);
-
- XmlFlattener::Options xmlOptions;
- xmlOptions.defaultPackage = item.originalPackage;
- if (!flattener.flatten(item.source, xmlParser, &outBuffer, xmlOptions)) {
- return false;
- }
-
- if (outApk->add(outBuffer, buildFileReference(item).data(), ZipEntry::kCompressDeflated,
- nullptr) != android::NO_ERROR) {
- Logger::error(options.output) << "failed to write linked file '" << item.source
- << "' to apk." << std::endl;
- return false;
- }
- return true;
-}
-
bool compilePng(const AaptOptions& options, const CompileItem& item, ZipFile* outApk) {
std::ifstream in(item.source.path, std::ifstream::binary);
if (!in) {
@@ -505,8 +492,8 @@
return true;
}
-bool compileManifest(const AaptOptions& options,
- const std::shared_ptr<ResourceTableResolver>& resolver, ZipFile* outApk) {
+bool compileManifest(const AaptOptions& options, const std::shared_ptr<IResolver>& resolver,
+ const android::ResTable& table, ZipFile* outApk) {
if (options.verbose) {
Logger::note(options.manifest) << "compiling AndroidManifest.xml." << std::endl;
}
@@ -534,7 +521,7 @@
return false;
}
- ManifestValidator validator(resolver->getResTable());
+ ManifestValidator validator(table);
if (!validator.validate(options.manifest, &tree)) {
return false;
}
@@ -661,7 +648,7 @@
newSource.path += "/";
newSource.path += pathUtf8;
outLinkQueue->push(LinkItem{
- newSource, name, value.config, pathUtf8, apk.get(),
+ name, value.config, newSource, pathUtf8, apk.get(),
table->getPackage() });
// Now rewrite the file path.
if (mangle) {
@@ -690,7 +677,7 @@
};
bool link(const AaptOptions& options, const std::shared_ptr<ResourceTable>& outTable,
- const std::shared_ptr<ResourceTableResolver>& resolver) {
+ const std::shared_ptr<IResolver>& resolver) {
std::map<std::shared_ptr<ResourceTable>, StaticLibraryData> apkFiles;
std::unordered_set<std::u16string> linkedPackages;
@@ -744,9 +731,18 @@
}
}
+ // Version all styles referencing attributes outside of their specified SDK version.
+ if (options.versionStylesAndLayouts) {
+ versionStylesForCompat(outTable);
+ }
+
{
// Now that everything is merged, let's link it.
- Linker linker(outTable, resolver);
+ Linker::Options linkerOptions;
+ if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
+ linkerOptions.linkResourceIds = false;
+ }
+ Linker linker(outTable, resolver, linkerOptions);
if (!linker.linkAndValidate()) {
return false;
}
@@ -771,7 +767,8 @@
return false;
}
- if (!compileManifest(options, resolver, &outApk)) {
+ android::ResTable binTable;
+ if (!compileManifest(options, resolver, binTable, &outApk)) {
return false;
}
@@ -790,8 +787,8 @@
void* uncompressedData = item.apk->uncompress(entry);
assert(uncompressedData);
- if (!linkXml(options, resolver, item, uncompressedData, entry->getUncompressedLen(),
- &outApk)) {
+ if (!linkXml(options, outTable, resolver, item, uncompressedData,
+ entry->getUncompressedLen(), &outApk, &linkQueue)) {
Logger::error(options.output) << "failed to link '" << item.originalPath << "'."
<< std::endl;
return false;
@@ -864,8 +861,8 @@
// Flatten the resource table.
TableFlattener::Options flattenerOptions;
- if (options.packageType == AaptOptions::PackageType::StaticLibrary) {
- flattenerOptions.useExtendedChunks = true;
+ if (options.packageType != AaptOptions::PackageType::StaticLibrary) {
+ flattenerOptions.useExtendedChunks = false;
}
if (!writeResourceTable(options, outTable, flattenerOptions, &outApk)) {
@@ -909,9 +906,9 @@
}
compileQueue.push(CompileItem{
- source,
ResourceName{ table->getPackage(), *type, pathData.name },
pathData.config,
+ source,
pathData.extension
});
}
@@ -920,12 +917,6 @@
if (error) {
return false;
}
-
- // Version all styles referencing attributes outside of their specified SDK version.
- if (options.versionStylesAndLayouts) {
- versionStylesForCompat(table);
- }
-
// Open the output APK file for writing.
ZipFile outApk;
if (outApk.open(options.output.path.data(), kOpenFlags) != android::NO_ERROR) {
@@ -941,7 +932,7 @@
error |= !addFileReference(table, item);
if (item.extension == "xml") {
- error |= !compileXml(options, table, item, &compileQueue, &outApk);
+ error |= !compileXml(options, table, item, &outApk);
} else if (item.extension == "png" || item.extension == "9.png") {
error |= !compilePng(options, item, &outApk);
} else {
@@ -954,7 +945,7 @@
}
// Link and assign resource IDs.
- Linker linker(table, resolver);
+ Linker linker(table, resolver, {});
if (!linker.linkAndValidate()) {
return false;
}
@@ -984,6 +975,7 @@
std::cerr << "The following commands are supported:" << std::endl << std::endl;
std::cerr << "compile compiles a subset of resources" << std::endl;
std::cerr << "link links together compiled resources and libraries" << std::endl;
+ std::cerr << "dump dumps resource contents to to standard out" << std::endl;
std::cerr << std::endl;
std::cerr << "run aapt2 with one of the commands and the -h flag for extra details."
<< std::endl;
@@ -1009,48 +1001,67 @@
options.phase = AaptOptions::Phase::Link;
} else if (command == "compile") {
options.phase = AaptOptions::Phase::Compile;
+ } else if (command == "dump") {
+ options.phase = AaptOptions::Phase::Dump;
+ } else if (command == "dump-style-graph") {
+ options.phase = AaptOptions::Phase::DumpStyleGraph;
} else {
std::cerr << "invalid command '" << command << "'." << std::endl << std::endl;
printCommandsAndDie();
}
bool isStaticLib = false;
- if (options.phase == AaptOptions::Phase::Compile) {
- flag::requiredFlag("--package", "Android package name",
- [&options](const StringPiece& arg) {
- options.appInfo.package = util::utf8ToUtf16(arg);
- });
- flag::optionalFlag("--binding", "Output directory for binding XML files",
- [&options](const StringPiece& arg) {
- options.bindingOutput = Source{ arg.toString() };
- });
- flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning",
- false, &options.versionStylesAndLayouts);
+ if (options.phase == AaptOptions::Phase::Compile ||
+ options.phase == AaptOptions::Phase::Link) {
+ if (options.phase == AaptOptions::Phase::Compile) {
+ flag::requiredFlag("--package", "Android package name",
+ [&options](const StringPiece& arg) {
+ options.appInfo.package = util::utf8ToUtf16(arg);
+ });
+ } else if (options.phase == AaptOptions::Phase::Link) {
+ flag::requiredFlag("--manifest", "AndroidManifest.xml of your app",
+ [&options](const StringPiece& arg) {
+ options.manifest = Source{ arg.toString() };
+ });
- } else if (options.phase == AaptOptions::Phase::Link) {
- flag::requiredFlag("--manifest", "AndroidManifest.xml of your app",
- [&options](const StringPiece& arg) {
- options.manifest = Source{ arg.toString() };
- });
+ flag::optionalFlag("-I", "add an Android APK to link against",
+ [&options](const StringPiece& arg) {
+ options.libraries.push_back(Source{ arg.toString() });
+ });
- flag::optionalFlag("-I", "add an Android APK to link against",
- [&options](const StringPiece& arg) {
- options.libraries.push_back(Source{ arg.toString() });
- });
+ flag::optionalFlag("--java", "directory in which to generate R.java",
+ [&options](const StringPiece& arg) {
+ options.generateJavaClass = Source{ arg.toString() };
+ });
- flag::optionalFlag("--java", "directory in which to generate R.java",
- [&options](const StringPiece& arg) {
- options.generateJavaClass = Source{ arg.toString() };
+ flag::optionalSwitch("--static-lib", "generate a static Android library", true,
+ &isStaticLib);
+
+ flag::optionalFlag("--binding", "Output directory for binding XML files",
+ [&options](const StringPiece& arg) {
+ options.bindingOutput = Source{ arg.toString() };
+ });
+ flag::optionalSwitch("--no-version", "Disables automatic style and layout versioning",
+ false, &options.versionStylesAndLayouts);
+ }
+
+ // Common flags for all steps.
+ flag::requiredFlag("-o", "Output path", [&options](const StringPiece& arg) {
+ options.output = Source{ arg.toString() };
+ });
+ } else if (options.phase == AaptOptions::Phase::DumpStyleGraph) {
+ flag::requiredFlag("--style", "Name of the style to dump",
+ [&options](const StringPiece& arg, std::string* outError) -> bool {
+ Reference styleReference;
+ if (!ResourceParser::parseStyleParentReference(util::utf8ToUtf16(arg),
+ &styleReference, outError)) {
+ return false;
+ }
+ options.dumpStyleTarget = styleReference.name;
+ return true;
});
- flag::optionalSwitch("--static-lib", "generate a static Android library", true,
- &isStaticLib);
}
- // Common flags for all steps.
- flag::requiredFlag("-o", "Output path", [&options](const StringPiece& arg) {
- options.output = Source{ arg.toString() };
- });
-
bool help = false;
flag::optionalSwitch("-v", "enables verbose logging", true, &options.verbose);
flag::optionalSwitch("-h", "displays this help menu", true, &help);
@@ -1078,10 +1089,56 @@
return options;
}
+static bool doDump(const AaptOptions& options) {
+ for (const Source& source : options.input) {
+ std::unique_ptr<ZipFile> zipFile = util::make_unique<ZipFile>();
+ if (zipFile->open(source.path.data(), ZipFile::kOpenReadOnly) != android::NO_ERROR) {
+ Logger::error(source) << "failed to open: " << strerror(errno) << std::endl;
+ return false;
+ }
+
+ std::shared_ptr<ResourceTable> table = std::make_shared<ResourceTable>();
+ std::shared_ptr<ResourceTableResolver> resolver =
+ std::make_shared<ResourceTableResolver>(
+ table, std::vector<std::shared_ptr<const android::AssetManager>>());
+
+ ZipEntry* entry = zipFile->getEntryByName("resources.arsc");
+ if (!entry) {
+ Logger::error(source) << "missing 'resources.arsc'." << std::endl;
+ return false;
+ }
+
+ std::unique_ptr<void, DeleteMalloc> uncompressedData = std::unique_ptr<void, DeleteMalloc>(
+ zipFile->uncompress(entry));
+ assert(uncompressedData);
+
+ BinaryResourceParser parser(table, resolver, source, uncompressedData.get(),
+ entry->getUncompressedLen());
+ if (!parser.parse()) {
+ return false;
+ }
+
+ if (options.phase == AaptOptions::Phase::Dump) {
+ Debug::printTable(table);
+ } else if (options.phase == AaptOptions::Phase::DumpStyleGraph) {
+ Debug::printStyleGraph(table, options.dumpStyleTarget);
+ }
+ }
+ return true;
+}
+
int main(int argc, char** argv) {
Logger::setLog(std::make_shared<Log>(std::cerr, std::cerr));
AaptOptions options = prepareArgs(argc, argv);
+ if (options.phase == AaptOptions::Phase::Dump ||
+ options.phase == AaptOptions::Phase::DumpStyleGraph) {
+ if (!doDump(options)) {
+ return 1;
+ }
+ return 0;
+ }
+
// If we specified a manifest, go ahead and load the package name from the manifest.
if (!options.manifest.path.empty()) {
if (!loadAppInfo(options.manifest, &options.appInfo)) {
@@ -1105,37 +1162,26 @@
}
// Load the included libraries.
- std::shared_ptr<android::AssetManager> libraries = std::make_shared<android::AssetManager>();
+ std::vector<std::shared_ptr<const android::AssetManager>> sources;
for (const Source& source : options.libraries) {
- if (util::stringEndsWith<char>(source.path, ".arsc")) {
- // We'll process these last so as to avoid a cookie issue.
- continue;
- }
-
+ std::shared_ptr<android::AssetManager> assetManager =
+ std::make_shared<android::AssetManager>();
int32_t cookie;
- if (!libraries->addAssetPath(android::String8(source.path.data()), &cookie)) {
+ if (!assetManager->addAssetPath(android::String8(source.path.data()), &cookie)) {
Logger::error(source) << "failed to load library." << std::endl;
return false;
}
- }
- for (const Source& source : options.libraries) {
- if (!util::stringEndsWith<char>(source.path, ".arsc")) {
- // We've already processed this.
- continue;
- }
-
- // Dirty hack but there is no other way to get a
- // writeable ResTable.
- if (!loadResTable(const_cast<android::ResTable*>(&libraries->getResources(false)),
- source)) {
+ if (cookie == 0) {
+ Logger::error(source) << "failed to load library." << std::endl;
return false;
}
+ sources.push_back(assetManager);
}
// Make the resolver that will cache IDs for us.
std::shared_ptr<ResourceTableResolver> resolver = std::make_shared<ResourceTableResolver>(
- table, libraries);
+ table, sources);
if (options.phase == AaptOptions::Phase::Compile) {
if (!compile(options, table, resolver)) {
diff --git a/tools/aapt2/MockResolver.h b/tools/aapt2/MockResolver.h
index 48ff6a6..0c9b954 100644
--- a/tools/aapt2/MockResolver.h
+++ b/tools/aapt2/MockResolver.h
@@ -34,7 +34,7 @@
MockResolver(const std::shared_ptr<ResourceTable>& table,
const std::map<ResourceName, ResourceId>& items) :
mResolver(std::make_shared<ResourceTableResolver>(
- table, std::make_shared<const android::AssetManager>())),
+ table, std::vector<std::shared_ptr<const android::AssetManager>>())),
mAttr(false, android::ResTable_map::TYPE_ANY), mItems(items) {
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index e7e824c..13f916b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -193,18 +193,18 @@
std::unique_ptr<BinaryPrimitive> ResourceParser::tryParseNullOrEmpty(const StringPiece16& str) {
StringPiece16 trimmedStr(util::trimWhitespace(str));
- uint32_t data = 0;
+ android::Res_value value = {};
if (trimmedStr == u"@null") {
- data = android::Res_value::DATA_NULL_UNDEFINED;
+ // TYPE_NULL with data set to 0 is interpreted by the runtime as an error.
+ // Instead we set the data type to TYPE_REFERENCE with a value of 0.
+ value.dataType = android::Res_value::TYPE_REFERENCE;
} else if (trimmedStr == u"@empty") {
- data = android::Res_value::DATA_NULL_EMPTY;
+ // TYPE_NULL with value of DATA_NULL_EMPTY is handled fine by the runtime.
+ value.dataType = android::Res_value::TYPE_NULL;
+ value.data = android::Res_value::DATA_NULL_EMPTY;
} else {
return {};
}
-
- android::Res_value value = {};
- value.dataType = android::Res_value::TYPE_NULL;
- value.data = data;
return util::make_unique<BinaryPrimitive>(value);
}
@@ -1163,7 +1163,7 @@
bool ResourceParser::parseStyle(XmlPullParser* parser, const ResourceNameRef& resourceName) {
const SourceLine source = mSource.line(parser->getLineNumber());
- std::unique_ptr<Style> style = util::make_unique<Style>(false);
+ std::unique_ptr<Style> style = util::make_unique<Style>();
const auto endAttrIter = parser->endAttributes();
const auto parentAttrIter = parser->findAttribute(u"", u"parent");
@@ -1181,6 +1181,16 @@
// If no package is specified, this can not be an alias and is the local package.
style->parent.name.package = mTable->getPackage();
}
+ } else {
+ // No parent was specified, so try inferring it from the style name.
+ std::u16string styleName = resourceName.entry.toString();
+ size_t pos = styleName.find_last_of(u'.');
+ if (pos != std::string::npos) {
+ style->parentInferred = true;
+ style->parent.name.package = mTable->getPackage();
+ style->parent.name.type = ResourceType::kStyle;
+ style->parent.name.entry = styleName.substr(0, pos);
+ }
}
bool success = true;
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 00be3bd..a93d0ff 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -191,6 +191,32 @@
EXPECT_EQ(std::u16string(u"?123"), *str->value);
}
+TEST_F(ResourceParserTest, ParseNull) {
+ std::string input = "<integer name=\"foo\">@null</integer>";
+ ASSERT_TRUE(testParse(input));
+
+ // The Android runtime treats a value of android::Res_value::TYPE_NULL as
+ // a non-existing value, and this causes problems in styles when trying to resolve
+ // an attribute. Null values must be encoded as android::Res_value::TYPE_REFERENCE
+ // with a data value of 0.
+ const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
+ u"android", ResourceType::kInteger, u"foo" });
+ ASSERT_NE(nullptr, integer);
+ EXPECT_EQ(uint16_t(android::Res_value::TYPE_REFERENCE), integer->value.dataType);
+ EXPECT_EQ(0u, integer->value.data);
+}
+
+TEST_F(ResourceParserTest, ParseEmpty) {
+ std::string input = "<integer name=\"foo\">@empty</integer>";
+ ASSERT_TRUE(testParse(input));
+
+ const BinaryPrimitive* integer = findResource<BinaryPrimitive>(ResourceName{
+ u"android", ResourceType::kInteger, u"foo" });
+ ASSERT_NE(nullptr, integer);
+ EXPECT_EQ(uint16_t(android::Res_value::TYPE_NULL), integer->value.dataType);
+ EXPECT_EQ(uint32_t(android::Res_value::DATA_NULL_EMPTY), integer->value.data);
+}
+
TEST_F(ResourceParserTest, ParseAttr) {
std::string input = "<attr name=\"foo\" format=\"string\"/>\n"
"<attr name=\"bar\"/>";
@@ -355,6 +381,28 @@
style->entries[0].key.name);
}
+TEST_F(ResourceParserTest, ParseStyleWithInferredParent) {
+ std::string input = "<style name=\"foo.bar\"/>";
+ ASSERT_TRUE(testParse(input));
+
+ const Style* style = findResource<Style>(ResourceName{
+ u"android", ResourceType::kStyle, u"foo.bar" });
+ ASSERT_NE(style, nullptr);
+ EXPECT_EQ(style->parent.name, (ResourceName{ u"android", ResourceType::kStyle, u"foo" }));
+ EXPECT_TRUE(style->parentInferred);
+}
+
+TEST_F(ResourceParserTest, ParseStyleWithInferredParentOverridenByEmptyParentAttribute) {
+ std::string input = "<style name=\"foo.bar\" parent=\"\"/>";
+ ASSERT_TRUE(testParse(input));
+
+ const Style* style = findResource<Style>(ResourceName{
+ u"android", ResourceType::kStyle, u"foo.bar" });
+ ASSERT_NE(style, nullptr);
+ EXPECT_FALSE(style->parent.name.isValid());
+ EXPECT_FALSE(style->parentInferred);
+}
+
TEST_F(ResourceParserTest, ParseAutoGeneratedIdReference) {
std::string input = "<string name=\"foo\">@+id/bar</string>";
ASSERT_TRUE(testParse(input));
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 9468860..c93ecc7 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -42,6 +42,8 @@
}
ResourceTable::ResourceTable() : mPackageId(kUnsetPackageId) {
+ // Make sure attrs always have type ID 1.
+ findOrCreateType(ResourceType::kAttr)->typeId = 1;
}
std::unique_ptr<ResourceTableType>& ResourceTable::findOrCreateType(ResourceType type) {
@@ -142,10 +144,30 @@
}
static constexpr const char16_t* kValidNameChars = u"._-";
+static constexpr const char16_t* kValidNameMangledChars = u"._-$";
+
+bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
+ const SourceLine& source, std::unique_ptr<Value> value) {
+ return addResourceImpl(name, ResourceId{}, config, source, std::move(value), kValidNameChars);
+}
bool ResourceTable::addResource(const ResourceNameRef& name, const ResourceId resId,
- const ConfigDescription& config, const SourceLine& source,
- std::unique_ptr<Value> value) {
+ const ConfigDescription& config, const SourceLine& source,
+ std::unique_ptr<Value> value) {
+ return addResourceImpl(name, resId, config, source, std::move(value), kValidNameChars);
+}
+
+bool ResourceTable::addResourceAllowMangled(const ResourceNameRef& name,
+ const ConfigDescription& config,
+ const SourceLine& source,
+ std::unique_ptr<Value> value) {
+ return addResourceImpl(name, ResourceId{}, config, source, std::move(value),
+ kValidNameMangledChars);
+}
+
+bool ResourceTable::addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
+ const ConfigDescription& config, const SourceLine& source,
+ std::unique_ptr<Value> value, const char16_t* validChars) {
if (!name.package.empty() && name.package != mPackage) {
Logger::error(source)
<< "resource '"
@@ -157,7 +179,7 @@
return false;
}
- auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+ auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
if (badCharIter != name.entry.end()) {
Logger::error(source)
<< "resource '"
@@ -233,13 +255,18 @@
return true;
}
-bool ResourceTable::addResource(const ResourceNameRef& name, const ConfigDescription& config,
- const SourceLine& source, std::unique_ptr<Value> value) {
- return addResource(name, ResourceId{}, config, source, std::move(value));
-}
-
bool ResourceTable::markPublic(const ResourceNameRef& name, const ResourceId resId,
const SourceLine& source) {
+ return markPublicImpl(name, resId, source, kValidNameChars);
+}
+
+bool ResourceTable::markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
+ const SourceLine& source) {
+ return markPublicImpl(name, resId, source, kValidNameMangledChars);
+}
+
+bool ResourceTable::markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
+ const SourceLine& source, const char16_t* validChars) {
if (!name.package.empty() && name.package != mPackage) {
Logger::error(source)
<< "resource '"
@@ -251,7 +278,7 @@
return false;
}
- auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, kValidNameChars);
+ auto badCharIter = util::findNonAlphaNumericAndNotInSet(name.entry, validChars);
if (badCharIter != name.entry.end()) {
Logger::error(source)
<< "resource '"
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 94bacd8..706f56a 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -143,11 +143,21 @@
bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
const SourceLine& source, std::unique_ptr<Value> value);
+ /**
+ * Same as addResource, but doesn't verify the validity of the name. This is used
+ * when loading resources from an existing binary resource table that may have mangled
+ * names.
+ */
+ bool addResourceAllowMangled(const ResourceNameRef& name, const ConfigDescription& config,
+ const SourceLine& source, std::unique_ptr<Value> value);
+
bool addResource(const ResourceNameRef& name, const ResourceId resId,
const ConfigDescription& config, const SourceLine& source,
std::unique_ptr<Value> value);
bool markPublic(const ResourceNameRef& name, const ResourceId resId, const SourceLine& source);
+ bool markPublicAllowMangled(const ResourceNameRef& name, const ResourceId resId,
+ const SourceLine& source);
/*
* Merges the resources from `other` into this table, mangling the names of the resources
@@ -176,6 +186,12 @@
std::unique_ptr<ResourceEntry>& findOrCreateEntry(std::unique_ptr<ResourceTableType>& type,
const StringPiece16& name);
+ bool addResourceImpl(const ResourceNameRef& name, const ResourceId resId,
+ const ConfigDescription& config, const SourceLine& source,
+ std::unique_ptr<Value> value, const char16_t* validChars);
+ bool markPublicImpl(const ResourceNameRef& name, const ResourceId resId,
+ const SourceLine& source, const char16_t* validChars);
+
std::u16string mPackage;
size_t mPackageId;
diff --git a/tools/aapt2/ResourceTableResolver.cpp b/tools/aapt2/ResourceTableResolver.cpp
index 0a9f521..910c2c0 100644
--- a/tools/aapt2/ResourceTableResolver.cpp
+++ b/tools/aapt2/ResourceTableResolver.cpp
@@ -31,13 +31,15 @@
ResourceTableResolver::ResourceTableResolver(
std::shared_ptr<const ResourceTable> table,
- std::shared_ptr<const android::AssetManager> sources) :
+ const std::vector<std::shared_ptr<const android::AssetManager>>& sources) :
mTable(table), mSources(sources) {
- const android::ResTable& resTable = mSources->getResources(false);
- const size_t packageCount = resTable.getBasePackageCount();
- for (size_t i = 0; i < packageCount; i++) {
- std::u16string packageName = resTable.getBasePackageName(i).string();
- mIncludedPackages.insert(std::move(packageName));
+ for (const auto& assetManager : mSources) {
+ const android::ResTable& resTable = assetManager->getResources(false);
+ const size_t packageCount = resTable.getBasePackageCount();
+ for (size_t i = 0; i < packageCount; i++) {
+ std::u16string packageName = resTable.getBasePackageName(i).string();
+ mIncludedPackages.insert(std::move(packageName));
+ }
}
}
@@ -99,20 +101,23 @@
}
Maybe<ResourceName> ResourceTableResolver::findName(ResourceId resId) {
- const android::ResTable& table = mSources->getResources(false);
+ for (const auto& assetManager : mSources) {
+ const android::ResTable& table = assetManager->getResources(false);
- android::ResTable::resource_name resourceName;
- if (!table.getResourceName(resId.id, false, &resourceName)) {
- return {};
+ android::ResTable::resource_name resourceName;
+ if (!table.getResourceName(resId.id, false, &resourceName)) {
+ continue;
+ }
+
+ const ResourceType* type = parseResourceType(StringPiece16(resourceName.type,
+ resourceName.typeLen));
+ assert(type);
+ return ResourceName{
+ { resourceName.package, resourceName.packageLen },
+ *type,
+ { resourceName.name, resourceName.nameLen } };
}
-
- const ResourceType* type = parseResourceType(StringPiece16(resourceName.type,
- resourceName.typeLen));
- assert(type);
- return ResourceName{
- { resourceName.package, resourceName.packageLen },
- *type,
- { resourceName.name, resourceName.nameLen } };
+ return {};
}
/**
@@ -122,73 +127,76 @@
*/
const ResourceTableResolver::CacheEntry* ResourceTableResolver::buildCacheEntry(
const ResourceName& name) {
- const android::ResTable& table = mSources->getResources(false);
+ for (const auto& assetManager : mSources) {
+ const android::ResTable& table = assetManager->getResources(false);
- const StringPiece16 type16 = toString(name.type);
- ResourceId resId {
- table.identifierForName(
- name.entry.data(), name.entry.size(),
- type16.data(), type16.size(),
- name.package.data(), name.package.size())
- };
+ const StringPiece16 type16 = toString(name.type);
+ ResourceId resId {
+ table.identifierForName(
+ name.entry.data(), name.entry.size(),
+ type16.data(), type16.size(),
+ name.package.data(), name.package.size())
+ };
- if (!resId.isValid()) {
- return nullptr;
- }
+ if (!resId.isValid()) {
+ continue;
+ }
- CacheEntry& entry = mCache[name];
- entry.id = resId;
+ CacheEntry& entry = mCache[name];
+ entry.id = resId;
- //
- // Now check to see if this resource is an Attribute.
- //
+ //
+ // Now check to see if this resource is an Attribute.
+ //
- const android::ResTable::bag_entry* bagBegin;
- ssize_t bags = table.lockBag(resId.id, &bagBegin);
- if (bags < 1) {
+ const android::ResTable::bag_entry* bagBegin;
+ ssize_t bags = table.lockBag(resId.id, &bagBegin);
+ if (bags < 1) {
+ table.unlockBag(bagBegin);
+ return &entry;
+ }
+
+ // Look for the ATTR_TYPE key in the bag and check the types it supports.
+ uint32_t attrTypeMask = 0;
+ for (ssize_t i = 0; i < bags; i++) {
+ if (bagBegin[i].map.name.ident == android::ResTable_map::ATTR_TYPE) {
+ attrTypeMask = bagBegin[i].map.value.data;
+ }
+ }
+
+ entry.attr = util::make_unique<Attribute>(false);
+
+ if (attrTypeMask & android::ResTable_map::TYPE_ENUM ||
+ attrTypeMask & android::ResTable_map::TYPE_FLAGS) {
+ for (ssize_t i = 0; i < bags; i++) {
+ if (Res_INTERNALID(bagBegin[i].map.name.ident)) {
+ // Internal IDs are special keys, which are not enum/flag symbols, so skip.
+ continue;
+ }
+
+ android::ResTable::resource_name symbolName;
+ bool result = table.getResourceName(bagBegin[i].map.name.ident, false,
+ &symbolName);
+ assert(result);
+ const ResourceType* type = parseResourceType(
+ StringPiece16(symbolName.type, symbolName.typeLen));
+ assert(type);
+
+ entry.attr->symbols.push_back(Attribute::Symbol{
+ Reference(ResourceNameRef(
+ StringPiece16(symbolName.package, symbolName.packageLen),
+ *type,
+ StringPiece16(symbolName.name, symbolName.nameLen))),
+ bagBegin[i].map.value.data
+ });
+ }
+ }
+
+ entry.attr->typeMask |= attrTypeMask;
table.unlockBag(bagBegin);
return &entry;
}
-
- // Look for the ATTR_TYPE key in the bag and check the types it supports.
- uint32_t attrTypeMask = 0;
- for (ssize_t i = 0; i < bags; i++) {
- if (bagBegin[i].map.name.ident == android::ResTable_map::ATTR_TYPE) {
- attrTypeMask = bagBegin[i].map.value.data;
- }
- }
-
- entry.attr = util::make_unique<Attribute>(false);
-
- if (attrTypeMask & android::ResTable_map::TYPE_ENUM ||
- attrTypeMask & android::ResTable_map::TYPE_FLAGS) {
- for (ssize_t i = 0; i < bags; i++) {
- if (Res_INTERNALID(bagBegin[i].map.name.ident)) {
- // Internal IDs are special keys, which are not enum/flag symbols, so skip.
- continue;
- }
-
- android::ResTable::resource_name symbolName;
- bool result = table.getResourceName(bagBegin[i].map.name.ident, false,
- &symbolName);
- assert(result);
- const ResourceType* type = parseResourceType(
- StringPiece16(symbolName.type, symbolName.typeLen));
- assert(type);
-
- entry.attr->symbols.push_back(Attribute::Symbol{
- Reference(ResourceNameRef(
- StringPiece16(symbolName.package, symbolName.packageLen),
- *type,
- StringPiece16(symbolName.name, symbolName.nameLen))),
- bagBegin[i].map.value.data
- });
- }
- }
-
- entry.attr->typeMask |= attrTypeMask;
- table.unlockBag(bagBegin);
- return &entry;
+ return nullptr;
}
} // namespace aapt
diff --git a/tools/aapt2/ResourceTableResolver.h b/tools/aapt2/ResourceTableResolver.h
index c8e8ab7..8f6b0b5 100644
--- a/tools/aapt2/ResourceTableResolver.h
+++ b/tools/aapt2/ResourceTableResolver.h
@@ -24,7 +24,6 @@
#include "ResourceValues.h"
#include <androidfw/AssetManager.h>
-#include <androidfw/ResourceTypes.h>
#include <memory>
#include <vector>
#include <unordered_set>
@@ -40,8 +39,9 @@
* Creates a resolver with a local ResourceTable and an AssetManager
* loaded with library packages.
*/
- ResourceTableResolver(std::shared_ptr<const ResourceTable> table,
- std::shared_ptr<const android::AssetManager> sources);
+ ResourceTableResolver(
+ std::shared_ptr<const ResourceTable> table,
+ const std::vector<std::shared_ptr<const android::AssetManager>>& sources);
ResourceTableResolver(const ResourceTableResolver&) = delete; // Not copyable.
@@ -51,8 +51,6 @@
virtual Maybe<ResourceName> findName(ResourceId resId) override;
- const android::ResTable& getResTable() const;
-
private:
struct CacheEntry {
ResourceId id;
@@ -62,15 +60,11 @@
const CacheEntry* buildCacheEntry(const ResourceName& name);
std::shared_ptr<const ResourceTable> mTable;
- std::shared_ptr<const android::AssetManager> mSources;
+ std::vector<std::shared_ptr<const android::AssetManager>> mSources;
std::map<ResourceName, CacheEntry> mCache;
std::unordered_set<std::u16string> mIncludedPackages;
};
-inline const android::ResTable& ResourceTableResolver::getResTable() const {
- return mSources->getResources(false);
-}
-
} // namespace aapt
#endif // AAPT_RESOURCE_TABLE_RESOLVER_H
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index 2bf38e4..aabb375 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -101,8 +101,8 @@
}
bool Id::flatten(android::Res_value& out) const {
- out.dataType = android::Res_value::TYPE_NULL;
- out.data = android::Res_value::DATA_NULL_UNDEFINED;
+ out.dataType = android::Res_value::TYPE_INT_BOOLEAN;
+ out.data = 0;
return true;
}
@@ -231,17 +231,15 @@
return attr;
}
-void Attribute::print(std::ostream& out) const {
- out << "(attr)";
+void Attribute::printMask(std::ostream& out) const {
if (typeMask == android::ResTable_map::TYPE_ANY) {
- out << " any";
+ out << "any";
return;
}
bool set = false;
if ((typeMask & android::ResTable_map::TYPE_REFERENCE) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -251,7 +249,6 @@
if ((typeMask & android::ResTable_map::TYPE_STRING) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -261,7 +258,6 @@
if ((typeMask & android::ResTable_map::TYPE_INTEGER) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -271,7 +267,6 @@
if ((typeMask & android::ResTable_map::TYPE_BOOLEAN) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -281,7 +276,6 @@
if ((typeMask & android::ResTable_map::TYPE_COLOR) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -291,7 +285,6 @@
if ((typeMask & android::ResTable_map::TYPE_FLOAT) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -301,7 +294,6 @@
if ((typeMask & android::ResTable_map::TYPE_DIMENSION) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -311,7 +303,6 @@
if ((typeMask & android::ResTable_map::TYPE_FRACTION) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -321,7 +312,6 @@
if ((typeMask & android::ResTable_map::TYPE_ENUM) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
@@ -331,13 +321,17 @@
if ((typeMask & android::ResTable_map::TYPE_FLAGS) != 0) {
if (!set) {
- out << " ";
set = true;
} else {
out << "|";
}
out << "flags";
}
+}
+
+void Attribute::print(std::ostream& out) const {
+ out << "(attr) ";
+ printMask(out);
out << " ["
<< util::joiner(symbols.begin(), symbols.end(), ", ")
@@ -348,20 +342,10 @@
}
}
-static ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
- return out << s.symbol.name.entry << "=" << s.value;
-}
-
-Style::Style(bool weak) : weak(weak) {
-}
-
-bool Style::isWeak() const {
- return weak;
-}
-
Style* Style::clone(StringPool* newPool) const {
- Style* style = new Style(weak);
+ Style* style = new Style();
style->parent = parent;
+ style->parentInferred = parentInferred;
for (auto& entry : entries) {
style->entries.push_back(Entry{
entry.key,
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index f8ece6f..ef6594e 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -222,6 +222,7 @@
bool isWeak() const override;
virtual Attribute* clone(StringPool* newPool) const override;
+ void printMask(std::ostream& out) const;
virtual void print(std::ostream& out) const override;
};
@@ -231,12 +232,16 @@
std::unique_ptr<Item> value;
};
- bool weak;
Reference parent;
+
+ /**
+ * If set to true, the parent was auto inferred from the
+ * style's name.
+ */
+ bool parentInferred = false;
+
std::vector<Entry> entries;
- Style(bool weak);
- bool isWeak() const override;
Style* clone(StringPool* newPool) const override;
void print(std::ostream& out) const override;
};
@@ -280,6 +285,10 @@
return out;
}
+inline ::std::ostream& operator<<(::std::ostream& out, const Attribute::Symbol& s) {
+ return out << s.symbol.name.entry << "=" << s.value;
+}
+
/**
* The argument object that gets passed through the value
* back to the ValueVisitor. Subclasses of ValueVisitor should
diff --git a/tools/aapt2/TableFlattener.cpp b/tools/aapt2/TableFlattener.cpp
index aa0f1d5..539c48f 100644
--- a/tools/aapt2/TableFlattener.cpp
+++ b/tools/aapt2/TableFlattener.cpp
@@ -79,6 +79,7 @@
// Write the key.
if (!Res_INTERNALID(key.id.id) && !key.id.isValid()) {
+ assert(key.name.isValid());
mSymbols->push_back(std::make_pair(ResourceNameRef(key.name),
mOut->size() - sizeof(*outMapEntry)));
}
@@ -96,6 +97,23 @@
outMapEntry->value.size = sizeof(outMapEntry->value);
}
+ void flattenValueOnly(const Item& value) {
+ mMap->count++;
+
+ android::ResTable_map* outMapEntry = mOut->nextBlock<android::ResTable_map>();
+
+ // Write the value.
+ value.flatten(outMapEntry->value);
+
+ if (outMapEntry->value.data == 0x0) {
+ visitFunc<Reference>(value, [&](const Reference& reference) {
+ mSymbols->push_back(std::make_pair(ResourceNameRef(reference.name),
+ mOut->size() - sizeof(outMapEntry->value.data)));
+ });
+ }
+ outMapEntry->value.size = sizeof(outMapEntry->value);
+ }
+
static bool compareStyleEntries(const Style::Entry* lhs, const Style::Entry* rhs) {
return lhs->key.id < rhs->key.id;
}
@@ -139,7 +157,7 @@
void visit(const Array& array, ValueVisitorArgs&) override {
for (const auto& item : array.items) {
- flattenEntry({}, *item);
+ flattenValueOnly(*item);
}
}
@@ -334,6 +352,10 @@
spec->id = type->typeId;
spec->entryCount = type->entries.size();
+ if (type->entries.empty()) {
+ continue;
+ }
+
// Reserve space for the masks of each resource in this type. These
// show for which configuration axis the resource changes.
uint32_t* configMasks = typeBlock.nextBlock<uint32_t>(type->entries.size());
diff --git a/tools/aapt2/XmlFlattener.cpp b/tools/aapt2/XmlFlattener.cpp
index 650e624..f78e38d 100644
--- a/tools/aapt2/XmlFlattener.cpp
+++ b/tools/aapt2/XmlFlattener.cpp
@@ -300,6 +300,7 @@
elem->attributeCount = sortedAttributes.size();
// Flatten the sorted attributes.
+ uint16_t attributeIndex = 1;
for (auto entry : sortedAttributes) {
android::ResXMLTree_attribute* attr =
out.nextBlock<android::ResXMLTree_attribute>();
@@ -310,44 +311,65 @@
attr->ns.index = -1;
}
- stringRefs.emplace_back(entry.nameRef, &attr->name);
- attr->rawValue.index = -1;
-
StringPool::Ref rawValueRef = pool.makeRef(entry.xmlAttr->value, lowPriority);
- if (entry.attr) {
- std::unique_ptr<Item> value = ResourceParser::parseItemForAttribute(
- entry.xmlAttr->value, *entry.attr);
- if (value) {
- AttributeValueFlattener flattener(
- mResolver,
- &logger,
- &attr->typedValue,
- parser,
- &error,
- rawValueRef,
- &options.defaultPackage,
- &stringRefs);
- value->accept(flattener, {});
- } else if (!(entry.attr->typeMask & android::ResTable_map::TYPE_STRING)) {
- logger.error(parser->getLineNumber())
- << "'"
- << *rawValueRef
- << "' is not compatible with attribute "
- << *entry.attr
- << "."
- << std::endl;
- error = true;
- } else {
- attr->typedValue.dataType = android::Res_value::TYPE_STRING;
- stringRefs.emplace_back(rawValueRef, &attr->rawValue);
- stringRefs.emplace_back(rawValueRef,
- reinterpret_cast<android::ResStringPool_ref*>(
- &attr->typedValue.data));
+ stringRefs.emplace_back(entry.nameRef, &attr->name);
+
+ if (options.keepRawValues) {
+ stringRefs.emplace_back(rawValueRef, &attr->rawValue);
+ } else {
+ attr->rawValue.index = -1;
+ }
+
+ // Assign the indices for specific attributes.
+ if (entry.xmlAttr->namespaceUri == kSchemaAndroid &&
+ entry.xmlAttr->name == u"id") {
+ elem->idIndex = attributeIndex;
+ } else if (entry.xmlAttr->namespaceUri.empty()) {
+ if (entry.xmlAttr->name == u"class") {
+ elem->classIndex = attributeIndex;
+ } else if (entry.xmlAttr->name == u"style") {
+ elem->styleIndex = attributeIndex;
}
+ }
+ attributeIndex++;
+
+ std::unique_ptr<Item> value;
+ if (entry.attr) {
+ value = ResourceParser::parseItemForAttribute(entry.xmlAttr->value,
+ *entry.attr);
+ } else {
+ bool create = false;
+ value = ResourceParser::tryParseReference(entry.xmlAttr->value, &create);
+ }
+
+ if (mResolver && value) {
+ AttributeValueFlattener flattener(
+ mResolver,
+ &logger,
+ &attr->typedValue,
+ parser,
+ &error,
+ rawValueRef,
+ &options.defaultPackage,
+ &stringRefs);
+ value->accept(flattener, {});
+ } else if (!value && entry.attr &&
+ !(entry.attr->typeMask & android::ResTable_map::TYPE_STRING)) {
+ logger.error(parser->getLineNumber())
+ << "'"
+ << *rawValueRef
+ << "' is not compatible with attribute "
+ << *entry.attr
+ << "."
+ << std::endl;
+ error = true;
} else {
attr->typedValue.dataType = android::Res_value::TYPE_STRING;
- stringRefs.emplace_back(rawValueRef, &attr->rawValue);
+ if (!options.keepRawValues) {
+ // Don't set the string twice.
+ stringRefs.emplace_back(rawValueRef, &attr->rawValue);
+ }
stringRefs.emplace_back(rawValueRef,
reinterpret_cast<android::ResStringPool_ref*>(
&attr->typedValue.data));
@@ -440,6 +462,9 @@
header->header.type = android::RES_XML_TYPE;
header->header.headerSize = sizeof(*header);
+ // Flatten the StringPool.
+ StringPool::flattenUtf16(outBuffer, pool);
+
// Write the array of resource IDs, indexed by StringPool order.
const size_t beforeResIdMapIndex = outBuffer->size();
android::ResChunk_header* resIdMapChunk = outBuffer->nextBlock<android::ResChunk_header>();
@@ -458,10 +483,7 @@
}
resIdMapChunk->size = outBuffer->size() - beforeResIdMapIndex;
- // Flatten the StringPool.
- StringPool::flattenUtf16(outBuffer, pool);
-
- // Move the temporary BigBuffer into outBuffer->
+ // Move the temporary BigBuffer into outBuffer.
outBuffer->appendBuffer(std::move(out));
header->header.size = outBuffer->size() - beforeXmlTreeIndex;
diff --git a/tools/aapt2/XmlFlattener.h b/tools/aapt2/XmlFlattener.h
index 60a500e..2cfcc16 100644
--- a/tools/aapt2/XmlFlattener.h
+++ b/tools/aapt2/XmlFlattener.h
@@ -47,6 +47,12 @@
* max SDK.
*/
Maybe<size_t> maxSdkAttribute;
+
+ /**
+ * Setting this to true will keep the raw string value of
+ * an attribute's value when it has been resolved.
+ */
+ bool keepRawValues = false;
};
/**
diff --git a/tools/aapt2/data/Makefile b/tools/aapt2/data/Makefile
index 6b5fafa..ce5201b 100644
--- a/tools/aapt2/data/Makefile
+++ b/tools/aapt2/data/Makefile
@@ -49,7 +49,7 @@
# returns: out/values-v4.apk: res/values-v4/styles.xml res/values-v4/colors.xml
define make-collect-rule
$(LOCAL_OUT)/$1.apk: $(filter $(LOCAL_RESOURCE_DIR)/$1/%,$(PRIVATE_RESOURCES))
- $(AAPT) compile --package $(LOCAL_PACKAGE) --binding $(LOCAL_GEN) -o $$@ $$^
+ $(AAPT) compile --package $(LOCAL_PACKAGE) -o $$@ $$^
endef
# Collect: out/values-v4.apk <- res/values-v4/styles.xml res/values-v4/colors.xml
diff --git a/tools/layoutlib/.idea/libraries/asm_4_0.xml b/tools/layoutlib/.idea/libraries/asm_4_0.xml
deleted file mode 100644
index 7df287f..0000000
--- a/tools/layoutlib/.idea/libraries/asm_4_0.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="asm-4.0">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/asm/asm-4.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/asm/src.zip!/" />
- </SOURCES>
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/guava.xml b/tools/layoutlib/.idea/libraries/guava.xml
deleted file mode 100644
index eb60719..0000000
--- a/tools/layoutlib/.idea/libraries/guava.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="guava">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
- </SOURCES>
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/icu4j.xml b/tools/layoutlib/.idea/libraries/icu4j.xml
deleted file mode 100644
index dbe0bd7..0000000
--- a/tools/layoutlib/.idea/libraries/icu4j.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="icu4j">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/icu4j/icu4j.jar!/" />
- </CLASSES>
- <JAVADOC>
- <root url="http://icu-project.org/apiref/icu4j50rc/" />
- </JAVADOC>
- <SOURCES />
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml b/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
deleted file mode 100644
index 2a65050..0000000
--- a/tools/layoutlib/.idea/libraries/kxml2_2_3_0.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="kxml2-2.3.0">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$PROJECT_DIR$/../../../../libcore/xml/src/main/java" />
- </SOURCES>
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml b/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
deleted file mode 100644
index f34f7dd..0000000
--- a/tools/layoutlib/.idea/libraries/ninepatch_prebuilt.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<component name="libraryTable">
- <library name="ninepatch-prebuilt">
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
- </SOURCES>
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml b/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
deleted file mode 100644
index b325ad4..0000000
--- a/tools/layoutlib/.idea/libraries/tools_common_prebuilt.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<component name="libraryTable">
- <library name="tools-common-prebuilt">
- <ANNOTATIONS>
- <root url="file://$PROJECT_DIR$" />
- </ANNOTATIONS>
- <CLASSES>
- <root url="jar://$PROJECT_DIR$/../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" />
- </SOURCES>
- </library>
-</component>
\ No newline at end of file
diff --git a/tools/layoutlib/.idea/runConfigurations/Create.xml b/tools/layoutlib/.idea/runConfigurations/Create.xml
index ff173e5..58f057a 100644
--- a/tools/layoutlib/.idea/runConfigurations/Create.xml
+++ b/tools/layoutlib/.idea/runConfigurations/Create.xml
@@ -3,7 +3,7 @@
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
<option name="VM_PARAMETERS" value="" />
- <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
+ <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/icu4j-icudata-jarjar_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-jarjar_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../../../../" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index 9300401..61ddb04 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -37,6 +37,10 @@
built_ext_classes := $(call java-lib-files,ext)
built_ext_data := $(call intermediates-dir-for, \
JAVA_LIBRARIES,ext,,COMMON)/javalib.jar
+built_icudata_dep := $(call java-lib-deps,icu4j-icudata-jarjar)
+built_icudata_data := $(call java-lib-files,icu4j-icudata-jarjar)
+built_icutzdata_dep := $(call java-lib-deps,icu4j-icutzdata-jarjar)
+built_icutzdata_data := $(call java-lib-files,icu4j-icutzdata-jarjar)
built_layoutlib_create_jar := $(call intermediates-dir-for, \
JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar
@@ -56,6 +60,8 @@
$(built_framework_dep) \
$(built_ext_dep) \
$(built_ext_data) \
+ $(built_icudata_dep) \
+ $(built_icutzdata_dep) \
$(built_layoutlib_create_jar)
$(hide) echo "host layoutlib_create: $@"
$(hide) mkdir -p $(dir $@)
@@ -66,6 +72,8 @@
$(built_core_classes) \
$(built_framework_classes) \
$(built_ext_classes) \
+ $(built_icudata_data) \
+ $(built_icutzdata_data) \
$(built_ext_data)
$(hide) ls -l $(built_framework_classes)
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index cfd597e..0dbdd56 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -22,8 +22,6 @@
LOCAL_JAVA_LIBRARIES := \
- kxml2-2.3.0 \
- icu4j \
layoutlib_api-prebuilt \
tools-common-prebuilt
diff --git a/tools/layoutlib/bridge/bridge.iml b/tools/layoutlib/bridge/bridge.iml
index 0f96916..af2fe7f 100644
--- a/tools/layoutlib/bridge/bridge.iml
+++ b/tools/layoutlib/bridge/bridge.iml
@@ -24,15 +24,57 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="icu4j" level="project" />
- <orderEntry type="library" name="kxml2-2.3.0" level="project" />
<orderEntry type="library" name="layoutlib_api-prebuilt" level="project" />
- <orderEntry type="library" name="ninepatch-prebuilt" level="project" />
- <orderEntry type="library" name="tools-common-prebuilt" level="project" />
+ <orderEntry type="module-library">
+ <library name="ninepatch-prebuilt">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$ANDROID_SRC$/tools/base/ninepatch/src/main/java" />
+ </SOURCES>
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library">
+ <library name="tools-common-prebuilt">
+ <ANNOTATIONS>
+ <root url="file://$MODULE_DIR$/.." />
+ </ANNOTATIONS>
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/tools-common/tools-common-prebuilt.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$ANDROID_SRC$/tools/base/common/src/main/java" />
+ </SOURCES>
+ </library>
+ </orderEntry>
<orderEntry type="library" name="framework.jar" level="project" />
- <orderEntry type="library" scope="TEST" name="guava" level="project" />
<orderEntry type="module-library" scope="TEST">
- <library>
+ <library name="kxml2-2.3.0">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/kxml2/kxml2-2.3.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="file://$MODULE_DIR$/../../../../../libcore/xml/src/main/java" />
+ </SOURCES>
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library" scope="TEST">
+ <library name="guava">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/tools/common/m2/repository/com/google/guava/guava/15.0/guava-15.0-sources.jar!/" />
+ </SOURCES>
+ </library>
+ </orderEntry>
+ <orderEntry type="module-library" scope="TEST">
+ <library name="sdk-common">
<CLASSES>
<root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/sdk-common/sdk-common.jar!/" />
</CLASSES>
@@ -44,5 +86,4 @@
</orderEntry>
<orderEntry type="library" scope="TEST" name="JUnit4" level="application" />
</component>
-</module>
-
+</module>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_100.png
deleted file mode 100644
index f17189a..0000000
--- a/tools/layoutlib/bridge/resources/bars/hdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_100.png
deleted file mode 100644
index 2a9757d..0000000
--- a/tools/layoutlib/bridge/resources/bars/mdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
index 599ca08..79920a1 100644
--- a/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
+++ b/tools/layoutlib/bridge/resources/bars/navigation_bar.xml
@@ -1,20 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
- <TextView
+ <View
android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ <ImageView
android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:scaleType="centerInside"/>
+ <View
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
android:layout_weight="1"/>
<ImageView
android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <ImageView
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"/>
- <TextView
android:layout_width="wrap_content"
+ android:scaleType="centerInside"/>
+ <View
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_weight="1"/>
+ <ImageView
android:layout_height="wrap_content"
- android:layout_weight="1"/>
+ android:layout_width="wrap_content"
+ android:scaleType="centerInside"/>
+ <View
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
</merge>
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
index b28624f..d2760bb 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
index 3f3e288..df43e21 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
index 06dcd20..6fab1d6 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
index e464347..2fcfdde 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
index 1b578a6..48708a5 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
index 373e84a..3d73184 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
index 6b19593..786935d 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/ldrtl-xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
index f878093..1d8c3af 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
index 8e9583b..66de0ec 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
index e2a89c3..30c65f5 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
index ec2951d..a356285 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
index 254f757..ba2d0b2 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
index 8a8e941..94a74b1 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
index 77969b8..29da099 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
index d60229f..59b32f2 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
index a261f85..ba66d27 100644
--- a/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
+++ b/tools/layoutlib/bridge/resources/bars/v21/xxhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_100.png b/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_100.png
deleted file mode 100644
index 555bcd9..0000000
--- a/tools/layoutlib/bridge/resources/bars/xhdpi/stat_sys_battery_100.png
+++ /dev/null
Binary files differ
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 7d4271b..572fdc9 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -758,6 +758,17 @@
return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
}
+ @Override
+ public int getType(int index) {
+ if (!hasValue(index)) {
+ return TypedValue.TYPE_NULL;
+ }
+ ResourceValue value = mResourceData[index];
+ ResourceType resourceType = value.getResourceType();
+ return 0;
+ // TODO: fixme.
+ }
+
/**
* Determines whether there is an attribute at <var>index</var>.
*
diff --git a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
index a4a3b7d..21f36ce 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BidiRenderer.java
@@ -19,6 +19,12 @@
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
+import android.graphics.Paint_Delegate.FontInfo;
+import android.icu.lang.UScript;
+import android.icu.lang.UScriptRun;
+import android.icu.text.Bidi;
+import android.icu.text.BidiRun;
+
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Toolkit;
@@ -29,13 +35,6 @@
import java.util.LinkedList;
import java.util.List;
-import com.ibm.icu.lang.UScript;
-import com.ibm.icu.lang.UScriptRun;
-import com.ibm.icu.text.Bidi;
-import com.ibm.icu.text.BidiRun;
-
-import android.graphics.Paint_Delegate.FontInfo;
-
/**
* Render the text by breaking it into various scripts and using the right font for each script.
* Can be used to measure the text without actually drawing it.
diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
index e9b5d6e..af47aeb 100644
--- a/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/BitmapShader_Delegate.java
@@ -23,7 +23,15 @@
import android.graphics.Shader.TileMode;
+import java.awt.PaintContext;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
+import java.awt.image.Raster;
/**
* Delegate implementing the native methods of android.graphics.BitmapShader
@@ -67,9 +75,9 @@
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static long nativeCreate(long native_bitmap, int shaderTileModeX,
+ /*package*/ static long nativeCreate(Bitmap androidBitmap, int shaderTileModeX,
int shaderTileModeY) {
- Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(native_bitmap);
+ Bitmap_Delegate bitmap = Bitmap_Delegate.getDelegate(androidBitmap);
if (bitmap == null) {
return 0;
}
@@ -83,17 +91,17 @@
// ---- Private delegate/helper methods ----
- private BitmapShader_Delegate(java.awt.image.BufferedImage image,
+ private BitmapShader_Delegate(BufferedImage image,
TileMode tileModeX, TileMode tileModeY) {
mJavaPaint = new BitmapShaderPaint(image, tileModeX, tileModeY);
}
private class BitmapShaderPaint implements java.awt.Paint {
- private final java.awt.image.BufferedImage mImage;
+ private final BufferedImage mImage;
private final TileMode mTileModeX;
private final TileMode mTileModeY;
- BitmapShaderPaint(java.awt.image.BufferedImage image,
+ BitmapShaderPaint(BufferedImage image,
TileMode tileModeX, TileMode tileModeY) {
mImage = image;
mTileModeX = tileModeX;
@@ -101,29 +109,24 @@
}
@Override
- public java.awt.PaintContext createContext(
- java.awt.image.ColorModel colorModel,
- java.awt.Rectangle deviceBounds,
- java.awt.geom.Rectangle2D userBounds,
- java.awt.geom.AffineTransform xform,
- java.awt.RenderingHints hints) {
-
- java.awt.geom.AffineTransform canvasMatrix;
+ public PaintContext createContext(ColorModel colorModel, Rectangle deviceBounds,
+ Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
+ AffineTransform canvasMatrix;
try {
canvasMatrix = xform.createInverse();
- } catch (java.awt.geom.NoninvertibleTransformException e) {
+ } catch (NoninvertibleTransformException e) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
"Unable to inverse matrix in BitmapShader", e, null /*data*/);
- canvasMatrix = new java.awt.geom.AffineTransform();
+ canvasMatrix = new AffineTransform();
}
- java.awt.geom.AffineTransform localMatrix = getLocalMatrix();
+ AffineTransform localMatrix = getLocalMatrix();
try {
localMatrix = localMatrix.createInverse();
- } catch (java.awt.geom.NoninvertibleTransformException e) {
+ } catch (NoninvertibleTransformException e) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_INVERSE,
"Unable to inverse matrix in BitmapShader", e, null /*data*/);
- localMatrix = new java.awt.geom.AffineTransform();
+ localMatrix = new AffineTransform();
}
if (!colorModel.isCompatibleRaster(mImage.getRaster())) {
@@ -134,16 +137,16 @@
return new BitmapShaderContext(canvasMatrix, localMatrix, colorModel);
}
- private class BitmapShaderContext implements java.awt.PaintContext {
+ private class BitmapShaderContext implements PaintContext {
- private final java.awt.geom.AffineTransform mCanvasMatrix;
- private final java.awt.geom.AffineTransform mLocalMatrix;
- private final java.awt.image.ColorModel mColorModel;
+ private final AffineTransform mCanvasMatrix;
+ private final AffineTransform mLocalMatrix;
+ private final ColorModel mColorModel;
public BitmapShaderContext(
- java.awt.geom.AffineTransform canvasMatrix,
- java.awt.geom.AffineTransform localMatrix,
- java.awt.image.ColorModel colorModel) {
+ AffineTransform canvasMatrix,
+ AffineTransform localMatrix,
+ ColorModel colorModel) {
mCanvasMatrix = canvasMatrix;
mLocalMatrix = localMatrix;
mColorModel = colorModel;
@@ -154,13 +157,13 @@
}
@Override
- public java.awt.image.ColorModel getColorModel() {
+ public ColorModel getColorModel() {
return mColorModel;
}
@Override
- public java.awt.image.Raster getRaster(int x, int y, int w, int h) {
- java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(
+ public Raster getRaster(int x, int y, int w, int h) {
+ BufferedImage image = new BufferedImage(
mColorModel, mColorModel.createCompatibleWritableRaster(w, h),
mColorModel.isAlphaPremultiplied(), null);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 970b9d0..874bc9d 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -16,6 +16,7 @@
package android.graphics;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -82,6 +83,12 @@
return sManager.getDelegate(native_bitmap);
}
+ @Nullable
+ public static Bitmap_Delegate getDelegate(@Nullable Bitmap bitmap) {
+ // refSkPixelRef is a hack to get the native pointer: see #nativeRefPixelRef()
+ return bitmap == null ? null : getDelegate(bitmap.refSkPixelRef());
+ }
+
/**
* Creates and returns a {@link Bitmap} initialized with the given file content.
*
@@ -180,18 +187,7 @@
return createBitmap(delegate, createFlags, density.getDpiValue());
}
- public static int getBufferedImageType(int nativeBitmapConfig) {
- switch (Config.nativeToConfig(nativeBitmapConfig)) {
- case ALPHA_8:
- return BufferedImage.TYPE_INT_ARGB;
- case RGB_565:
- return BufferedImage.TYPE_INT_ARGB;
- case ARGB_4444:
- return BufferedImage.TYPE_INT_ARGB;
- case ARGB_8888:
- return BufferedImage.TYPE_INT_ARGB;
- }
-
+ private static int getBufferedImageType() {
return BufferedImage.TYPE_INT_ARGB;
}
@@ -218,10 +214,6 @@
return mHasAlpha && mConfig != Config.RGB_565;
}
- public boolean hasMipMap() {
- // TODO: check if more checks are required as in hasAlpha.
- return mHasMipMap;
- }
/**
* Update the generationId.
*
@@ -236,7 +228,7 @@
@LayoutlibDelegate
/*package*/ static Bitmap nativeCreate(int[] colors, int offset, int stride, int width,
int height, int nativeConfig, boolean isMutable) {
- int imageType = getBufferedImageType(nativeConfig);
+ int imageType = getBufferedImageType();
// create the image
BufferedImage image = new BufferedImage(width, height, imageType);
@@ -264,7 +256,7 @@
int width = srcImage.getWidth();
int height = srcImage.getHeight();
- int imageType = getBufferedImageType(nativeConfig);
+ int imageType = getBufferedImageType();
// create the image
BufferedImage image = new BufferedImage(width, height, imageType);
@@ -353,22 +345,16 @@
/*package*/ static boolean nativeHasAlpha(long nativeBitmap) {
// get the delegate from the native int.
Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
- if (delegate == null) {
- return true;
- }
+ return delegate == null || delegate.mHasAlpha;
- return delegate.mHasAlpha;
}
@LayoutlibDelegate
/*package*/ static boolean nativeHasMipMap(long nativeBitmap) {
// get the delegate from the native int.
Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
- if (delegate == null) {
- return true;
- }
+ return delegate == null || delegate.mHasMipMap;
- return delegate.mHasMipMap;
}
@LayoutlibDelegate
@@ -489,11 +475,6 @@
}
@LayoutlibDelegate
- /*package*/ static void nativePrepareToDraw(long nativeBitmap) {
- // nothing to be done here.
- }
-
- @LayoutlibDelegate
/*package*/ static boolean nativeIsPremultiplied(long nativeBitmap) {
// get the delegate from the native int.
Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
@@ -579,6 +560,14 @@
return Arrays.equals(argb1, argb2);
}
+ // Only used by AssetAtlasService, which we don't care about.
+ @LayoutlibDelegate
+ /*package*/ static long nativeRefPixelRef(long nativeBitmap) {
+ // Hack: This is called by Bitmap.refSkPixelRef() and LayoutLib uses that method to get
+ // the native pointer from a Bitmap. So, we return nativeBitmap here.
+ return nativeBitmap;
+ }
+
// ---- Private delegate/helper methods ----
private Bitmap_Delegate(BufferedImage image, Config config) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index e1091f0..47acc42 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -16,6 +16,7 @@
package android.graphics;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -114,7 +115,11 @@
}
@LayoutlibDelegate
- /*package*/ static long initRaster(long nativeBitmapOrZero) {
+ /*package*/ static long initRaster(@Nullable Bitmap bitmap) {
+ long nativeBitmapOrZero = 0;
+ if (bitmap != null) {
+ nativeBitmapOrZero = bitmap.refSkPixelRef();
+ }
if (nativeBitmapOrZero > 0) {
// get the Bitmap from the int
Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
@@ -132,8 +137,7 @@
}
@LayoutlibDelegate
- /*package*/
- static void native_setBitmap(long canvas, long bitmap, boolean copyState) {
+ /*package*/ static void native_setBitmap(long canvas, Bitmap bitmap) {
Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
if (canvasDelegate == null || bitmapDelegate==null) {
@@ -427,8 +431,7 @@
canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
- if (canvasDelegate.mDrawFilter != null &&
- canvasDelegate.mDrawFilter.isSupported() == false) {
+ if (canvasDelegate.mDrawFilter != null && !canvasDelegate.mDrawFilter.isSupported()) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
}
@@ -444,7 +447,7 @@
}
Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
- if (rect != null && rect.isEmpty() == false) {
+ if (rect != null && !rect.isEmpty()) {
bounds.left = rect.x;
bounds.top = rect.y;
bounds.right = rect.x + rect.width;
@@ -720,7 +723,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
+ /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
float left, float top,
long nativePaintOrZero,
int canvasDensity,
@@ -742,7 +745,7 @@
}
@LayoutlibDelegate
- /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
+ /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, Bitmap bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
long nativePaintOrZero, int screenDensity, int bitmapDensity) {
@@ -783,7 +786,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, long nBitmap,
+ /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, Bitmap bitmap,
long nMatrix, long nPaint) {
// get the delegate from the native int.
Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
@@ -795,7 +798,7 @@
Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
// get the delegate from the native int.
- Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap);
+ Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
if (bitmapDelegate == null) {
return;
}
@@ -824,7 +827,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDrawBitmapMesh(long nCanvas, long nBitmap,
+ /*package*/ static void nativeDrawBitmapMesh(long nCanvas, Bitmap bitmap,
int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
int colorOffset, long nPaint) {
// FIXME
@@ -1041,8 +1044,7 @@
}
/**
- * Restores the {@link GcSnapshot} to <var>saveCount</var>
- * @param saveCount the saveCount
+ * Restores the top {@link GcSnapshot}
*/
private void restore() {
mSnapshot = mSnapshot.restore();
@@ -1105,7 +1107,7 @@
// before drawing it.
if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
fixAlpha8Bitmap(image);
- } else if (bitmap.hasAlpha() == false) {
+ } else if (!bitmap.hasAlpha()) {
// hasAlpha is merely a rendering hint. There can in fact be alpha values
// in the bitmap but it should be ignored at drawing time.
// There is two ways to do this:
@@ -1125,7 +1127,7 @@
}
// if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
- if (forceSrcMode[0] == false) {
+ if (!forceSrcMode[0]) {
image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
}
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
index e16dbda..e8d34d0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java
@@ -90,7 +90,7 @@
if (oos != null) {
try {
oos.close();
- } catch (IOException e) {
+ } catch (IOException ignored) {
}
}
}
@@ -136,7 +136,7 @@
if (ois != null) {
try {
ois.close();
- } catch (IOException e) {
+ } catch (IOException ignored) {
}
}
}
@@ -150,15 +150,12 @@
@LayoutlibDelegate
/*package*/ static boolean isNinePatchChunk(byte[] chunk) {
NinePatchChunk chunkObject = getChunk(chunk);
- if (chunkObject != null) {
- return true;
- }
+ return chunkObject != null;
- return false;
}
@LayoutlibDelegate
- /*package*/ static long validateNinePatchChunk(long bitmap, byte[] chunk) {
+ /*package*/ static long validateNinePatchChunk(byte[] chunk) {
// the default JNI implementation only checks that the byte[] has the same
// size as the C struct it represent. Since we cannot do the same check (serialization
// will return different size depending on content), we do nothing.
@@ -173,7 +170,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDraw(long canvas_instance, RectF loc, long bitmap_instance,
+ /*package*/ static void nativeDraw(long canvas_instance, RectF loc, Bitmap bitmap_instance,
long chunk, long paint_instance_or_null, int destDensity, int srcDensity) {
draw(canvas_instance,
(int) loc.left, (int) loc.top, (int) loc.right, (int) loc.bottom,
@@ -182,7 +179,7 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeDraw(long canvas_instance, Rect loc, long bitmap_instance,
+ /*package*/ static void nativeDraw(long canvas_instance, Rect loc, Bitmap bitmap_instance,
long chunk, long paint_instance_or_null, int destDensity, int srcDensity) {
draw(canvas_instance,
loc.left, loc.top, loc.right, loc.bottom,
@@ -191,7 +188,7 @@
}
@LayoutlibDelegate
- /*package*/ static long nativeGetTransparentRegion(long bitmap, long chunk, Rect location) {
+ /*package*/ static long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location) {
return 0;
}
@@ -199,7 +196,7 @@
private static void draw(long canvas_instance,
final int left, final int top, final int right, final int bottom,
- long bitmap_instance, long chunk, long paint_instance_or_null,
+ Bitmap bitmap_instance, long chunk, long paint_instance_or_null,
final int destDensity, final int srcDensity) {
// get the delegate from the native int.
final Bitmap_Delegate bitmap_delegate = Bitmap_Delegate.getDelegate(bitmap_instance);
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index f5ef01b..3b1e3f9 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -16,6 +16,8 @@
package android.graphics;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -83,6 +85,8 @@
private float mTextScaleX;
private float mTextSkewX;
private int mHintingMode = Paint.HINTING_ON;
+ private int mHyphenEdit;
+ private float mLetterSpacing; // not used in actual text rendering.
// Variant of the font. A paint's variant can only be compact or elegant.
private FontVariant mFontVariant = FontVariant.COMPACT;
@@ -100,6 +104,7 @@
// ---- Public Helper methods ----
+ @Nullable
public static Paint_Delegate getDelegate(long native_paint) {
return sManager.getDelegate(native_paint);
}
@@ -1088,18 +1093,107 @@
@LayoutlibDelegate
/*package*/ static float native_getLetterSpacing(long nativePaint) {
- // TODO: throw a fidelity warning.
- return 0;
+ Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+ if (delegate == null) {
+ return 0;
+ }
+ return delegate.mLetterSpacing;
}
@LayoutlibDelegate
/*package*/ static void native_setLetterSpacing(long nativePaint, float letterSpacing) {
- // pass.
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+ "Paint.setLetterSpacing() not supported.", null, null);
+ Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+ if (delegate == null) {
+ return;
+ }
+ delegate.mLetterSpacing = letterSpacing;
}
@LayoutlibDelegate
/*package*/ static void native_setFontFeatureSettings(long nativePaint, String settings) {
- // pass.
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+ "Paint.setFontFeatureSettings() not supported.", null, null);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static int native_getHyphenEdit(long nativePaint) {
+ Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+ if (delegate == null) {
+ return 0;
+ }
+ return delegate.mHyphenEdit;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void native_setHyphenEdit(long nativePaint, int hyphen) {
+ Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+ if (delegate == null) {
+ return;
+ }
+ delegate.mHyphenEdit = hyphen;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static boolean native_hasGlyph(long nativePaint, long nativeTypeface, int bidiFlags,
+ String string) {
+ Paint_Delegate delegate = sManager.getDelegate(nativePaint);
+ if (delegate == null) {
+ return false;
+ }
+ if (string.length() == 0) {
+ return false;
+ }
+ if (string.length() > 1) {
+ Bridge.getLog().fidelityWarning(LayoutLog.TAG_TEXT_RENDERING,
+ "Paint.hasGlyph() is not supported for ligatures.", null, null);
+ return false;
+ }
+ assert nativeTypeface == delegate.mNativeTypeface;
+ Typeface_Delegate typeface_delegate = Typeface_Delegate.getDelegate(nativeTypeface);
+
+ char c = string.charAt(0);
+ for (Font font : typeface_delegate.getFonts(delegate.mFontVariant)) {
+ if (font.canDisplay(c)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ @LayoutlibDelegate
+ /*package*/ static float native_getRunAdvance(long nativePaint, long nativeTypeface,
+ @NonNull char[] text, int start, int end, int contextStart, int contextEnd,
+ boolean isRtl, int offset) {
+ int count = end - start;
+ float[] advances = new float[count];
+ native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
+ contextStart, contextEnd - contextStart, isRtl, advances, 0);
+ float sum = 0;
+ for (int i = 0; i < offset; i++) {
+ sum += advances[i];
+ }
+ return sum;
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static int native_getOffsetForAdvance(long nativePaint, long nativeTypeface,
+ char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl,
+ float advance) {
+ int count = end - start;
+ float[] advances = new float[count];
+ native_getTextRunAdvances(nativePaint, nativeTypeface, text, start, count,
+ contextStart, contextEnd - contextStart, isRtl, advances, 0);
+ float sum = 0;
+ int i;
+ for (i = 0; i < count && sum < advance; i++) {
+ sum += advances[i];
+ }
+ float distanceToI = sum - advance;
+ float distanceToIMinus1 = advance - (sum - advances[i]);
+ return distanceToI > distanceToIMinus1 ? i : i - 1;
}
// ---- Private delegate/helper methods ----
@@ -1137,7 +1231,7 @@
}
private void reset() {
- mFlags = Paint.DEFAULT_PAINT_FLAGS | Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
+ mFlags = Paint.HIDDEN_DEFAULT_PAINT_FLAGS;
mColor = 0xFF000000;
mStyle = Paint.Style.FILL.nativeInt;
mCap = Paint.Cap.BUTT.nativeInt;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 14e9960..0d491a0 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -81,14 +81,15 @@
}
@LayoutlibDelegate
- /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) {
+ /*package*/ static long nativeSetLocalMatrix(long native_shader, long matrix_instance) {
// get the delegate from the native int.
Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
if (shaderDelegate == null) {
- return;
+ return native_shader;
}
shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
+ return native_shader;
}
// ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
index 6247dae..38171dc 100644
--- a/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/AndroidBidi_Delegate.java
@@ -19,8 +19,8 @@
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.Bidi;
+import android.icu.text.Bidi;
/**
* Delegate used to provide new implementation for the native methods of {@link AndroidBidi}
diff --git a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
index c72efc2..b95cda6 100644
--- a/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/GreedyLineBreaker.java
@@ -36,7 +36,7 @@
}
@Override
- public void computeBreaks(LineBreaks lineBreaks) {
+ public void computeBreaks(@NonNull LineBreaks lineBreaks) {
BreakInfo breakInfo = new BreakInfo();
int lineNum = 0;
float width = 0, printedWidth = 0;
diff --git a/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
new file mode 100644
index 0000000..5a59597
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/text/Hyphenator_Delegate.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import java.io.File;
+
+/**
+ * Delegate that overrides implementation for certain methods in {@link android.text.StaticLayout}
+ * <p/>
+ * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
+ * by calls to methods of the same name in this delegate class.
+ */
+public class Hyphenator_Delegate {
+
+ private static final DelegateManager<Hyphenator_Delegate> sDelegateManager = new
+ DelegateManager<Hyphenator_Delegate>(Hyphenator_Delegate.class);
+
+ @LayoutlibDelegate
+ /*package*/ static File getSystemHyphenatorLocation() {
+ // FIXME
+ return null;
+ }
+
+ /*package*/ static long loadHyphenator(String patternData) {
+ return sDelegateManager.addNewDelegate(new Hyphenator_Delegate());
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/LineBreaker.java b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
index 54445a42..edeef78 100644
--- a/tools/layoutlib/bridge/src/android/text/LineBreaker.java
+++ b/tools/layoutlib/bridge/src/android/text/LineBreaker.java
@@ -39,6 +39,5 @@
mTabStops = tabStops;
}
- @NonNull
public abstract void computeBreaks(@NonNull LineBreaks breakInfo);
}
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 86d8da3..dda8ebb 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -8,15 +8,15 @@
import android.graphics.Paint;
import android.graphics.Paint_Delegate;
import android.graphics.RectF;
-import android.text.StaticLayout.LineBreaks;
+import android.icu.text.BreakIterator;
+import android.icu.util.ULocale;
import android.text.Primitive.PrimitiveType;
+import android.text.StaticLayout.LineBreaks;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import com.ibm.icu.text.BreakIterator;
-import com.ibm.icu.util.ULocale;
import javax.swing.text.Segment;
/**
@@ -38,15 +38,55 @@
new DelegateManager<Builder>(Builder.class);
@LayoutlibDelegate
- /*package*/ static int nComputeLineBreaks(long nativeBuilder,
- int length, float firstWidth, int firstWidthLineCount, float restWidth,
- int[] variableTabStops, int defaultTabStop, boolean optimize, LineBreaks recycle,
- int[] recycleBreaks, float[] recycleWidths, boolean[] recycleFlags, int recycleLength) {
+ /*package*/ static long nNewBuilder() {
+ return sBuilderManager.addNewDelegate(new Builder());
+ }
+ @LayoutlibDelegate
+ /*package*/ static void nFreeBuilder(long nativeBuilder) {
+ sBuilderManager.removeJavaReferenceFor(nativeBuilder);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nFinishBuilder(long nativeBuilder) {
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static long nLoadHyphenator(String patternData) {
+ return Hyphenator_Delegate.loadHyphenator(patternData);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nSetLocale(long nativeBuilder, String locale, long nativeHyphenator) {
Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder != null) {
+ builder.mLocale = locale;
+ builder.mNativeHyphenator = nativeHyphenator;
+ }
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nSetIndents(long nativeBuilder, int[] indents) {
+ // TODO.
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nSetupParagraph(long nativeBuilder, char[] text, int length,
+ float firstWidth, int firstWidthLineCount, float restWidth,
+ int[] variableTabStops, int defaultTabStop, int breakStrategy,
+ int hyphenationFrequency) {
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder == null) {
+ return;
+ }
+
+ builder.mText = text;
+ builder.mWidths = new float[length];
+
// compute all possible breakpoints.
BreakIterator it = BreakIterator.getLineInstance(new ULocale(builder.mLocale));
it.setText(new Segment(builder.mText, 0, length));
+
// average word length in english is 5. So, initialize the possible breaks with a guess.
List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d));
int loc;
@@ -54,17 +94,73 @@
while ((loc = it.next()) != BreakIterator.DONE) {
breaks.add(loc);
}
-
LineWidth lineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth);
TabStops tabStopCalculator = new TabStops(variableTabStops, defaultTabStop);
- List<Primitive> primitives = computePrimitives(builder.mText, builder.mWidths, length, breaks);
- LineBreaker lineBreaker;
- if (optimize) {
- lineBreaker = new OptimizingLineBreaker(primitives, lineWidth, tabStopCalculator);
- } else {
- lineBreaker = new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
+ List<Primitive> primitives =
+ computePrimitives(builder.mText, builder.mWidths, length, breaks);
+ BreakStrategy strategy = BreakStrategy.getStrategy(breakStrategy);
+ switch (strategy) {
+ case GREEDY:
+ builder.mLineBreaker =
+ new GreedyLineBreaker(primitives, lineWidth, tabStopCalculator);
+ break;
+ case HIGH_QUALITY:
+ // TODO
+// break;
+ case BALANCED:
+ builder.mLineBreaker = new OptimizingLineBreaker(primitives, lineWidth,
+ tabStopCalculator);
+ break;
}
- lineBreaker.computeBreaks(recycle);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
+ int start, int end, boolean isRtl) {
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+
+ int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
+ return builder == null ? 0 :
+ measureText(nativePaint, builder.mText, start, end - start, builder.mWidths,
+ bidiFlags);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder != null) {
+ System.arraycopy(widths, start, builder.mWidths, start, end - start);
+ }
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder == null) {
+ return;
+ }
+ builder.mWidths[start] = width;
+ Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder != null) {
+ System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
+ }
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static int nComputeLineBreaks(long nativeBuilder,
+ LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths,
+ int[] recycleFlags, int recycleLength) {
+
+ Builder builder = sBuilderManager.getDelegate(nativeBuilder);
+ if (builder == null) {
+ return 0;
+ }
+ builder.mLineBreaker.computeBreaks(recycle);
return recycle.breaks.length;
}
@@ -109,63 +205,6 @@
return primitives;
}
- @LayoutlibDelegate
- /*package*/ static long nNewBuilder() {
- return sBuilderManager.addNewDelegate(new Builder());
- }
-
- @LayoutlibDelegate
- /*package*/ static void nFinishBuilder(long nativeBuilder) {
- }
-
- @LayoutlibDelegate
- /*package*/ static void nFreeBuilder(long nativeBuilder) {
- sBuilderManager.removeJavaReferenceFor(nativeBuilder);
- }
-
- @LayoutlibDelegate
- /*package*/ static void nSetLocale(long nativeBuilder, String locale) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
- builder.mLocale = locale;
- }
-
- @LayoutlibDelegate
- /*package*/ static void nSetText(long nativeBuilder, char[] text, int length) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
- builder.mText = text;
- builder.mWidths = new float[length];
- }
-
-
- @LayoutlibDelegate
- /*package*/ static float nAddStyleRun(long nativeBuilder, long nativePaint, long nativeTypeface,
- int start, int end, boolean isRtl) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
-
- int bidiFlags = isRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR;
- return measureText(nativePaint, builder.mText, start, end - start, builder.mWidths, bidiFlags);
- }
-
-
- @LayoutlibDelegate
- /*package*/ static void nAddMeasuredRun(long nativeBuilder, int start, int end, float[] widths) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
- System.arraycopy(widths, start, builder.mWidths, start, end - start);
- }
-
- @LayoutlibDelegate
- /*package*/ static void nAddReplacementRun(long nativeBuilder, int start, int end, float width) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
- builder.mWidths[start] = width;
- Arrays.fill(builder.mWidths, start + 1, end, 0.0f);
- }
-
- @LayoutlibDelegate
- /*package*/ static void nGetWidths(long nativeBuilder, float[] floatsArray) {
- Builder builder = sBuilderManager.getDelegate(nativeBuilder);
- System.arraycopy(builder.mWidths, 0, floatsArray, 0, builder.mWidths.length);
- }
-
private static float measureText(long nativePaint, char []text, int index, int count,
float[] widths, int bidiFlags) {
Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint);
@@ -174,12 +213,32 @@
return bounds.right - bounds.left;
}
+ // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker.
/**
* Java representation of the native Builder class.
*/
- static class Builder {
+ private static class Builder {
String mLocale;
char[] mText;
float[] mWidths;
+ LineBreaker mLineBreaker;
+ long mNativeHyphenator;
+ }
+
+ private enum BreakStrategy {
+ GREEDY, HIGH_QUALITY, BALANCED;
+
+ static BreakStrategy getStrategy(int strategy) {
+ switch (strategy) {
+ case 0:
+ return GREEDY;
+ case 1:
+ return HIGH_QUALITY;
+ case 2:
+ return BALANCED;
+ default:
+ throw new AssertionError("Unknown break strategy: " + strategy);
+ }
+ }
}
}
diff --git a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java b/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
index a193330..213e848 100644
--- a/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/util/Xml_Delegate.java
@@ -17,9 +17,9 @@
package android.util;
import com.android.layoutlib.bridge.impl.DelegateManager;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -37,11 +37,7 @@
@LayoutlibDelegate
/*package*/ static XmlPullParser newPullParser() {
try {
- KXmlParser parser = new KXmlParser();
- // The prebuilt kxml2 library with the IDE doesn't support DOCECL.
-// parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true);
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- return parser;
+ return ParserFactory.instantiateParser(null);
} catch (XmlPullParserException e) {
throw new AssertionError();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index c6d60f8..af67a43 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -16,9 +16,6 @@
package com.android.layoutlib.bridge;
-import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
-import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
-
import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.Capability;
import com.android.ide.common.rendering.api.DrawableParams;
@@ -36,13 +33,12 @@
import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;
import com.android.util.Pair;
-import com.ibm.icu.util.ULocale;
-import libcore.io.MemoryMappedFile_Delegate;
import android.content.res.BridgeAssetManager;
import android.graphics.Bitmap;
import android.graphics.FontFamily_Delegate;
import android.graphics.Typeface_Delegate;
+import android.icu.util.ULocale;
import android.os.Looper;
import android.os.Looper_Accessor;
import android.view.View;
@@ -60,6 +56,11 @@
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;
+import libcore.io.MemoryMappedFile_Delegate;
+
+import static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
+import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
+
/**
* Main entry point of the LayoutLib Bridge.
* <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
index ea5f1ea..e589d9e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/AndroidLocale.java
@@ -16,9 +16,9 @@
package com.android.layoutlib.bridge.android;
-import java.util.Locale;
+import android.icu.util.ULocale;
-import com.ibm.icu.util.ULocale;
+import java.util.Locale;
/**
* This class provides an alternate implementation for {@code java.util.Locale#toLanguageTag}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 4c4454d..66092fc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -91,7 +91,11 @@
}
@Override
- public void doneAnimating() {
+ public void onAnimationStarted(int remainingFrameCount) {
+ }
+
+ @Override
+ public void onAnimationStopped() {
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index 04aadff..16f477b 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -32,6 +33,14 @@
/** Navigation bar background color attribute name. */
private static final String ATTR_COLOR = "navigationBarColor";
+ // These correspond to @dimen/navigation_side_padding in the system ui code.
+ private static final int PADDING_WIDTH_DEFAULT = 36;
+ private static final int PADDING_WIDTH_SW360 = 40;
+ private static final int PADDING_WIDTH_SW400 = 50;
+ // These corresponds to @dimen/navigation_key_width in the system ui code.
+ private static final int WIDTH_DEFAULT = 36;
+ private static final int WIDTH_SW360 = 40;
+ private static final int WIDTH_SW600 = 48;
/**
* Constructor to be used when creating the {@link NavigationBar} as a regular control.
@@ -45,7 +54,7 @@
((BridgeContext) context).getConfiguration().getLayoutDirection() ==
View.LAYOUT_DIRECTION_RTL,
(context.getApplicationInfo().flags & ApplicationInfo.FLAG_SUPPORTS_RTL) != 0,
- context.getApplicationInfo().targetSdkVersion);
+ 0);
}
public NavigationBar(BridgeContext context, Density density, int orientation, boolean isRtl,
@@ -61,19 +70,70 @@
// We do know the order though.
// 0 is a spacer.
int back = 1;
- int recent = 3;
+ int recent = 5;
if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
// If RTL is enabled, then layoutlib mirrors the layout for us.
- back = 3;
+ back = 5;
recent = 1;
}
//noinspection SpellCheckingInspection
- loadIcon(back, "ic_sysbar_back.png", density, isRtl);
+ loadIcon(back, "ic_sysbar_back.png", density, isRtl);
//noinspection SpellCheckingInspection
- loadIcon(2, "ic_sysbar_home.png", density, isRtl);
+ loadIcon(3, "ic_sysbar_home.png", density, isRtl);
//noinspection SpellCheckingInspection
loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
+ setupNavBar(context, orientation);
+ }
+
+ private void setupNavBar(BridgeContext context, int orientation) {
+ View leftPadding = getChildAt(0);
+ View rightPadding = getChildAt(6);
+ setSize(context, leftPadding, orientation, getSidePadding(context));
+ setSize(context, rightPadding, orientation, getSidePadding(context));
+ for (int i = 1; i < 6; i += 2) {
+ View navButton = getChildAt(i);
+ setSize(context, navButton, orientation, getWidth(context));
+ }
+ }
+
+ private static void setSize(BridgeContext context, View view, int orientation, int size) {
+ size *= context.getMetrics().density;
+ LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
+ if (orientation == HORIZONTAL) {
+ layoutParams.width = size;
+ } else {
+ layoutParams.height = size;
+ }
+ view.setLayoutParams(layoutParams);
+ }
+
+ private static int getSidePadding(BridgeContext context) {
+ DisplayMetrics metrics = context.getMetrics();
+ float sw = metrics.widthPixels > metrics.heightPixels
+ ? metrics.heightPixels : metrics.widthPixels;
+ sw /= metrics.density;
+ if (sw >= 400) {
+ return PADDING_WIDTH_SW400;
+ }
+ if (sw >= 360) {
+ return PADDING_WIDTH_SW360;
+ }
+ return PADDING_WIDTH_DEFAULT;
+ }
+
+ private static int getWidth(BridgeContext context) {
+ DisplayMetrics metrics = context.getMetrics();
+ float sw = metrics.widthPixels > metrics.heightPixels
+ ? metrics.heightPixels : metrics.widthPixels;
+ sw /= metrics.density;
+ if (sw >= 600) {
+ return WIDTH_SW600;
+ }
+ if (sw >= 360) {
+ return WIDTH_SW360;
+ }
+ return WIDTH_DEFAULT;
}
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
index 261cc98..dbee9ea 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/DelegateManager.java
@@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.impl;
+import com.android.annotations.Nullable;
import com.android.layoutlib.bridge.util.Debug;
import com.android.layoutlib.bridge.util.SparseWeakArray;
@@ -48,7 +49,7 @@
* int -> Delegate class link.
*
* Native methods usually always have the int as parameters. The first thing the delegate method
- * will do is call {@link #getDelegate(int)} to get the Java object matching the int.
+ * will do is call {@link #getDelegate(long)} to get the Java object matching the int.
*
* Typical native init methods are returning a new int back to the Java class, so
* {@link #addNewDelegate(Object)} does the same.
@@ -57,7 +58,7 @@
* the Java object needs to count as a reference (even though it only holds an int), we use the
* following mechanism:
*
- * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(int)} adds and removes
+ * - {@link #addNewDelegate(Object)} and {@link #removeJavaReferenceFor(long)} adds and removes
* the delegate to/from a list. This list hold the reference and prevents the GC from reclaiming
* the delegate.
*
@@ -70,12 +71,13 @@
* @param <T> the delegate class to manage
*/
public final class DelegateManager<T> {
+ @SuppressWarnings("FieldCanBeLocal")
private final Class<T> mClass;
private final SparseWeakArray<T> mDelegates = new SparseWeakArray<T>();
/** list used to store delegates when their main object holds a reference to them.
* This is to ensure that the WeakReference in the SparseWeakArray doesn't get GC'ed
* @see #addNewDelegate(Object)
- * @see #removeJavaReferenceFor(int)
+ * @see #removeJavaReferenceFor(long)
*/
private final List<T> mJavaReferences = new ArrayList<T>();
private int mDelegateCounter = 0;
@@ -94,6 +96,7 @@
* @param native_object the native int.
* @return the delegate or null if not found.
*/
+ @Nullable
public T getDelegate(long native_object) {
if (native_object > 0) {
T delegate = mDelegates.get(native_object);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
index 803849f..646f960 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
@@ -17,7 +17,9 @@
package com.android.layoutlib.bridge.impl;
-import org.kxml2.io.KXmlParser;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -35,24 +37,36 @@
*/
public class ParserFactory {
- private final static String ENCODING = "UTF-8"; //$NON-NLS-1$
-
public final static boolean LOG_PARSER = false;
- public static XmlPullParser create(File f)
+ private final static String ENCODING = "UTF-8"; //$NON-NLS-1$
+
+ // Used to get a new XmlPullParser from the client.
+ @Nullable
+ private static com.android.ide.common.rendering.api.ParserFactory sParserFactory;
+
+ public static void setParserFactory(
+ @Nullable com.android.ide.common.rendering.api.ParserFactory parserFactory) {
+ sParserFactory = parserFactory;
+ }
+
+ @NonNull
+ public static XmlPullParser create(@NonNull File f)
throws XmlPullParserException, FileNotFoundException {
InputStream stream = new FileInputStream(f);
return create(stream, f.getName(), f.length());
}
- public static XmlPullParser create(InputStream stream, String name)
+ @NonNull
+ public static XmlPullParser create(@NonNull InputStream stream, @Nullable String name)
throws XmlPullParserException {
return create(stream, name, -1);
}
- private static XmlPullParser create(InputStream stream, String name, long size)
- throws XmlPullParserException {
- KXmlParser parser = instantiateParser(name);
+ @NonNull
+ private static XmlPullParser create(@NonNull InputStream stream, @Nullable String name,
+ long size) throws XmlPullParserException {
+ XmlPullParser parser = instantiateParser(name);
stream = readAndClose(stream, name, size);
@@ -60,19 +74,20 @@
return parser;
}
- private static KXmlParser instantiateParser(String name) throws XmlPullParserException {
- KXmlParser parser;
- if (name != null) {
- parser = new CustomParser(name);
- } else {
- parser = new KXmlParser();
+ @NonNull
+ public static XmlPullParser instantiateParser(@Nullable String name)
+ throws XmlPullParserException {
+ if (sParserFactory == null) {
+ throw new XmlPullParserException("ParserFactory not initialized.");
}
+ XmlPullParser parser = sParserFactory.createParser(name);
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
return parser;
}
- private static InputStream readAndClose(InputStream stream, String name, long size)
- throws XmlPullParserException {
+ @NonNull
+ private static InputStream readAndClose(@NonNull InputStream stream, @Nullable String name,
+ long size) throws XmlPullParserException {
// just a sanity check. It's doubtful we'll have such big files!
if (size > Integer.MAX_VALUE) {
throw new XmlPullParserException("File " + name + " is too big to be parsed");
@@ -121,22 +136,8 @@
} finally {
try {
bufferedStream.close();
- } catch (IOException e) {
+ } catch (IOException ignored) {
}
}
}
-
- private static class CustomParser extends KXmlParser {
- private final String mName;
-
- CustomParser(String name) {
- super();
- mName = name;
- }
-
- @Override
- public String toString() {
- return mName;
- }
- }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
index c708316..2b95488 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java
@@ -99,6 +99,9 @@
return result;
}
+ // setup the ParserFactory
+ ParserFactory.setParserFactory(mParams.getLayoutlibCallback().getParserFactory());
+
HardwareConfig hardwareConfig = mParams.getHardwareConfig();
// setup the display Metrics.
@@ -271,6 +274,7 @@
mContext.getRenderResources().setFrameworkResourceIdProvider(null);
mContext.getRenderResources().setLogger(null);
}
+ ParserFactory.setParserFactory(null);
}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
deleted file mode 100644
index d94c205..0000000
--- a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java
+++ /dev/null
@@ -1,74 +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 libcore.icu;
-
-import java.text.FieldPosition;
-
-import com.android.ide.common.rendering.api.LayoutLog;
-import com.android.layoutlib.bridge.Bridge;
-import com.android.layoutlib.bridge.impl.DelegateManager;
-import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.DateIntervalFormat;
-import com.ibm.icu.util.DateInterval;
-import com.ibm.icu.util.TimeZone;
-import com.ibm.icu.util.ULocale;
-
-public class DateIntervalFormat_Delegate {
-
- // ---- delegate manager ----
- private static final DelegateManager<DateIntervalFormat_Delegate> sManager =
- new DelegateManager<DateIntervalFormat_Delegate>(DateIntervalFormat_Delegate.class);
-
- // ---- delegate data ----
- private DateIntervalFormat mFormat;
-
-
- // ---- native methods ----
-
- @LayoutlibDelegate
- /*package*/static String formatDateInterval(long address, long fromDate, long toDate) {
- DateIntervalFormat_Delegate delegate = sManager.getDelegate((int)address);
- if (delegate == null) {
- Bridge.getLog().error(LayoutLog.TAG_BROKEN,
- "Unable for find native DateIntervalFormat", null);
- return null;
- }
- DateInterval interval = new DateInterval(fromDate, toDate);
- StringBuffer sb = new StringBuffer();
- FieldPosition pos = new FieldPosition(0);
- delegate.mFormat.format(interval, sb, pos);
- return sb.toString();
- }
-
- @LayoutlibDelegate
- /*package*/ static long createDateIntervalFormat(String skeleton, String localeName,
- String tzName) {
- TimeZone prevDefaultTz = TimeZone.getDefault();
- TimeZone.setDefault(TimeZone.getTimeZone(tzName));
- DateIntervalFormat_Delegate newDelegate = new DateIntervalFormat_Delegate();
- newDelegate.mFormat =
- DateIntervalFormat.getInstance(skeleton, new ULocale(localeName));
- TimeZone.setDefault(prevDefaultTz);
- return sManager.addNewDelegate(newDelegate);
- }
-
- @LayoutlibDelegate
- /*package*/ static void destroyDateIntervalFormat(long address) {
- sManager.removeJavaReferenceFor((int)address);
- }
-
-}
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index b8b5fed..9c58010 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -17,9 +17,11 @@
package libcore.icu;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
-import com.ibm.icu.text.DateTimePatternGenerator;
-import com.ibm.icu.util.Currency;
-import com.ibm.icu.util.ULocale;
+
+import android.icu.text.DateTimePatternGenerator;
+import android.icu.util.Currency;
+import android.icu.util.ULocale;
+import android.icu.util.VersionInfo;
import java.util.Locale;
@@ -53,18 +55,19 @@
}
@LayoutlibDelegate
+ @SuppressWarnings("deprecation")
/*package*/ static String getCldrVersion() {
- return "22.1.1"; // TODO: check what the right value should be.
+ return VersionInfo.ICU_DATA_VERSION.toString();
}
@LayoutlibDelegate
/*package*/ static String getIcuVersion() {
- return "unknown_layoutlib";
+ return VersionInfo.ICU_VERSION.toString();
}
@LayoutlibDelegate
/*package*/ static String getUnicodeVersion() {
- return "5.2";
+ return VersionInfo.UNICODE_7_0.toString();
}
@LayoutlibDelegate
@@ -181,8 +184,8 @@
/*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) {
// Used by Calendar.
- result.firstDayOfWeek = Integer.valueOf(1);
- result.minimalDaysInFirstWeek = Integer.valueOf(1);
+ result.firstDayOfWeek = 1;
+ result.minimalDaysInFirstWeek = 1;
// Used by DateFormatSymbols.
result.amPm = new String[] { "AM", "PM" };
@@ -252,4 +255,9 @@
/*package*/ static String getDefaultLocale() {
return ICU.getDefaultLocale();
}
+
+ @LayoutlibDelegate
+ /*package*/ static String getTZDataVersion() {
+ return ICU.getTZDataVersion();
+ }
}
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
index 11390c3..5eef24a 100644
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -26,7 +26,6 @@
LOCAL_JAVA_LIBRARIES := layoutlib \
kxml2-2.3.0 \
- icu4j \
layoutlib_api-prebuilt \
tools-common-prebuilt \
sdk-common \
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
index c9b76be..2b86bfb 100644
--- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
index 8b362ec..d8937f4 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
@@ -192,12 +192,12 @@
StringBuilder sb = new StringBuilder(method.getName() + "(");
for (int j = 0; j < parameters.length; j++) {
Class<?> theClass = parameters[j];
- sb.append(theClass.getName());
int dimensions = 0;
while (theClass.isArray()) {
dimensions++;
theClass = theClass.getComponentType();
}
+ sb.append(theClass.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index 92fcf90..4623f69 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -16,14 +16,27 @@
package com.android.layoutlib.bridge.android;
+import com.android.annotations.NonNull;
import com.android.layoutlib.bridge.impl.ParserFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.kxml2.io.KXmlParser;
import org.w3c.dom.Node;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
-public class BridgeXmlBlockParserTest extends TestCase {
+public class BridgeXmlBlockParserTest {
+
+ @BeforeClass
+ public static void setUp() {
+ ParserFactory.setParserFactory(new ParserFactoryImpl());
+ }
+
+ @Test
public void testXmlBlockParser() throws Exception {
XmlPullParser parser = ParserFactory.create(
@@ -65,7 +78,7 @@
//------------
/**
- * Quick'n'dirty debug helper that dumps an XML structure to stdout.
+ * Quick 'n' dirty debug helper that dumps an XML structure to stdout.
*/
@SuppressWarnings("unused")
private void dump(Node node, String prefix) {
@@ -104,7 +117,20 @@
if (n != null) {
dump(n, prefix);
}
-
}
+ @AfterClass
+ public static void tearDown() {
+ ParserFactory.setParserFactory(null);
+ }
+
+ private static class ParserFactoryImpl
+ extends com.android.ide.common.rendering.api.ParserFactory {
+
+ @NonNull
+ @Override
+ public XmlPullParser createParser(String displayName) throws XmlPullParserException {
+ return new KXmlParser();
+ }
+ }
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index f2a039e..91be0bd 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -17,6 +17,7 @@
package com.android.layoutlib.bridge.intensive;
import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
@@ -34,7 +35,8 @@
import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser;
import com.android.utils.ILogger;
-import org.junit.Before;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
@@ -81,11 +83,11 @@
/** Location of the app's res dir inside {@link #TEST_RES_DIR}*/
private static final String APP_TEST_RES = APP_TEST_DIR + "/src/main/res";
- private LayoutLog mLayoutLibLog;
- private FrameworkResources mFrameworkRepo;
- private ResourceRepository mProjectResources;
- private ILogger mLogger;
- private Bridge mBridge;
+ private static LayoutLog sLayoutLibLog;
+ private static FrameworkResources sFrameworkRepo;
+ private static ResourceRepository sProjectResources;
+ private static ILogger sLogger;
+ private static Bridge sBridge;
static {
// Test that System Properties are properly set.
@@ -249,15 +251,15 @@
/**
* Initialize the bridge and the resource maps.
*/
- @Before
- public void setUp() {
+ @BeforeClass
+ public static void setUp() {
File data_dir = new File(PLATFORM_DIR, "data");
File res = new File(data_dir, "res");
- mFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
- mFrameworkRepo.loadResources();
- mFrameworkRepo.loadPublicResources(getLogger());
+ sFrameworkRepo = new FrameworkResources(new FolderWrapper(res));
+ sFrameworkRepo.loadResources();
+ sFrameworkRepo.loadPublicResources(getLogger());
- mProjectResources =
+ sProjectResources =
new ResourceRepository(new FolderWrapper(TEST_RES_DIR + APP_TEST_RES), false) {
@NonNull
@Override
@@ -265,13 +267,13 @@
return new ResourceItem(name);
}
};
- mProjectResources.loadResources();
+ sProjectResources.loadResources();
File fontLocation = new File(data_dir, "fonts");
File buildProp = new File(PLATFORM_DIR, "build.prop");
File attrs = new File(res, "values" + File.separator + "attrs.xml");
- mBridge = new Bridge();
- mBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
+ sBridge = new Bridge();
+ sBridge.init(ConfigGenerator.loadProperties(buildProp), fontLocation,
ConfigGenerator.getEnumMap(attrs), getLayoutLog());
}
@@ -288,6 +290,15 @@
renderAndVerify("allwidgets.xml", "allwidgets.png");
}
+ @AfterClass
+ public static void tearDown() {
+ sLayoutLibLog = null;
+ sFrameworkRepo = null;
+ sProjectResources = null;
+ sLogger = null;
+ sBridge = null;
+ }
+
/**
* Create a new rendering session and test that rendering given layout on nexus 5
* doesn't throw any exceptions and matches the provided image.
@@ -302,7 +313,7 @@
// TODO: Set up action bar handler properly to test menu rendering.
// Create session params.
SessionParams params = getSessionParams(parser, ConfigGenerator.NEXUS_5, layoutLibCallback);
- RenderSession session = mBridge.createSession(params);
+ RenderSession session = sBridge.createSession(params);
if (!session.getResult().isSuccess()) {
getLogger().error(session.getResult().getException(),
session.getResult().getErrorMessage());
@@ -328,8 +339,8 @@
ConfigGenerator configGenerator, LayoutLibTestCallback layoutLibCallback) {
FolderConfiguration config = configGenerator.getFolderConfig();
ResourceResolver resourceResolver =
- ResourceResolver.create(mProjectResources.getConfiguredResources(config),
- mFrameworkRepo.getConfiguredResources(config),
+ ResourceResolver.create(sProjectResources.getConfiguredResources(config),
+ sFrameworkRepo.getConfiguredResources(config),
"Theme.Material.Light.DarkActionBar", false);
return new SessionParams(
@@ -344,9 +355,9 @@
getLayoutLog());
}
- private LayoutLog getLayoutLog() {
- if (mLayoutLibLog == null) {
- mLayoutLibLog = new LayoutLog() {
+ private static LayoutLog getLayoutLog() {
+ if (sLayoutLibLog == null) {
+ sLayoutLibLog = new LayoutLog() {
@Override
public void warning(String tag, String message, Object data) {
System.out.println("Warning " + tag + ": " + message);
@@ -354,13 +365,14 @@
}
@Override
- public void fidelityWarning(String tag, String message, Throwable throwable,
- Object data) {
+ public void fidelityWarning(@Nullable String tag, String message,
+ Throwable throwable, Object data) {
+
System.out.println("FidelityWarning " + tag + ": " + message);
if (throwable != null) {
throwable.printStackTrace();
}
- failWithMsg(message);
+ failWithMsg(message == null ? "" : message);
}
@Override
@@ -379,18 +391,18 @@
}
};
}
- return mLayoutLibLog;
+ return sLayoutLibLog;
}
- private ILogger getLogger() {
- if (mLogger == null) {
- mLogger = new ILogger() {
+ private static ILogger getLogger() {
+ if (sLogger == null) {
+ sLogger = new ILogger() {
@Override
- public void error(Throwable t, String msgFormat, Object... args) {
+ public void error(Throwable t, @Nullable String msgFormat, Object... args) {
if (t != null) {
t.printStackTrace();
}
- failWithMsg(msgFormat, args);
+ failWithMsg(msgFormat == null ? "" : msgFormat, args);
}
@Override
@@ -409,7 +421,7 @@
}
};
}
- return mLogger;
+ return sLogger;
}
private static void failWithMsg(@NonNull String msgFormat, Object... args) {
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
index 1191df6..8964c45 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/ConfigGenerator.java
@@ -111,6 +111,21 @@
.setSoftButtons(true)
.setNavigation(Navigation.NONAV);
+ public static final ConfigGenerator NEXUS_5_LAND = new ConfigGenerator()
+ .setScreenHeight(1080)
+ .setScreenWidth(1920)
+ .setXdpi(445)
+ .setYdpi(445)
+ .setOrientation(ScreenOrientation.LANDSCAPE)
+ .setDensity(Density.XXHIGH)
+ .setRatio(ScreenRatio.NOTLONG)
+ .setSize(ScreenSize.NORMAL)
+ .setKeyboard(Keyboard.NOKEY)
+ .setTouchScreen(TouchScreen.FINGER)
+ .setKeyboardState(KeyboardState.SOFT)
+ .setSoftButtons(true)
+ .setNavigation(Navigation.NONAV);
+
private static final String TAG_ATTR = "attr";
private static final String TAG_ENUM = "enum";
private static final String TAG_FLAG = "flag";
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
index 5b648ef..ab682fd 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/setup/LayoutLibTestCallback.java
@@ -17,10 +17,13 @@
package com.android.layoutlib.bridge.intensive.setup;
import com.android.SdkConstants;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.ActionBarCallback;
import com.android.ide.common.rendering.api.AdapterBinding;
import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.LayoutlibCallback;
+import com.android.ide.common.rendering.api.ParserFactory;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.IntArrayWrapper;
@@ -28,6 +31,10 @@
import com.android.util.Pair;
import com.android.utils.ILogger;
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -155,4 +162,17 @@
public boolean supports(int ideFeature) {
return false;
}
+
+ @NonNull
+ @Override
+ public ParserFactory getParserFactory() {
+ return new ParserFactory() {
+ @NonNull
+ @Override
+ public XmlPullParser createParser(@Nullable String debugName)
+ throws XmlPullParserException {
+ return new KXmlParser();
+ }
+ };
+ }
}
diff --git a/tools/layoutlib/bridge/update_nav_icons.sh b/tools/layoutlib/bridge/update_nav_icons.sh
new file mode 100755
index 0000000..7030d19
--- /dev/null
+++ b/tools/layoutlib/bridge/update_nav_icons.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+# copies the navigation bar icons from system ui code to layoutlib.
+# to run, simply execute the script. (if not using bash, cd to the dir
+# containing this script and then run by ./update_nav_icons.sh)
+
+# Try to get the location of this script.
+if [ -n $BASH ]; then
+ # see http://stackoverflow.com/a/246128/1546000
+ MY_LOCATION=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+ cd $MY_LOCATION
+else
+ # Let's assume script was run from the same dir.
+ MY_LOCATION=$(pwd)
+fi
+
+# Check mac or linux to get sed argument to enable extended regex.
+case $(uname -s) in
+ Darwin)
+ EXT_REGEX="-E"
+ ;;
+ *)
+ EXT_REGEX="-r"
+ ;;
+esac
+
+
+FB="frameworks/base"
+# frameworks/base relative to current location
+FB=$(echo $MY_LOCATION | sed $EXT_REGEX -e "s,.*$FB[^/]*/,," -e "s,[^/]+,..,g")
+CURRENT_API=21 # update only if icons change from this api version.
+DENSITIES="ldpi mdpi hdpi xhdpi xxhdpi"
+ICONS="ic_sysbar_back.png ic_sysbar_home.png ic_sysbar_recent.png"
+BARS="./resources/bars/"
+
+for icon in $ICONS
+do
+ for density in $DENSITIES
+ do
+ destination="$BARS/v$CURRENT_API/$density/"
+ mkdir -p "$destination" # create if not present.
+ cp -v "$FB/packages/SystemUI/res/drawable-$density/$icon" "$destination"
+ done
+
+ for density in $DENSITIES
+ do
+ destination="$BARS/v$CURRENT_API/ldrtl-$density/"
+ mkdir -p "$destination"
+ cp -v "$FB/packages/SystemUI/res/drawable-ldrtl-$density/$icon" "$destination"
+ done
+done
diff --git a/tools/layoutlib/create/create.iml b/tools/layoutlib/create/create.iml
index b7e8eb3..9b18e73 100644
--- a/tools/layoutlib/create/create.iml
+++ b/tools/layoutlib/create/create.iml
@@ -11,8 +11,17 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="asm-4.0" level="project" />
+ <orderEntry type="module-library">
+ <library name="asm-4.0">
+ <CLASSES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/asm-4.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES>
+ <root url="jar://$MODULE_DIR$/../../../../../prebuilts/misc/common/asm/src.zip!/" />
+ </SOURCES>
+ </library>
+ </orderEntry>
<orderEntry type="library" scope="TEST" name="JUnit4" level="application" />
</component>
-</module>
-
+</module>
\ No newline at end of file
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index f5e8292..245cd61 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -156,6 +156,7 @@
"android.os.HandlerThread#run",
"android.preference.Preference#getView",
"android.text.format.DateFormat#is24HourFormat",
+ "android.text.Hyphenator#getSystemHyphenatorLocation",
"android.util.Xml#newPullParser",
"android.view.Choreographer#getRefreshRate",
"android.view.Display#updateDisplayInfoLocked",
@@ -231,7 +232,6 @@
"android.text.AndroidBidi",
"android.text.StaticLayout",
"android.view.Display",
- "libcore.icu.DateIntervalFormat",
"libcore.icu.ICU",
};
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index fa570c8..7872fee 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -118,10 +118,12 @@
"android.app.DatePickerDialog", // b.android.com/28318
"android.app.TimePickerDialog", // b.android.com/61515
"com.android.internal.view.menu.ActionMenu",
+ "android.icu.**", // needed by LayoutLib
},
excludeClasses,
new String[] {
"com/android/i18n/phonenumbers/data/*",
+ "android/icu/impl/data/**"
});
aa.analyze();
agen.generate();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 5e996725..a2b1858 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -757,7 +757,7 @@
* of state change events.
* <p>
* <b>Note:</b> If an application's target SDK version is
- * {@link android.os.Build.VERSION_CODES#MNC} or newer, network
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network
* communication may not use Wi-Fi even if Wi-Fi is connected; traffic may
* instead be sent through another network, such as cellular data,
* Bluetooth tethering, or Ethernet. For example, traffic will never use a
@@ -776,7 +776,7 @@
* @return {@code true} if the operation succeeded
*/
public boolean enableNetwork(int netId, boolean disableOthers) {
- final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.MNC;
+ final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP;
if (pin) {
registerPinningNetworkCallback();
}
@@ -1057,7 +1057,7 @@
}
synchronized(this) {
record = mService.reportActivityInfo();
- if (record.isValid()) {
+ if (record != null && record.isValid()) {
return record;
} else {
return null;