Merge "Allow only U+0020..U+007E characters for axis tag."
diff --git a/Android.bp b/Android.bp
index 010b2b4..dba49ce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13,6 +13,7 @@
// limitations under the License.
subdirs = [
+ "libs/*",
"native/android",
"native/graphics/jni",
]
diff --git a/Android.mk b/Android.mk
index 23aeae5..5d902c2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -79,6 +79,7 @@
core/java/android/app/IBackupAgent.aidl \
core/java/android/app/IEphemeralResolver.aidl \
core/java/android/app/IInstrumentationWatcher.aidl \
+ core/java/android/app/IOnNotificationChannelCreatedListener.aidl \
core/java/android/app/INotificationManager.aidl \
core/java/android/app/IProcessObserver.aidl \
core/java/android/app/ISearchManager.aidl \
diff --git a/api/current.txt b/api/current.txt
index 2bac65b..bab071b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -99,6 +99,7 @@
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
+ field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
@@ -4071,6 +4072,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -5393,7 +5395,7 @@
method public void cancel(int);
method public void cancel(java.lang.String, int);
method public void cancelAll();
- method public void createNotificationChannel(android.app.NotificationChannel);
+ method public void createNotificationChannel(android.app.NotificationChannel, android.app.NotificationManager.OnNotificationChannelCreatedListener, android.os.Handler);
method public void deleteNotificationChannel(java.lang.String);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
@@ -5427,6 +5429,10 @@
field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
}
+ public static abstract interface NotificationManager.OnNotificationChannelCreatedListener {
+ method public abstract void onNotificationChannelCreated(android.app.NotificationChannel);
+ }
+
public static class NotificationManager.Policy implements android.os.Parcelable {
ctor public NotificationManager.Policy(int, int, int);
ctor public NotificationManager.Policy(int, int, int, int);
@@ -12008,6 +12014,7 @@
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
+ method public static android.graphics.ColorSpace.Renderer createRenderer();
method public float[] fromXyz(float, float, float);
method public abstract float[] fromXyz(float[]);
method public static android.graphics.ColorSpace get(android.graphics.ColorSpace.Named);
@@ -12089,6 +12096,15 @@
enum_constant public static final android.graphics.ColorSpace.RenderIntent SATURATION;
}
+ public static class ColorSpace.Renderer {
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, int);
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, float, float, float, int);
+ method public android.graphics.ColorSpace.Renderer clip(boolean);
+ method public android.graphics.Bitmap render();
+ method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
+ method public android.graphics.ColorSpace.Renderer size(int);
+ }
+
public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
ctor public ColorSpace.Rgb(java.lang.String, float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator);
ctor public ColorSpace.Rgb(java.lang.String, float[], float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator, float, float);
@@ -20183,8 +20199,8 @@
}
public class AudioTrack implements android.media.AudioRouting {
- ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
- ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
@@ -21468,11 +21484,12 @@
method public void prepareAsync() throws java.lang.IllegalStateException;
method public void release();
method public void reset();
+ method public void seekTo(int, int) throws java.lang.IllegalStateException;
method public void seekTo(int) throws java.lang.IllegalStateException;
method public void selectTrack(int) throws java.lang.IllegalStateException;
method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
- method public void setAudioStreamType(int);
+ method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -21520,6 +21537,10 @@
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 SEEK_CLOSEST = 3; // 0x3
+ field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
+ field public static final int SEEK_NEXT_SYNC = 1; // 0x1
+ field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
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
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 23fe0c0..4a2f2d5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -172,6 +172,7 @@
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final java.lang.String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
+ field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
@@ -4207,6 +4208,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -5560,7 +5562,7 @@
method public void cancel(int);
method public void cancel(java.lang.String, int);
method public void cancelAll();
- method public void createNotificationChannel(android.app.NotificationChannel);
+ method public void createNotificationChannel(android.app.NotificationChannel, android.app.NotificationManager.OnNotificationChannelCreatedListener, android.os.Handler);
method public void deleteNotificationChannel(java.lang.String);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
@@ -5594,6 +5596,10 @@
field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
}
+ public static abstract interface NotificationManager.OnNotificationChannelCreatedListener {
+ method public abstract void onNotificationChannelCreated(android.app.NotificationChannel);
+ }
+
public static class NotificationManager.Policy implements android.os.Parcelable {
ctor public NotificationManager.Policy(int, int, int);
ctor public NotificationManager.Policy(int, int, int, int);
@@ -12493,6 +12499,7 @@
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
+ method public static android.graphics.ColorSpace.Renderer createRenderer();
method public float[] fromXyz(float, float, float);
method public abstract float[] fromXyz(float[]);
method public static android.graphics.ColorSpace get(android.graphics.ColorSpace.Named);
@@ -12574,6 +12581,15 @@
enum_constant public static final android.graphics.ColorSpace.RenderIntent SATURATION;
}
+ public static class ColorSpace.Renderer {
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, int);
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, float, float, float, int);
+ method public android.graphics.ColorSpace.Renderer clip(boolean);
+ method public android.graphics.Bitmap render();
+ method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
+ method public android.graphics.ColorSpace.Renderer size(int);
+ }
+
public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
ctor public ColorSpace.Rgb(java.lang.String, float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator);
ctor public ColorSpace.Rgb(java.lang.String, float[], float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator, float, float);
@@ -21750,8 +21766,8 @@
}
public class AudioTrack implements android.media.AudioRouting {
- ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
- ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
@@ -23035,11 +23051,12 @@
method public void prepareAsync() throws java.lang.IllegalStateException;
method public void release();
method public void reset();
+ method public void seekTo(int, int) throws java.lang.IllegalStateException;
method public void seekTo(int) throws java.lang.IllegalStateException;
method public void selectTrack(int) throws java.lang.IllegalStateException;
method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
- method public void setAudioStreamType(int);
+ method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -23087,6 +23104,10 @@
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 SEEK_CLOSEST = 3; // 0x3
+ field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
+ field public static final int SEEK_NEXT_SYNC = 1; // 0x1
+ field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
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
}
@@ -38018,19 +38039,7 @@
package android.service.persistentdata {
- public abstract interface IPersistentDataBlockService implements android.os.IInterface {
- method public abstract int getDataBlockSize() throws android.os.RemoteException;
- method public abstract int getFlashLockState() throws android.os.RemoteException;
- method public abstract long getMaximumDataBlockSize() throws android.os.RemoteException;
- method public abstract boolean getOemUnlockEnabled() throws android.os.RemoteException;
- method public abstract byte[] read() throws android.os.RemoteException;
- method public abstract void setOemUnlockEnabled(boolean) throws android.os.RemoteException;
- method public abstract void wipe() throws android.os.RemoteException;
- method public abstract int write(byte[]) throws android.os.RemoteException;
- }
-
public class PersistentDataBlockManager {
- ctor public PersistentDataBlockManager(android.service.persistentdata.IPersistentDataBlockService);
method public int getDataBlockSize();
method public int getFlashLockState();
method public long getMaximumDataBlockSize();
diff --git a/api/test-current.txt b/api/test-current.txt
index 2c68584..b888911 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -99,6 +99,7 @@
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
+ field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
@@ -4081,6 +4082,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -5403,7 +5405,7 @@
method public void cancel(int);
method public void cancel(java.lang.String, int);
method public void cancelAll();
- method public void createNotificationChannel(android.app.NotificationChannel);
+ method public void createNotificationChannel(android.app.NotificationChannel, android.app.NotificationManager.OnNotificationChannelCreatedListener, android.os.Handler);
method public void deleteNotificationChannel(java.lang.String);
method public android.service.notification.StatusBarNotification[] getActiveNotifications();
method public android.app.AutomaticZenRule getAutomaticZenRule(java.lang.String);
@@ -5438,6 +5440,10 @@
field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
}
+ public static abstract interface NotificationManager.OnNotificationChannelCreatedListener {
+ method public abstract void onNotificationChannelCreated(android.app.NotificationChannel);
+ }
+
public static class NotificationManager.Policy implements android.os.Parcelable {
ctor public NotificationManager.Policy(int, int, int);
ctor public NotificationManager.Policy(int, int, int, int);
@@ -12039,6 +12045,7 @@
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
+ method public static android.graphics.ColorSpace.Renderer createRenderer();
method public float[] fromXyz(float, float, float);
method public abstract float[] fromXyz(float[]);
method public static android.graphics.ColorSpace get(android.graphics.ColorSpace.Named);
@@ -12120,6 +12127,15 @@
enum_constant public static final android.graphics.ColorSpace.RenderIntent SATURATION;
}
+ public static class ColorSpace.Renderer {
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, int);
+ method public android.graphics.ColorSpace.Renderer add(android.graphics.ColorSpace, float, float, float, int);
+ method public android.graphics.ColorSpace.Renderer clip(boolean);
+ method public android.graphics.Bitmap render();
+ method public android.graphics.ColorSpace.Renderer showWhitePoint(boolean);
+ method public android.graphics.ColorSpace.Renderer size(int);
+ }
+
public static class ColorSpace.Rgb extends android.graphics.ColorSpace {
ctor public ColorSpace.Rgb(java.lang.String, float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator);
ctor public ColorSpace.Rgb(java.lang.String, float[], float[], java.util.function.DoubleUnaryOperator, java.util.function.DoubleUnaryOperator, float, float);
@@ -20270,8 +20286,8 @@
}
public class AudioTrack implements android.media.AudioRouting {
- ctor public AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
- ctor public AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
+ ctor public deprecated AudioTrack(int, int, int, int, int, int, int) throws java.lang.IllegalArgumentException;
ctor public AudioTrack(android.media.AudioAttributes, android.media.AudioFormat, int, int, int) throws java.lang.IllegalArgumentException;
method public void addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, android.os.Handler);
method public deprecated void addOnRoutingChangedListener(android.media.AudioTrack.OnRoutingChangedListener, android.os.Handler);
@@ -21555,11 +21571,12 @@
method public void prepareAsync() throws java.lang.IllegalStateException;
method public void release();
method public void reset();
+ method public void seekTo(int, int) throws java.lang.IllegalStateException;
method public void seekTo(int) throws java.lang.IllegalStateException;
method public void selectTrack(int) throws java.lang.IllegalStateException;
method public void setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
- method public void setAudioStreamType(int);
+ method public deprecated void setAudioStreamType(int);
method public void setAuxEffectSendLevel(float);
method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -21607,6 +21624,10 @@
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 SEEK_CLOSEST = 3; // 0x3
+ field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
+ field public static final int SEEK_NEXT_SYNC = 1; // 0x1
+ field public static final int SEEK_PREVIOUS_SYNC = 0; // 0x0
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
}
diff --git a/cmds/app_process/Android.mk b/cmds/app_process/Android.mk
index f4314fb..eaad3a7 100644
--- a/cmds/app_process/Android.mk
+++ b/cmds/app_process/Android.mk
@@ -48,41 +48,20 @@
LOCAL_CFLAGS += $(app_process_cflags)
-# In SANITIZE_LITE mode, the main app_process is not sanitized - special
-# binaries below do that.
+# In SANITIZE_LITE mode, we create the sanitized binary in a separate location (but reuse
+# the same module). Using the same module also works around an issue with make: binaries
+# that depend on sanitized libraries will be relinked, even if they set LOCAL_SANITIZE := never.
+#
+# Also pull in the asanwrapper helper.
ifeq ($(SANITIZE_LITE),true)
-LOCAL_SANITIZE := never
+LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
+LOCAL_REQUIRED_MODULES := asanwrapper
endif
include $(BUILD_EXECUTABLE)
# Create a symlink from app_process to app_process32 or 64
# depending on the target configuration.
+ifneq ($(SANITIZE_LITE),true)
include $(BUILD_SYSTEM)/executable_prefer_symlink.mk
-
-# Build a variant of app_process binary linked with ASan runtime.
-# Built when SANITIZE_LITE is enabled.
-ifeq ($(SANITIZE_LITE),true)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(app_process_src_files)
-
-LOCAL_LDFLAGS_32 := $(app_process_ldflags_32)
-LOCAL_LDFLAGS_64 := $(app_process_ldflags_64)
-
-LOCAL_SHARED_LIBRARIES := $(app_process_common_shared_libs)
-
-LOCAL_WHOLE_STATIC_LIBRARIES := $(app_process_common_static_libs)
-
-LOCAL_MODULE := app_process__asan
-LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := app_process32
-LOCAL_MODULE_STEM_64 := app_process64
-LOCAL_MODULE_PATH := $(TARGET_OUT_EXECUTABLES)/asan
-
-LOCAL_CFLAGS += $(app_process_cflags)
-
-include $(BUILD_EXECUTABLE)
-
-endif # SANITIZE_LITE
+endif
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 4291c77..db3772d 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -92,6 +92,8 @@
runSetEmulateFbe();
} else if ("get-fbe-mode".equals(op)) {
runGetFbeMode();
+ } else if ("fstrim".equals(op)) {
+ runFstrim();
} else {
throw new IllegalArgumentException();
}
@@ -210,7 +212,7 @@
mSm.benchmark(volId);
}
- public void runForget() throws RemoteException{
+ public void runForget() throws RemoteException {
final String fsUuid = nextArg();
if ("all".equals(fsUuid)) {
mSm.forgetAllVolumes();
@@ -219,6 +221,10 @@
}
}
+ public void runFstrim() throws RemoteException {
+ mSm.fstrim(0);
+ }
+
private String nextArg() {
if (mNextArg >= mArgs.length) {
return null;
@@ -240,6 +246,7 @@
System.err.println(" sm unmount VOLUME");
System.err.println(" sm format VOLUME");
System.err.println(" sm benchmark VOLUME");
+ System.err.println(" sm fstrim");
System.err.println("");
System.err.println(" sm forget [UUID|all]");
System.err.println("");
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 65f74d1..312d3a5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -561,8 +561,11 @@
/** ID of stack that always on top (always visible) when it exist. */
public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
+ /** Recents activity stack ID. */
+ public static final int RECENTS_STACK_ID = PINNED_STACK_ID + 1;
+
/** Last static stack stack ID. */
- public static final int LAST_STATIC_STACK_ID = PINNED_STACK_ID;
+ public static final int LAST_STATIC_STACK_ID = RECENTS_STACK_ID;
/** Start of ID range used by stacks that are created dynamically. */
public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1;
@@ -735,6 +738,13 @@
}
/**
+ * Returns true if the input {@param stackId} is HOME_STACK_ID or RECENTS_STACK_ID
+ */
+ public static boolean isHomeOrRecentsStack(int stackId) {
+ return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID;
+ }
+
+ /**
* Returns true if activities contained in this stack can request visible behind by
* calling {@link Activity#requestVisibleBehind}.
*/
@@ -760,7 +770,8 @@
/** Returns true if the input stack and its content can affect the device orientation. */
public static boolean canSpecifyOrientation(int stackId) {
- return stackId == HOME_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID;
+ return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID
+ || stackId == FULLSCREEN_WORKSPACE_STACK_ID;
}
}
@@ -1509,7 +1520,7 @@
* Ignores all tasks that are on the home stack.
* @hide
*/
- public static final int RECENT_IGNORE_HOME_STACK_TASKS = 0x0008;
+ public static final int RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS = 0x0008;
/**
* Ignores the top task in the docked stack.
@@ -2052,15 +2063,6 @@
}
}
- /** @hide */
- public boolean isInHomeStack(int taskId) {
- try {
- return getService().isInHomeStack(taskId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
/**
* Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
* activity along with the task, so it is positioned immediately behind
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ba6bc15..67fbc5a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -241,8 +241,10 @@
public static final int OP_RUN_IN_BACKGROUND = 63;
/** @hide */
public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
+ /** @hide Read the phone number. */
+ public static final int OP_READ_PHONE_NUMBER = 65;
/** @hide */
- public static final int _NUM_OP = 65;
+ public static final int _NUM_OP = 66;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -343,6 +345,8 @@
/** @hide Get device accounts. */
public static final String OPSTR_GET_ACCOUNTS
= "android:get_accounts";
+ public static final String OPSTR_READ_PHONE_NUMBER
+ = "android:read_phone_number";
private static final int[] RUNTIME_PERMISSIONS_OPS = {
// Contacts
@@ -367,6 +371,7 @@
OP_FINE_LOCATION,
// Phone
OP_READ_PHONE_STATE,
+ OP_READ_PHONE_NUMBER,
OP_CALL_PHONE,
OP_READ_CALL_LOG,
OP_WRITE_CALL_LOG,
@@ -455,6 +460,7 @@
OP_GET_ACCOUNTS,
OP_RUN_IN_BACKGROUND,
OP_AUDIO_ACCESSIBILITY_VOLUME,
+ OP_READ_PHONE_NUMBER,
};
/**
@@ -527,6 +533,7 @@
OPSTR_GET_ACCOUNTS,
null,
null, // OP_AUDIO_ACCESSIBILITY_VOLUME
+ OPSTR_READ_PHONE_NUMBER,
};
/**
@@ -599,6 +606,7 @@
"GET_ACCOUNTS",
"RUN_IN_BACKGROUND",
"AUDIO_ACCESSIBILITY_VOLUME",
+ "READ_PHONE_NUMBER",
};
/**
@@ -671,6 +679,7 @@
Manifest.permission.GET_ACCOUNTS,
null, // no permission for running in background
null, // no permission for changing accessibility volume
+ Manifest.permission.READ_PHONE_NUMBER,
};
/**
@@ -744,6 +753,7 @@
null, // GET_ACCOUNTS
null, // RUN_IN_BACKGROUND
UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
+ null, // READ_PHONE_NUMBER
};
/**
@@ -816,6 +826,7 @@
false, // GET_ACCOUNTS
false, // RUN_IN_BACKGROUND
false, // AUDIO_ACCESSIBILITY_VOLUME
+ false, // READ_PHONE_NUMBER
};
/**
@@ -887,6 +898,7 @@
AppOpsManager.MODE_ALLOWED,
AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND
AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ACCESSIBILITY_VOLUME
+ AppOpsManager.MODE_ALLOWED,
};
/**
@@ -962,6 +974,7 @@
false,
false,
false, // OP_AUDIO_ACCESSIBILITY_VOLUME
+ false,
};
/**
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 1a36d1a..640ca6c 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -370,7 +370,6 @@
// Start of L transactions
String getTagForIntentSender(in IIntentSender sender, in String prefix);
boolean startUserInBackground(int userid);
- boolean isInHomeStack(int taskId);
void startLockTaskModeById(int taskId);
void startLockTaskModeByToken(in IBinder token);
void stopLockTaskMode();
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 2a7341a..927ef6c 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -2,21 +2,22 @@
**
** Copyright 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
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this 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
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT 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.app.IOnNotificationChannelCreatedListener;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -58,7 +59,8 @@
int getImportance(String pkg, int uid);
int getPackageImportance(String pkg);
- void createNotificationChannel(String pkg, in NotificationChannel channel);
+ void createNotificationChannel(String pkg, in NotificationChannel channel,
+ in IOnNotificationChannelCreatedListener listener);
void updateNotificationChannelForPackage(String pkg, int uid, in NotificationChannel channel);
NotificationChannel getNotificationChannel(String pkg, String channelId);
NotificationChannel getNotificationChannelForPackage(String pkg, int uid, String channelId);
diff --git a/core/java/android/app/IOnNotificationChannelCreatedListener.aidl b/core/java/android/app/IOnNotificationChannelCreatedListener.aidl
new file mode 100644
index 0000000..8e66542
--- /dev/null
+++ b/core/java/android/app/IOnNotificationChannelCreatedListener.aidl
@@ -0,0 +1,25 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.app;
+
+import android.app.NotificationChannel;
+
+/** {@hide} */
+oneway interface IOnNotificationChannelCreatedListener {
+ void onNotificationChannelCreated(in NotificationChannel channel);
+}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 1fd082f4..c1e2072 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -37,6 +37,7 @@
import android.graphics.drawable.Icon;
import android.media.AudioAttributes;
import android.media.AudioManager;
+import android.media.PlayerBase;
import android.media.session.MediaSession;
import android.net.Uri;
import android.os.BadParcelableException;
@@ -2821,6 +2822,7 @@
*/
@Deprecated
public Builder setSound(Uri sound, int streamType) {
+ PlayerBase.deprecateStreamTypeForPlayback(streamType, "Notification", "setSound()");
mN.sound = sound;
mN.audioStreamType = streamType;
return this;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 047f349..7693d76 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.TestApi;
import android.app.Notification.Builder;
@@ -30,6 +31,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -379,12 +381,42 @@
}
/**
- * Creates a notification channel that notifications can be posted to.
+ * Listener passed to {@link NotificationManager#createNotificationChannel} to notify
+ * caller of result.
*/
- public void createNotificationChannel(NotificationChannel channel) {
+ public interface OnNotificationChannelCreatedListener {
+ /**
+ * @param createdChannel NotificationChannel created by the system. Value is null iff an
+ * exception was thrown during channel creation.
+ */
+ public void onNotificationChannelCreated(NotificationChannel createdChannel);
+ }
+
+ /**
+ * Creates a notification channel that notifications can be posted to.
+ *
+ * @param channel the channel to attempt to create. Note that the created channel may differ
+ * from this value.
+ * @param listener Called when operation is finished.
+ * @param handler The handler to invoke the listener on, or {@code null} to use the main
+ * handler.
+ */
+ public void createNotificationChannel(
+ @NonNull NotificationChannel channel,
+ @NonNull OnNotificationChannelCreatedListener listener,
+ @Nullable Handler handler) {
INotificationManager service = getService();
try {
- service.createNotificationChannel(mContext.getPackageName(), channel);
+ final Handler actualHandler =
+ handler != null ? handler : new Handler(Looper.getMainLooper());
+ service.createNotificationChannel(mContext.getPackageName(), channel,
+ new IOnNotificationChannelCreatedListener.Stub() {
+ @Override public void onNotificationChannelCreated(
+ NotificationChannel channel) {
+ actualHandler.post(
+ () -> { listener.onNotificationChannelCreated(channel); });
+ }
+ });
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -583,7 +615,7 @@
* <p>
* Callers can only update rules that they own. See {@link AutomaticZenRule#getOwner}.
* @param id The id of the rule to update
- * @param automaticZenRule the rule to update.
+ * @param automaticZenRule the rule to update.
* @return Whether the rule was successfully updated.
*/
public boolean updateAutomaticZenRule(String id, AutomaticZenRule automaticZenRule) {
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 5162a73..ca3658b 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -853,14 +853,29 @@
* @hide
*/
public void prepareToLeaveProcess(boolean leavingPackage) {
+ prepareToLeaveProcess(leavingPackage, 0);
+ }
+
+ /**
+ * Prepare this {@link ClipData} to leave an app process.
+ *
+ * @hide
+ */
+ public void prepareToLeaveProcess(boolean leavingPackage, int intentFlags) {
final int size = mItems.size();
for (int i = 0; i < size; i++) {
final Item item = mItems.get(i);
if (item.mIntent != null) {
item.mIntent.prepareToLeaveProcess(leavingPackage);
}
- if (item.mUri != null && StrictMode.vmFileUriExposureEnabled() && leavingPackage) {
- item.mUri.checkFileUriExposed("ClipData.Item.getUri()");
+ if (item.mUri != null && leavingPackage) {
+ if (StrictMode.vmFileUriExposureEnabled()) {
+ item.mUri.checkFileUriExposed("ClipData.Item.getUri()");
+ }
+ if (StrictMode.vmContentUriWithoutPermissionEnabled()) {
+ item.mUri.checkContentUriWithoutPermission("ClipData.Item.getUri()",
+ intentFlags);
+ }
}
}
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 50589fe..a5d7999 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -9009,7 +9009,7 @@
mSelector.prepareToLeaveProcess(leavingPackage);
}
if (mClipData != null) {
- mClipData.prepareToLeaveProcess(leavingPackage);
+ mClipData.prepareToLeaveProcess(leavingPackage, getFlags());
}
if (mAction != null && mData != null && StrictMode.vmFileUriExposureEnabled()
@@ -9036,6 +9036,17 @@
mData.checkFileUriExposed("Intent.getData()");
}
}
+
+ if (mAction != null && mData != null && StrictMode.vmContentUriWithoutPermissionEnabled()
+ && leavingPackage) {
+ switch (mAction) {
+ case ACTION_PROVIDER_CHANGED:
+ // Ignore actions that don't need to grant
+ break;
+ default:
+ mData.checkContentUriWithoutPermission("Intent.getData()", getFlags());
+ }
+ }
}
/**
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 2beca7b..358787e 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -89,6 +89,7 @@
* @return The label for the activity.
*/
public CharSequence getLabel() {
+ // TODO: Go through LauncherAppsService
return mActivityInfo.loadLabel(mPm);
}
@@ -101,6 +102,7 @@
* @return The drawable associated with the activity.
*/
public Drawable getIcon(int density) {
+ // TODO: Go through LauncherAppsService
final int iconRes = mActivityInfo.getIconResource();
Drawable icon = null;
// Get the preferred density icon from the app's resources
@@ -144,8 +146,9 @@
*/
public long getFirstInstallTime() {
try {
+ // TODO: Go through LauncherAppsService
return mPm.getPackageInfo(mActivityInfo.packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES).firstInstallTime;
+ PackageManager.MATCH_UNINSTALLED_PACKAGES).firstInstallTime;
} catch (NameNotFoundException nnfe) {
// Sorry, can't find package
return 0;
@@ -171,6 +174,7 @@
Drawable originalIcon = getIcon(density);
if (originalIcon instanceof BitmapDrawable) {
+ // TODO: Go through LauncherAppsService
return mPm.getUserBadgedIcon(originalIcon, mUser);
} else {
Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 6b23da9..7fc8044 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -447,12 +447,12 @@
/**
* Retrieve all of the information we know about a particular package / application.
*
- * @param packageName The package of the application
+ * @param packageName The package name of the application
* @param flags Additional option flags {@link PackageManager#getApplicationInfo}
* @param user The UserHandle of the profile.
*
* @return An {@link ApplicationInfo} containing information about the package or
- * null of the package isn't found.
+ * null if the package isn't installed for the given user.
* @hide
*/
public ApplicationInfo getApplicationInfo(String packageName, @ApplicationInfoFlags int flags,
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5087bc8..3f052d38 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -435,6 +435,20 @@
public static final int MATCH_FACTORY_ONLY = 0x00200000;
/**
+ * Allows querying of packages installed for any user, not just the specific one. This flag
+ * is only meant for use by apps that have INTERACT_ACROSS_USERS_FULL permission.
+ * @hide
+ */
+ public static final int MATCH_ANY_USER = 0x00400000;
+
+ /**
+ * Combination of MATCH_ANY_USER and MATCH_UNINSTALLED_PACKAGES to mean any known
+ * package.
+ * @hide
+ */
+ public static final int MATCH_KNOWN_PACKAGES = MATCH_UNINSTALLED_PACKAGES | MATCH_ANY_USER;
+
+ /**
* Internal flag used to indicate that a system component has done their
* homework and verified that they correctly handle packages and components
* that come and go over time. In particular:
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index bb9c18a..f363bd8 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -478,20 +478,25 @@
/**
* Returns true if the package is installed and not hidden, or if the caller
* explicitly wanted all uninstalled and hidden packages as well.
+ * @param appInfo The applicationInfo of the app being checked.
*/
- private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state) {
- return (state.installed && !state.hidden)
- || (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
+ private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state,
+ ApplicationInfo appInfo) {
+ // If available for the target user, or trying to match uninstalled packages and it's
+ // a system app.
+ return state.isAvailable(flags)
+ || (appInfo != null && appInfo.isSystemApp()
+ && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0);
}
public static boolean isAvailable(PackageUserState state) {
- return checkUseInstalledOrHidden(0, state);
+ return checkUseInstalledOrHidden(0, state, null);
}
public static PackageInfo generatePackageInfo(PackageParser.Package p,
int gids[], int flags, long firstInstallTime, long lastUpdateTime,
Set<String> grantedPermissions, PackageUserState state, int userId) {
- if (!checkUseInstalledOrHidden(flags, state) || !p.isMatch(flags)) {
+ if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
return null;
}
PackageInfo pi = new PackageInfo();
@@ -1696,6 +1701,11 @@
String str = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
if (str != null && str.length() > 0) {
+ if ((flags & PARSE_IS_EPHEMERAL) != 0) {
+ outError[0] = "sharedUserId not allowed in ephemeral application";
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
+ return null;
+ }
String nameError = validateName(str, true, false);
if (nameError != null && !"android".equals(pkg.packageName)) {
outError[0] = "<manifest> specifies bad sharedUserId name \""
@@ -5445,7 +5455,7 @@
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
- if (!checkUseInstalledOrHidden(flags, state) || !p.isMatch(flags)) {
+ if (!checkUseInstalledOrHidden(flags, state, p.applicationInfo) || !p.isMatch(flags)) {
return null;
}
if (!copyNeeded(flags, p, state, null, userId)
@@ -5483,7 +5493,7 @@
public static ApplicationInfo generateApplicationInfo(ApplicationInfo ai, int flags,
PackageUserState state, int userId) {
if (ai == null) return null;
- if (!checkUseInstalledOrHidden(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state, ai)) {
return null;
}
// This is only used to return the ResolverActivity; we will just always
@@ -5549,7 +5559,7 @@
public static final ActivityInfo generateActivityInfo(Activity a, int flags,
PackageUserState state, int userId) {
if (a == null) return null;
- if (!checkUseInstalledOrHidden(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state, a.owner.applicationInfo)) {
return null;
}
if (!copyNeeded(flags, a.owner, state, a.metaData, userId)) {
@@ -5565,7 +5575,7 @@
public static final ActivityInfo generateActivityInfo(ActivityInfo ai, int flags,
PackageUserState state, int userId) {
if (ai == null) return null;
- if (!checkUseInstalledOrHidden(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state, ai.applicationInfo)) {
return null;
}
// This is only used to return the ResolverActivity; we will just always
@@ -5603,7 +5613,7 @@
public static final ServiceInfo generateServiceInfo(Service s, int flags,
PackageUserState state, int userId) {
if (s == null) return null;
- if (!checkUseInstalledOrHidden(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state, s.owner.applicationInfo)) {
return null;
}
if (!copyNeeded(flags, s.owner, state, s.metaData, userId)) {
@@ -5652,7 +5662,7 @@
public static final ProviderInfo generateProviderInfo(Provider p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
- if (!checkUseInstalledOrHidden(flags, state)) {
+ if (!checkUseInstalledOrHidden(flags, state, p.owner.applicationInfo)) {
return null;
}
if (!copyNeeded(flags, p.owner, state, p.metaData, userId)
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 8ce8a13..1821458 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -29,7 +29,6 @@
import android.util.ArraySet;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
/**
@@ -80,9 +79,14 @@
/**
* Test if this package is installed.
*/
- public boolean isInstalled(int flags) {
- return (this.installed && !this.hidden)
- || (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
+ public boolean isAvailable(int flags) {
+ // True if it is installed for this user and it is not hidden. If it is hidden,
+ // still return true if the caller requested MATCH_UNINSTALLED_PACKAGES
+ final boolean matchAnyUser = (flags & PackageManager.MATCH_ANY_USER) != 0;
+ final boolean matchUninstalled = (flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0;
+ return matchAnyUser
+ || (this.installed
+ && (!this.hidden || matchUninstalled));
}
/**
@@ -95,11 +99,14 @@
* </p>
*/
public boolean isMatch(ComponentInfo componentInfo, int flags) {
- if (!isInstalled(flags)) return false;
+ final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
+ final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
+ if (!isAvailable(flags)
+ && !(isSystemApp && matchUninstalled)) return false;
if (!isEnabled(componentInfo, flags)) return false;
if ((flags & MATCH_SYSTEM_ONLY) != 0) {
- if (!componentInfo.applicationInfo.isSystemApp()) {
+ if (!isSystemApp) {
return false;
}
}
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index a854b89..56f914e 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -314,9 +314,11 @@
*
* @hide
*/
- public void enforceMandatoryFields() {
+ public void enforceMandatoryFields(boolean forPinned) {
Preconditions.checkStringNotEmpty(mId, "Shortcut ID must be provided");
- Preconditions.checkNotNull(mActivity, "Activity must be provided");
+ if (!forPinned) {
+ Preconditions.checkNotNull(mActivity, "Activity must be provided");
+ }
if (mTitle == null && mTitleResId == 0) {
throw new IllegalArgumentException("Short label must be provided");
}
@@ -1055,6 +1057,11 @@
* Launcher apps should show the launcher icon for the returned activity alongside
* this shortcut.
*
+ * <p>When a shortcut is dynamic or manifest
+ * (i.e. either {@link #isDynamic()} or {@link #isDeclaredInManifest()} returns {@code TRUE}),
+ * then it should always have a non-null target activity.
+ * Otherwise it will return null.
+ *
* @see Builder#setActivity
*/
@Nullable
@@ -1361,7 +1368,7 @@
}
/**
- * @return true if pinned but neither static nor dynamic.
+ * Return {@code TRUE} if a shortcut is pinned but neither manifest nor dynamic.
* @hide
*/
public boolean isFloating() {
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 9e00b65..45cd084 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -440,7 +440,7 @@
*/
public abstract void createCaptureSessionByOutputConfigurations(
List<OutputConfiguration> outputConfigurations,
- CameraCaptureSession.StateCallback callback, Handler handler)
+ CameraCaptureSession.StateCallback callback, @Nullable Handler handler)
throws CameraAccessException;
/**
* Create a new reprocessable camera capture session by providing the desired reprocessing
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c2286ad..a0f74ec 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -144,7 +144,7 @@
* scorer.
*/
public String getActiveScorerPackage() {
- NetworkScorerAppData app = NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData app = new NetworkScorerAppManager(mContext).getActiveScorer();
if (app == null) {
return null;
}
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 29291ca..ebb31c9 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -41,14 +41,17 @@
*
* @hide
*/
-public final class NetworkScorerAppManager {
+public class NetworkScorerAppManager {
private static final String TAG = "NetworkScorerAppManager";
private static final Intent SCORE_INTENT =
new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS);
- /** This class cannot be instantiated. */
- private NetworkScorerAppManager() {}
+ private final Context mContext;
+
+ public NetworkScorerAppManager(Context context) {
+ mContext = context;
+ }
public static class NetworkScorerAppData {
/** Package name of this scorer app. */
@@ -108,7 +111,7 @@
*
* @return the list of scorers, or the empty list if there are no valid scorers.
*/
- public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) {
+ public Collection<NetworkScorerAppData> getAllValidScorers() {
// Network scorer apps can only run as the primary user so exit early if we're not the
// primary user.
if (UserHandle.getCallingUserId() != UserHandle.USER_SYSTEM) {
@@ -116,7 +119,7 @@
}
List<NetworkScorerAppData> scorers = new ArrayList<>();
- PackageManager pm = context.getPackageManager();
+ PackageManager pm = mContext.getPackageManager();
// Only apps installed under the primary user of the device can be scorers.
// TODO: http://b/23422763
List<ResolveInfo> receivers =
@@ -179,10 +182,10 @@
* selected) or if the previously-set scorer is no longer a valid scorer app (e.g. because
* it was disabled or uninstalled).
*/
- public static NetworkScorerAppData getActiveScorer(Context context) {
- String scorerPackage = Settings.Global.getString(context.getContentResolver(),
+ public NetworkScorerAppData getActiveScorer() {
+ String scorerPackage = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.NETWORK_SCORER_APP);
- return getScorer(context, scorerPackage);
+ return getScorer(scorerPackage);
}
/**
@@ -190,13 +193,12 @@
*
* <p>The caller must have permission to write to {@link android.provider.Settings.Global}.
*
- * @param context the context of the calling application
* @param packageName the packageName of the new scorer to use. If null, scoring will be
* disabled. Otherwise, the scorer will only be set if it is a valid scorer application.
* @return true if the scorer was changed, or false if the package is not a valid scorer.
*/
- public static boolean setActiveScorer(Context context, String packageName) {
- String oldPackageName = Settings.Global.getString(context.getContentResolver(),
+ public boolean setActiveScorer(String packageName) {
+ String oldPackageName = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.NETWORK_SCORER_APP);
if (TextUtils.equals(oldPackageName, packageName)) {
// No change.
@@ -206,13 +208,13 @@
Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName);
if (packageName == null) {
- Settings.Global.putString(context.getContentResolver(),
+ Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.NETWORK_SCORER_APP, null);
return true;
} else {
// We only make the change if the new package is valid.
- if (getScorer(context, packageName) != null) {
- Settings.Global.putString(context.getContentResolver(),
+ if (getScorer(packageName) != null) {
+ Settings.Global.putString(mContext.getContentResolver(),
Settings.Global.NETWORK_SCORER_APP, packageName);
return true;
} else {
@@ -223,8 +225,8 @@
}
/** Determine whether the application with the given UID is the enabled scorer. */
- public static boolean isCallerActiveScorer(Context context, int callingUid) {
- NetworkScorerAppData defaultApp = getActiveScorer(context);
+ public boolean isCallerActiveScorer(int callingUid) {
+ NetworkScorerAppData defaultApp = getActiveScorer();
if (defaultApp == null) {
return false;
}
@@ -233,16 +235,16 @@
}
// To be extra safe, ensure the caller holds the SCORE_NETWORKS permission. It always
// should, since it couldn't become the active scorer otherwise, but this can't hurt.
- return context.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) ==
+ return mContext.checkCallingPermission(Manifest.permission.SCORE_NETWORKS) ==
PackageManager.PERMISSION_GRANTED;
}
/** Returns the {@link NetworkScorerAppData} for the given app, or null if it's not a scorer. */
- public static NetworkScorerAppData getScorer(Context context, String packageName) {
+ public NetworkScorerAppData getScorer(String packageName) {
if (TextUtils.isEmpty(packageName)) {
return null;
}
- Collection<NetworkScorerAppData> applications = getAllValidScorers(context);
+ Collection<NetworkScorerAppData> applications = getAllValidScorers();
for (NetworkScorerAppData app : applications) {
if (packageName.equals(app.mPackageName)) {
return app;
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 67378bd..7396189 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -16,6 +16,7 @@
package android.net;
+import android.content.Intent;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
@@ -2342,12 +2343,25 @@
* @hide
*/
public void checkFileUriExposed(String location) {
- if ("file".equals(getScheme()) && !getPath().startsWith("/system/")) {
+ if ("file".equals(getScheme())
+ && (getPath() != null) && !getPath().startsWith("/system/")) {
StrictMode.onFileUriExposed(this, location);
}
}
/**
+ * If this is a {@code content://} Uri without access flags, it will be
+ * reported to {@link StrictMode}.
+ *
+ * @hide
+ */
+ public void checkContentUriWithoutPermission(String location, int flags) {
+ if ("content".equals(getScheme()) && !Intent.isAccessUriMode(flags)) {
+ StrictMode.onContentUriWithoutPermission(this, location);
+ }
+ }
+
+ /**
* Test if this is a path prefix match against the given Uri. Verifies that
* scheme, authority, and atomic path segments match.
*
diff --git a/core/java/android/os/IProxyFileDescriptorCallback.java b/core/java/android/os/IProxyFileDescriptorCallback.java
new file mode 100644
index 0000000..e41e194
--- /dev/null
+++ b/core/java/android/os/IProxyFileDescriptorCallback.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.system.ErrnoException;
+
+/**
+ * Callback that handles file system requests from ProxyFileDescriptor.
+ * @hide
+ */
+public interface IProxyFileDescriptorCallback {
+ /**
+ * Returns size of bytes provided by the file descriptor.
+ * @return Size of bytes
+ * @throws ErrnoException
+ */
+ long onGetSize() throws ErrnoException;
+
+ /**
+ * Provides bytes read from file descriptor.
+ * It needs to return exact requested size of bytes unless it reaches file end.
+ * @param offset Where to read bytes from.
+ * @param size Size for read bytes.
+ * @param data Byte array to store read bytes.
+ * @return Size of bytes returned by the function.
+ * @throws ErrnoException
+ */
+ int onRead(long offset, int size, byte[] data) throws ErrnoException;
+
+ /**
+ * Handles bytes written to file descriptor.
+ * @param offset Where to write bytes to.
+ * @param size Size for write bytes.
+ * @param data Byte array to be written to somewhere.
+ * @return Size of bytes processed by the function.
+ * @throws ErrnoException
+ */
+ int onWrite(long offset, int size, byte[] data) throws ErrnoException;
+
+ /**
+ * Processes fsync request.
+ * @throws ErrnoException
+ */
+ void onFsync() throws ErrnoException;
+}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ef79b66..f2519be 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -1800,6 +1800,13 @@
/**
* @hide
*/
+ public static boolean vmContentUriWithoutPermissionEnabled() {
+ return (sVmPolicyMask & DETECT_VM_FILE_URI_EXPOSURE) != 0;
+ }
+
+ /**
+ * @hide
+ */
public static boolean vmCleartextNetworkEnabled() {
return (sVmPolicyMask & DETECT_VM_CLEARTEXT_NETWORK) != 0;
}
@@ -1847,6 +1854,16 @@
/**
* @hide
*/
+ public static void onContentUriWithoutPermission(Uri uri, String location) {
+ final String message = uri + " exposed beyond app through " + location
+ + " without permission grant flags; did you forget"
+ + " FLAG_GRANT_READ_URI_PERMISSION?";
+ onVmPolicyViolation(null, new Throwable(message));
+ }
+
+ /**
+ * @hide
+ */
public static void onCleartextNetworkDetected(byte[] firstPacket) {
byte[] rawAddr = null;
if (firstPacket != null) {
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 98cbce6..27c0526 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -288,4 +288,5 @@
ParcelFileDescriptor mountAppFuse(in String name) = 69;
void addUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 70;
void fixateNewestUserKeyAuth(int userId) = 71;
-}
\ No newline at end of file
+ void fstrim(int flags) = 72;
+}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 0472e02..3fc7dba 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -134,6 +134,11 @@
/** {@hide} */
public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10;
+ /** {@hide} */
+ public static final int FSTRIM_FLAG_DEEP = 1 << 0;
+ /** {@hide} */
+ public static final int FSTRIM_FLAG_BENCHMARK = 1 << 1;
+
/** @hide The volume is not encrypted. */
public static final int ENCRYPTION_STATE_NONE = 1;
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index dfb6b86..b0b2065 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -349,7 +349,8 @@
if (mContext == null) {
try {
ApplicationInfo ai = context.getPackageManager()
- .getApplicationInfo(pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
+ .getApplicationInfoAsUser(pkg, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ getUserId());
mContext = context.createApplicationContext(ai,
Context.CONTEXT_RESTRICTED);
} catch (PackageManager.NameNotFoundException e) {
diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
index 0f92ed0..cb021bc 100644
--- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java
+++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
@@ -68,6 +68,7 @@
@Retention(RetentionPolicy.SOURCE)
public @interface FlashLockState {}
+ /** @hide */
public PersistentDataBlockManager(IPersistentDataBlockService service) {
sService = service;
}
@@ -79,6 +80,9 @@
* Returns the number of bytes written or -1 on error. If the block is too big
* to fit on the partition, returns -MAX_BLOCK_SIZE.
*
+ * {@link #wipe} will block any further {@link #write} operation until reboot,
+ * in which case -1 will be returned.
+ *
* @param data the data to write
*/
public int write(byte[] data) {
@@ -129,6 +133,8 @@
/**
* Zeroes the previously written block in its entirety. Calling this method
* will erase all data written to the persistent data partition.
+ * It will also prevent any further {@link #write} operation until reboot,
+ * in order to prevent a potential race condition. See b/30352311.
*/
public void wipe() {
try {
diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java
index eec5555..924437a 100644
--- a/core/java/android/view/animation/PathInterpolator.java
+++ b/core/java/android/view/animation/PathInterpolator.java
@@ -25,6 +25,9 @@
import android.view.InflateException;
import com.android.internal.R;
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
/**
* An interpolator that can traverse a Path that extends from <code>Point</code>
@@ -42,7 +45,8 @@
* path.lineTo(1f, 1f);
* </pre></blockquote></p>
*/
-public class PathInterpolator extends BaseInterpolator {
+@HasNativeInterpolator
+public class PathInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
// This governs how accurate the approximation of the Path is.
private static final float PRECISION = 0.002f;
@@ -229,4 +233,11 @@
float endY = mY[endIndex];
return startY + (fraction * (endY - startY));
}
+
+ /** @hide **/
+ @Override
+ public long createNativeInterpolator() {
+ return NativeInterpolatorFactoryHelper.createPathInterpolator(mX, mY);
+ }
+
}
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java
index c206974..e0d589a 100644
--- a/core/java/android/webkit/WebViewZygote.java
+++ b/core/java/android/webkit/WebViewZygote.java
@@ -53,6 +53,10 @@
return sPackage.packageName;
}
+ public static boolean isMultiprocessEnabled() {
+ return sMultiprocessEnabled && sPackage != null;
+ }
+
public static void setMultiprocessEnabled(boolean enabled) {
sMultiprocessEnabled = enabled;
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index a3134b3b..98d87d3 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -355,7 +355,7 @@
ApplicationInfo existingInfo = null;
try {
existingInfo = context.getPackageManager().getApplicationInfo(packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
} catch (NameNotFoundException ignored) {
}
@@ -445,7 +445,7 @@
ApplicationInfo existingInfo = null;
try {
existingInfo = context.getPackageManager().getApplicationInfo(packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
} catch (NameNotFoundException ignored) {
}
diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java
new file mode 100644
index 0000000..34253ce
--- /dev/null
+++ b/core/java/com/android/internal/os/FuseAppLoop.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.IProxyFileDescriptorCallback;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.util.Log;
+import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+public class FuseAppLoop {
+ private static final String TAG = "FuseAppLoop";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ public static final int ROOT_INODE = 1;
+ private static final int MIN_INODE = 2;
+
+ private final Object mLock = new Object();
+ private final File mParent;
+
+ @GuardedBy("mLock")
+ private final SparseArray<CallbackEntry> mCallbackMap = new SparseArray<>();
+
+ @GuardedBy("mLock")
+ private boolean mActive = true;
+
+ /**
+ * Sequential number can be used as file name and inode in AppFuse.
+ * 0 is regarded as an error, 1 is mount point. So we start the number from 2.
+ */
+ @GuardedBy("mLock")
+ private int mNextInode = MIN_INODE;
+
+ private FuseAppLoop(@NonNull File parent) {
+ mParent = parent;
+ }
+
+ public static @NonNull FuseAppLoop open(
+ @NonNull File parent, @NonNull ParcelFileDescriptor fd) {
+ Preconditions.checkNotNull(parent);
+ Preconditions.checkNotNull(fd);
+ final FuseAppLoop bridge = new FuseAppLoop(parent);
+ final int rawFd = fd.detachFd();
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ bridge.native_start_loop(rawFd);
+ }
+ }, TAG).start();
+ return bridge;
+ }
+
+ public @NonNull ParcelFileDescriptor openFile(int mode, IProxyFileDescriptorCallback callback)
+ throws UnmountedException, IOException {
+ int id;
+ synchronized (mLock) {
+ if (!mActive) {
+ throw new UnmountedException();
+ }
+ if (mCallbackMap.size() >= Integer.MAX_VALUE - MIN_INODE) {
+ throw new IOException("Too many opened files.");
+ }
+ while (true) {
+ id = mNextInode;
+ mNextInode++;
+ if (mNextInode < 0) {
+ mNextInode = MIN_INODE;
+ }
+ if (mCallbackMap.get(id) == null) {
+ break;
+ }
+ }
+
+ // Register callback after we succeed to create pfd.
+ mCallbackMap.put(id, new CallbackEntry(callback));
+ }
+ try {
+ return ParcelFileDescriptor.open(new File(mParent, String.valueOf(id)), mode);
+ } catch (FileNotFoundException error) {
+ synchronized (mLock) {
+ mCallbackMap.remove(id);
+ }
+ throw error;
+ }
+ }
+
+ public @Nullable File getMountPoint() {
+ synchronized (mLock) {
+ return mActive ? mParent : null;
+ }
+ }
+
+ private CallbackEntry getCallbackEntryOrThrowLocked(long inode) throws ErrnoException {
+ final CallbackEntry entry = mCallbackMap.get(checkInode(inode));
+ if (entry != null) {
+ return entry;
+ } else {
+ throw new ErrnoException("getCallbackEntry", OsConstants.ENOENT);
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private long onGetSize(long inode) {
+ synchronized(mLock) {
+ try {
+ return getCallbackEntryOrThrowLocked(inode).callback.onGetSize();
+ } catch (ErrnoException exp) {
+ return -exp.errno;
+ }
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private int onOpen(long inode) {
+ synchronized(mLock) {
+ try {
+ final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode);
+ if (entry.opened) {
+ throw new ErrnoException("onOpen", OsConstants.EMFILE);
+ }
+ entry.opened = true;
+ // Use inode as file handle. It's OK because AppFuse does not allow to open the same
+ // file twice.
+ return (int) inode;
+ } catch (ErrnoException exp) {
+ return -exp.errno;
+ }
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private int onFsync(long inode) {
+ synchronized(mLock) {
+ try {
+ getCallbackEntryOrThrowLocked(inode).callback.onFsync();
+ return 0;
+ } catch (ErrnoException exp) {
+ return -exp.errno;
+ }
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private int onRelease(long inode) {
+ synchronized(mLock) {
+ mCallbackMap.remove(checkInode(inode));
+ if (mCallbackMap.size() == 0) {
+ mActive = false;
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private int onRead(long inode, long offset, int size, byte[] bytes) {
+ synchronized(mLock) {
+ try {
+ return getCallbackEntryOrThrowLocked(inode).callback.onRead(offset, size, bytes);
+ } catch (ErrnoException exp) {
+ return -exp.errno;
+ }
+ }
+ }
+
+ // Called by JNI.
+ @SuppressWarnings("unused")
+ private int onWrite(long inode, long offset, int size, byte[] bytes) {
+ synchronized(mLock) {
+ try {
+ return getCallbackEntryOrThrowLocked(inode).callback.onWrite(offset, size, bytes);
+ } catch (ErrnoException exp) {
+ return -exp.errno;
+ }
+ }
+ }
+
+ native boolean native_start_loop(int fd);
+
+ private static int checkInode(long inode) {
+ Preconditions.checkArgumentInRange(inode, MIN_INODE, Integer.MAX_VALUE, "checkInode");
+ return (int) inode;
+ }
+
+ public static class UnmountedException extends Exception {}
+
+ private static class CallbackEntry {
+ final IProxyFileDescriptorCallback callback;
+ boolean opened;
+ CallbackEntry(IProxyFileDescriptorCallback callback) {
+ Preconditions.checkNotNull(callback);
+ this.callback = callback;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java b/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
index 7cd75f3..ebeec40 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
+++ b/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
@@ -32,5 +32,6 @@
public static native long createDecelerateInterpolator(float factor);
public static native long createLinearInterpolator();
public static native long createOvershootInterpolator(float tension);
+ public static native long createPathInterpolator(float[] x, float[] y);
public static native long createLutInterpolator(float[] values);
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a4e9576..77934fe 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -183,6 +183,7 @@
android_content_res_Configuration.cpp \
android_animation_PropertyValuesHolder.cpp \
com_android_internal_net_NetworkStatsFactory.cpp \
+ com_android_internal_os_FuseAppLoop.cpp \
com_android_internal_os_PathClassLoaderFactory.cpp \
com_android_internal_os_Zygote.cpp \
com_android_internal_util_VirtualRefBasePtr.cpp \
@@ -201,6 +202,7 @@
$(TOP)/frameworks/base/media/jni \
$(TOP)/system/core/base/include \
$(TOP)/system/core/include \
+ $(TOP)/system/core/libappfuse/include \
$(TOP)/system/media/camera/include \
$(TOP)/system/netd/include \
external/giflib \
@@ -215,7 +217,6 @@
external/skia/src/images \
external/sqlite/dist \
external/sqlite/android \
- external/expat/lib \
external/tremor/Tremor \
external/harfbuzz_ng/src \
libcore/include \
@@ -230,18 +231,16 @@
LOCAL_SHARED_LIBRARIES := \
libmemtrack \
libandroidfw \
+ libappfuse \
libbase \
- libexpat \
libnativehelper \
liblog \
libcutils \
libutils \
libbinder \
- libnetutils \
libui \
libgui \
libinput \
- libinputflinger \
libcamera_client \
libcamera_metadata \
libskia \
@@ -254,18 +253,13 @@
libhardware \
libhardware_legacy \
libselinux \
- libsonivox \
- libcrypto \
- libssl \
libicuuc \
- libicui18n \
libmedia \
libaudioclient \
libjpeg \
libusbhost \
libharfbuzz_ng \
libz \
- libaudioutils \
libpdfium \
libimg_utils \
libnetd_client \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index cdaa4dc..1f810ac 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -201,6 +201,7 @@
extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
extern int register_com_android_internal_content_NativeLibraryHelper(JNIEnv *env);
extern int register_com_android_internal_net_NetworkStatsFactory(JNIEnv *env);
+extern int register_com_android_internal_os_FuseAppLoop(JNIEnv* env);
extern int register_com_android_internal_os_PathClassLoaderFactory(JNIEnv* env);
extern int register_com_android_internal_os_Zygote(JNIEnv *env);
extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
@@ -1419,7 +1420,7 @@
REG_JNI(register_android_animation_PropertyValuesHolder),
REG_JNI(register_com_android_internal_content_NativeLibraryHelper),
REG_JNI(register_com_android_internal_net_NetworkStatsFactory),
-
+ REG_JNI(register_com_android_internal_os_FuseAppLoop),
};
/*
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 173afd8..3219d59 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -16,16 +16,14 @@
#include <fcntl.h>
+#include <log/log_event_list.h>
+
#include "JNIHelp.h"
#include "core_jni_helpers.h"
#include "jni.h"
-#include <log/logger.h>
#define UNUSED __attribute__((__unused__))
-// The size of the tag number comes out of the payload size.
-#define MAX_EVENT_PAYLOAD (LOGGER_ENTRY_MAX_PAYLOAD - sizeof(int32_t))
-
namespace android {
static jclass gCollectionClass;
@@ -53,7 +51,9 @@
jobject clazz UNUSED,
jint tag, jint value)
{
- return android_btWriteLog(tag, EVENT_TYPE_INT, &value, sizeof(value));
+ android_log_event_list ctx(tag);
+ ctx << (int32_t)value;
+ return ctx.write();
}
/*
@@ -64,7 +64,9 @@
jobject clazz UNUSED,
jint tag, jlong value)
{
- return android_btWriteLog(tag, EVENT_TYPE_LONG, &value, sizeof(value));
+ android_log_event_list ctx(tag);
+ ctx << (int64_t)value;
+ return ctx.write();
}
/*
@@ -75,7 +77,9 @@
jobject clazz UNUSED,
jint tag, jfloat value)
{
- return android_btWriteLog(tag, EVENT_TYPE_FLOAT, &value, sizeof(value));
+ android_log_event_list ctx(tag);
+ ctx << (float)value;
+ return ctx.write();
}
/*
@@ -85,22 +89,17 @@
static jint android_util_EventLog_writeEvent_String(JNIEnv* env,
jobject clazz UNUSED,
jint tag, jstring value) {
- uint8_t buf[MAX_EVENT_PAYLOAD];
-
+ android_log_event_list ctx(tag);
// Don't throw NPE -- I feel like it's sort of mean for a logging function
// to be all crashy if you pass in NULL -- but make the NULL value explicit.
- const char *str = value != NULL ? env->GetStringUTFChars(value, NULL) : "NULL";
- uint32_t len = strlen(str);
- size_t max = sizeof(buf) - sizeof(len) - 2; // Type byte, final newline
- if (len > max) len = max;
-
- buf[0] = EVENT_TYPE_STRING;
- memcpy(&buf[1], &len, sizeof(len));
- memcpy(&buf[1 + sizeof(len)], str, len);
- buf[1 + sizeof(len) + len] = '\n';
-
- if (value != NULL) env->ReleaseStringUTFChars(value, str);
- return android_bWriteLog(tag, buf, 2 + sizeof(len) + len);
+ if (value != NULL) {
+ const char *str = env->GetStringUTFChars(value, NULL);
+ ctx << str;
+ env->ReleaseStringUTFChars(value, str);
+ } else {
+ ctx << "NULL";
+ }
+ return ctx.write();
}
/*
@@ -109,45 +108,29 @@
*/
static jint android_util_EventLog_writeEvent_Array(JNIEnv* env, jobject clazz,
jint tag, jobjectArray value) {
- if (value == NULL) {
- return android_util_EventLog_writeEvent_String(env, clazz, tag, NULL);
- }
+ android_log_event_list ctx(tag);
- uint8_t buf[MAX_EVENT_PAYLOAD];
- const size_t max = sizeof(buf) - 1; // leave room for final newline
- size_t pos = 2; // Save room for type tag & array count
+ if (value == NULL) {
+ ctx << "[NULL]";
+ return ctx.write();
+ }
jsize copied = 0, num = env->GetArrayLength(value);
for (; copied < num && copied < 255; ++copied) {
+ if (ctx.status()) break;
jobject item = env->GetObjectArrayElement(value, copied);
- if (item == NULL || env->IsInstanceOf(item, gStringClass)) {
- if (pos + 1 + sizeof(jint) > max) break;
- const char *str = item != NULL ? env->GetStringUTFChars((jstring) item, NULL) : "NULL";
- jint len = strlen(str);
- if (pos + 1 + sizeof(len) + len > max) len = max - pos - 1 - sizeof(len);
- buf[pos++] = EVENT_TYPE_STRING;
- memcpy(&buf[pos], &len, sizeof(len));
- memcpy(&buf[pos + sizeof(len)], str, len);
- pos += sizeof(len) + len;
- if (item != NULL) env->ReleaseStringUTFChars((jstring) item, str);
+ if (item == NULL) {
+ ctx << "NULL";
+ } else if (env->IsInstanceOf(item, gStringClass)) {
+ const char *str = env->GetStringUTFChars((jstring) item, NULL);
+ ctx << str;
+ env->ReleaseStringUTFChars((jstring) item, str);
} else if (env->IsInstanceOf(item, gIntegerClass)) {
- jint intVal = env->GetIntField(item, gIntegerValueID);
- if (pos + 1 + sizeof(intVal) > max) break;
- buf[pos++] = EVENT_TYPE_INT;
- memcpy(&buf[pos], &intVal, sizeof(intVal));
- pos += sizeof(intVal);
+ ctx << (int32_t)env->GetIntField(item, gIntegerValueID);
} else if (env->IsInstanceOf(item, gLongClass)) {
- jlong longVal = env->GetLongField(item, gLongValueID);
- if (pos + 1 + sizeof(longVal) > max) break;
- buf[pos++] = EVENT_TYPE_LONG;
- memcpy(&buf[pos], &longVal, sizeof(longVal));
- pos += sizeof(longVal);
+ ctx << (int64_t)env->GetLongField(item, gLongValueID);
} else if (env->IsInstanceOf(item, gFloatClass)) {
- jfloat floatVal = env->GetFloatField(item, gFloatValueID);
- if (pos + 1 + sizeof(floatVal) > max) break;
- buf[pos++] = EVENT_TYPE_FLOAT;
- memcpy(&buf[pos], &floatVal, sizeof(floatVal));
- pos += sizeof(floatVal);
+ ctx << (float)env->GetFloatField(item, gFloatValueID);
} else {
jniThrowException(env,
"java/lang/IllegalArgumentException",
@@ -156,11 +139,7 @@
}
env->DeleteLocalRef(item);
}
-
- buf[0] = EVENT_TYPE_LIST;
- buf[1] = copied;
- buf[pos++] = '\n';
- return android_bWriteLog(tag, buf, pos);
+ return ctx.write();
}
/*
diff --git a/core/jni/com_android_internal_os_FuseAppLoop.cpp b/core/jni/com_android_internal_os_FuseAppLoop.cpp
new file mode 100644
index 0000000..92a6934
--- /dev/null
+++ b/core/jni/com_android_internal_os_FuseAppLoop.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FuseAppLoopJNI"
+#define LOG_NDEBUG 0
+
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#include <android_runtime/Log.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <jni.h>
+#include <libappfuse/FuseAppLoop.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "core_jni_helpers.h"
+
+namespace android {
+
+namespace {
+
+constexpr const char* CLASS_NAME = "com/android/internal/os/FuseAppLoop";
+
+jclass gFuseAppLoopClass;
+jmethodID gOnGetSizeMethod;
+jmethodID gOnOpenMethod;
+jmethodID gOnFsyncMethod;
+jmethodID gOnReleaseMethod;
+jmethodID gOnReadMethod;
+jmethodID gOnWriteMethod;
+
+class Callback : public fuse::FuseAppLoopCallback {
+private:
+ static constexpr size_t kBufferSize = std::max(fuse::kFuseMaxWrite, fuse::kFuseMaxRead);
+ static_assert(kBufferSize <= INT32_MAX, "kBufferSize should be fit in int32_t.");
+
+ JNIEnv* const mEnv;
+ jobject const mSelf;
+ ScopedLocalRef<jbyteArray> mJniBuffer;
+ bool mActive;
+
+ template <typename T>
+ T checkException(T result) const {
+ if (mEnv->ExceptionCheck()) {
+ LOGE_EX(mEnv, nullptr);
+ mEnv->ExceptionClear();
+ return -EIO;
+ }
+ return result;
+ }
+
+public:
+ Callback(JNIEnv* env, jobject self) :
+ mEnv(env),
+ mSelf(self),
+ mJniBuffer(env, nullptr),
+ mActive(true) {}
+
+ bool Init() {
+ mJniBuffer.reset(mEnv->NewByteArray(kBufferSize));
+ return mJniBuffer.get();
+ }
+
+ bool IsActive() override {
+ return mActive;
+ }
+
+ int64_t OnGetSize(uint64_t inode) override {
+ return checkException(mEnv->CallLongMethod(mSelf, gOnGetSizeMethod, inode));
+ }
+
+ int32_t OnOpen(uint64_t inode) override {
+ return checkException(mEnv->CallIntMethod(mSelf, gOnOpenMethod, inode));
+ }
+
+ int32_t OnFsync(uint64_t inode) override {
+ return checkException(mEnv->CallIntMethod(mSelf, gOnFsyncMethod, inode));
+ }
+
+ int32_t OnRelease(uint64_t inode) override {
+ if (checkException(mEnv->CallIntMethod(mSelf, gOnReleaseMethod, inode)) == -1) {
+ mActive = false;
+ }
+ return fuse::kFuseSuccess;
+ }
+
+ int32_t OnRead(uint64_t inode, uint64_t offset, uint32_t size, void* buffer) override {
+ CHECK_LE(size, static_cast<uint32_t>(kBufferSize));
+ const int32_t result = checkException(mEnv->CallIntMethod(
+ mSelf, gOnReadMethod, inode, offset, size, mJniBuffer.get()));
+ if (result <= 0) {
+ return result;
+ }
+ if (result > static_cast<int32_t>(size)) {
+ LOG(ERROR) << "Returned size is too large.";
+ return -EIO;
+ }
+
+ mEnv->GetByteArrayRegion(mJniBuffer.get(), 0, result, static_cast<jbyte*>(buffer));
+ CHECK(!mEnv->ExceptionCheck());
+
+ return checkException(result);
+ }
+
+ int32_t OnWrite(uint64_t inode, uint64_t offset, uint32_t size, const void* buffer) override {
+ CHECK_LE(size, static_cast<uint32_t>(kBufferSize));
+
+ mEnv->SetByteArrayRegion(mJniBuffer.get(), 0, size, static_cast<const jbyte*>(buffer));
+ CHECK(!mEnv->ExceptionCheck());
+
+ return checkException(mEnv->CallIntMethod(
+ mSelf, gOnWriteMethod, inode, offset, size, mJniBuffer.get()));
+ }
+};
+
+jboolean com_android_internal_os_FuseAppLoop_start_loop(JNIEnv* env, jobject self, jint jfd) {
+ base::unique_fd fd(jfd);
+ Callback callback(env, self);
+
+ if (!callback.Init()) {
+ LOG(ERROR) << "Failed to init callback";
+ return JNI_FALSE;
+ }
+
+ return fuse::StartFuseAppLoop(fd.release(), &callback);
+}
+
+const JNINativeMethod methods[] = {
+ {
+ "native_start_loop",
+ "(I)Z",
+ (void *) com_android_internal_os_FuseAppLoop_start_loop
+ }
+};
+
+} // namespace
+
+int register_com_android_internal_os_FuseAppLoop(JNIEnv* env) {
+ gFuseAppLoopClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, CLASS_NAME));
+ gOnGetSizeMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onGetSize", "(J)J");
+ gOnOpenMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onOpen", "(J)I");
+ gOnFsyncMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onFsync", "(J)I");
+ gOnReleaseMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRelease", "(J)I");
+ gOnReadMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onRead", "(JJI[B)I");
+ gOnWriteMethod = GetMethodIDOrDie(env, gFuseAppLoopClass, "onWrite", "(JJI[B)I");
+ RegisterMethodsOrDie(env, CLASS_NAME, methods, NELEM(methods));
+ return 0;
+}
+
+} // namespace android
diff --git a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp b/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
index 6781e13..f4d2e7b 100644
--- a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
+++ b/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
@@ -18,6 +18,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
+#include <cutils/log.h>
#include "core_jni_helpers.h"
#include <Interpolator.h>
@@ -62,6 +63,19 @@
return reinterpret_cast<jlong>(new OvershootInterpolator(tension));
}
+static jlong createPathInterpolator(JNIEnv* env, jobject clazz, jfloatArray jX, jfloatArray jY) {
+ jsize lenX = env->GetArrayLength(jX);
+ jsize lenY = env->GetArrayLength(jY);
+ LOG_ALWAYS_FATAL_IF(lenX != lenY || lenX <= 0, "Invalid path interpolator, x size: %d,"
+ " y size: %d", lenX, lenY);
+ std::vector<float> x(lenX);
+ std::vector<float> y(lenY);
+ env->GetFloatArrayRegion(jX, 0, lenX, x.data());
+ env->GetFloatArrayRegion(jY, 0, lenX, y.data());
+
+ return reinterpret_cast<jlong>(new PathInterpolator(std::move(x), std::move(y)));
+}
+
static jlong createLutInterpolator(JNIEnv* env, jobject clazz, jfloatArray jlut) {
jsize len = env->GetArrayLength(jlut);
if (len <= 0) {
@@ -88,6 +102,7 @@
{ "createDecelerateInterpolator", "(F)J", (void*) createDecelerateInterpolator },
{ "createLinearInterpolator", "()J", (void*) createLinearInterpolator },
{ "createOvershootInterpolator", "(F)J", (void*) createOvershootInterpolator },
+ { "createPathInterpolator", "([F[F)J", (void*) createPathInterpolator },
{ "createLutInterpolator", "([F)J", (void*) createLutInterpolator },
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 94f7bec..62ff85d 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -182,6 +182,10 @@
android:name="android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS" />
<protected-broadcast
android:name="android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED" />
+ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY" />
+ <protected-broadcast android:name="android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY" />
<protected-broadcast
android:name="com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT" />
<protected-broadcast
@@ -189,6 +193,7 @@
<protected-broadcast
android:name="android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.pbap.intent.action.PBAP_STATE_CHANGED" />
+ <protected-broadcast android:name="android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED" />
<protected-broadcast android:name="android.btopp.intent.action.INCOMING_FILE_NOTIFICATION" />
<protected-broadcast android:name="android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT" />
@@ -769,6 +774,15 @@
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readPhoneState"
android:description="@string/permdesc_readPhoneState"
+ android:protectionLevel="dangerous" />
+
+ <!-- Allows read access to the device's phone number. This is a subset of the capabilities
+ granted by {@link #READ_PHONE_STATE} but is exposed to ephemeral applications.
+ <p>Protection level: dangerous-->
+ <permission android:name="android.permission.READ_PHONE_NUMBER"
+ android:permissionGroup="android.permission-group.PHONE"
+ android:label="@string/permlab_readPhoneNumber"
+ android:description="@string/permdesc_readPhoneNumber"
android:protectionLevel="dangerous|ephemeral" />
<!-- Allows an application to initiate a phone call without going through
diff --git a/core/res/res/anim/slide_out_micro.xml b/core/res/res/anim/slide_out_micro.xml
index 7532ee3..cccf697 100644
--- a/core/res/res/anim/slide_out_micro.xml
+++ b/core/res/res/anim/slide_out_micro.xml
@@ -19,7 +19,7 @@
-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:zAdjustment="top">
+ android:zAdjustment="normal">
<translate android:fromXDelta="0" android:toXDelta="5%p"
android:duration="250"
android:interpolator="@android:interpolator/fast_out_slow_in"/>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index b2212f9..a24bce1 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Kennisgewing-volume"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Verstekluitoon"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Verstek (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Luitone"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Wekkerklanke"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Kennisgewingsklanke"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Onbekend"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi netwerke beskikbaar</item>
<item quantity="one">Wi-Fi-netwerk beskikbaar</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Kies jaar"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> uitgevee"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Raak en hou Terug om hierdie skerm te ontspeld."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Program is vasgespeld: Dit mag nie op hierdie toestel ontspeld word nie."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skerm vasgespeld"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Stel nou terug"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Het <xliff:g id="LABEL">%1$s</xliff:g> gedeaktiveer"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferensie-oproep"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Nutswenk-opspringer"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 2b92730..6bab82c 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"የማህደረ መረጃ ክፍልፍል"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"የማሳወቂያ ክፍልፍል"</string>
<string name="ringtone_default" msgid="3789758980357696936">"ነባሪ የስልክ ላይ ጥሪ"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"ነባሪ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"ምንም"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"ጥሪ ድምፆች"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"የማንቂያ ድምጾች"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"የማሳወቂያ ድምፆች"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"ያልታወቀ"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">የWi-Fi አውታረ መረቦች አሉ</item>
<item quantity="other">የWi-Fi አውታረ መረቦች አሉ</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"ዓመት ይምረጡ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ተሰርዟል"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ይህን ማያ ገጽ ለመንቀል ተመለስን ይንኩትና ያዙት።"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"መተግበሪያ ተሰክቷል፦ በዚህ መሣሪያ ላይ ማላቀቅ አይፈቀድም።"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ማያ ገጽ ተሰክቷል"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"አሁን ዳግም አስጀምር"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ተሰናክሏል"</string>
<string name="conference_call" msgid="3751093130790472426">"የስብሰባ ጥሪ"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"የመሣሪያ ጥቆማ ብቅ-ባይ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b2835cc..7c9baeb 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1151,16 +1151,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"مستوى صوت الوسائط"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"مستوى صوت الإشعار"</string>
<string name="ringtone_default" msgid="3789758980357696936">"نغمة الرنين الافتراضية"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"الافتراضية (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"لا شيء"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"نغمات الرنين"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"أصوات التنبيه"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"أصوات الإشعار"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"غير معروف"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="zero">لا تتوفر أية شبكات Wi-Fi</item>
<item quantity="two">تتوفر شبكتا Wi-Fi</item>
@@ -1672,6 +1668,10 @@
<string name="select_year" msgid="7952052866994196170">"تحديد العام"</string>
<string name="deleted_key" msgid="7659477886625566590">"تم حذف <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> المخصص للعمل"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"لإزالة تثبيت هذه الشاشة، يمكنك لمس زر الرجوع مع الاستمرار."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"التطبيق مقيد: ولا يسمح بإلغاء التقييد على هذا الجهاز."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"تم تثبيت الشاشة"</string>
@@ -1827,6 +1827,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"إعادة التعيين الآن"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"تم تعطيل <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"مكالمة جماعية"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"نافذة منبثقة لتلميح"</string>
</resources>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 5d09077..11133d1 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Media həcmi"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildiriş səsi"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Defolt rinqton"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Defolt (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Heç biri"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Zəng səsləri"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zəngli saat səsləri"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Bildiriş səsləri"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Naməlum"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Əlçatan Wi-Fi şəbəkələri</item>
<item quantity="one">Əlçatan Wi-Fi şəbəkəsi</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"İl seçin"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"İş <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Sancağı götürmək üçün Geri düyməsinə toxunun və saxlayın."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Tətbiq sancılıb: Açmağa bu cihazda icazə verilmir."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"İndi sıfırlayın"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> deaktiv edildi"</string>
<string name="conference_call" msgid="3751093130790472426">"Konfrans Zəngi"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Tooltip Popap"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index b65ed4d..d2799c4 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1082,16 +1082,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka medija"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka obaveštenja"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Podrazumevani zvuk zvona"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Podrazumevano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Zvukovi zvona"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obaveštenja"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi mreže su dostupne</item>
<item quantity="few">Wi-Fi mreže su dostupne</item>
@@ -1591,6 +1587,10 @@
<string name="select_year" msgid="7952052866994196170">"Izaberite godinu"</string>
<string name="deleted_key" msgid="7659477886625566590">"Izbrisali ste <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> na poslu"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Da biste otkačili ovaj ekran, dodirnite i zadržite Nazad."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je zakačena: otkačinjanje nije dozvoljeno na ovom uređaju."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
@@ -1719,6 +1719,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetuj"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Vidžet <xliff:g id="LABEL">%1$s</xliff:g> je onemogućen"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferencijski poziv"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Iskačuće objašnjenje"</string>
</resources>
diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml
index 63359a1..a7be24e 100644
--- a/core/res/res/values-be-rBY/strings.xml
+++ b/core/res/res/values-be-rBY/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Гучнасць прайгравальніка"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучнасць апавяшчэнняў"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Стандартны рынгтон"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Стандартны (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Няма"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Рынгтоны"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Гукі будзільніка"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Гукі апавяшчэнняў"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Невядома"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">сетка Wi-Fi даступная</item>
<item quantity="few">сеткі Wi-Fi даступныя</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Выберыце год"</string>
<string name="deleted_key" msgid="7659477886625566590">"Выдалена: <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (праца)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Каб адмацаваць гэты экран, дакраніцеся і ўтрымлівайце кнопку \"Назад\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Праграма замацавана: адмацаванне на гэтай прыладзе не дапускаецца."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран замацаваны"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Выканаць скід"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Адключаны <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Канферэнц-выклік"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Усплывальная падказка"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index a818b7e..1900b074 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Сила на звука"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Сила на звука при известие"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Стандартна мелодия"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"По подразбиране (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Без"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Звуци на будилника"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Звуци на известията"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Няма информация"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Има достъпни Wi-Fi мрежи</item>
<item quantity="one">Има достъпна Wi-Fi мрежа</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Избиране на година"</string>
<string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> за работа"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"За да освободите този екран, докоснете и задръжте бутона за връщане назад."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Приложението е фиксирано. Освобождаването му не е разрешено на това устройство."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екранът е фиксиран"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Нулиране сега"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>: Деактивирано"</string>
<string name="conference_call" msgid="3751093130790472426">"Конферентно обаждане"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Изскачащ прозорец с подсказка"</string>
</resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 20343af..bdbea68 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"বছর নির্বাচন করুন"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"কর্মক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"এই স্ক্রীনটিকে আনপিন করতে, \'ফিরুন\' স্পর্শ করুন এবং ধরে রাখুন৷"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"অ্যাপ্লিকেশান পিন করা আছে: এই ডিভাইস এটিকে পিনমুক্ত করা মঞ্জুরিপ্রাপ্ত নয়৷"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রীন পিন করা হয়েছে"</string>
diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml
index 205bffb..f62dac7 100644
--- a/core/res/res/values-bs-rBA/strings.xml
+++ b/core/res/res/values-bs-rBA/strings.xml
@@ -551,35 +551,35 @@
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Kuća"</item>
<item msgid="869923650527136615">"Mobilni"</item>
- <item msgid="7897544654242874543">"Poslovni"</item>
+ <item msgid="7897544654242874543">"Posao"</item>
<item msgid="1103601433382158155">"Poslovni faks"</item>
<item msgid="1735177144948329370">"Kućni faks"</item>
<item msgid="603878674477207394">"Pejdžer"</item>
<item msgid="1650824275177931637">"Ostalo"</item>
- <item msgid="9192514806975898961">"Dodatno"</item>
+ <item msgid="9192514806975898961">"Prilagođeno"</item>
</string-array>
<string-array name="emailAddressTypes">
<item msgid="8073994352956129127">"Kućni"</item>
- <item msgid="7084237356602625604">"Poslovni"</item>
- <item msgid="1112044410659011023">"Ostali"</item>
- <item msgid="2374913952870110618">"Dodatni"</item>
+ <item msgid="7084237356602625604">"Posao"</item>
+ <item msgid="1112044410659011023">"Ostalo"</item>
+ <item msgid="2374913952870110618">"Prilagođeno"</item>
</string-array>
<string-array name="postalAddressTypes">
<item msgid="6880257626740047286">"Kuća"</item>
<item msgid="5629153956045109251">"Posao"</item>
<item msgid="4966604264500343469">"Ostalo"</item>
- <item msgid="4932682847595299369">"Dodatno"</item>
+ <item msgid="4932682847595299369">"Prilagođeno"</item>
</string-array>
<string-array name="imAddressTypes">
<item msgid="1738585194601476694">"Kućni"</item>
- <item msgid="1359644565647383708">"Poslovni"</item>
- <item msgid="7868549401053615677">"Ostali"</item>
- <item msgid="3145118944639869809">"Dodatni"</item>
+ <item msgid="1359644565647383708">"Posao"</item>
+ <item msgid="7868549401053615677">"Ostalo"</item>
+ <item msgid="3145118944639869809">"Prilagođeno"</item>
</string-array>
<string-array name="organizationTypes">
<item msgid="7546335612189115615">"Posao"</item>
<item msgid="4378074129049520373">"Ostalo"</item>
- <item msgid="3455047468583965104">"Dodatno"</item>
+ <item msgid="3455047468583965104">"Prilagođeno"</item>
</string-array>
<string-array name="imProtocols">
<item msgid="8595261363518459565">"AIM"</item>
@@ -600,15 +600,15 @@
<string name="phoneTypePager" msgid="7582359955394921732">"Pejdžer"</string>
<string name="phoneTypeOther" msgid="1544425847868765990">"Ostalo"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"Povratni poziv"</string>
- <string name="phoneTypeCar" msgid="8738360689616716982">"Auto"</string>
- <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Glavni broj kompanije"</string>
+ <string name="phoneTypeCar" msgid="8738360689616716982">"Automobil"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Poslovni glavni"</string>
<string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
<string name="phoneTypeMain" msgid="6766137010628326916">"Glavni"</string>
<string name="phoneTypeOtherFax" msgid="8587657145072446565">"Drugi faks"</string>
<string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Teleks"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
- <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Posao mobilni"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Poslovni mobilni"</string>
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Poslovni pejdžer"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Pomoćnik"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
@@ -616,10 +616,10 @@
<string name="eventTypeBirthday" msgid="2813379844211390740">"Rođendan"</string>
<string name="eventTypeAnniversary" msgid="3876779744518284000">"Godišnjica"</string>
<string name="eventTypeOther" msgid="7388178939010143077">"Ostalo"</string>
- <string name="emailTypeCustom" msgid="8525960257804213846">"Prilagođeni"</string>
+ <string name="emailTypeCustom" msgid="8525960257804213846">"Prilagođeno"</string>
<string name="emailTypeHome" msgid="449227236140433919">"Kućni"</string>
- <string name="emailTypeWork" msgid="3548058059601149973">"Poslovni"</string>
- <string name="emailTypeOther" msgid="2923008695272639549">"Ostali"</string>
+ <string name="emailTypeWork" msgid="3548058059601149973">"Posao"</string>
+ <string name="emailTypeOther" msgid="2923008695272639549">"Ostalo"</string>
<string name="emailTypeMobile" msgid="119919005321166205">"Mobilni"</string>
<string name="postalTypeCustom" msgid="8903206903060479902">"Prilagođeno"</string>
<string name="postalTypeHome" msgid="8165756977184483097">"Kućna adresa"</string>
@@ -1084,16 +1084,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Jačina zvuka za medijske sadržaje"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Jačina zvuka za obavještenja"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Zadano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Bez zvuka"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuci alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuci obavještenja"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi mreže su dostupne</item>
<item quantity="few">Wi-Fi mreže su dostupne</item>
@@ -1593,6 +1589,10 @@
<string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
<string name="deleted_key" msgid="7659477886625566590">"Broj <xliff:g id="KEY">%1$s</xliff:g> je izbrisan"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Poslovni <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Da biste otkačili ovaj ekran, dodirnite i držite dugme Nazad."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikačena. Na ovom uređaju nije dozvoljeno otkačivanje."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran je zakačen"</string>
@@ -1721,6 +1721,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Vrati sada na početne postavke"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Onemogućen <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferencijski poziv"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Iskočni prozor sa savjetom u vezi alata"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a1797cb..f335d44 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volum de multimèdia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volum de notificació"</string>
<string name="ringtone_default" msgid="3789758980357696936">"So predeterminat"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predeterminat (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Cap"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Sons"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons de l\'alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificació"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconegut"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Xarxes Wi-Fi disponibles</item>
<item quantity="one">Xarxa Wi-Fi disponible</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Selecciona un any"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> suprimit"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Toca i mantén premuda l\'opció Enrere per deixar de fixar aquesta pantalla."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"S\'ha fixat l\'aplicació. En aquest dispositiu no es permet anul·lar-ne la fixació."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restableix ara"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> s\'ha desactivat"</string>
<string name="conference_call" msgid="3751093130790472426">"Conferència"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Descripció emergent"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 2c8f843..0bdd212 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitost médií"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitost oznámení"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Výchozí vyzváněcí tón"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Výchozí (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Žádný"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuky budíku"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuky upozornění"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Neznámé"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="few">K dispozici jsou sítě Wi-Fi</item>
<item quantity="many">K dispozici jsou sítě Wi-Fi</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
<string name="deleted_key" msgid="7659477886625566590">"Číslice <xliff:g id="KEY">%1$s</xliff:g> byla smazána"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Pracovní <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Chcete-li tuto obrazovku uvolnit, klepněte na tlačítko Zpět a podržte jej."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikace je připnutá: Odepnutí v tomto zařízení není povoleno."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Obrazovka připnuta"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetovat"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – zakázáno"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferenční hovor"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Vyskakovací okno s popiskem"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 20b859c..f80f5f0 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Vælg år"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> – arbejde"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Hvis du vil frigøre dette skærmbillede, skal du trykke på Tilbage og holde fingeren nede."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen er fastgjort: Det er ikke tilladt at frigøre den på denne enhed."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skærmen blev fastgjort"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index fcad7c2..1ceb0cc 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Jahr auswählen"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> gelöscht"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Um die Fixierung dieses Bildschirms aufzuheben, \"Zurück\" berühren und halten."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Die App ist fixiert. Das Aufheben der Fixierung ist auf diesem Gerät nicht zulässig."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Bildschirm fixiert"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 2117233..b9d9503 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Ένταση ήχου πολυμέσων"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Ένταση ήχου ειδοποιήσεων"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Προεπιλεγμένος ήχος κλήσης"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Προεπιλογή (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Κανένας"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ήχοι κλήσης"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Ήχοι ξυπνητηριού"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Ήχοι ειδοποίησης"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Άγνωστο"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Υπάρχουν διαθέσιμα δίκτυα Wi-Fi</item>
<item quantity="one">Υπάρχει διαθέσιμο δίκτυο Wi-Fi</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Επιλογή έτους"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> διαγράφηκε"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Εργασία <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα \"Επιστροφή\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Η εφαρμογή καρφιτσώθηκε: Το ξεκαρφίτσωμα δεν επιτρέπεται σε αυτήν τη συσκευή."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Η οθόνη καρφιτσώθηκε"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Επαναφορά τώρα"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Απενεργοποιημένο <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Κλήση συνδιάσκεψης"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Αναδυόμενο παράθυρο επεξήγησης εργαλείου"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 47be8cf..5bc43e0 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarm Sounds"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Notification Sounds"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Unknown"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi networks available</item>
<item quantity="one">Wi-Fi network available</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Tooltip Pop-up"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 47be8cf..5bc43e0 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarm Sounds"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Notification Sounds"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Unknown"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi networks available</item>
<item quantity="one">Wi-Fi network available</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Tooltip Pop-up"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 47be8cf..5bc43e0 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Media volume"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Notification volume"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Default ringtone"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"None"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtones"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarm Sounds"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Notification Sounds"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Unknown"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi networks available</item>
<item quantity="one">Wi-Fi network available</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Select year"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reset now"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Conference Call"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Tooltip Pop-up"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 50c4a67..cd2c5aa 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen de los medios"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificación"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Tono predeterminado"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos de llamada"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sonidos de la alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sonidos de notificaciones"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconocido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">redes de Wi-Fi disponibles</item>
<item quantity="one">red de Wi-Fi disponible</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para dejar de fijar esta pantalla, mantén presionado Atrás."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"La aplicación está fijada, no se puede anular la fijación en este dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fija"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer ahora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Se inhabilitó <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Conferencia"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Ventana emergente de la información sobre la herramienta"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a91fc1c..fe7d1ac 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volumen multimedia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volumen de notificaciones"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Tono por defecto"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ninguno"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tonos"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sonidos de la alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sonidos de notificaciones"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconocido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Redes Wi-Fi disponibles</item>
<item quantity="one">Red Wi-Fi disponible</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Mantén pulsado el botón Atrás para dejar de fijar esta pantalla."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"La aplicación está fijada: no se puede deshacer la fijación en este dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fijada"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer ahora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> inhabilitado"</string>
<string name="conference_call" msgid="3751093130790472426">"Conferencia"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Descripción emergente"</string>
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index dc926d4..09668cb 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -650,7 +650,7 @@
<string name="relationTypeMother" msgid="4578571352962758304">"Ema"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"Vanem"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
- <string name="relationTypeReferredBy" msgid="101573059844135524">"Viitas:"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"Soovitaja"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"Sugulane"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Õde"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Abikaasa"</string>
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Aasta valimine"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ekraani vabastamiseks puudutage pikalt nuppu Tagasi."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Rakendus on kinnitatud: vabastamine pole selles seadmes lubatud."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekraan on kinnitatud"</string>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 190d61b..2ea4bed 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Euskarriaren bolumena"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Jakinarazpenen bolumena"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Tonu lehenetsia"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Lehenetsia (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Bat ere ez"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tonuak"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarma-soinuak"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Jakinarazpen-soinuak"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Ezezaguna"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi sareak erabilgarri</item>
<item quantity="one">Wi-Fi sarea erabilgarri</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Hautatu urtea"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ezabatu da"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Laneko <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pantailari aingura kentzeko, eduki sakatuta Atzera botoia."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikazioa ainguratuta dago. Gailu honetan ezin da aingura kendu."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantaila ainguratu da"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Berrezarri"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desgaituta dago"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferentzia-deia"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Aholkudun leiho gainerakorra"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index d1d120f..55e67bc 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"انتخاب سال"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> حذف شد"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> محل کار"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"برای برداشتن پین این صفحه، «برگشت» را لمس کنید و نگه دارید."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"برنامه پین شده است: برداشتن پین در این دستگاه مجاز نیست."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"صفحه پین شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 425b235..6800fa8 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Median äänenvoimakkuus"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Ilmoituksen äänenvoimakkuus"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Oletussoittoääni"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Oletus (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ei mitään"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Soittoäänet"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Hälytysäänet"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Ilmoitusäänet"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Tuntematon"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi-verkkoja käytettävissä</item>
<item quantity="one">Wi-Fi-verkko käytettävissä</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Valitse vuosi"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (työ)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Irrota näyttö koskettamalla Takaisin-painiketta pitkään."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Sovellus on kiinnitetty. Irrottaminen ei ole sallittua tällä laitteella."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Näyttö kiinnitetty"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Palauta nyt"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ei ole käytössä."</string>
<string name="conference_call" msgid="3751093130790472426">"Puhelinneuvottelu"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Työkaluvinkki ponnahdusikkunassa"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 4ba4871..009b9eb 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Sélectionnez une année"</string>
<string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pour annuler l\'épinglage de cet écran, maintenez enfoncée la touche Retour."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'application est épinglée : l\'annulation de l\'épinglage n\'est pas autorisée sur cet appareil."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 3dc8b28..5b21dd4 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Sélectionner une année"</string>
<string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Retour\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'application est épinglée. L\'annulation de l\'épinglage n\'est pas autorisée sur cet appareil."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé."</string>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index 077f4e0..10a7647 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume dos elementos multimedia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume das notificacións"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Ton de chamada predeterminado"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predeterminado (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ningún"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tons de chamada"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons de alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificación"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Descoñecido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Redes wifi dispoñibles</item>
<item quantity="one">Rede wifi dispoñible</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Seleccionar ano"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para soltar a pantalla, mantén premido Volver."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"A aplicación está fixada: non se permite soltala neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Restablecer agora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Desactivouse <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Conferencia telefónica"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Ventá emerxente do cadro de información"</string>
</resources>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 149e466..9a7d432 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"મીડિયા વોલ્યુમ"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"સૂચના વૉલ્યૂમ"</string>
<string name="ringtone_default" msgid="3789758980357696936">"ડિફોલ્ટ રિંગટોન"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"ડિફૉલ્ટ (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"કોઈ નહીં"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"રિંગટોન્સ"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"એલાર્મ ધ્વનિઓ"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"સૂચના ધ્વનિઓ"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"અજાણી"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
<item quantity="other">Wi-Fi નેટવર્ક્સ ઉપલબ્ધ</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"વર્ષ પસંદ કરો"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> કાઢી નાખી"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"કાર્યાલય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળને ટચ કરીને પકડી રાખો."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ઍપ્લિકેશન પિન કરેલ છે. આ ઉપકરણ પર અનપિન કરવાની મંજૂરી નથી."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"સ્ક્રીન પિન કરી"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"હમણાં ફરીથી સેટ કરો"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> અક્ષમ કર્યું"</string>
<string name="conference_call" msgid="3751093130790472426">"કોન્ફરન્સ કૉલ"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"ટૂલટિપ પોપઅપ"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c006df9..c46102b 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"वर्ष चुनें"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> को हटा दिया गया"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्यस्थल का <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"इस स्क्रीन को अनपिन करने के लिए, वापस जाएं को स्पर्श करके रखें."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ऐप पिन किया गया है: इस डिवाइस पर अनपिन करने की अनुमति नहीं है."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन की गई"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 8d90eb92..fa593acd 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1082,16 +1082,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Glasnoća medija"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Glasnoća obavijesti"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Zadana melodija zvona"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Zadano (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ništa"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Melodije zvona"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvukovi alarma"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvukovi obavijesti"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Nepoznato"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Dostupne su Wi-Fi mreže</item>
<item quantity="few">Dostupne su Wi-Fi mreže</item>
@@ -1591,6 +1587,10 @@
<string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
<string name="deleted_key" msgid="7659477886625566590">"Izbrisan je broj <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Da biste otkvačili ovaj zaslon, dodirnite i zadržite Natrag."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikvačena: otkvačivanje nije dopušteno na tom uređaju."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pričvršćen"</string>
@@ -1719,6 +1719,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Vrati na zadano sada"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – onemogućeno"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferencijski poziv"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Skočni prozor opisa"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 67e1c0f..d21e47e 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Média hangereje"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Értesítés hangereje"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Alapértelmezett csengőhang"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Alapértelmezett (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Egyik sem"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Csengőhangok"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Ébresztőhangok"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Értesítőhangok"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Ismeretlen"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi hálózatok érhetők el</item>
<item quantity="one">Van elérhető Wi-Fi hálózat</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Válassza ki az évet"</string>
<string name="deleted_key" msgid="7659477886625566590">"A(z) <xliff:g id="KEY">%1$s</xliff:g> érték törölve"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza lehetőséget."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Az alkalmazás rögzítve van: a rögzítés feloldása nem engedélyezett ezen az eszközön."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Képernyő rögzítve"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Visszaállítás most"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"A(z) <xliff:g id="LABEL">%1$s</xliff:g> letiltva"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferenciahívás"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Elemleíró előugró ablak"</string>
</resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 6444b51..10072a2 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Ընտրեք տարին"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Աշխատանքային <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Այս էկրանն ապամրացնելու համար հպեք և պահեք Հետ կոճակը:"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Հավելվածն ամրացված է: Ապամրացումն այս սարքում չի թույլատրվում:"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Էկրանն ամրացված է"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 873e3ae..29d820e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume media"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume pemberitahuan"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Nada dering default"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Default (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Tidak Ada"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Nada dering"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Suara alarm"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Suara notifikasi"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Tidak diketahui"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Jaringan Wi-Fi tersedia</item>
<item quantity="one">Jaringan Wi-Fi tersedia</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dihapus"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Kantor <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Untuk melepas pin layar ini, sentuh & tahan tombol Kembali."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Pin dipasang ke aplikasi. Melepas pin tidak diizinkan di perangkat ini."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Layar disematkan"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Setel ulang sekarang"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferensi Telepon"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Munculan Keterangan Alat"</string>
</resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index 70a41be..655c521 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Hljóðstyrkur efnisspilunar"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Hljóðstyrkur tilkynninga"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Sjálfgefinn hringitónn"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Sjálfgefið (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ekkert"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Hringitónar"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Vekjarahljóð"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Tilkynningarhljóð"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Óþekkt"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi net í boði</item>
<item quantity="other">Wi-Fi net í boði</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Veldu ár"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eytt"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Til að taka lásinn af þessari skjámynd skaltu halda inni bakkhnappinum."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Forritið er fest: Ekki er hægt að losa forrit í þessu tæki."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skjár festur"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Endurstilla núna"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Slökkt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Símafundur"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Ábendingarsprettigluggi"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index b3521ff..446e367 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume contenuti multimediali"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume notifiche"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Suoneria predefinita"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predefinita (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Nessuna"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Suonerie"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Suoni delle sveglie"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Suoni di notifica"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Sconosciuta"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Reti Wi-Fi disponibili</item>
<item quantity="one">Rete Wi-Fi disponibile</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Seleziona anno"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminato"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> lavoro"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Per sbloccare questa schermata tieni premuta l\'opzione Indietro."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'app è bloccata. Su questo dispositivo non è consentito lo sblocco."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Schermata bloccata"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ripristina ora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> disattivato"</string>
<string name="conference_call" msgid="3751093130790472426">"Audioconferenza"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Popup descrizione comando"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index dd41f23..1881ae4 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1618,6 +1618,10 @@
<string name="select_year" msgid="7952052866994196170">"בחר שנה"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"עבודה <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"כדי לבטל את הצמדת המסך הזה, לחץ לחיצה ממושכת על הלחצן \'הקודם\'."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"האפליקציה מוצמדת: ביטול ההצמדה אסור במכשיר הזה."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"המסך מוצמד"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 28db181..fdfb890 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"年を選択"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"仕事の<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"この画面の固定を解除するには [戻る] を押し続けます。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"アプリは固定されています。この端末では固定を解除できません。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"画面を固定しました"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index c58803d..56f0a62 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"მედიის ხმა"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"შეტყობინების ხმა"</string>
<string name="ringtone_default" msgid="3789758980357696936">"ნაგულისხმევი ზარი"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"ნაგულისხმევი (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"არც ერთი"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"ზარები"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"მაღვიძარას ხმები"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"შეტყობინების ხმები"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"უცნობი"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">ხელმისაწვდომია Wi-Fi ქსელები</item>
<item quantity="one">ხელმისაწვდომია Wi-Fi ქსელი</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"აირჩიეთ წელი"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკს „უკან“."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"აპი მიმაგრებულია: მიმაგრების მოხსნა არ არის ნებადართული ამ მოწყობილობაზე."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ეკრანი დაფიქსირდა"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ახლავე გადაყენება"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"გათიშული <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"საკონფერენციო ზარი"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"მინიშნების კონტექსტური სარკმელი"</string>
</resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index a62cbf0..51d1dcc 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Жыл таңдау"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> жойылды"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Жұмыс <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Осы экранды босату үшін \"Артқа\" түймесін басып тұрыңыз."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Бағдарлама белгіленді: Бұл құрылғыда белгіні алуға рұқсат берілмейді."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран түйрелді"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 08cac8c..aa6cb77 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -1566,6 +1566,10 @@
<string name="select_year" msgid="7952052866994196170">"ជ្រើសឆ្នាំ"</string>
<string name="deleted_key" msgid="7659477886625566590">"បានលុប <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"កន្លែងធ្វើការ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ដើម្បីផ្តាច់អេក្រង់នេះ សូមប៉ះ និងសង្កត់ប៊ូតុងថយក្រោយឲ្យជាប់។"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"កម្មវិធីនេះត្រូវបានខ្ទាស់។ មិនអនុញ្ញាតឲ្យដោះការខ្ទាស់នៅលើឧបករណ៍នេះទេ។"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"បានភ្ជាប់អេក្រង់"</string>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index ab9cd90e..30d7e4e0 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"ವರ್ಷವನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ಅಳಿಸಲಾಗಿದೆ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ಕೆಲಸ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಂಂದೆ ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ಅಪ್ಲಿಕೇಶನ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ: ಈ ಸಾಧನದಲ್ಲಿ ಅನ್ಪಿನ್ ಮಾಡುವುದನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ಸ್ಕ್ರೀನ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 10bb801..dbb14890 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"연도 선택"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"이 화면을 고정 해제하려면 \'뒤로\'를 길게 터치합니다."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"앱이 고정되었습니다. 이 기기에서는 고정 해제를 허용하지 않습니다."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"화면 고정됨"</string>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 0d8a38e..3583189 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Медиа үнүнүн деңгээли"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Эскертме үнүнүн деңгээли"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Демейки рингтон"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Демейки рингтон (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Эч бир"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ринтондор"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Ойготкучтун добуштары"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Эскертменин добуштары"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Белгисиз"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi тармагы жеткиликтүү</item>
<item quantity="one">Wi-Fi тармагы жеткиликтүү</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Жылды тандаңыз"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> өчүрүлдү"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Бул экранды бошотуу үчүн \"Артка\" баскычын басып, кармап туруңуз."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Колдонмо кадалган: Бул түзмөктө бошотууга уруксат жок."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран кадалды"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Баштапкы абалга келтирүү"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> өчүрүлдү"</string>
<string name="conference_call" msgid="3751093130790472426">"Конференц чалуу"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Калкып чыгуучу кеңеш"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index ab1a468..baf6d51 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"ເລືອກປີ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ຖືກລຶບແລ້ວ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ບ່ອນເຮັດວຽກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ກົດປຸ່ມກັບຄືນຄ້າງໄວ້ເພື່ອເຊົາປັກໝຸດໜ້າຈໍນີ້."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ແອັບຖືກປັກໝຸດແລ້ວ: ບໍ່ອະນຸຍາດໃຫ້ຖອນປັກໝຸດຢູ່ເທິງອຸປະກອນນີ້."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 4557264..f9293c4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1618,6 +1618,10 @@
<string name="select_year" msgid="7952052866994196170">"Pasirinkite metus"</string>
<string name="deleted_key" msgid="7659477886625566590">"Ištrinta: <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite „Atgal“."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Programa prisegta: šiame įrenginyje negalima atsegti."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrano prisegtas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 0965cf6..04ea14e 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1591,6 +1591,10 @@
<string name="select_year" msgid="7952052866994196170">"Atlasiet gadu."</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> tika dzēsts."</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Darbā: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Lai atspraustu šo ekrānu, pieskarieties pogai “Atpakaļ” un turiet to."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Lietotne ir piesprausta. Atspraušana šajā ierīcē nav atļauta."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrāns ir piesprausts"</string>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 8d96f5c7..aeb0c41 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина на звук на медиуми"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина на звук на известување"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Стандардна мелодија"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Стандардна (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ниедна"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Звуци за аларм"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Звуци за известување"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Непозната"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi мрежи се достапни</item>
<item quantity="other">Wi-Fi мрежи се достапни</item>
@@ -1566,6 +1562,10 @@
<string name="select_year" msgid="7952052866994196170">"Избери година"</string>
<string name="deleted_key" msgid="7659477886625566590">"Избришано <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Работа <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"За откачување на екранов, допрете и задржете Назад."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Апликацијата е закачена: откачување не е дозволено на уредов."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екранот е закачен"</string>
@@ -1685,6 +1685,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ресетирај сега"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Оневозможен <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Конференциски повик"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Појавен прозорец на совет за алатка"</string>
</resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 446d4f2..4193079 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"വർഷം തിരഞ്ഞെടുക്കുക"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ഇല്ലാതാക്കി"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ഔദ്യോഗികം <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, ബാക്ക് ബട്ടൺ സ്പർശിച്ച് പിടിക്കുക"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"അപ്ലിക്കേഷൻ പിൻ ചെയ്തു: ഈ ഉപകരണത്തിൽ അൺപിൻ ചെയ്യാനാവില്ല."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"സ്ക്രീൻ പിൻ ചെയ്തു"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 6199727..74006da 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Жилийг сонгоно уу"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> устсан"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ажлын <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Энэ дэлгэцийг эхэнд нээхийг болиулахын тулд Буцах товчлуурыг дараад, хүлээнэ үү."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App-ыг тусгайлан тэмдэглэсэн байна: Энэ төхөөрөмж дээр тусгайлан тэмдэглэсэн сонголтыг устгах боломжгүй."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Дэлгэцийг тогтоосон"</string>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index 8f2fc0f..dd99f15 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"मीडिया व्हॉल्यूम"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना व्हॉल्यूम"</string>
<string name="ringtone_default" msgid="3789758980357696936">"डीफॉल्ट रिंगटोन"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"डीफॉल्ट (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"काहीही नाही"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"रिंगटोन"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"अलार्म ध्वनी"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"सूचना ध्वनी"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"अज्ञात"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">वाय-फाय नेटवर्क उपलब्ध</item>
<item quantity="other">वाय-फाय नेटवर्क उपलब्ध</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"वर्ष निवडा"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटविली"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ही स्क्रीन अनपिन करण्यासाठी, परत ला स्पर्श करा आणि धरून ठेवा."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"अॅप पिन केलेला आहे: या डिव्हाइसवर अनपिन करण्यास अनुमती नाही."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन केली"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"आता रीसेट करा"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> अक्षम केले"</string>
<string name="conference_call" msgid="3751093130790472426">"परिषद कॉल"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"टूलटिप पॉपअप"</string>
</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 9b6a20a8..57edab8 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Untuk menyahsematkan skrin ni, ketik & tahan Kembali."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Apl disemat: Nyahsemat tidak dibenarkan pada peranti ini."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skrin disemat"</string>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 3276dcd..834a665 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"မီဒီယာအသံအတိုးအကျယ်"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"အကြောင်းကြားသံအတိုးအကျယ်"</string>
<string name="ringtone_default" msgid="3789758980357696936">"မူရင်းမြည်သံ"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"မူရင်း (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"တစ်ခုမှမဟုတ်"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"မြည်သံများ"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"နှိုးစက်သံ"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"အကြောင်းကြားချက်အသံ"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"အမျိုးအမည်မသိ"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi ကွန်ယက်များရရှိနိုင်သည်</item>
<item quantity="one">Wi-Fi ကွန်ယက်ရရှိနိုင်သည်</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"ခုနှစ်ကို ရွေးပါ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ကို ဖျက်ပြီးပါပြီ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"အလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန် \"နောက်သို့\" ကိုထိပြီးဖိထားပါ။"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"အက်ပ်ကို ပင်ထိုးထားသည်။ ပင်ဖျက်ခြင်းကို ဒီစက်မှာ မရနိုင်ပါ။"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"မျက်နှာပြင်ကို ပင်ထိုးထား"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"ယခုပြန်လည်သတ်မှတ်ပါ"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"ပိတ်ထားသည့် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"လူအမြောက်အမြားတပြိုင်နက် ခေါ်ဆိုမှု"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"အကြံပြုချက်ပြ ပေါ့အပ်ဝင်းဒိုး"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index dba56dc..61e74a2 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Medievolum"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Varslingsvolum"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Standard ringetone"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Standard (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringelyder"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarmlyder"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Varsellyder"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Ukjent"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi-nettverk er tilgjengelig</item>
<item quantity="one">Wi-Fi-nettverk er tilgjengelig</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Velg året"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Jobb-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"For å løsne denne skjermen, trykk og hold inne Tilbake."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen er festet – du kan ikke løsne apper på denne enheten."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skjermen er festet"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Tilbakestill nå"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> er slått av"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferansesamtale"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Verktøytips i forgrunnen"</string>
</resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 27abf1a..d6c8612 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -1065,16 +1065,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"मिडियाको मात्रा"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"सूचना भोल्युम"</string>
<string name="ringtone_default" msgid="3789758980357696936">"पूर्वनिर्धारित रिङटोन"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"पूर्वनिर्धारित (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"कुनै पनि होइन"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"रिङटोनहरू"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"अलार्मका आवाजहरू"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"सूचना सम्बन्धी आवाजहरू"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"अज्ञात"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi सञ्जालहरू उपलब्ध छन्</item>
<item quantity="one">Wi-Fi सञ्जाल उपलब्ध छ</item>
@@ -1570,6 +1566,10 @@
<string name="select_year" msgid="7952052866994196170">"वर्ष चयन गर्नुहोस्"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटाइयो"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"यस स्क्रिनलाई अनपिन गर्न पछाडि बटनलाई छोइराख्नुहोस्।"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"अनुप्रयोग पिन गरियो: यस यन्त्रमा अनपिन गर्ने अनुमति छैन।"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रिन पिन गरियो"</string>
@@ -1689,6 +1689,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"अहिले रिसेट गर्नुहोस्"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> लाई असक्षम गरियो"</string>
<string name="conference_call" msgid="3751093130790472426">"सम्मेलन कल"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"उपकरणको वर्णन गर्ने पपअप"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b02c9e1..f7c76cd 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolume"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Meldingsvolume"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Standaardbeltoon"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Standaard (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Geen"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Beltonen"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Alarmgeluiden"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Meldingsgeluiden"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Onbekend"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wifi-netwerken beschikbaar</item>
<item quantity="one">Wifi-netwerk beschikbaar</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Jaar selecteren"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> verwijderd"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Werk <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Tik op Terug en houd vast om dit scherm los te maken."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is vastgezet: losmaken is niet toegestaan op dit apparaat."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Scherm vastgezet"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Nu resetten"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> uitgeschakeld"</string>
<string name="conference_call" msgid="3751093130790472426">"Telefonische vergadering"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Pop-up met knopinfo"</string>
</resources>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index cb63a54..39c5dfa 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"ਸਾਲ ਚੁਣੋ"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ਹਟਾਇਆ ਗਿਆ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ਕੰਮ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, ਸਪਰਸ਼ ਕਰੋ & ਦਬਾਈ ਰੱਖੋ।"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ਐਪ ਪਿੰਨਡ ਹੈ: ਇਸ ਡੀਵਾਈਸ ਤੇ ਅਨਪਿਨ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ।"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 3cfb242..4ffd963 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Głośność multimediów"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Głośność powiadomień"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Dzwonek domyślny"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Domyślny (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Brak"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Dzwonki"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Dźwięki alarmu"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Dźwięki powiadomień"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Nieznany"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="few">Dostępne są sieci Wi-Fi</item>
<item quantity="many">Dostępne są sieci Wi-Fi</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Wybierz rok"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (praca)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Aby odpiąć ten ekran, naciśnij i przytrzymaj Wstecz."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacja jest przypięta. Nie możesz jej odpiąć na tym urządzeniu."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran przypięty"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetuj teraz"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Wyłączono: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Połączenie konferencyjne"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Wyskakujące okno z etykietką"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index b5b30a8..482c1e9 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons do alarme"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Redes Wi-Fi disponíveis</item>
<item quantity="other">Redes Wi-Fi disponíveis</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para liberar esta tela, toque no botão \"Voltar\" e mantenha-o pressionado."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"O app está fixado. A liberação não é permitida neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Tela fixada"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reiniciar agora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
<string name="conference_call" msgid="3751093130790472426">"Teleconferência"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Pop-up de dica"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 952df71..3f9417e 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume de multimédia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume de notificações"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Toque predefinido"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predefinição (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Nada"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons de alarme"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Redes Wi-Fi disponíveis</item>
<item quantity="one">Rede Wi-Fi disponível</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Selecionar ano"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para soltar este ecrã, toque sem soltar em Anterior."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"A aplicação está fixa: não é permitido soltá-la neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ecrã fixo"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Repor agora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
<string name="conference_call" msgid="3751093130790472426">"Conferência"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Pop-up de sugestão"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index b5b30a8..482c1e9 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Volume da mídia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Volume da notificação"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Toque padrão"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Nenhum"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Toques"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sons do alarme"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sons de notificação"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Desconhecido"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Redes Wi-Fi disponíveis</item>
<item quantity="other">Redes Wi-Fi disponíveis</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para liberar esta tela, toque no botão \"Voltar\" e mantenha-o pressionado."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"O app está fixado. A liberação não é permitida neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Tela fixada"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Reiniciar agora"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
<string name="conference_call" msgid="3751093130790472426">"Teleconferência"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Pop-up de dica"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 6f938d9..5735f7c 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1591,6 +1591,10 @@
<string name="select_year" msgid="7952052866994196170">"Selectați anul"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de serviciu"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pentru a anula fixarea acestui ecran, atingeți lung opțiunea Înapoi."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplicația este fixată: Anularea fixării nu este permisă pe acest dispozitiv."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ecran fixat"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 83ae58b..0d6ca06 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Громкость мультимедиа"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Громкость уведомлений"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Мелодия по умолчанию"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"По умолчанию (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодии"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Сигнал будильника"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Мелодии уведомлений"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Неизвестно"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Есть доступные сети Wi-Fi</item>
<item quantity="few">Есть доступные сети Wi-Fi</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Выберите год"</string>
<string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Чтобы открепить экран, нажмите и удерживайте кнопку \"Назад\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Включена блокировка в приложении. Ее отключение запрещено правилами организации."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Блокировка включена"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Сбросить"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виджет <xliff:g id="LABEL">%1$s</xliff:g> отключен"</string>
<string name="conference_call" msgid="3751093130790472426">"Конференц-связь"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Подсказка"</string>
</resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index 2a4ee66..7526c1e 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -108,7 +108,7 @@
<string name="serviceClassDataSync" msgid="7530000519646054776">"සමමුහුර්ත කිරීම"</string>
<string name="serviceClassPacket" msgid="6991006557993423453">"පැකැට්ටුව"</string>
<string name="serviceClassPAD" msgid="3235259085648271037">"PAD"</string>
- <string name="roamingText0" msgid="7170335472198694945">"රෝමිං දර්ශකය සක්රියයි"</string>
+ <string name="roamingText0" msgid="7170335472198694945">"රෝමිං දර්ශකය ක්රියාත්මකයි"</string>
<string name="roamingText1" msgid="5314861519752538922">"රෝමිං දර්ශකය අක්රියයි"</string>
<string name="roamingText2" msgid="8969929049081268115">"රෝමිං දර්ශකය සැණෙලි වෙයි"</string>
<string name="roamingText3" msgid="5148255027043943317">"වටපිටාවෙන් ඉවත්ව"</string>
@@ -189,7 +189,7 @@
<string name="turn_on_radio" msgid="3912793092339962371">"නොරැහන් සක්රිය කරන්න"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"නොරැහැන් අක්රිය කරන්න"</string>
<string name="screen_lock" msgid="799094655496098153">"තිර අගුල"</string>
- <string name="power_off" msgid="4266614107412865048">"බලය අක්රිය කරන්න"</string>
+ <string name="power_off" msgid="4266614107412865048">"බල රහිත කරන්න"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"හඬ නඟනය අක්රියයි"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"හඬ නඟනය කම්පනය"</string>
<string name="silent_mode_ring" msgid="8592241816194074353">"හඬ නඟනය සක්රීයයි"</string>
@@ -213,7 +213,7 @@
<string name="global_actions" product="tv" msgid="7240386462508182976">"රූපවාහිනී විකල්ප"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"දුරකථන විකල්ප"</string>
<string name="global_action_lock" msgid="2844945191792119712">"තිර අගුල"</string>
- <string name="global_action_power_off" msgid="4471879440839879722">"බලය අක්රිය කරන්න"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"බල රහිත කරන්න"</string>
<string name="global_action_emergency" msgid="7112311161137421166">"හදිසි"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"දෝෂ වර්තාව"</string>
<string name="bugreport_title" msgid="2667494803742548533">"දෝෂ වාර්තාවක් ගන්න"</string>
@@ -228,7 +228,7 @@
</plurals>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"නිහඬ ආකාරය"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ශබ්දය අක්රියයි"</string>
- <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"හඬ සක්රියයි"</string>
+ <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"හඬ ක්රියාත්මකයි"</string>
<string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"අහස්යානා ආකාරය"</string>
<string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"අහස්යානා ආකාරය සක්රීයයි."</string>
<string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"අහස්යානා අකාරය අක්රියයි"</string>
@@ -975,7 +975,7 @@
<string name="whichViewApplicationLabel" msgid="2666774233008808473">"විවෘත කරන්න"</string>
<string name="whichEditApplication" msgid="144727838241402655">"සමඟ සංස්කරණය කරන්න"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"%1$s සමඟ සංස්කරණය කරන්න"</string>
- <string name="whichEditApplicationLabel" msgid="7183524181625290300">"සංස්කරණය කරන්න"</string>
+ <string name="whichEditApplicationLabel" msgid="7183524181625290300">"සංස්කරණය"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"සමඟ බෙදාගන්න"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"%s සමඟ බෙදාගන්න"</string>
<string name="whichSendApplicationLabel" msgid="4579076294675975354">"බෙදා ගන්න"</string>
@@ -1104,7 +1104,7 @@
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"ඍජු Wi-Fi"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ඍජු Wi-Fi ආරම්භ කරන්න. මෙය Wi-Fi සේවාදායක/හොට්ස්පොට් එක අක්රිය කරනු ඇත."</string>
<string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ඍජු Wi-Fi ආරම්භ කළ නොහැක."</string>
- <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ඍජු සම්බන්ධතාව සක්රියයි"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ක්රියාත්මකයි"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"සැකසීම් සඳහා තට්ටු කරන්න"</string>
<string name="accept" msgid="1645267259272829559">"පිළිගන්න"</string>
<string name="decline" msgid="2112225451706137894">"ප්රතික්ෂේප කරන්න"</string>
@@ -1336,7 +1336,7 @@
<string name="storage_usb_drive" msgid="6261899683292244209">"USB ධාවකය"</string>
<string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB ධාවකය"</string>
<string name="storage_usb" msgid="3017954059538517278">"USB ආචයනය"</string>
- <string name="extract_edit_menu_button" msgid="8940478730496610137">"සංස්කරණය කරන්න"</string>
+ <string name="extract_edit_menu_button" msgid="8940478730496610137">"සංස්කරණය"</string>
<string name="data_usage_warning_title" msgid="3620440638180218181">"දත්ත භාවිතය ගැන ඇඟවීම"</string>
<string name="data_usage_warning_body" msgid="6660692274311972007">"භාවිතය සහ සැකසීම් බැලීමට තට්ටු කරන්න."</string>
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G දත්ත සීමාවට ළඟාවී ඇත"</string>
@@ -1382,7 +1382,7 @@
<string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"පද්ධතිය"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"බ්ලූටූත් ශ්රව්ය"</string>
- <string name="wireless_display_route_description" msgid="9070346425023979651">"රැහැන් රහිත දර්ශනය"</string>
+ <string name="wireless_display_route_description" msgid="9070346425023979651">"නොරැහැන් සංදර්ශකය"</string>
<string name="media_route_button_content_description" msgid="591703006349356016">"Cast"</string>
<string name="media_route_chooser_title" msgid="1751618554539087622">"උපාංගයට සම්බන්ධ වන්න"</string>
<string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"තිරය උපාංගයට යොමු කරන්න"</string>
@@ -1566,6 +1566,10 @@
<string name="select_year" msgid="7952052866994196170">"වසර තෝරන්න"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> මකා දමන ලදි"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"මෙම තිරය ඇමුණුම් ඉවත් කිරීමට, ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"යෙදුම අමුණා ඇත: ගැලවීමට මෙම උපාංගය මත ඉඩ දිය නොහැකිය."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"තිරය අගුළු දමා ඇත"</string>
@@ -1614,7 +1618,7 @@
</plurals>
<string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string>
<string name="zen_mode_alarm" msgid="9128205721301330797">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක් (ඊළඟ එලාමය)"</string>
- <string name="zen_mode_forever" msgid="7420011936770086993">"ඔබ මෙය අක්රිය කරන තුරු"</string>
+ <string name="zen_mode_forever" msgid="7420011936770086993">"ඔබ මෙය ක්රියාවිරහිත කරන තුරු"</string>
<string name="zen_mode_forever_dnd" msgid="3792132696572189081">"බාධා නොකරන්න ඔබ අක්රිය කරන තුරු"</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>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index ef7678c..7ff3ce2 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitosť médií"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitosť upozornení"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Predvolený tón zvonenia"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Predvolený (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Žiadny"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Tóny zvonenia"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Zvuky budíka"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Zvuky upozornení"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Neznáme"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="few">K dispozícii sú siete Wi-Fi</item>
<item quantity="many">K dispozícii sú siete Wi-Fi</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
<string name="deleted_key" msgid="7659477886625566590">"Číslo <xliff:g id="KEY">%1$s</xliff:g> bolo odstránené"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Práca – <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ak chcete uvoľniť túto obrazovku, klepnite na tlačidlo Späť a podržte ho."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikácia je pripnutá. Uvoľnenie nie je na tomto zariadení povolené."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Obrazovka bola pripnutá"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Resetovať"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Deaktivovaná miniaplikácia <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferenčný hovor"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Kontextové okno s popisom"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index f3a2d23..f7b8096 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -656,7 +656,7 @@
<string name="relationTypeMother" msgid="4578571352962758304">"Mati"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"Starši"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
- <string name="relationTypeReferredBy" msgid="101573059844135524">"Predlagatelj:"</string>
+ <string name="relationTypeReferredBy" msgid="101573059844135524">"Predlagatelj"</string>
<string name="relationTypeRelative" msgid="1799819930085610271">"Sorodnik"</string>
<string name="relationTypeSister" msgid="1735983554479076481">"Sestra"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"Zakonski partner"</string>
@@ -1618,6 +1618,10 @@
<string name="select_year" msgid="7952052866994196170">"Izberite leto"</string>
<string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za delo"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Če želite odpeti ta zaslon, se dotaknite tipke za nazaj in jo pridržite."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je pripeta: v tej napravi odpenjanje ni dovoljeno."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pripet"</string>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index 69f14d5..c3ccaca 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Përzgjidh vitin"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> u fshi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Puna <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Për të hequr gozhdimin e ekranit, prek dhe mbaj të shtypur \"Prapa\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ekrani është i gozhduar. Anulimi i mbërthimit nuk lejohet nga organizata jote."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrani u gozhdua"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 881421c..da44a65 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1082,16 +1082,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Јачина звука медија"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Јачина звука обавештења"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Подразумевани звук звона"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Подразумевано (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Без звука"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Звукови звона"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Звуци аларма"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Звуци обавештења"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Непознато"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Wi-Fi мреже су доступне</item>
<item quantity="few">Wi-Fi мреже су доступне</item>
@@ -1591,6 +1587,10 @@
<string name="select_year" msgid="7952052866994196170">"Изаберите годину"</string>
<string name="deleted_key" msgid="7659477886625566590">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Да бисте откачили овај екран, додирните и задржите Назад."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Апликација је закачена: откачињање није дозвољено на овом уређају."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екран је закачен"</string>
@@ -1719,6 +1719,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Ресетуј"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виџет <xliff:g id="LABEL">%1$s</xliff:g> је онемогућен"</string>
<string name="conference_call" msgid="3751093130790472426">"Конференцијски позив"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Искачуће објашњење"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index fdffd46..1bf5196 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Mediavolym"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Meddelandevolym"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Standardringsignal"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Standard (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Ingen"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringsignaler"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Ljud för alarm"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Aviseringsljud"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Okänt"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi-nätverk är tillgängliga</item>
<item quantity="one">Wi-Fi-nätverk är tillgängligt</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Välj år"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> har tagits bort"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> för arbetet"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Om du vill lossa skärmen trycker du länge på Tillbaka."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen är fäst. Att lossa den är inte tillåtet på den här enheten."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skärmen är fäst"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Återställ nu"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> har inaktiverats"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferenssamtal"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Popup-fönster med beskrivning"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 500b33b..1d3c7ac 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1057,16 +1057,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Sauti ya midia"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Sauti ya arifa"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Mlio chaguo-msingi"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Chaguo-msingi (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Hamna"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Toni za mlio"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Sauti za kengele"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Sauti za arifa"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Haijulikani"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Mitandao ya Wi-Fi inapatikana</item>
<item quantity="one">Mtandao wa Wi-Fi unapatikana</item>
@@ -1562,6 +1558,10 @@
<string name="select_year" msgid="7952052866994196170">"Chagua mwaka"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> kimefutwa"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ya kazini <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ili kubandua skrini hii, gusa na ushikilie Nyuma."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Programu imebanwa: Kubanuliwa hakuruhusiwi kwenye kifaa hiki."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skrini imebandikwa"</string>
@@ -1681,6 +1681,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Weka upya sasa"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> imezimwa"</string>
<string name="conference_call" msgid="3751093130790472426">"Simu ya Kongamano"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Kidirisha Ibukizi cha vidokezo"</string>
</resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 131d03f..46a4589 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"ஆண்டைத் தேர்ந்தெடுக்கவும்"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> நீக்கப்பட்டது"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"பணியிடம் <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"இந்தத் திரையை விலக்க, \"முந்தையது\" பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"பயன்பாடு பொருத்தப்பட்டது: பொருத்தியதை நீக்குவதற்கு இந்தச் சாதனத்தில் அனுமதியில்லை."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"திரை பின் செய்யப்பட்டது"</string>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 2d6b2ad..c6722ee 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"సంవత్సరాన్ని ఎంచుకోండి"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> తొలగించబడింది"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"ఈ స్క్రీన్ని అన్పిన్ చేయడానికి, వెనుకకు తాకి & అలాగే పట్టుకోండి."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"అనువర్తనం పిన్ చేయబడింది: ఈ పరికరంలో అన్పిన్ చేయడానికి అనుమతి లేదు."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"స్క్రీన్ పిన్ చేయబడింది"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index c6a8544..ab04bec 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"เลือกปี"</string>
<string name="deleted_key" msgid="7659477886625566590">"ลบ <xliff:g id="KEY">%1$s</xliff:g> แล้ว"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g>ที่ทำงาน"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"หากต้องการเลิกตรึงหน้าจอนี้ แตะ \"กลับ\" ค้างไว้"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"มีการตรึงแอป: ไม่อนุญาตให้เลิกตรึงบนอุปกรณ์นี้"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ตรึงหน้าจอแล้ว"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index abcb19a..e7cec56 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Pumili ng taon"</string>
<string name="deleted_key" msgid="7659477886625566590">"Tinanggal ang <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Bumalik."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Naka-pin ang app: Hindi pinapayagan ang pag-a-unpin sa device na ito."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Naka-pin ang screen"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 4550784..59dc68e 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Yılı seçin"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (İş)"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Bu ekranın sabitlemesini kaldırmak için Geri\'ye dokunup basılı tutun."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Uygulama sabitlendi. Bu cihazda sabitlemenin kaldırılmasına izin verilmiyor."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran sabitlendi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index b5561b9..0ac3b80 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1105,16 +1105,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Гучність медіа"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Гучність сповіщення"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Мелодія за умовчанням"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"За умовчанням (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Немає"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Мелодії"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Сигнали будильника"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Сигнали сповіщень"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Невідомо"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Мережі Wi-Fi доступні</item>
<item quantity="few">Мережі Wi-Fi доступні</item>
@@ -1618,6 +1614,10 @@
<string name="select_year" msgid="7952052866994196170">"Виберіть рік"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> видалено"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Робоча <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Щоб відкріпити цей екран, натисніть і утримуйте кнопку \"Назад\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Додаток закріплено. Його не можна відкріпити на цьому пристрої."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екран закріплено"</string>
@@ -1755,6 +1755,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Скинути"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> вимкнено"</string>
<string name="conference_call" msgid="3751093130790472426">"Конференц-виклик"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Спливаюча підказка"</string>
</resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index ecb6ee0..715dbed 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"سال منتخب کریں"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> کو حذف کر دیا گیا"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"دفتر <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"اس اسکرین سے پن ہٹانے کیلئے، پیچھے کو تھپتھپائیں اور دبا کر رکھیں۔"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ایپ کو پن کر دیا گیا ہے: اس آلہ پر پن ہٹانے کی اجازت نہیں ہے۔"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"اسکرین کو پن کر دیا گیا"</string>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index dd8b8ba..255982c 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Multimedia ovozi"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Eslatma tovushi"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Standart rington"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Standart (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Yo‘q"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Ringtonlar"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Signal ovozlari"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Bildirishnoma ovozlari"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Noma’lum"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="other">Wi-Fi tarmoqlari aniqlandi</item>
<item quantity="one">Wi-Fi tarmog‘i aniqlandi</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Yilni tanlash"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> raqami o‘chirib tashlandi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ish <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Bu ekrandan chiqish uchun “Orqaga” tugmasini bosib turing."</string>
<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>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Asl holatga qaytarish"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> vidjeti o‘chirilgan"</string>
<string name="conference_call" msgid="3751093130790472426">"Konferens-aloqa"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Qalqib chiquvchi maslahat oynasi"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 37f1a9b..1f6a1cd 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"Chọn năm"</string>
<string name="deleted_key" msgid="7659477886625566590">"Đã xóa <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> làm việc"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Để bỏ ghim màn hình này, nhấn và giữ Quay lại."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ứng dụng được ghim: Không được phép bỏ ghim trên thiết bị này."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Đã ghim màn hình"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 9def7db..5991f54 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"选择年份"</string>
<string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"要取消固定此屏幕,请触摸并按住“返回”按钮。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"应用处于固定状态:在此设备上不允许退出该模式。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"已固定屏幕"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 6f101ab..7191a3d 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1240,7 +1240,7 @@
<string name="wallpaper_binding_label" msgid="1240087844304687662">"桌布"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"變更桌布"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"通知接聽器"</string>
- <string name="vr_listener_binding_label" msgid="4316591939343607306">"虛擬現實接聽器"</string>
+ <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR 接聽器"</string>
<string name="condition_provider_service_binding_label" msgid="1321343352906524564">"條件供應商"</string>
<string name="notification_ranker_binding_label" msgid="774540592299064747">"通知排序服務"</string>
<string name="vpn_title" msgid="19615213552042827">"VPN 已啟用。"</string>
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"選取年份"</string>
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 已刪除"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"公司<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"如要取消固定這個畫面,請按住 [返回]。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"應用程式已固定:不允許在此裝置上取消固定。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"螢幕已固定"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 93acd0e..9e37672 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1564,6 +1564,10 @@
<string name="select_year" msgid="7952052866994196170">"選取年份"</string>
<string name="deleted_key" msgid="7659477886625566590">"已刪除 <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"公司<xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"如要取消固定這個畫面,請按住「返回」按鈕。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"應用程式已固定:無法在這部裝置取消固定。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"已固定螢幕"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 14ea738..66d1010 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1059,16 +1059,12 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Ivolumu yemidiya"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Ivolumu yesaziso"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Iringithoni emisiwe"</string>
- <!-- no translation found for ringtone_default_with_actual (1767304850491060581) -->
- <skip />
+ <string name="ringtone_default_with_actual" msgid="1767304850491060581">"Okuzenzakalelayo (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Akunalutho"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Amaringithoni"</string>
- <!-- no translation found for ringtone_picker_title_alarm (6473325356070549702) -->
- <skip />
- <!-- no translation found for ringtone_picker_title_notification (4837740874822788802) -->
- <skip />
- <!-- no translation found for ringtone_unknown (3914515995813061520) -->
- <skip />
+ <string name="ringtone_picker_title_alarm" msgid="6473325356070549702">"Imisindo ye-alamu"</string>
+ <string name="ringtone_picker_title_notification" msgid="4837740874822788802">"Imisindo yezaziso"</string>
+ <string name="ringtone_unknown" msgid="3914515995813061520">"Akwaziwa"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
<item quantity="one">Amanethiwekhi we-Wi-Fi ayatholakala</item>
<item quantity="other">Amanethiwekhi we-Wi-Fi ayatholakala</item>
@@ -1564,6 +1560,10 @@
<string name="select_year" msgid="7952052866994196170">"Khetha unyaka"</string>
<string name="deleted_key" msgid="7659477886625566590">"I-<xliff:g id="KEY">%1$s</xliff:g> isusiwe"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Umsebenzi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
+ <!-- no translation found for managed_profile_label_badge_2 (5048136430082124036) -->
+ <skip />
+ <!-- no translation found for managed_profile_label_badge_3 (2808305070321719040) -->
+ <skip />
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ukuze ususe ukuphina lesi sikrini, thinta futhi ubambe okuthi Emuva."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Uhlelo lokusebenza luphiniwe: Ukususa ukuphina akuvunyelwe kule divayisi."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Isikrini siphiniwe"</string>
@@ -1683,6 +1683,5 @@
<string name="demo_user_inactivity_timeout_right_button" msgid="5019306703066964808">"Setha kabusha manje"</string>
<string name="suspended_widget_accessibility" msgid="6712143096475264190">"I-<xliff:g id="LABEL">%1$s</xliff:g> ekhutshaziwe"</string>
<string name="conference_call" msgid="3751093130790472426">"Ikholi yengqungquthela"</string>
- <!-- no translation found for tooltip_popup_title (8101791425834697618) -->
- <skip />
+ <string name="tooltip_popup_title" msgid="8101791425834697618">"Okuzivelelayo kwe-tooltip"</string>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8546aa5..af77b1f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1059,6 +1059,11 @@
connected by a call.</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_readPhoneNumber">read phone number</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_readPhoneNumber">Allows the app to access the phone number of the device.</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_wakeLock" product="tablet">prevent tablet from sleeping</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_wakeLock" product="tv">prevent TV from sleeping</string>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index a15cba0..33a0493 100644
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -620,7 +620,7 @@
try {
pkgInfo = pm.getPackageInfo(pkg,
PackageManager.GET_PERMISSIONS
- | PackageManager.GET_UNINSTALLED_PACKAGES);
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException e) {
pkgInfo = null;
}
@@ -712,7 +712,7 @@
// Make sure the package doesn't exist
try {
ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
invokeDeletePackage(pkg.packageName, 0, receiver);
} catch (NameNotFoundException e) {
@@ -974,7 +974,7 @@
public boolean invokeDeletePackage(final String pkgName, int flags, GenericReceiver receiver)
throws Exception {
ApplicationInfo info = getPm().getApplicationInfo(pkgName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
mContext.registerReceiver(receiver, receiver.filter);
try {
@@ -1019,7 +1019,7 @@
Log.i(TAG, "okay4");
try {
info = getPm().getApplicationInfo(ip.pkg.packageName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException e) {
info = null;
}
@@ -1323,7 +1323,7 @@
ApplicationInfo info = null;
try {
- info = getPm().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ info = getPm().getApplicationInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES);
} catch (NameNotFoundException ignored) {
}
@@ -1350,7 +1350,7 @@
Log.i(TAG, "Deleting package : " + pkgName);
try {
ApplicationInfo info = getPm().getApplicationInfo(pkgName,
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
if (info != null) {
DeleteObserver observer = new DeleteObserver(pkgName);
@@ -3756,7 +3756,7 @@
public void testGetUnInstalledPackages() throws Exception {
List<PackageInfo> packages = getPm().getInstalledPackages(
- PackageManager.GET_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
assertNotNull("installed packages cannot be null", packages);
assertTrue("installed packages cannot be empty", packages.size() > 0);
}
@@ -3769,7 +3769,7 @@
| PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
| PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
| PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
- | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+ | PackageManager.GET_SIGNATURES | PackageManager.MATCH_UNINSTALLED_PACKAGES;
final InstallParams ip =
installFromRawResource("install.apk", R.raw.install_complete_package_info,
@@ -3809,12 +3809,12 @@
* flags when the GET_UNINSTALLED_PACKAGES flag is set.
*/
public void testGetUnInstalledPackagesAll() throws Exception {
- final int flags = PackageManager.GET_UNINSTALLED_PACKAGES
+ final int flags = PackageManager.MATCH_UNINSTALLED_PACKAGES
| PackageManager.GET_ACTIVITIES | PackageManager.GET_GIDS
| PackageManager.GET_CONFIGURATIONS | PackageManager.GET_INSTRUMENTATION
| PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
| PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES
- | PackageManager.GET_SIGNATURES | PackageManager.GET_UNINSTALLED_PACKAGES;
+ | PackageManager.GET_SIGNATURES;
// first, install the package
final InstallParams ip =
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index e7aca78..02c2517 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -42,6 +42,8 @@
@Mock private Context mMockContext;
@Mock private PackageManager mMockPm;
+ private NetworkScorerAppManager mNetworkScorerAppManager;
+
@Override
public void setUp() throws Exception {
super.setUp();
@@ -54,6 +56,7 @@
MockitoAnnotations.initMocks(this);
Mockito.when(mMockContext.getPackageManager()).thenReturn(mMockPm);
+ mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext);
}
public void testGetAllValidScorers() throws Exception {
@@ -81,7 +84,7 @@
setScorers(scorers);
Iterator<NetworkScorerAppData> result =
- NetworkScorerAppManager.getAllValidScorers(mMockContext).iterator();
+ mNetworkScorerAppManager.getAllValidScorers().iterator();
assertTrue(result.hasNext());
NetworkScorerAppData next = result.next();
diff --git a/docs/html/reference/images/graphics/colorspace_clipped.png b/docs/html/reference/images/graphics/colorspace_clipped.png
new file mode 100644
index 0000000..28204e6
--- /dev/null
+++ b/docs/html/reference/images/graphics/colorspace_clipped.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/colorspace_comparison.png b/docs/html/reference/images/graphics/colorspace_comparison.png
new file mode 100644
index 0000000..b1b015c
--- /dev/null
+++ b/docs/html/reference/images/graphics/colorspace_comparison.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/colorspace_comparison2.png b/docs/html/reference/images/graphics/colorspace_comparison2.png
new file mode 100644
index 0000000..b263aa1f
--- /dev/null
+++ b/docs/html/reference/images/graphics/colorspace_comparison2.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/colorspace_points.png b/docs/html/reference/images/graphics/colorspace_points.png
new file mode 100644
index 0000000..84d1e77
--- /dev/null
+++ b/docs/html/reference/images/graphics/colorspace_points.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/colorspace_renderer.png b/docs/html/reference/images/graphics/colorspace_renderer.png
new file mode 100644
index 0000000..acf30c3
--- /dev/null
+++ b/docs/html/reference/images/graphics/colorspace_renderer.png
Binary files differ
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 4f2465f..7dc5de3 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -16,12 +16,16 @@
package android.graphics;
+import android.annotation.ColorInt;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Size;
import android.annotation.Nullable;
+import android.util.Pair;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.function.DoubleUnaryOperator;
/**
@@ -118,11 +122,38 @@
* and {@link #connect(ColorSpace, ColorSpace)}, are also guaranteed to be
* thread-safe.</p>
*
+ * <h3>Visualization and debugging</h3>
+ *
+ * <p>To visualize and debug color spaces, you can call {@link #createRenderer()}.
+ * The {@link Renderer} created by calling this method can be used to compare
+ * color spaces and locate specific colors on a CIE 1931 chromaticity diagram.</p>
+ *
+ * <p>The following code snippet shows how to render a bitmap that compares
+ * the color gamuts and white points of {@link Named#DCI_P3} and
+ * {@link Named#PRO_PHOTO_RGB}:</p>
+ *
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .size(768)
+ * .clip(true)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .add(ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), 0xff097ae9)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_renderer.png" />
+ * <figcaption style="text-align: center;">DCI-P3 vs ProPhoto RGB</figcaption>
+ * </p>
+ *
+ * <p>Please refer to the documentation of the {@link Renderer} class for more
+ * information about its options and capabilities.</p>
+ *
* @see #get(Named)
* @see Named
* @see Model
* @see Connector
* @see Adaptation
+ * @see Renderer
*/
@SuppressWarnings("StaticInitializerReferencesSubClass")
public abstract class ColorSpace {
@@ -1333,6 +1364,20 @@
return sNamedColorSpaces[name.ordinal()];
}
+ /**
+ * <p>Creates a new {@link Renderer} that can be used to visualize and
+ * debug color spaces. See the documentation of {@link Renderer} for
+ * more information.</p>
+ *
+ * @return A new non-null {@link Renderer} instance
+ *
+ * @see Renderer
+ */
+ @NonNull
+ public static Renderer createRenderer() {
+ return new Renderer();
+ }
+
static {
sNamedColorSpaces[Named.SRGB.ordinal()] = new ColorSpace.Rgb(
"sRGB IEC61966-2.1",
@@ -3113,4 +3158,688 @@
};
}
}
+
+ /**
+ * <p>A color space renderer can be used to visualize and compare the gamut and
+ * white point of one or more color spaces. The output is an sRGB {@link Bitmap}
+ * showing a CIE 1931 xyY chromaticity diagram.</p>
+ *
+ * <p>The following code snippet shows how to compare the {@link Named#SRGB}
+ * and {@link Named#DCI_P3} color spaces:</p>
+ *
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .size(768)
+ * .clip(true)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
+ * <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
+ * </p>
+ *
+ * <p>A renderer can also be used to show the location of specific colors,
+ * associated with a color space, in the CIE 1931 xyY chromaticity diagram.
+ * See {@link #add(ColorSpace, float, float, float, int)} for more information.</p>
+ *
+ * @see ColorSpace#createRenderer()
+ */
+ public static class Renderer {
+ private static final int NATIVE_SIZE = 1440;
+
+ @IntRange(from = 128, to = Integer.MAX_VALUE)
+ private int mSize = 1024;
+
+ private boolean mShowWhitePoint = true;
+ private boolean mClip = false;
+
+ private final List<Pair<ColorSpace, Integer>> mColorSpaces = new ArrayList<>(2);
+ private final List<Point> mPoints = new ArrayList<>(0);
+
+ private Renderer() {
+ }
+
+ /**
+ * <p>Defines whether the chromaticity diagram should be clipped by the first
+ * registered color space. The default value is false.</p>
+ *
+ * <p>The following code snippet and image show the default behavior:</p>
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
+ * <figcaption style="text-align: center;">Clipping disabled</figcaption>
+ * </p>
+ *
+ * <p>Here is the same example with clipping enabled:</p>
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .clip(true)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
+ * <figcaption style="text-align: center;">Clipping enabled</figcaption>
+ * </p>
+ *
+ * @param clip True to clip the chromaticity diagram to the first registered color space,
+ * false otherwise
+ * @return This instance of {@link Renderer}
+ */
+ @NonNull
+ public Renderer clip(boolean clip) {
+ mClip = clip;
+ return this;
+ }
+
+ /**
+ * Sets the dimensions (width and height) in pixels of the output bitmap.
+ * The size must be at least 128px and defaults to 1024px.
+ *
+ * @param size The size in pixels of the output bitmap
+ * @return This instance of {@link Renderer}
+ */
+ @NonNull
+ public Renderer size(@IntRange(from = 128, to = Integer.MAX_VALUE) int size) {
+ mSize = Math.max(128, size);
+ return this;
+ }
+
+ /**
+ * Shows or hides the white point of each color space in the output bitmap.
+ * The default is true.
+ *
+ * @param show True to show the white point of each color space, false
+ * otherwise
+ * @return This instance of {@link Renderer}
+ */
+ @NonNull
+ public Renderer showWhitePoint(boolean show) {
+ mShowWhitePoint = show;
+ return this;
+ }
+
+ /**
+ * <p>Adds a color space to represent on the output CIE 1931 chromaticity
+ * diagram. The color space is represented as a triangle showing the
+ * footprint of its color gamut and, optionally, the location of its
+ * white point.</p>
+ *
+ * <p class="note">Color spaces with a color model that is not RGB are
+ * accepted but ignored.</p>
+ *
+ * <p>The following code snippet and image show an example of calling this
+ * method to compare {@link Named#SRGB sRGB} and {@link Named#DCI_P3 DCI-P3}:</p>
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
+ * <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
+ * </p>
+ *
+ * <p>Adding a color space extending beyond the boundaries of the
+ * spectral locus will alter the size of the diagram within the output
+ * bitmap as shown in this example:</p>
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffc845)
+ * .add(ColorSpace.get(ColorSpace.Named.ACES), 0xff097ae9)
+ * .add(ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB), 0xff000000)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
+ * <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
+ * </p>
+ *
+ * @param colorSpace The color space whose gamut to render on the diagram
+ * @param color The sRGB color to use to render the color space's gamut and white point
+ * @return This instance of {@link Renderer}
+ *
+ * @see #clip(boolean)
+ * @see #showWhitePoint(boolean)
+ */
+ @NonNull
+ public Renderer add(@NonNull ColorSpace colorSpace, @ColorInt int color) {
+ mColorSpaces.add(new Pair<>(colorSpace, color));
+ return this;
+ }
+
+ /**
+ * <p>Adds a color to represent as a point on the chromaticity diagram.
+ * The color is associated with a color space which will be used to
+ * perform the conversion to CIE XYZ and compute the location of the point
+ * on the diagram. The point is rendered as a colored circle.</p>
+ *
+ * <p>The following code snippet and image show an example of calling this
+ * method to render the location of several sRGB colors as white circles:</p>
+ * <pre class="prettyprint">
+ * Bitmap bitmap = ColorSpace.createRenderer()
+ * .clip(true)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.0f, 0.1f, 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.1f, 0.1f, 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.2f, 0.1f, 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.3f, 0.1f, 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.4f, 0.1f, 0xffffffff)
+ * .add(ColorSpace.get(ColorSpace.Named.SRGB), 0.1f, 0.5f, 0.1f, 0xffffffff)
+ * .render();
+ * </pre>
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
+ * <figcaption style="text-align: center;">
+ * Locating colors on the chromaticity diagram
+ * </figcaption>
+ * </p>
+ *
+ * @param colorSpace The color space of the color to locate on the diagram
+ * @param r The first component of the color to locate on the diagram
+ * @param g The second component of the color to locate on the diagram
+ * @param b The third component of the color to locate on the diagram
+ * @param pointColor The sRGB color to use to render the point on the diagram
+ * @return This instance of {@link Renderer}
+ */
+ @NonNull
+ public Renderer add(@NonNull ColorSpace colorSpace, float r, float g, float b,
+ @ColorInt int pointColor) {
+ mPoints.add(new Point(colorSpace, new float[] { r, g, b }, pointColor));
+ return this;
+ }
+
+ /**
+ * <p>Renders the {@link #add(ColorSpace, int) color spaces} and
+ * {@link #add(ColorSpace, float, float, float, int) points} registered
+ * with this renderer. The output bitmap is an sRGB image with the
+ * dimensions specified by calling {@link #size(int)} (1204x1024px by
+ * default).</p>
+ *
+ * @return A new non-null {@link Bitmap} with the dimensions specified
+ * by {@link #size(int)} (1024x1024 by default)
+ */
+ @NonNull
+ public Bitmap render() {
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ Bitmap bitmap = Bitmap.createBitmap(mSize, mSize, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ float[] primaries = new float[6];
+ float[] whitePoint = new float[2];
+
+ int width = NATIVE_SIZE;
+ int height = NATIVE_SIZE;
+
+ Path path = new Path();
+
+ setTransform(canvas, width, height, primaries);
+ drawBox(canvas, width, height, paint, path);
+ drawLocus(canvas, width, height, paint, path, primaries);
+ drawGamuts(canvas, width, height, paint, path, primaries, whitePoint);
+ drawPoints(canvas, width, height, paint);
+
+ return bitmap;
+ }
+
+ /**
+ * Draws registered points at their correct position in the xyY coordinates.
+ * Each point is positioned according to its associated color space.
+ *
+ * @param canvas The canvas to transform
+ * @param width Width in pixel of the final image
+ * @param height Height in pixel of the final image
+ * @param paint A pre-allocated paint used to avoid temporary allocations
+ */
+ private void drawPoints(@NonNull Canvas canvas, int width, int height,
+ @NonNull Paint paint) {
+
+ paint.setStyle(Paint.Style.FILL);
+
+ float[] v = new float[3];
+ for (final Point point : mPoints) {
+ v[0] = point.mRgb[0];
+ v[1] = point.mRgb[1];
+ v[2] = point.mRgb[2];
+ point.mColorSpace.toXyz(v);
+
+ paint.setColor(point.mColor);
+
+ // XYZ to xyY, assuming Y=1.0
+ float sum = v[0] + v[1] + v[2];
+ canvas.drawCircle(width * v[0] / sum, height - height * v[1] / sum,
+ 4.0f, paint);
+ }
+ }
+
+ /**
+ * Draws the color gamuts and white points of all the registered color
+ * spaces. Only color spaces with an RGB color model are rendered, the
+ * others are ignored.
+ *
+ * @param canvas The canvas to transform
+ * @param width Width in pixel of the final image
+ * @param height Height in pixel of the final image
+ * @param paint A pre-allocated paint used to avoid temporary allocations
+ * @param path A pre-allocated path used to avoid temporary allocations
+ * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
+ * @param whitePoint A pre-allocated array of 2 floats to avoid temporary allocations
+ */
+ private void drawGamuts(
+ @NonNull Canvas canvas, int width, int height,
+ @NonNull Paint paint, @NonNull Path path,
+ @NonNull @Size(6) float[] primaries, @NonNull @Size(2) float[] whitePoint) {
+
+ for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
+ ColorSpace colorSpace = item.first;
+ int color = item.second;
+
+ if (colorSpace.getModel() != Model.RGB) continue;
+
+ Rgb rgb = (Rgb) colorSpace;
+ getPrimaries(rgb, primaries);
+
+ path.rewind();
+ path.moveTo(width * primaries[0], height - height * primaries[1]);
+ path.lineTo(width * primaries[2], height - height * primaries[3]);
+ path.lineTo(width * primaries[4], height - height * primaries[5]);
+ path.close();
+
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setColor(color);
+ canvas.drawPath(path, paint);
+
+ // Draw the white point
+ if (mShowWhitePoint) {
+ rgb.getWhitePoint(whitePoint);
+
+ paint.setStyle(Paint.Style.FILL);
+ paint.setColor(color);
+ canvas.drawCircle(width * whitePoint[0], height - height * whitePoint[1],
+ 4.0f, paint);
+ }
+ }
+ }
+
+ /**
+ * Returns the primaries of the specified RGB color space. This method handles
+ * the special case of the {@link Named#EXTENDED_SRGB} family of color spaces.
+ *
+ * @param rgb The color space whose primaries to extract
+ * @param primaries A pre-allocated array of 6 floats that will hold the result
+ */
+ @NonNull
+ @Size(6)
+ private static float[] getPrimaries(@NonNull Rgb rgb, @NonNull @Size(6) float[] primaries) {
+ // TODO: We should find a better way to handle these cases
+ if (rgb.equals(ColorSpace.get(Named.EXTENDED_SRGB)) ||
+ rgb.equals(ColorSpace.get(Named.LINEAR_EXTENDED_SRGB))) {
+ primaries[0] = 1.41f;
+ primaries[1] = 0.33f;
+ primaries[2] = 0.27f;
+ primaries[3] = 1.24f;
+ primaries[4] = -0.23f;
+ primaries[5] = -0.57f;
+ return primaries;
+ }
+ return rgb.getPrimaries(primaries);
+ }
+
+ /**
+ * Draws the CIE 1931 chromaticity diagram: the spectral locus and its inside.
+ * This method respect the clip parameter.
+ *
+ * @param canvas The canvas to transform
+ * @param width Width in pixel of the final image
+ * @param height Height in pixel of the final image
+ * @param paint A pre-allocated paint used to avoid temporary allocations
+ * @param path A pre-allocated path used to avoid temporary allocations
+ * @param primaries A pre-allocated array of 6 floats to avoid temporary allocations
+ */
+ private void drawLocus(
+ @NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
+ @NonNull Path path, @NonNull @Size(6) float[] primaries) {
+
+ int vertexCount = SPECTRUM_LOCUS_X.length * CHROMATICITY_RESOLUTION * 6;
+ float[] vertices = new float[vertexCount * 2];
+ int[] colors = new int[vertices.length];
+ computeChromaticityMesh(NATIVE_SIZE, NATIVE_SIZE, vertices, colors);
+
+ // Draw the spectral locus
+ if (mClip && mColorSpaces.size() > 0) {
+ for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
+ ColorSpace colorSpace = item.first;
+ if (colorSpace.getModel() != Model.RGB) continue;
+
+ Rgb rgb = (Rgb) colorSpace;
+ getPrimaries(rgb, primaries);
+ break;
+ }
+
+ path.rewind();
+ path.moveTo(width * primaries[0], height - height * primaries[1]);
+ path.lineTo(width * primaries[2], height - height * primaries[3]);
+ path.lineTo(width * primaries[4], height - height * primaries[5]);
+ path.close();
+
+ int[] solid = new int[colors.length];
+ Arrays.fill(solid, 0xff6c6c6c);
+ canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
+ null, 0, solid, 0, null, 0, 0, paint);
+
+ canvas.save();
+ canvas.clipPath(path);
+
+ canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
+ null, 0, colors, 0, null, 0, 0, paint);
+
+ canvas.restore();
+ } else {
+ canvas.drawVertices(Canvas.VertexMode.TRIANGLES, vertices.length, vertices, 0,
+ null, 0, colors, 0, null, 0, 0, paint);
+ }
+
+ // Draw the non-spectral locus
+ int index = (CHROMATICITY_RESOLUTION - 1) * 12;
+ path.reset();
+ path.moveTo(vertices[index], vertices[index + 1]);
+ for (int x = 2; x < SPECTRUM_LOCUS_X.length; x++) {
+ index += CHROMATICITY_RESOLUTION * 12;
+ path.lineTo(vertices[index], vertices[index + 1]);
+ }
+ path.close();
+
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setColor(0xff000000);
+ canvas.drawPath(path, paint);
+ }
+
+ /**
+ * Draws the diagram box, including borders, tick marks, grid lines
+ * and axis labels.
+ *
+ * @param canvas The canvas to transform
+ * @param width Width in pixel of the final image
+ * @param height Height in pixel of the final image
+ * @param paint A pre-allocated paint used to avoid temporary allocations
+ * @param path A pre-allocated path used to avoid temporary allocations
+ */
+ private void drawBox(@NonNull Canvas canvas, int width, int height, @NonNull Paint paint,
+ @NonNull Path path) {
+ // Draw the unit grid
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeWidth(2.0f);
+ paint.setColor(0xffc0c0c0);
+ for (int i = 1; i <= 9; i++) {
+ canvas.drawLine(0.0f, height - (height * i / 10.0f),
+ 0.9f * width, height - (height * i / 10.0f), paint);
+ canvas.drawLine(width * i / 10.0f, height,
+ width * i / 10.0f, 0.1f * height, paint);
+ }
+
+ // Draw tick marks
+ paint.setStrokeWidth(4.0f);
+ paint.setColor(0xff000000);
+ for (int i = 1; i <= 9; i++) {
+ canvas.drawLine(0.0f, height - (height * i / 10.0f),
+ width / 100.0f, height - (height * i / 10.0f), paint);
+ canvas.drawLine(width * i / 10.0f, height,
+ width * i / 10.0f, height - (height / 100.0f), paint);
+ }
+
+ // Draw the axis labels
+ paint.setStyle(Paint.Style.FILL);
+ paint.setTextSize(36.0f);
+ paint.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+
+ Rect bounds = new Rect();
+ for (int i = 1; i < 9; i++) {
+ String text = "0." + i;
+ paint.getTextBounds(text, 0, text.length(), bounds);
+
+ float y = height - (height * i / 10.0f);
+ canvas.drawText(text, -0.05f * width + 10, y + bounds.height() / 2.0f, paint);
+
+ float x = width * i / 10.0f;
+ canvas.drawText(text, x - bounds.width() / 2.0f,
+ height + bounds.height() + 16, paint);
+ }
+ paint.setStyle(Paint.Style.STROKE);
+
+ // Draw the diagram box
+ path.moveTo(0.0f, height);
+ path.lineTo(0.9f * width, height);
+ path.lineTo(0.9f * width, 0.1f * height);
+ path.lineTo(0.0f, 0.1f * height);
+ path.close();
+ canvas.drawPath(path, paint);
+ }
+
+ /**
+ * Computes and applies the Canvas transforms required to make the color
+ * gamut of each color space visible in the final image.
+ *
+ * @param canvas The canvas to transform
+ * @param width Width in pixel of the final image
+ * @param height Height in pixel of the final image
+ * @param primaries Array of 6 floats used to avoid temporary allocations
+ */
+ private void setTransform(@NonNull Canvas canvas, int width, int height,
+ @NonNull @Size(6) float[] primaries) {
+
+ RectF primariesBounds = new RectF();
+ for (final Pair<ColorSpace, Integer> item : mColorSpaces) {
+ ColorSpace colorSpace = item.first;
+ if (colorSpace.getModel() != Model.RGB) continue;
+
+ Rgb rgb = (Rgb) colorSpace;
+ getPrimaries(rgb, primaries);
+
+ primariesBounds.left = Math.min(primariesBounds.left, primaries[4]);
+ primariesBounds.top = Math.min(primariesBounds.top, primaries[5]);
+ primariesBounds.right = Math.max(primariesBounds.right, primaries[0]);
+ primariesBounds.bottom = Math.max(primariesBounds.bottom, primaries[3]);
+ }
+
+ primariesBounds.left = Math.min(0.0f, primariesBounds.left);
+ primariesBounds.top = Math.min(0.0f, primariesBounds.top);
+ primariesBounds.right = Math.max(0.9f, primariesBounds.right);
+ primariesBounds.bottom = Math.max(0.9f, primariesBounds.bottom);
+
+ float scaleX = 0.9f / primariesBounds.width();
+ float scaleY = 0.9f / primariesBounds.height();
+ float scale = Math.min(scaleX, scaleY);
+
+ canvas.scale(mSize / (float) NATIVE_SIZE, mSize / (float) NATIVE_SIZE);
+ canvas.scale(scale, scale);
+ canvas.translate(
+ (primariesBounds.width() - 0.9f) * width / 2.0f,
+ (primariesBounds.height() - 0.9f) * height / 2.0f);
+
+ // The spectrum extends ~0.85 vertically and ~0.65 horizontally
+ // We shift the canvas a little bit to get nicer margins
+ canvas.translate(0.05f * width, -0.05f * height);
+ }
+
+ // X coordinates of the spectral locus in CIE 1931
+ private static final float[] SPECTRUM_LOCUS_X = {
+ 0.175596f, 0.172787f, 0.170806f, 0.170085f, 0.160343f,
+ 0.146958f, 0.139149f, 0.133536f, 0.126688f, 0.115830f,
+ 0.109616f, 0.099146f, 0.091310f, 0.078130f, 0.068717f,
+ 0.054675f, 0.040763f, 0.027497f, 0.016270f, 0.008169f,
+ 0.004876f, 0.003983f, 0.003859f, 0.004646f, 0.007988f,
+ 0.013870f, 0.022244f, 0.027273f, 0.032820f, 0.038851f,
+ 0.045327f, 0.052175f, 0.059323f, 0.066713f, 0.074299f,
+ 0.089937f, 0.114155f, 0.138695f, 0.154714f, 0.192865f,
+ 0.229607f, 0.265760f, 0.301588f, 0.337346f, 0.373083f,
+ 0.408717f, 0.444043f, 0.478755f, 0.512467f, 0.544767f,
+ 0.575132f, 0.602914f, 0.627018f, 0.648215f, 0.665746f,
+ 0.680061f, 0.691487f, 0.700589f, 0.707901f, 0.714015f,
+ 0.719017f, 0.723016f, 0.734674f, 0.717203f, 0.699732f,
+ 0.682260f, 0.664789f, 0.647318f, 0.629847f, 0.612376f,
+ 0.594905f, 0.577433f, 0.559962f, 0.542491f, 0.525020f,
+ 0.507549f, 0.490077f, 0.472606f, 0.455135f, 0.437664f,
+ 0.420193f, 0.402721f, 0.385250f, 0.367779f, 0.350308f,
+ 0.332837f, 0.315366f, 0.297894f, 0.280423f, 0.262952f,
+ 0.245481f, 0.228010f, 0.210538f, 0.193067f, 0.175596f
+ };
+ // Y coordinates of the spectral locus in CIE 1931
+ private static final float[] SPECTRUM_LOCUS_Y = {
+ 0.005295f, 0.004800f, 0.005472f, 0.005976f, 0.014496f,
+ 0.026643f, 0.035211f, 0.042704f, 0.053441f, 0.073601f,
+ 0.086866f, 0.112037f, 0.132737f, 0.170464f, 0.200773f,
+ 0.254155f, 0.317049f, 0.387997f, 0.463035f, 0.538504f,
+ 0.587196f, 0.610526f, 0.654897f, 0.675970f, 0.715407f,
+ 0.750246f, 0.779682f, 0.792153f, 0.802971f, 0.812059f,
+ 0.819430f, 0.825200f, 0.829460f, 0.832306f, 0.833833f,
+ 0.833316f, 0.826231f, 0.814796f, 0.805884f, 0.781648f,
+ 0.754347f, 0.724342f, 0.692326f, 0.658867f, 0.624470f,
+ 0.589626f, 0.554734f, 0.520222f, 0.486611f, 0.454454f,
+ 0.424252f, 0.396516f, 0.372510f, 0.351413f, 0.334028f,
+ 0.319765f, 0.308359f, 0.299317f, 0.292044f, 0.285945f,
+ 0.280951f, 0.276964f, 0.265326f, 0.257200f, 0.249074f,
+ 0.240948f, 0.232822f, 0.224696f, 0.216570f, 0.208444f,
+ 0.200318f, 0.192192f, 0.184066f, 0.175940f, 0.167814f,
+ 0.159688f, 0.151562f, 0.143436f, 0.135311f, 0.127185f,
+ 0.119059f, 0.110933f, 0.102807f, 0.094681f, 0.086555f,
+ 0.078429f, 0.070303f, 0.062177f, 0.054051f, 0.045925f,
+ 0.037799f, 0.029673f, 0.021547f, 0.013421f, 0.005295f
+ };
+
+ // Number of subdivision of the inside of the spectral locus
+ private static final int CHROMATICITY_RESOLUTION = 32;
+ private static final double ONE_THIRD = 1.0 / 3.0;
+
+ /**
+ * Computes a 2D mesh representation of the CIE 1931 chromaticity
+ * diagram.
+ *
+ * @param width Width in pixels of the mesh
+ * @param height Height in pixels of the mesh
+ * @param vertices Array of floats that will hold the mesh vertices
+ * @param colors Array of floats that will hold the mesh colors
+ */
+ private static void computeChromaticityMesh(int width, int height,
+ @NonNull float[] vertices, @NonNull int[] colors) {
+
+ ColorSpace colorSpace = get(Named.SRGB);
+
+ float[] color = new float[3];
+
+ int vertexIndex = 0;
+ int colorIndex = 0;
+
+ for (int x = 0; x < SPECTRUM_LOCUS_X.length; x++) {
+ int nextX = (x % (SPECTRUM_LOCUS_X.length - 1)) + 1;
+
+ float a1 = (float) Math.atan2(
+ SPECTRUM_LOCUS_Y[x] - ONE_THIRD,
+ SPECTRUM_LOCUS_X[x] - ONE_THIRD);
+ float a2 = (float) Math.atan2(
+ SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD,
+ SPECTRUM_LOCUS_X[nextX] - ONE_THIRD);
+
+ float radius1 = (float) Math.pow(
+ sqr(SPECTRUM_LOCUS_X[x] - ONE_THIRD) +
+ sqr(SPECTRUM_LOCUS_Y[x] - ONE_THIRD),
+ 0.5);
+ float radius2 = (float) Math.pow(
+ sqr(SPECTRUM_LOCUS_X[nextX] - ONE_THIRD) +
+ sqr(SPECTRUM_LOCUS_Y[nextX] - ONE_THIRD),
+ 0.5);
+
+ // Compute patches; each patch is a quad with a different
+ // color associated with each vertex
+ for (int c = 1; c <= CHROMATICITY_RESOLUTION; c++) {
+ float f1 = c / (float) CHROMATICITY_RESOLUTION;
+ float f2 = (c - 1) / (float) CHROMATICITY_RESOLUTION;
+
+ double cr1 = radius1 * Math.cos(a1);
+ double sr1 = radius1 * Math.sin(a1);
+ double cr2 = radius2 * Math.cos(a2);
+ double sr2 = radius2 * Math.sin(a2);
+
+ // Compute the XYZ coordinates of the 4 vertices of the patch
+ float v1x = (float) (ONE_THIRD + cr1 * f1);
+ float v1y = (float) (ONE_THIRD + sr1 * f1);
+ float v1z = 1 - v1x - v1y;
+
+ float v2x = (float) (ONE_THIRD + cr1 * f2);
+ float v2y = (float) (ONE_THIRD + sr1 * f2);
+ float v2z = 1 - v2x - v2y;
+
+ float v3x = (float) (ONE_THIRD + cr2 * f2);
+ float v3y = (float) (ONE_THIRD + sr2 * f2);
+ float v3z = 1 - v3x - v3y;
+
+ float v4x = (float) (ONE_THIRD + cr2 * f1);
+ float v4y = (float) (ONE_THIRD + sr2 * f1);
+ float v4z = 1 - v4x - v4y;
+
+ // Compute the sRGB representation of each XYZ coordinate of the patch
+ colors[colorIndex ] = computeColor(color, v1x, v1y, v1z, colorSpace);
+ colors[colorIndex + 1] = computeColor(color, v2x, v2y, v2z, colorSpace);
+ colors[colorIndex + 2] = computeColor(color, v3x, v3y, v3z, colorSpace);
+ colors[colorIndex + 3] = colors[colorIndex];
+ colors[colorIndex + 4] = colors[colorIndex + 2];
+ colors[colorIndex + 5] = computeColor(color, v4x, v4y, v4z, colorSpace);
+ colorIndex += 6;
+
+ // Flip the mesh upside down to match Canvas' coordinates system
+ vertices[vertexIndex++] = v1x * width;
+ vertices[vertexIndex++] = height - v1y * height;
+ vertices[vertexIndex++] = v2x * width;
+ vertices[vertexIndex++] = height - v2y * height;
+ vertices[vertexIndex++] = v3x * width;
+ vertices[vertexIndex++] = height - v3y * height;
+ vertices[vertexIndex++] = v1x * width;
+ vertices[vertexIndex++] = height - v1y * height;
+ vertices[vertexIndex++] = v3x * width;
+ vertices[vertexIndex++] = height - v3y * height;
+ vertices[vertexIndex++] = v4x * width;
+ vertices[vertexIndex++] = height - v4y * height;
+ }
+ }
+ }
+
+ @ColorInt
+ private static int computeColor(@NonNull @Size(3) float[] color,
+ float x, float y, float z, @NonNull ColorSpace cs) {
+ color[0] = x;
+ color[1] = y;
+ color[2] = z;
+ cs.fromXyz(color);
+ return 0xff000000 |
+ (((int) (color[0] * 255.0f) & 0xff) << 16) |
+ (((int) (color[1] * 255.0f) & 0xff) << 8) |
+ (((int) (color[2] * 255.0f) & 0xff) );
+ }
+
+ private static double sqr(double v) {
+ return v * v;
+ }
+
+ private static class Point {
+ @NonNull final ColorSpace mColorSpace;
+ @NonNull final float[] mRgb;
+ final int mColor;
+
+ Point(@NonNull ColorSpace colorSpace,
+ @NonNull @Size(3) float[] rgb, @ColorInt int color) {
+ mColorSpace = colorSpace;
+ mRgb = rgb;
+ mColor = color;
+ }
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 2b950d3..9772009 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -299,7 +299,7 @@
final PackageManager pm = context.getPackageManager();
try {
ApplicationInfo ai = pm.getApplicationInfo(
- resPackage, PackageManager.GET_UNINSTALLED_PACKAGES);
+ resPackage, PackageManager.MATCH_UNINSTALLED_PACKAGES);
if (ai != null) {
mObj1 = pm.getResourcesForApplication(ai);
} else {
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
new file mode 100644
index 0000000..d501d25
--- /dev/null
+++ b/libs/androidfw/Android.bp
@@ -0,0 +1,74 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this 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.
+
+// libandroidfw is partially built for the host (used by obbtool, aapt, and others)
+
+cc_library {
+ name: "libandroidfw",
+ host_supported: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wunused",
+ "-Wunreachable-code",
+ ],
+ srcs: [
+ "Asset.cpp",
+ "AssetDir.cpp",
+ "AssetManager.cpp",
+ "AttributeResolution.cpp",
+ "LocaleData.cpp",
+ "misc.cpp",
+ "ObbFile.cpp",
+ "ResourceTypes.cpp",
+ "StreamingZipInflater.cpp",
+ "TypeWrappers.cpp",
+ "ZipFileRO.cpp",
+ "ZipUtils.cpp",
+ ],
+ export_include_dirs: ["include"],
+ target: {
+ android: {
+ srcs: [
+ "BackupData.cpp",
+ "BackupHelpers.cpp",
+ "CursorWindow.cpp",
+ "DisplayEventDispatcher.cpp",
+ ],
+ shared_libs: [
+ "libziparchive",
+ "libbase",
+ "libbinder",
+ "liblog",
+ "libcutils",
+ "libgui",
+ "libutils",
+ "libz",
+ ],
+ static: {
+ enabled: false,
+ },
+ },
+ host: {
+ cflags: ["-DSTATIC_ANDROIDFW_FOR_TOOLS"],
+ shared: {
+ enabled: false,
+ },
+ shared_libs: ["libz-host"],
+ },
+ windows: {
+ enabled: true,
+ },
+ },
+}
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
index 7689256..68c51ef 100644
--- a/libs/androidfw/Android.mk
+++ b/libs/androidfw/Android.mk
@@ -14,74 +14,6 @@
LOCAL_PATH:= $(call my-dir)
-# libandroidfw is partially built for the host (used by obbtool, aapt, and others)
-# These files are common to host and target builds.
-
-commonSources := \
- Asset.cpp \
- AssetDir.cpp \
- AssetManager.cpp \
- AttributeResolution.cpp \
- LocaleData.cpp \
- misc.cpp \
- ObbFile.cpp \
- ResourceTypes.cpp \
- StreamingZipInflater.cpp \
- TypeWrappers.cpp \
- ZipFileRO.cpp \
- ZipUtils.cpp
-
-deviceSources := \
- $(commonSources) \
- BackupData.cpp \
- BackupHelpers.cpp \
- CursorWindow.cpp \
- DisplayEventDispatcher.cpp
-
-hostSources := $(commonSources)
-
-# For the host
-# =====================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libandroidfw
-LOCAL_MODULE_HOST_OS := darwin linux windows
-LOCAL_CFLAGS += -DSTATIC_ANDROIDFW_FOR_TOOLS
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-LOCAL_SRC_FILES:= $(hostSources)
-LOCAL_C_INCLUDES := external/zlib
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# For the device
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= libandroidfw
-LOCAL_SRC_FILES:= $(deviceSources)
-LOCAL_C_INCLUDES := \
- system/core/include
-LOCAL_SHARED_LIBRARIES := \
- libziparchive \
- libbase \
- libbinder \
- liblog \
- libcutils \
- libgui \
- libutils \
- libz
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
-LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
-
-include $(BUILD_SHARED_LIBRARY)
-
-
# Include subdirectory makefiles
# ============================================================
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 6837f25..d18cb8f 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -28,6 +28,7 @@
Config_test.cpp \
ConfigLocale_test.cpp \
Idmap_test.cpp \
+ Main.cpp \
ResTable_test.cpp \
Split_test.cpp \
TestHelpers.cpp \
@@ -59,7 +60,8 @@
libutils \
libcutils \
liblog \
- libz \
+ libz
+LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
include $(BUILD_HOST_NATIVE_TEST)
@@ -80,7 +82,8 @@
libbase \
libcutils \
libutils \
- libui \
+ libui
+LOCAL_PICKUP_FILES := $(LOCAL_PATH)/data
include $(BUILD_NATIVE_TEST)
endif # Not SDK_ONLY
diff --git a/libs/androidfw/tests/AttributeResolution_test.cpp b/libs/androidfw/tests/AttributeResolution_test.cpp
index 7fbe6d3..d6d7890 100644
--- a/libs/androidfw/tests/AttributeResolution_test.cpp
+++ b/libs/androidfw/tests/AttributeResolution_test.cpp
@@ -15,24 +15,27 @@
*/
#include "androidfw/AttributeResolution.h"
+
+#include "android-base/file.h"
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+
#include "TestHelpers.h"
#include "data/styles/R.h"
-#include <android-base/file.h>
-#include <android-base/macros.h>
-
-using namespace android;
-using android::base::ReadFileToString;
using com::android::app::R;
+namespace android {
+
class AttributeResolutionTest : public ::testing::Test {
public:
virtual void SetUp() override {
- std::string test_source_dir = TestSourceDir();
+ std::string test_source_dir = GetTestDataPath();
std::string contents;
- LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/resources.arsc", &contents));
- LOG_ALWAYS_FATAL_IF(
- table_.add(contents.data(), contents.size(), 1 /*cookie*/, true /*copyData*/) != NO_ERROR);
+ CHECK(base::ReadFileToString(test_source_dir + "/styles/resources.arsc",
+ &contents));
+ CHECK(table_.add(contents.data(), contents.size(), 1 /*cookie*/,
+ true /*copyData*/) == NO_ERROR);
}
protected:
@@ -43,11 +46,12 @@
public:
virtual void SetUp() override {
AttributeResolutionTest::SetUp();
- std::string test_source_dir = TestSourceDir();
+ std::string test_source_dir = GetTestDataPath();
std::string contents;
- LOG_ALWAYS_FATAL_IF(!ReadFileToString(test_source_dir + "/styles/layout.xml", &contents));
- LOG_ALWAYS_FATAL_IF(xml_parser_.setTo(contents.data(), contents.size(), true /*copyData*/) !=
- NO_ERROR);
+ CHECK(base::ReadFileToString(test_source_dir + "/styles/layout.xml",
+ &contents));
+ CHECK(xml_parser_.setTo(contents.data(), contents.size(),
+ true /*copyData*/) == NO_ERROR);
// Skip to the first tag.
while (xml_parser_.next() != ResXMLParser::START_TAG) {
@@ -68,8 +72,9 @@
values.resize(arraysize(attrs) * 6);
ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/,
- nullptr /*src_values*/, 0 /*src_values_length*/, attrs, arraysize(attrs),
- values.data(), nullptr /*out_indices*/));
+ nullptr /*src_values*/, 0 /*src_values_length*/,
+ attrs, arraysize(attrs), values.data(),
+ nullptr /*out_indices*/));
const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
@@ -111,8 +116,8 @@
std::vector<uint32_t> values;
values.resize(arraysize(attrs) * 6);
- ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs, arraysize(attrs), values.data(),
- nullptr /*out_indices*/));
+ ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs, arraysize(attrs),
+ values.data(), nullptr /*out_indices*/));
uint32_t* values_cursor = values.data();
EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]);
@@ -151,13 +156,14 @@
ResTable::Theme theme(table_);
ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo));
- uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, R::attr::attr_four,
- R::attr::attr_five};
+ uint32_t attrs[] = {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three,
+ R::attr::attr_four, R::attr::attr_five};
std::vector<uint32_t> values;
values.resize(arraysize(attrs) * 6);
- ASSERT_TRUE(ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs,
- arraysize(attrs), values.data(), nullptr /*out_indices*/));
+ ASSERT_TRUE(ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/,
+ 0 /*def_style_res*/, attrs, arraysize(attrs),
+ values.data(), nullptr /*out_indices*/));
const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC;
@@ -199,3 +205,5 @@
EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]);
EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]);
}
+
+} // namespace android
diff --git a/libs/androidfw/tests/Main.cpp b/libs/androidfw/tests/Main.cpp
new file mode 100644
index 0000000..6a50691
--- /dev/null
+++ b/libs/androidfw/tests/Main.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libgen.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "android-base/file.h"
+#include "android-base/strings.h"
+#include "gtest/gtest.h"
+
+#include "TestHelpers.h"
+
+// Extract the directory of the current executable path.
+static std::string GetExecutableDir() {
+ const std::string path = android::base::GetExecutablePath();
+ std::unique_ptr<char, decltype(&std::free)> mutable_path = {
+ strdup(path.c_str()), std::free};
+ std::string executable_dir = dirname(mutable_path.get());
+ return executable_dir;
+}
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ // Set the default test data path to be the executable path directory.
+ android::SetTestDataPath(GetExecutableDir());
+
+ const char* command = argv[0];
+ ++argv;
+ --argc;
+
+ while (argc > 0) {
+ const std::string arg = *argv;
+ if (android::base::StartsWith(arg, "--testdata=")) {
+ android::SetTestDataPath(arg.substr(strlen("--testdata=")));
+ } else if (arg == "-h" || arg == "--help") {
+ std::cerr
+ << "\nAdditional options specific to this test:\n"
+ " --testdata=[PATH]\n"
+ " Specify the location of test data used within the tests.\n";
+ return 1;
+ } else {
+ std::cerr << command << ": Unrecognized argument '" << *argv << "'.\n";
+ return 1;
+ }
+
+ --argc;
+ ++argv;
+ }
+
+ std::cerr << "using --testdata=" << android::GetTestDataPath() << "\n";
+ return RUN_ALL_TESTS();
+}
diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp
index 3d1d5f5..702ee5c 100644
--- a/libs/androidfw/tests/TestHelpers.cpp
+++ b/libs/androidfw/tests/TestHelpers.cpp
@@ -16,26 +16,23 @@
#include "TestHelpers.h"
-#include <androidfw/ResourceTypes.h>
-#include <gtest/gtest.h>
#include <unistd.h>
-#include <utils/String8.h>
-std::string TestSourceDir() {
- const char* dir = getenv("ANDROID_BUILD_TOP");
- LOG_ALWAYS_FATAL_IF(dir == nullptr, "Environment variable ANDROID_BUILD_TOP must be set");
- std::string testdir = std::string(dir) + "/frameworks/base/libs/androidfw/tests/data";
-
- // Check that the directory exists.
- struct stat filestat;
- LOG_ALWAYS_FATAL_IF(stat(testdir.c_str(), &filestat) != 0, "test data path '%s' does not exist",
- testdir.c_str());
- return testdir;
-}
+#include "android-base/logging.h"
namespace android {
-::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
+static std::string sTestDataPath;
+
+void SetTestDataPath(const std::string& path) { sTestDataPath = path; }
+
+const std::string& GetTestDataPath() {
+ CHECK(!sTestDataPath.empty()) << "no test data path set.";
+ return sTestDataPath;
+}
+
+::testing::AssertionResult IsStringEqual(const ResTable& table,
+ uint32_t resource_id,
const char* expected_str) {
Res_value val;
ssize_t block = table.getResource(resource_id, &val, MAY_NOT_BE_BAG);
@@ -49,7 +46,8 @@
const ResStringPool* pool = table.getTableStringBlock(block);
if (pool == NULL) {
- return ::testing::AssertionFailure() << "table has no string pool for block " << block;
+ return ::testing::AssertionFailure()
+ << "table has no string pool for block " << block;
}
const String8 actual_str = pool->string8ObjectAt(val.data);
diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h
index 5f0c4552..c1e349f 100644
--- a/libs/androidfw/tests/TestHelpers.h
+++ b/libs/androidfw/tests/TestHelpers.h
@@ -14,24 +14,24 @@
* limitations under the License.
*/
-#ifndef __TEST_HELPERS_H
-#define __TEST_HELPERS_H
-
-#include <androidfw/ResourceTypes.h>
-#include <gtest/gtest.h>
-#include <utils/String16.h>
-#include <utils/String8.h>
+#ifndef TEST_HELPERS_H_
+#define TEST_HELPERS_H_
#include <ostream>
#include <string>
-std::string TestSourceDir();
+#include "androidfw/ResourceTypes.h"
+#include "gtest/gtest.h"
+#include "utils/String16.h"
+#include "utils/String8.h"
-static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) {
+static inline ::std::ostream& operator<<(::std::ostream& out,
+ const android::String8& str) {
return out << str.string();
}
-static inline ::std::ostream& operator<<(::std::ostream& out, const android::String16& str) {
+static inline ::std::ostream& operator<<(::std::ostream& out,
+ const android::String16& str) {
return out << android::String8(str).string();
}
@@ -39,18 +39,24 @@
enum { MAY_NOT_BE_BAG = false };
-static inline bool operator==(const android::ResTable_config& a,
- const android::ResTable_config& b) {
+void SetTestDataPath(const std::string& path);
+
+const std::string& GetTestDataPath();
+
+static inline bool operator==(const ResTable_config& a,
+ const ResTable_config& b) {
return a.compare(b) == 0;
}
-static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) {
+static inline ::std::ostream& operator<<(::std::ostream& out,
+ const ResTable_config& c) {
return out << c.toString().string();
}
-::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resource_id,
+::testing::AssertionResult IsStringEqual(const ResTable& table,
+ uint32_t resource_id,
const char* expected_str);
} // namespace android
-#endif // __TEST_HELPERS_H
+#endif // TEST_HELPERS_H_
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index eff2499..cf571e9 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -278,6 +278,7 @@
tests/unit/BakedOpDispatcherTests.cpp \
tests/unit/BakedOpRendererTests.cpp \
tests/unit/BakedOpStateTests.cpp \
+ tests/unit/BitmapTests.cpp \
tests/unit/CanvasContextTests.cpp \
tests/unit/CanvasStateTests.cpp \
tests/unit/ClipAreaTests.cpp \
@@ -297,6 +298,7 @@
tests/unit/MeshStateTests.cpp \
tests/unit/OffscreenBufferPoolTests.cpp \
tests/unit/OpDumperTests.cpp \
+ tests/unit/PathInterpolatorTests.cpp \
tests/unit/RenderNodeDrawableTests.cpp \
tests/unit/RecordingCanvasTests.cpp \
tests/unit/RenderNodeTests.cpp \
diff --git a/libs/hwui/Extensions.cpp b/libs/hwui/Extensions.cpp
index 1d67579..00238a2 100644
--- a/libs/hwui/Extensions.cpp
+++ b/libs/hwui/Extensions.cpp
@@ -37,6 +37,26 @@
Extensions::Extensions() {
+ const char* version = (const char*) glGetString(GL_VERSION);
+
+ // Section 6.1.5 of the OpenGL ES specification indicates the GL version
+ // string strictly follows this format:
+ //
+ // OpenGL<space>ES<space><version number><space><vendor-specific information>
+ //
+ // In addition section 6.1.5 describes the version number thusly:
+ //
+ // "The version number is either of the form major number.minor number or
+ // major number.minor number.release number, where the numbers all have one
+ // or more digits. The release number and vendor specific information are
+ // optional."
+
+ if (sscanf(version, "OpenGL ES %d.%d", &mVersionMajor, &mVersionMinor) != 2) {
+ // If we cannot parse the version number, assume OpenGL ES 2.0
+ mVersionMajor = 2;
+ mVersionMinor = 0;
+ }
+
auto extensions = StringUtils::split((const char*) glGetString(GL_EXTENSIONS));
mHasNPot = extensions.has("GL_OES_texture_npot");
mHasFramebufferFetch = extensions.has("GL_NV_shader_framebuffer_fetch");
@@ -58,26 +78,6 @@
mHasSRGB = false;
mHasSRGBWriteControl = false;
#endif
-
- const char* version = (const char*) glGetString(GL_VERSION);
-
- // Section 6.1.5 of the OpenGL ES specification indicates the GL version
- // string strictly follows this format:
- //
- // OpenGL<space>ES<space><version number><space><vendor-specific information>
- //
- // In addition section 6.1.5 describes the version number thusly:
- //
- // "The version number is either of the form major number.minor number or
- // major number.minor number.release number, where the numbers all have one
- // or more digits. The release number and vendor specific information are
- // optional."
-
- if (sscanf(version, "OpenGL ES %d.%d", &mVersionMajor, &mVersionMinor) != 2) {
- // If we cannot parse the version number, assume OpenGL ES 2.0
- mVersionMajor = 2;
- mVersionMinor = 0;
- }
}
}; // namespace uirenderer
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index bddb01b..f94a22d 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -88,6 +88,39 @@
return t * t * ((mTension + 1) * t + mTension) + 1.0f;
}
+float PathInterpolator::interpolate(float t) {
+ if (t <= 0) {
+ return 0;
+ } else if (t >= 1) {
+ return 1;
+ }
+ // Do a binary search for the correct x to interpolate between.
+ size_t startIndex = 0;
+ size_t endIndex = mX.size() - 1;
+
+ while (endIndex > startIndex + 1) {
+ int midIndex = (startIndex + endIndex) / 2;
+ if (t < mX[midIndex]) {
+ endIndex = midIndex;
+ } else {
+ startIndex = midIndex;
+ }
+ }
+
+ float xRange = mX[endIndex] - mX[startIndex];
+ if (xRange == 0) {
+ return mY[startIndex];
+ }
+
+ float tInRange = t - mX[startIndex];
+ float fraction = tInRange / xRange;
+
+ float startY = mY[startIndex];
+ float endY = mY[endIndex];
+ return startY + (fraction * (endY - startY));
+
+}
+
LUTInterpolator::LUTInterpolator(float* values, size_t size)
: mValues(values)
, mSize(size) {
diff --git a/libs/hwui/Interpolator.h b/libs/hwui/Interpolator.h
index 6512008..224cee7 100644
--- a/libs/hwui/Interpolator.h
+++ b/libs/hwui/Interpolator.h
@@ -20,6 +20,7 @@
#include <memory>
#include <cutils/compiler.h>
+#include <vector>
namespace android {
namespace uirenderer {
@@ -100,6 +101,16 @@
const float mTension;
};
+class ANDROID_API PathInterpolator : public Interpolator {
+public:
+ explicit PathInterpolator(std::vector<float>&& x, std::vector<float>&& y)
+ : mX (x), mY(y) {}
+ virtual float interpolate(float input) override;
+private:
+ std::vector<float> mX;
+ std::vector<float> mY;
+};
+
class ANDROID_API LUTInterpolator : public Interpolator {
public:
LUTInterpolator(float* values, size_t size);
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 6973209..d05e7f6 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -40,7 +40,7 @@
//mChildren is allocated and initialized only the first time onDraw is called and cached for
//subsequent calls
mChildren.reserve(mEndChildIndex - mBeginChildIndex + 1);
- for (unsigned int i = mBeginChildIndex; i <= mEndChildIndex; i++) {
+ for (int i = mBeginChildIndex; i <= mEndChildIndex; i++) {
mChildren.push_back(const_cast<RenderNodeDrawable*>(&mDisplayList->mChildNodes[i]));
}
}
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
index 298a732..9f00d23 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -47,8 +47,8 @@
virtual void onDraw(SkCanvas* canvas) override;
private:
- size_t mEndChildIndex;
- size_t mBeginChildIndex;
+ int mEndChildIndex;
+ int mBeginChildIndex;
FatVector<RenderNodeDrawable*, 16> mChildren;
SkiaDisplayList* mDisplayList;
diff --git a/libs/hwui/tests/unit/BitmapTests.cpp b/libs/hwui/tests/unit/BitmapTests.cpp
new file mode 100644
index 0000000..8c7e081
--- /dev/null
+++ b/libs/hwui/tests/unit/BitmapTests.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "hwui/Bitmap.h"
+
+#include <SkBitmap.h>
+#include <SkColorTable.h>
+#include <SkImageInfo.h>
+
+#include <tests/common/TestUtils.h>
+
+using namespace android;
+using namespace android::uirenderer;
+
+TEST(Bitmap, colorTableRefCounting) {
+ const SkPMColor c[] = { SkPackARGB32(0x80, 0x80, 0, 0) };
+ SkColorTable* ctable = new SkColorTable(c, SK_ARRAY_COUNT(c));
+
+ SkBitmap* bm = new SkBitmap();
+ bm->allocPixels(SkImageInfo::Make(1, 1, kIndex_8_SkColorType, kPremul_SkAlphaType),
+ nullptr, ctable);
+ sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(bm, ctable);
+ EXPECT_FALSE(ctable->unique());
+ delete bm;
+ bitmap.reset();
+ EXPECT_TRUE(ctable->unique());
+ ctable->unref();
+}
+
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index 950b2c4..a1c225f 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -1530,6 +1530,8 @@
RENDERTHREAD_TEST(FrameBuilder, zReorder) {
auto parent = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
[](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.insertReorderBarrier(true);
+ canvas.insertReorderBarrier(false);
drawOrderedNode(&canvas, 0, 10.0f); // in reorder=false at this point, so played inorder
drawOrderedRect(&canvas, 1);
canvas.insertReorderBarrier(true);
diff --git a/libs/hwui/tests/unit/PathInterpolatorTests.cpp b/libs/hwui/tests/unit/PathInterpolatorTests.cpp
new file mode 100644
index 0000000..d7cb23a
--- /dev/null
+++ b/libs/hwui/tests/unit/PathInterpolatorTests.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <Interpolator.h>
+
+namespace android {
+namespace uirenderer {
+
+struct TestData {
+ const std::vector<float> x;
+ const std::vector<float> y;
+ const std::vector<float> inFraction;
+ const std::vector<float> outFraction;
+};
+
+const static TestData sTestDataSet[] = {
+ {
+ // Straight line as a path.
+ {0.0f, 1.0f},
+ {0.0f, 1.0f},
+ {0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f},
+ {0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f},
+ },
+
+ {
+ {
+ 0.0f, 0.5f, 0.5178955f, 0.5341797f, 0.5489991f, 0.5625f, 0.5748291f,
+ 0.5861328f, 0.60625005f, 0.62402344f, 0.640625f, 0.675f, 0.6951172f,
+ 0.71875f, 0.7470703f, 0.78125f, 0.82246095f, 0.84606934f, 0.871875f,
+ 0.9000244f, 0.93066406f, 0.96394044f, 1.0f
+ },
+ {
+ 0.0f, 0.0f, 0.0028686523f, 0.011230469f, 0.024719238f, 0.04296875f,
+ 0.06561279f, 0.092285156f, 0.15625f, 0.2319336f, 0.31640625f, 0.5f,
+ 0.5932617f, 0.68359375f, 0.7680664f, 0.84375f, 0.90771484f, 0.9343872f,
+ 0.95703125f, 0.97528076f, 0.98876953f, 0.99713135f, 1.0f
+ },
+ {
+ 0.0f, 0.03375840187072754f, 0.13503384590148926f, 0.23630905151367188f,
+ 0.336834192276001f, 0.4508626461029053f, 0.564141035079956f,
+ 0.6781694889068604f, 0.7921979427337646f, 0.9054763317108154f, 1.0f
+ },
+ {
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0459827296435833f,
+ 0.5146934390068054f, 0.8607426285743713f, 0.9776809215545654f, 1.0f
+
+ }
+
+ },
+ {
+ {
+ 0.0f, 0.017895509f, 0.034179688f, 0.048999026f, 0.0625f, 0.0748291f,
+ 0.08613282f, 0.10625f, 0.12402344f, 0.140625f, 0.17500001f, 0.19511719f,
+ 0.21875f, 0.24707031f, 0.28125f, 0.32246095f, 0.34606934f, 0.371875f,
+ 0.4000244f, 0.43066406f, 0.46394044f, 0.5f, 1.0f
+ },
+ {
+ 0.0f, 0.0028686523f, 0.011230469f, 0.024719238f, 0.04296875f, 0.06561279f,
+ 0.092285156f, 0.15625f, 0.2319336f, 0.31640625f, 0.5f, 0.5932617f,
+ 0.68359375f, 0.7680664f, 0.84375f, 0.90771484f, 0.9343872f, 0.95703125f,
+ 0.97528076f, 0.98876953f, 0.99713135f, 1.0f, 1.0f
+ },
+ {
+ 0.0f, 0.102020263671875f, 0.20330810546875f, 0.3165740966796875f,
+ 0.43060302734375f, 0.5318756103515625f, 0.6331634521484375f,
+ 0.746429443359375f, 0.84771728515625f, 0.9617462158203125f, 1.0f
+ },
+ {
+ 0.0f, 0.14280107617378235f, 0.6245699524879456f, 0.8985776901245117f,
+ 0.9887426495552063f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
+ }
+ },
+
+
+};
+
+static std::vector<float> getX(const TestData& data) {
+ return data.x;
+}
+
+static std::vector<float> getY(const TestData& data) {
+ return data.y;
+}
+
+TEST(Interpolator, pathInterpolation) {
+ for (const TestData& data: sTestDataSet) {
+ PathInterpolator interpolator(getX(data), getY(data));
+ for (size_t i = 0; i < data.inFraction.size(); i++) {
+ EXPECT_FLOAT_EQ(data.outFraction[i], interpolator.interpolate(data.inFraction[i]));
+ }
+ }
+}
+
+}
+}
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index c2df9ec..f4b686d 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -102,6 +102,8 @@
auto parent = TestUtils::createSkiaNode(0, 0, 100, 100,
[](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+ canvas.insertReorderBarrier(true);
+ canvas.insertReorderBarrier(false);
drawOrderedNode(&canvas, 0, 10.0f); // in reorder=false at this point, so played inorder
drawOrderedRect(&canvas, 1);
canvas.insertReorderBarrier(true);
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 93e86af..4c39c30 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -131,14 +131,11 @@
public String text;
public int requestorIdEncoding;
public int textEncoding;
- public Bundle extras;
};
public static class GpsNiResponse {
/* User response, one of the values in GpsUserResponseType */
int userResponse;
- /* Optional extra data to pass with the user response */
- Bundle extras;
};
private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() {
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index dd5f6ba..c1a178a 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.content.Context;
+import android.media.PlayerBase;
import android.net.Uri;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -163,6 +164,7 @@
* @deprecated use {@link #play(Context, Uri, boolean, AudioAttributes)} instead
*/
public void play(Context context, Uri uri, boolean looping, int stream) {
+ PlayerBase.deprecateStreamTypeForPlayback(stream, "AsyncPlayer", "play()");
if (context == null || uri == null) {
return;
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 43fb4b9..16b3315 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -359,6 +359,9 @@
* for an AudioTrack instance in streaming mode.
* @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
* @throws java.lang.IllegalArgumentException
+ * @deprecated use {@link Builder} or
+ * {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
+ * {@link AudioAttributes} instead of the stream type which is only for volume control.
*/
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode)
@@ -414,6 +417,9 @@
* @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
* @param sessionId Id of audio session the AudioTrack must be attached to
* @throws java.lang.IllegalArgumentException
+ * @deprecated use {@link Builder} or
+ * {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
+ * {@link AudioAttributes} instead of the stream type which is only for volume control.
*/
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode, int sessionId)
@@ -429,6 +435,7 @@
.build(),
bufferSizeInBytes,
mode, sessionId);
+ deprecateStreamTypeForPlayback(streamType, "AudioTrack", "AudioTrack()");
}
/**
@@ -1044,11 +1051,12 @@
}
/**
- * Returns the type of audio stream this AudioTrack is configured for.
+ * Returns the volume stream type of this AudioTrack.
* Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
* {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
* {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
- * {@link AudioManager#STREAM_NOTIFICATION}, or {@link AudioManager#STREAM_DTMF}.
+ * {@link AudioManager#STREAM_NOTIFICATION}, {@link AudioManager#STREAM_DTMF} or
+ * {@link AudioManager#STREAM_ACCESSIBILITY}.
*/
public int getStreamType() {
return mStreamType;
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 36ad90b..78da59c 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -124,10 +124,10 @@
* is called. It is a programming error to invoke methods such
* as {@link #getCurrentPosition()},
* {@link #getDuration()}, {@link #getVideoHeight()},
- * {@link #getVideoWidth()}, {@link #setAudioStreamType(int)},
+ * {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
* {@link #setLooping(boolean)},
* {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
- * {@link #stop()}, {@link #seekTo(int)}, {@link #prepare()} or
+ * {@link #stop()}, {@link #seekTo(int, int)}, {@link #prepare()} or
* {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
* methods is called right after a MediaPlayer object is constructed,
* the user supplied callback method OnErrorListener.onError() won't be
@@ -273,19 +273,22 @@
* </ul>
* </li>
* <li>The playback position can be adjusted with a call to
- * {@link #seekTo(int)}.
+ * {@link #seekTo(int, int)}.
* <ul>
- * <li>Although the asynchronuous {@link #seekTo(int)}
- * call returns right way, the actual seek operation may take a while to
+ * <li>Although the asynchronuous {@link #seekTo(int, int)}
+ * call returns right away, the actual seek operation may take a while to
* finish, especially for audio/video being streamed. When the actual
* seek operation completes, the internal player engine calls a user
* supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener
* has been registered beforehand via
* {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
* <li>Please
- * note that {@link #seekTo(int)} can also be called in the other states,
+ * note that {@link #seekTo(int, int)} can also be called in the other states,
* such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
- * </em> state.</li>
+ * </em> state. When {@link #seekTo(int, int)} is called in those states,
+ * one video frame will be displayed if the stream has video and the requested
+ * position is valid.
+ * </li>
* <li>Furthermore, the actual current playback position
* can be retrieved with a call to {@link #getCurrentPosition()}, which
* is helpful for applications such as a Music player that need to keep
@@ -407,7 +410,7 @@
* Error} </p></td>
* <td>This method must be called in idle state as the audio session ID must be known before
* calling setDataSource. Calling it does not change the object state. </p></td></tr>
- * <tr><td>setAudioStreamType </p></td>
+ * <tr><td>setAudioStreamType (deprecated)</p></td>
* <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
* PlaybackCompleted}</p></td>
* <td>{Error}</p></td>
@@ -819,7 +822,7 @@
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
* <p>Note that since {@link #prepare()} is called automatically in this method,
- * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio
+ * you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
* (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
*
@@ -838,7 +841,7 @@
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
* <p>Note that since {@link #prepare()} is called automatically in this method,
- * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio
+ * you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
* (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
*
@@ -901,7 +904,7 @@
* to free the resources. If not released, too many MediaPlayer instances will
* result in an exception.</p>
* <p>Note that since {@link #prepare()} is called automatically in this method,
- * you cannot change the audio stream type (see {@link #setAudioStreamType(int)}), audio
+ * you cannot change the audio
* session ID (see {@link #setAudioSessionId(int)}) or audio attributes
* (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
*
@@ -1502,13 +1505,107 @@
public native SyncParams getSyncParams();
/**
+ * Seek modes used in method seekTo(int, int) to move media position
+ * to a specified location.
+ *
+ * Do not change these mode values without updating their counterparts
+ * in include/media/IMediaSource.h!
+ */
+ /**
+ * This mode is used with {@link #seekTo(int, int)} to move media position to
+ * a sync (or key) frame associated with a data source that is located
+ * right before or at the given time.
+ *
+ * @see #seekTo(int, int)
+ */
+ public static final int SEEK_PREVIOUS_SYNC = 0x00;
+ /**
+ * This mode is used with {@link #seekTo(int, int)} to move media position to
+ * a sync (or key) frame associated with a data source that is located
+ * right after or at the given time.
+ *
+ * @see #seekTo(int, int)
+ */
+ public static final int SEEK_NEXT_SYNC = 0x01;
+ /**
+ * This mode is used with {@link #seekTo(int, int)} to move media position to
+ * a sync (or key) frame associated with a data source that is located
+ * closest to (in time) or at the given time.
+ *
+ * @see #seekTo(int, int)
+ */
+ public static final int SEEK_CLOSEST_SYNC = 0x02;
+ /**
+ * This mode is used with {@link #seekTo(int, int)} to move media position to
+ * a frame (not necessarily a key frame) associated with a data source that
+ * is located closest to or at the given time.
+ *
+ * @see #seekTo(int, int)
+ */
+ public static final int SEEK_CLOSEST = 0x03;
+
+ /** @hide */
+ @IntDef(
+ value = {
+ SEEK_PREVIOUS_SYNC,
+ SEEK_NEXT_SYNC,
+ SEEK_CLOSEST_SYNC,
+ SEEK_CLOSEST,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SeekMode {}
+
+ private native final void _seekTo(int msec, int mode);
+
+ /**
+ * Moves the media to specified time position by considering the given mode.
+ * <p>
+ * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
+ * There is at most one active seekTo processed at any time. If there is a to-be-completed
+ * seekTo, new seekTo requests will be queued in such a way that only the last request
+ * is kept. When current seekTo is completed, the queued request will be processed if
+ * that request is different from just-finished seekTo operation, i.e., the requested
+ * position or mode is different.
+ *
+ * @param msec the offset in milliseconds from the start to seek to.
+ * When seeking to the given time position, there is no guarantee that the data source
+ * has a frame located at the position. When this happens, a frame nearby will be rendered.
+ * If msec is negative, time position zero will be used.
+ * If msec is larger than duration, duration will be used.
+ * @param mode the mode indicating where exactly to seek to.
+ * Use {@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame
+ * that has a timestamp earlier than or the same as msec. Use
+ * {@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame
+ * that has a timestamp later than or the same as msec. Use
+ * {@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame
+ * that has a timestamp closest to or the same as msec. Use
+ * {@link #SEEK_CLOSEST} if one wants to seek to a frame that may
+ * or may not be a sync frame but is closest to or the same as msec.
+ * {@link #SEEK_CLOSEST} often has larger performance overhead compared
+ * to the other options if there is no sync frame located at msec.
+ * @throws IllegalStateException if the internal player engine has not been
+ * initialized
+ * @throws IllegalArgumentException if the mode is invalid.
+ */
+ public void seekTo(int msec, @SeekMode int mode) throws IllegalStateException {
+ if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
+ final String msg = "Illegal seek mode: " + mode;
+ throw new IllegalArgumentException(msg);
+ }
+ _seekTo(msec, mode);
+ }
+
+ /**
* Seeks to specified time position.
+ * Same as {@link #seekTo(int, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
*
* @param msec the offset in milliseconds from the start to seek to
* @throws IllegalStateException if the internal player engine has not been
* initialized
*/
- public native void seekTo(int msec) throws IllegalStateException;
+ public void seekTo(int msec) throws IllegalStateException {
+ seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
+ }
/**
* Get current playback position as a {@link MediaTimestamp}.
@@ -1746,9 +1843,11 @@
* thereafter.
*
* @param streamtype the audio stream type
+ * @deprecated use {@link #setAudioAttributes(AudioAttributes)}
* @see android.media.AudioManager
*/
public void setAudioStreamType(int streamtype) {
+ deprecateStreamTypeForPlayback(streamtype, "MediaPlayer", "setAudioStreamType()");
baseUpdateAudioAttributes(
new AudioAttributes.Builder().setInternalLegacyStreamType(streamtype).build());
_setAudioStreamType(streamtype);
diff --git a/media/java/android/media/PlayerBase.java b/media/java/android/media/PlayerBase.java
index 690a553..42f6b83 100644
--- a/media/java/android/media/PlayerBase.java
+++ b/media/java/android/media/PlayerBase.java
@@ -236,4 +236,28 @@
*/
abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume);
abstract int playerSetAuxEffectSendLevel(boolean muting, float level);
+
+ //=====================================================================
+ // Utilities
+
+ /**
+ * Use to generate warning or exception in legacy code paths that allowed passing stream types
+ * to qualify audio playback.
+ * @param streamType the stream type to check
+ * @throws IllegalArgumentException
+ */
+ public static void deprecateStreamTypeForPlayback(int streamType, String className,
+ String opName) throws IllegalArgumentException {
+ // STREAM_ACCESSIBILITY was introduced at the same time the use of stream types
+ // for audio playback was deprecated, so it is not allowed at all to qualify a playback
+ // use case
+ if (streamType == AudioManager.STREAM_ACCESSIBILITY) {
+ throw new IllegalArgumentException("Use of STREAM_ACCESSIBILITY is reserved for "
+ + "volume control");
+ }
+ Log.e(className, "Use of stream types is deprecated for operations other than " +
+ "volume control.");
+ Log.e(className, "See the documentation of " + opName + " for what to use instead with " +
+ "android.media.AudioAttributes to qualify your playback use case");
+ }
}
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index 7767712..209ec42 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -103,6 +103,7 @@
*/
@Deprecated
public void setStreamType(int streamType) {
+ PlayerBase.deprecateStreamTypeForPlayback(streamType, "Ringtone", "setStreamType()");
setAudioAttributes(new AudioAttributes.Builder()
.setInternalLegacyStreamType(streamType)
.build());
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 3cb01de..de9f020 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -297,7 +297,7 @@
}
/**
- * Infers the playback stream type based on what type of ringtones this
+ * Infers the volume stream type based on what type of ringtones this
* manager is returning.
*
* @return The stream type.
@@ -616,6 +616,7 @@
return getRingtone(context, ringtoneUri, -1);
}
+ //FIXME bypass the notion of stream types within the class
/**
* Returns a {@link Ringtone} for a given sound URI on the given stream
* type. Normally, if you change the stream type on the returned
@@ -630,6 +631,7 @@
try {
final Ringtone r = new Ringtone(context, true);
if (streamType >= 0) {
+ //FIXME deprecated call
r.setStreamType(streamType);
}
r.setUri(ringtoneUri);
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index b429e22..838767c 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -24,6 +24,7 @@
import android.app.AppOpsManager;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
+import android.media.PlayerBase;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -146,6 +147,7 @@
public SoundPool(int maxStreams, int streamType, int srcQuality) {
this(maxStreams,
new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+ PlayerBase.deprecateStreamTypeForPlayback(streamType, "SoundPool", "SoundPool()");
}
private SoundPool(int maxStreams, AudioAttributes attributes) {
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index c825702..c52ed94 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -577,15 +577,15 @@
}
static void
-android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec)
+android_media_MediaPlayer_seekTo(JNIEnv *env, jobject thiz, jint msec, jint mode)
{
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
return;
}
- ALOGV("seekTo: %d(msec)", msec);
- process_media_player_call( env, thiz, mp->seekTo(msec), NULL, NULL );
+ ALOGV("seekTo: %d(msec), mode=%d", msec, mode);
+ process_media_player_call( env, thiz, mp->seekTo(msec, (MediaPlayerSeekMode)mode), NULL, NULL );
}
static jint
@@ -1056,7 +1056,7 @@
{"getPlaybackParams", "()Landroid/media/PlaybackParams;", (void *)android_media_MediaPlayer_getPlaybackParams},
{"setSyncParams", "(Landroid/media/SyncParams;)V", (void *)android_media_MediaPlayer_setSyncParams},
{"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer_getSyncParams},
- {"seekTo", "(I)V", (void *)android_media_MediaPlayer_seekTo},
+ {"_seekTo", "(II)V", (void *)android_media_MediaPlayer_seekTo},
{"_pause", "()V", (void *)android_media_MediaPlayer_pause},
{"isPlaying", "()Z", (void *)android_media_MediaPlayer_isPlaying},
{"getCurrentPosition", "()I", (void *)android_media_MediaPlayer_getCurrentPosition},
diff --git a/opengl/java/android/opengl/GLES30.java b/opengl/java/android/opengl/GLES30.java
index 74181c5..3b805d2 100644
--- a/opengl/java/android/opengl/GLES30.java
+++ b/opengl/java/android/opengl/GLES30.java
@@ -590,6 +590,10 @@
// C function void glGetBufferPointerv ( GLenum target, GLenum pname, GLvoid** params )
+ /**
+ * The {@link java.nio.Buffer} instance returned by this method is guaranteed
+ * to be an instance of {@link java.nio.ByteBuffer}.
+ */
public static native java.nio.Buffer glGetBufferPointerv(
int target,
int pname
@@ -761,6 +765,10 @@
// C function GLvoid * glMapBufferRange ( GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access )
+ /**
+ * The {@link java.nio.Buffer} instance returned by this method is guaranteed
+ * to be an instance of {@link java.nio.ByteBuffer}.
+ */
public static native java.nio.Buffer glMapBufferRange(
int target,
int offset,
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index d0abbf9..a281bba 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"ብጁ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"እገዛ እና ግብረመልስ"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"ምናሌ"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"ጂኤምቲ"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0eebcd7..9f6c440 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"مخصص (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"المساعدة والتعليقات"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"القائمة"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"غرينيتش"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index cbb2271..cad5980 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Prilagođeni (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Pomoć i povratne informacije"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Meni"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml
index 12f103d..ba5b100 100644
--- a/packages/SettingsLib/res/values-be-rBY/strings.xml
+++ b/packages/SettingsLib/res/values-be-rBY/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Карыстальніцкі (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Даведка і водгукі"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 19382ec..c360f87 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalitzat (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ajuda i suggeriments"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 032d73d..f331080 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Προσαρμοσμένη (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Βοήθεια και σχόλια"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Μενού"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 57738e8..e27822f 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 57738e8..e27822f 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 57738e8..e27822f 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Custom (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Help & feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 259e7fb..4353282 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ayuda y sugerencias"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menú"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml
index 952fda8..3e08c77 100644
--- a/packages/SettingsLib/res/values-eu-rES/strings.xml
+++ b/packages/SettingsLib/res/values-eu-rES/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Pertsonalizatua (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Laguntza eta iritziak"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menua"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index bf96b59..648f7b3 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Muokattu (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ohje ja palaute"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Valikko"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml
index 1cded3d..a732ea1 100644
--- a/packages/SettingsLib/res/values-gu-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"કસ્ટમ (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"સહાય અને પ્રતિસાદ"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"મેનુ"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 07241b5..9559887 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"(<xliff:g id="DENSITYDPI">%d</xliff:g>) khusus"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Bantuan & masukan"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml
index 8e8307b..8be8444 100644
--- a/packages/SettingsLib/res/values-is-rIS/strings.xml
+++ b/packages/SettingsLib/res/values-is-rIS/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Sérsniðið (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Hjálp og ábendingar"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Valmynd"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index d894ccf..74ee5a1 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizzato (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Guida e feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml
index 609cb33..8a3b81b 100644
--- a/packages/SettingsLib/res/values-ka-rGE/strings.xml
+++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"მორგებული (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"დახმარება და გამოხმაურება"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"მენიუ"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml
index a2eb86d..3783cce 100644
--- a/packages/SettingsLib/res/values-ky-rKG/strings.xml
+++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Ыңгайлаштырылган (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Жардам жана жооп пикир"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml
index 711b949..ebe8d00 100644
--- a/packages/SettingsLib/res/values-mk-rMK/strings.xml
+++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Приспособен (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Помош и повратни информации"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Мени"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml
index 20f64fe..be1fbc6 100644
--- a/packages/SettingsLib/res/values-mr-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"सानुकूल करा (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"मदत आणि अभिप्राय"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"मेनू"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml
index a8a918b..834580b 100644
--- a/packages/SettingsLib/res/values-ne-rNP/strings.xml
+++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"अनुकूलन (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"मद्दत र प्रतिक्रिया"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"मेनु"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 8bb4579..0f2e6d4 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Help en feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 4db3e6e..738974f 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Niestandardowe (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Pomoc i opinie"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 7855beb..ab866c8 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 2c366c6..2e4bbdc8 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizado (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e comentários"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 7855beb..ab866c8 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Personalizada (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Ajuda e feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 2cf68a5..5fd58a5 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Прилагођени (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Помоћ и повратне информације"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Мени"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 975a4aa..ee93622 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Anpassad (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Hjälp och feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Meny"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index b538545..29557ec 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Спеціальний масштаб (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Довідка й відгуки"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Меню"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 8d1056a..05879a2 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -341,6 +341,5 @@
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Moslashtirilgan (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
<string name="help_feedback_label" msgid="6815040660801785649">"Yordam va fikr-mulohaza"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menyu"</string>
- <!-- no translation found for time_zone_gmt (2587097992671450782) -->
- <skip />
+ <string name="time_zone_gmt" msgid="2587097992671450782">"GMT"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index f0ec107..2b1582d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -135,11 +135,11 @@
mBackgroundHandler = new BackgroundHandler(mThread.getLooper());
// Only the owner can see all apps.
- mAdminRetrieveFlags = PackageManager.GET_UNINSTALLED_PACKAGES |
- PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
- mRetrieveFlags = PackageManager.GET_DISABLED_COMPONENTS |
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS;
+ mAdminRetrieveFlags = PackageManager.MATCH_ANY_USER |
+ PackageManager.MATCH_DISABLED_COMPONENTS |
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
+ mRetrieveFlags = PackageManager.MATCH_DISABLED_COMPONENTS |
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS;
/**
* This is a trick to prevent the foreground thread from being delayed.
@@ -855,7 +855,7 @@
// explicitly include both direct boot aware and unaware components here.
List<ResolveInfo> intents = mPm.queryIntentActivitiesAsUser(
launchIntent,
- PackageManager.GET_DISABLED_COMPONENTS
+ PackageManager.MATCH_DISABLED_COMPONENTS
| PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
userId
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
index 5c577f8..e520319 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java
@@ -409,8 +409,8 @@
// Measure all apps hosted on this volume for all users
if (mVolume.getType() == VolumeInfo.TYPE_PRIVATE) {
final List<ApplicationInfo> apps = packageManager.getInstalledApplications(
- PackageManager.GET_UNINSTALLED_PACKAGES
- | PackageManager.GET_DISABLED_COMPONENTS);
+ PackageManager.MATCH_ANY_USER
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
final List<ApplicationInfo> volumeApps = new ArrayList<>();
for (ApplicationInfo app : apps) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
index c189e1d..c4aa57d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -112,7 +112,7 @@
// Enable selected apps
try {
ApplicationInfo info = mIPm.getApplicationInfo(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ PackageManager.MATCH_ANY_USER, userId);
if (info == null || !info.enabled
|| (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier());
@@ -178,7 +178,7 @@
addSystemApps(mVisibleApps, widgetIntent, excludePackages);
List<ApplicationInfo> installedApps = pm.getInstalledApplications(
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
for (ApplicationInfo app : installedApps) {
// If it's not installed, skip
if ((app.flags & ApplicationInfo.FLAG_INSTALLED) == 0) continue;
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 444f0f0..078f9d7 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -24,17 +24,36 @@
android:outlineProvider="none"
android:elevation="5dp" > <!-- Put it above the status bar header -->
- <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
- android:id="@+id/keyguard_indication_text"
+ <LinearLayout
+ android:id="@+id/keyguard_indication_area"
+ android:forceHasOverlappingRendering="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
android:layout_gravity="bottom|center_horizontal"
- android:gravity="center_horizontal"
- android:textStyle="italic"
- android:textColor="#ffffff"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:accessibilityLiveRegion="polite" />
+ android:orientation="vertical">
+
+ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+ android:id="@+id/keyguard_indication_enterprise_disclosure"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:textStyle="italic"
+ android:textColor="#ffffff"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:visibility="gone" />
+
+ <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
+ android:id="@+id/keyguard_indication_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:textStyle="italic"
+ android:textColor="#ffffff"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:accessibilityLiveRegion="polite" />
+
+ </LinearLayout>
<FrameLayout
android:id="@+id/preview_container"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 5294c9c..40308dc 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Toeganklikheid"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tik om te ontdemp."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tik om op vibreer te stel. Toeganklikheidsdienste kan dalk gedemp wees."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 601930a..f807ba9 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"ተደራሽነት"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s። ድምጸ-ከል ለማድረግ መታ ያድርጉ"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s። ወደ ንዝረት ለማቀናበር መታ ያድርጉ። የተደራሽነት አገልግሎቶች ድምጸ-ከል ሊደረግባቸው ይችላል።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index a1a8f8d..33110ce 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -459,6 +459,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"إمكانية الوصول"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. انقر لإلغاء التجاهل."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. انقر للتعيين على الاهتزاز. قد يتم تجاهل خدمات إمكانية الوصول."</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 1bc9e59..49f27b2 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Münasiblik"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Səsli etmək üçün tıklayın."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Vibrasiyanı ayarlamaq üçün tıklayın. Əlçatımlılıq xidmətləri səssiz edilmiş ola bilər."</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 8105d9e..dc21bde 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Pristupačnost"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Dodirnite da biste uključili zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite da biste podesili na vibraciju. Zvuk usluga pristupačnosti će možda biti isključen."</string>
diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml
index 83c67d4..ac93da7 100644
--- a/packages/SystemUI/res/values-be-rBY/strings.xml
+++ b/packages/SystemUI/res/values-be-rBY/strings.xml
@@ -457,6 +457,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Спецыяльныя магчымасці"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Дакраніцеся, каб уключыць гук."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Дакраніцеся, каб уключыць вібрацыю. Можа быць адключаны гук службаў спецыяльных магчымасцей."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index bf3a614..7814efb 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Достъпност"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Докоснете, за да включите отново звука."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Докоснете, за да зададете вибриране. Възможно е звукът на услугите за достъпност да бъде заглушен."</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index bd599bc..c80efa4 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> হল ভলিউম ডায়লগ"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"আসলটি পুনঃস্থাপন করতে আলতো চাপ দিন৷"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"আপনি আপনার কাজের প্রোফাইল ব্যবহার করছেন"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"কল করুন"</item>
- <item msgid="5997713001067658559">"সিস্টেম"</item>
- <item msgid="7858983209929864160">"রিং"</item>
- <item msgid="1850038478268896762">"মিডিয়া"</item>
- <item msgid="8265110906352372092">"অ্যালার্ম"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ব্লুটুথ"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s। সশব্দ করতে আলতো চাপুন।"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s। কম্পন এ সেট করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে নিঃশব্দ করা হতে পারে।"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। নিঃশব্দ করতে আলতো চাপুন। অ্যাক্সেসযোগ্যতার পরিষেবাগুলিকে নিঃশব্দ করা হতে পারে।"</string>
diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml
index 5ba720c..2d02a4f 100644
--- a/packages/SystemUI/res/values-bs-rBA/strings.xml
+++ b/packages/SystemUI/res/values-bs-rBA/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Pristupačnost"</item>
</string-array>
<!-- String.format failed for translation -->
<!-- no translation found for volume_stream_content_description_unmute (4436631538779230857) -->
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 927e75b..b0e6fe5 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accessibilitat"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toca per activar el so."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toca per activar la vibració. Pot ser que els serveis d\'accessibilitat se silenciïn."</string>
@@ -472,7 +473,7 @@
<string name="status_bar_airplane" msgid="7057575501472249002">"Mode d\'avió"</string>
<string name="add_tile" msgid="2995389510240786221">"Afegeix un mosaic"</string>
<string name="broadcast_tile" msgid="3894036511763289383">"Mosaic d\'emissió"</string>
- <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Si no desactives aquesta opció abans, <xliff:g id="WHEN">%1$s</xliff:g> no sentiràs la pròxima alarma"</string>
+ <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"Si no desactives aquesta opció abans, no sentiràs la pròxima alarma (<xliff:g id="WHEN">%1$s</xliff:g>)"</string>
<string name="zen_alarm_warning" msgid="444533119582244293">"<xliff:g id="WHEN">%1$s</xliff:g> no sentiràs la pròxima alarma"</string>
<string name="alarm_template" msgid="3980063409350522735">"Hora: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
<string name="alarm_template_far" msgid="4242179982586714810">"Dia: <xliff:g id="WHEN">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 69629a9..639f8b5 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -457,6 +457,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Přístupnost"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Klepnutím zapnete zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Klepnutím aktivujete režim vibrací. Služby přístupnosti mohou být ztlumeny."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 8e34bd0..8fa27ad 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"Tryk for at gendanne det oprindelige."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du bruger din arbejdsprofil"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Opkald"</item>
- <item msgid="5997713001067658559">"System"</item>
- <item msgid="7858983209929864160">"Ring"</item>
- <item msgid="1850038478268896762">"Medier"</item>
- <item msgid="8265110906352372092">"Alarm"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tryk for at slå lyden til."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tryk for at konfigurere til at vibrere. Tilgængelighedstjenester kan blive deaktiveret."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Tryk for at slå lyden fra. Lyden i tilgængelighedstjenester kan blive slået fra."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index b3a457d..564625f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -442,18 +442,7 @@
<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="8819536904234337445">"Tippe, um das Original wiederherzustellen."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du verwendest dein Arbeitsprofil."</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Anruf"</item>
- <item msgid="5997713001067658559">"System"</item>
- <item msgid="7858983209929864160">"Klingeln lassen"</item>
- <item msgid="1850038478268896762">"Medien"</item>
- <item msgid="8265110906352372092">"Wecker"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Zum Aufheben der Stummschaltung tippen."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tippen, um Vibrieren festzulegen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Zum Stummschalten tippen. Bedienungshilfen werden unter Umständen stummgeschaltet."</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 050d7f8..a5c790c 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Προσβασιμότητα"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Πατήστε για κατάργηση σίγασης."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Πατήστε για ενεργοποιήσετε τη δόνηση. Οι υπηρεσίες προσβασιμότητας ενδέχεται να τεθούν σε σίγαση."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 9aca3cc..5dacfb2 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accessibility"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 9aca3cc..5dacfb2 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accessibility"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 9aca3cc..5dacfb2 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accessibility"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tap to unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tap to set to vibrate. Accessibility services may be muted."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 90c2ca1..3ba4360 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accesibilidad"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Presiona para dejar de silenciar."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Presiona para establecer el modo vibración. Es posible que los servicios de accesibilidad estén silenciados."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 5558cac..969f812 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accesibilidad"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toca para activar el sonido."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toca para poner el dispositivo en vibración. Los servicios de accesibilidad pueden silenciarse."</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 84fadb2..e1ebfd2 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -442,18 +442,7 @@
<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="8819536904234337445">"Puudutage originaali taastamiseks."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Kasutate oma tööprofiili"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Helistamine"</item>
- <item msgid="5997713001067658559">"Süsteem"</item>
- <item msgid="7858983209929864160">"Helin"</item>
- <item msgid="1850038478268896762">"Meedia"</item>
- <item msgid="8265110906352372092">"Äratus"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Puudutage vaigistuse tühistamiseks."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Puudutage värinarežiimi määramiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Puudutage vaigistamiseks. Juurdepääsetavuse teenused võidakse vaigistada."</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index d6578a2..fa0c711 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Erabilerraztasuna"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Sakatu audioa aktibatzeko."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Sakatu dardara ezartzeko. Baliteke erabilerraztasun-eginbideen audioa desaktibatzea."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e00c5b5..bd3c4fc 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> کنترلکننده صدا است"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"برای بازیابی نسخه اصلی ضربه بزنید."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"درحال استفاده از نمایه کاریتان هستید"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"تماس"</item>
- <item msgid="5997713001067658559">"سیستم"</item>
- <item msgid="7858983209929864160">"تماس"</item>
- <item msgid="1850038478268896762">"رسانه"</item>
- <item msgid="8265110906352372092">"هشدار"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"بلوتوث"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. برای باصدا کردن ضربه بزنید."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. برای تنظیم روی لرزش ضربه بزنید. ممکن است سرویسهای دسترسپذیری بیصدا شوند."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. برای بیصدا کردن ضربه بزنید. ممکن است سرویسهای دسترسپذیری بیصدا شوند."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 08572fe..446c9f8 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Esteettömyys"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Poista mykistys koskettamalla."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Siirry värinätilaan koskettamalla. Myös esteettömyyspalvelut saattavat mykistyä."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 830bfa7..a03e897 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -442,18 +442,7 @@
<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="8819536904234337445">"Touchez pour restaurer l\'original."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Appeler"</item>
- <item msgid="5997713001067658559">"Système"</item>
- <item msgid="7858983209929864160">"Sonnerie"</item>
- <item msgid="1850038478268896762">"Multimédia"</item>
- <item msgid="8265110906352372092">"Alarme"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Touchez pour réactiver le son."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Touchez pour activer les vibrations. Il est possible de couper le son des services d\'accessibilité."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Touchez pour couper le son. Il est possible de couper le son des services d\'accessibilité."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 3b138c2..1e72795 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -442,18 +442,7 @@
<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="8819536904234337445">"Appuyez pour rétablir la version d\'origine."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Vous utilisez votre profil professionnel."</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Appeler"</item>
- <item msgid="5997713001067658559">"Système"</item>
- <item msgid="7858983209929864160">"Sonnerie"</item>
- <item msgid="1850038478268896762">"Multimédia"</item>
- <item msgid="8265110906352372092">"Alarme"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Appuyez pour ne plus ignorer."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Appuyez pour mettre en mode vibreur. Vous pouvez ignorer les services d\'accessibilité."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Appuyez pour ignorer. Vous pouvez ignorer les services d\'accessibilité."</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 579335d..515c729 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accesibilidade"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toca para activar o son."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toca para establecer a vibración. Pódense silenciar os servizos de accesibilidade."</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 48a6d0f..9778b86 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"ઍક્સેસિબિલિટી"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. અનમ્યૂટ કરવા માટે ટૅપ કરો."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. વાઇબ્રેટ પર સેટ કરવા માટે ટૅપ કરો. ઍક્સેસિબિલિટી સેવાઓ મ્યૂટ કરવામાં આવી શકે છે."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 97f3926..1010126 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> वॉल्यूम संवाद है"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"मूल को पुन: स्थापित करने के लिए टैप करें."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"आप अपनी कार्य प्रोफ़ाइल का उपयोग कर रहे हैं"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"कॉल करें"</item>
- <item msgid="5997713001067658559">"सिस्टम"</item>
- <item msgid="7858983209929864160">"रिंग करें"</item>
- <item msgid="1850038478268896762">"मीडिया"</item>
- <item msgid="8265110906352372092">"अलार्म"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ब्लूटूथ"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. अनम्यूट करने के लिए टैप करें."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. कंपन पर सेट करने के लिए टैप करें. एक्सेस-योग्यता सेवाएं म्यूट हो सकती हैं."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. म्यूट करने के लिए टैप करें. एक्सेस-योग्यता सेवाएं म्यूट हो सकती हैं."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 7ff63bd..5d9162e 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Pristupačnost"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Dodirnite da biste uključili zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dodirnite da biste postavili na vibraciju. Usluge pristupačnosti možda neće imati zvuk."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index bd0805b..bb78030 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Kisegítő lehetőségek"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Koppintson a némítás megszüntetéséhez."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Koppintson a rezgés beállításához. Előfordulhat, hogy a kisegítő lehetőségek szolgáltatásai le vannak némítva."</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 07966cf..d9ec09e 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը ձայնի ուժգնության երկխոսության հավելված է"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"Հպեք՝ բնօրինակը վերականգնելու համար:"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Դուք օգտագործում եք ձեր աշխատանքային պրոֆիլը"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Զանգել"</item>
- <item msgid="5997713001067658559">"Համակարգ"</item>
- <item msgid="7858983209929864160">"Զանգ"</item>
- <item msgid="1850038478268896762">"Մեդիա"</item>
- <item msgid="8265110906352372092">"Զարթուցիչ"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s: Հպեք՝ ձայնը միացնելու համար:"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s: Հպեք՝ թրթռումը միացնելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s: Հպեք՝ ձայնն անջատելու համար: Մատչելիության ծառայությունների ձայնը կարող է անջատվել:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6444ae5..49d5221 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Aksesibilitas"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Ketuk untuk menyuarakan."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Ketuk untuk menyetel agar bergetar. Layanan aksesibilitas mungkin dibisukan."</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 7e08a01..f95d35f 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Aðgengi"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Ýttu til að hætta að þagga."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Ýttu til að stilla á titring. Hugsanlega verður slökkt á hljóði aðgengisþjónustu."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 8ffb10d..b30516d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Accessibilità"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tocca per riattivare l\'audio."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tocca per attivare la vibrazione. L\'audio dei servizi di accessibilità può essere disattivato."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a6d7983..c9f907a 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -444,18 +444,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא תיבת הדו-שיח של עוצמת הקול"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"הקש כדי לשחזר את המקור."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"אתה משתמש בפרופיל העבודה שלך"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"שיחה"</item>
- <item msgid="5997713001067658559">"מערכת"</item>
- <item msgid="7858983209929864160">"השמע צלצול"</item>
- <item msgid="1850038478268896762">"מדיה"</item>
- <item msgid="8265110906352372092">"התראה"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. הקש כדי לבטל את ההשתקה."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. הקש כדי להגדיר רטט. ייתכן ששירותי הנגישות מושתקים."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. הקש כדי להשתיק. ייתכן ששירותי הנגישות מושתקים."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6ef9f73..b891b61 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -442,18 +442,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>を音量ダイアログとして使用"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"タップすると元に戻ります。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"仕事用プロファイルを使用しています"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"通話"</item>
- <item msgid="5997713001067658559">"システム"</item>
- <item msgid="7858983209929864160">"着信音"</item>
- <item msgid="1850038478268896762">"メディア"</item>
- <item msgid="8265110906352372092">"アラーム"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s。タップしてミュートを解除します。"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s。タップしてバイブレーションに設定します。ユーザー補助機能サービスがミュートされる場合があります。"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。タップしてミュートします。ユーザー補助機能サービスがミュートされる場合があります。"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 695279d..e00d6b3 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"მარტივი წვდომა"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. შეეხეთ დადუმების გასაუქმებლად."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. შეეხეთ ვიბრაციაზე დასაყენებლად. შეიძლება დადუმდეს მარტივი წვდომის სერვისებიც."</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index ba71182..92b94bd 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> — көлем диалогтық терезесі"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"Бастапқы қалпына келтіру үшін түртіңіз."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Сіз жұмыс профиліңізді пайдаланып жатырсыз"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Қоңырау шалу"</item>
- <item msgid="5997713001067658559">"Жүйе"</item>
- <item msgid="7858983209929864160">"Шылдырлау"</item>
- <item msgid="1850038478268896762">"Мультимeдиа"</item>
- <item msgid="8265110906352372092">"Дабыл"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Дыбысын қосу үшін түртіңіз."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Діріл режимін орнату үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дыбысын өшіру үшін түртіңіз. Арнайы мүмкіндік қызметтерінің дыбысы өшуі мүмкін."</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index b222555..9a352fc 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាប្រអប់សម្លេង"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"ប៉ះដើម្បីស្តារច្បាប់ដើម"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"អ្នកកំពុងប្រើប្រវត្តិរូបការងាររបស់អ្នក"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"ហៅ"</item>
- <item msgid="5997713001067658559">"ប្រព័ន្ធ"</item>
- <item msgid="7858983209929864160">"រោទ៍"</item>
- <item msgid="1850038478268896762">"មេឌៀ"</item>
- <item msgid="8265110906352372092">"ម៉ោងរោទ៍"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ប៊្លូធូស"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s។ ប៉ះដើម្បីបើកសំឡេង។"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s។ ប៉ះដើម្បីកំណត់ឲ្យញ័រ។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s។ ប៉ះដើម្បីបិទសំឡេង។ សេវាកម្មលទ្ធភាពប្រើប្រាស់អាចនឹងត្រូវបានបិទសំឡេង។"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index b2a6f27..990c721 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ವಾಲ್ಯೂಮ್ ಸಂವಾದವಾಗಿದೆ"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"ಮೂಲಕ್ಕೆ ಮರುಸ್ಥಾಪಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ನಿಮ್ಮ ಕೆಲಸದ ಪ್ರೊಫೈಲ್ ಅನ್ನು ನೀವು ಬಳಸುತ್ತಿರುವಿರಿ"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"ಕರೆಮಾಡಿ"</item>
- <item msgid="5997713001067658559">"ಸಿಸ್ಟಂ"</item>
- <item msgid="7858983209929864160">"ಉಂಗುರ"</item>
- <item msgid="1850038478268896762">"ಮಾಧ್ಯಮ"</item>
- <item msgid="8265110906352372092">"ಅಲಾರಮ್"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ಬ್ಲೂಟೂತ್"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ಅನ್ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. ಕಂಪನಕ್ಕೆ ಹೊಂದಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ಮ್ಯೂಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಪ್ರವೇಶಿಸುವಿಕೆ ಸೇವೆಗಳನ್ನು ಮ್ಯೂಟ್ ಮಾಡಬಹುದು."</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index cefb57a..b06f15e 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -442,18 +442,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>은(는) 볼륨 대화입니다."</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"원본을 복원하려면 탭하세요."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"직장 프로필을 사용하고 있습니다."</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"통화"</item>
- <item msgid="5997713001067658559">"시스템"</item>
- <item msgid="7858983209929864160">"벨 울리기"</item>
- <item msgid="1850038478268896762">"미디어"</item>
- <item msgid="8265110906352372092">"알람"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"블루투스"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. 탭하여 음소거를 해제하세요."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. 탭하여 진동으로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. 탭하여 음소거로 설정하세요. 접근성 서비스가 음소거될 수 있습니다."</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index e013c6b..d5af0b3 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Атайын мүмкүнчүлүктөр"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Үнүн чыгаруу үчүн таптап коюңуз."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Дирилдөөгө коюу үчүн таптап коюңуз. Атайын мүмкүнчүлүктөр кызматынын үнүн өчүрүп койсо болот."</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 94e789a..711a68d 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນໜ້າຕ່າງລະດັບສຽງ"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"ແຕະເພື່ອກູ້ຕົ້ນສະບັບຄືນມາ."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ທ່ານກຳລັງໃຊ້ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຂອງທ່ານ"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"ໂທ"</item>
- <item msgid="5997713001067658559">"ລະບົບ"</item>
- <item msgid="7858983209929864160">"ເຕືອນດ້ວຍສຽງ"</item>
- <item msgid="1850038478268896762">"ມີເດຍ"</item>
- <item msgid="8265110906352372092">"ໂມງປຸກ"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ແຕະເພື່ອເຊົາປິດສຽງ."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. ແຕະເພື່ອຕັ້ງເປັນສັ່ນ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ແຕະເພື່ອປິດສຽງ. ບໍລິການຊ່ວຍເຂົ້າເຖິງອາດຖືກປິດສຽງໄວ້."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 5af5979..aec484d 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -444,18 +444,7 @@
<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="8819536904234337445">"Palieskite, kad atkurtumėte originalą."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Naudojate darbo profilį"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Skambinti"</item>
- <item msgid="5997713001067658559">"Sistema"</item>
- <item msgid="7858983209929864160">"Skambinti"</item>
- <item msgid="1850038478268896762">"Medija"</item>
- <item msgid="8265110906352372092">"Signalas"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Palieskite, kad įjungtumėte garsą."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Palieskite, kad nustatytumėte vibravimą. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Palieskite, kad nutildytumėte. Gali būti nutildytos pritaikymo neįgaliesiems paslaugos."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 503c8c8..900a955d 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -442,18 +442,7 @@
<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="8819536904234337445">"Pieskarieties, lai atjaunotu sākotnējo saturu."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Jūs izmantojat darba profilu."</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Zvans"</item>
- <item msgid="5997713001067658559">"Sistēma"</item>
- <item msgid="7858983209929864160">"Zvanīt"</item>
- <item msgid="1850038478268896762">"Multivide"</item>
- <item msgid="8265110906352372092">"Signāls"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Pieskarieties, lai ieslēgtu skaņu."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Pieskarieties, lai iestatītu uz vibrozvanu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Pieskarieties, lai izslēgtu skaņu. Var tikt izslēgti pieejamības pakalpojumu signāli."</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 62fc350..716f76c 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Пристапност"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Допрете за да вклучите звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Допрете за да поставите на вибрации. Можеби ќе се исклучи звукот на услугите за достапност."</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 9e7d2f2..6c14826 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g>, വോളിയം ഡയലോഗാണ്"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"ഒറിജിനൽ പുനഃസ്ഥാപിക്കാൻ ടാപ്പുചെയ്യുക."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"നിങ്ങൾ ഉപയോഗിക്കുന്നത് ഔദ്യോഗിക പ്രൊഫൈലാണ്"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"വിളിക്കുക"</item>
- <item msgid="5997713001067658559">"സിസ്റ്റം"</item>
- <item msgid="7858983209929864160">"റിംഗുചെയ്യുക"</item>
- <item msgid="1850038478268896762">"മീഡിയ"</item>
- <item msgid="8265110906352372092">"അലാറം"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ബ്ലൂടൂത്ത്"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. അൺമ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. വൈബ്രേറ്റിലേക്ക് സജ്ജമാക്കുന്നതിന് ടാപ്പുചെയ്യുക. പ്രവേശനക്ഷമതാ സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. മ്യൂട്ടുചെയ്യുന്നതിന് ടാപ്പുചെയ്യുക. പ്രവേശനക്ഷമതാ സേവനങ്ങൾ മ്യൂട്ടുചെയ്യപ്പെട്ടേക്കാം."</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 04fb4c2..8171310 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -410,12 +410,12 @@
<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="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="6259179342284742878">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вебсайт зэрэг сүлжээний хувийн үйл ажиллагааг хянах боломжтой."</string>
+ <string name="monitoring_description_app" msgid="6259179342284742878">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вэбсайт зэрэг сүлжээний үйл ажиллагааг хянах боломжтой."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"Та <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон бөгөөд энэ нь таны имэйл, апп, вэбсайт зэрэг сүлжээний хувийн үйл ажиллагааг хянах боломжтой."</string>
<string name="branded_monitoring_description_app_personal" msgid="2669518213949202599">"Та имэйл, апп, вэб хуудас зэрэг хувийн сүлжээнийхээ үйл ажиллагааг хянах боломжтой <xliff:g id="APPLICATION">%1$s</xliff:g>-д холбогдсон байна."</string>
- <string name="monitoring_description_app_work" msgid="1754325860918060897">"Таны ажлын профайлыг <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="4946600443852045903">"Таны ажлын профайлыг <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="monitoring_description_app_work" msgid="1754325860918060897">"Таны ажлын профайлыг <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="4946600443852045903">"Таны ажлын профайлыг <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>
@@ -438,18 +438,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь дууны диалог юм."</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"Эх хувилбарыг сэргээхийн тулд дарна уу."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Та өөрийн ажлын профайлыг ашиглаж байна"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Дуудлага"</item>
- <item msgid="5997713001067658559">"Систем"</item>
- <item msgid="7858983209929864160">"Хонх дуугаргах"</item>
- <item msgid="1850038478268896762">"Медиа"</item>
- <item msgid="8265110906352372092">"Сэрүүлэг"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Дууг нь нээхийн тулд товшино уу."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Чичиргээнд тохируулахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Дууг нь хаахын тулд товшино уу. Хүртээмжийн үйлчилгээний дууг хаасан."</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index a21019a..ade3921 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"प्रवेशयोग्यता"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. सशब्द करण्यासाठी टॅप करा."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. कंपन सेट करण्यासाठी टॅप करा. प्रवेशयोग्यता सेवा नि:शब्द केल्या जाऊ शकतात."</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index ce94295..ebe2cf8 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"Ketik untuk memulihkan yang asal."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Anda sedang menggunakan profil kerja"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Panggil"</item>
- <item msgid="5997713001067658559">"Sistem"</item>
- <item msgid="7858983209929864160">"Dering"</item>
- <item msgid="1850038478268896762">"Media"</item>
- <item msgid="8265110906352372092">"Penggera"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Ketik untuk menyahredam."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Ketik untuk menetapkan pada getar. Perkhidmatan kebolehaksesan mungkin diredamkan."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Ketik untuk meredam. Perkhidmatan kebolehaksesan mungkin diredamkan."</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 8ab1de0..a1e6d37 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"အများသုံးစွဲနိုင်မှု"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s။ အသံပြန်ဖွင့်ရန် တို့ပါ။"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s။ တုန်ခါမှုကို သတ်မှတ်ရန် တို့ပါ။ အများသုံးစွဲနိုင်မှု ဝန်ဆောင်မှုများကို အသံပိတ်ထားနိုင်ပါသည်။"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index c6312e1..4508276 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Tilgjengelighet"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Trykk for å slå på lyden."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Trykk for å angi vibrasjon. Lyden kan bli slått av for tilgjengelighetstjenestene."</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index f87223c..7afcac1 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"पहुँच"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s। अनम्यूट गर्नका लागि ट्याप गर्नुहोस्।"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s। कम्पनमा सेट गर्नका लागि ट्याप गर्नुहोस्। पहुँच सम्बन्धी सेवाहरू म्यूट हुन सक्छन्।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4ea9585..a13030d 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Toegankelijkheid"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tik om dempen op te heffen."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tik om in te stellen op trillen. Toegankelijkheidsservices kunnen zijn gedempt."</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index f25662b..6b5abe4 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਵੋਲਯੂਮ ਡਾਇਲੌਗ ਹੈ"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"ਅਸਲ ਨੂੰ ਮੁੜ-ਬਹਾਲ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ਤੁਸੀਂ ਆਪਣੀ ਕੰਮ ਪ੍ਰੋਫਾਈਲ ਵਰਤ ਰਹੇ ਹੋ"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"ਕਾਲ ਕਰੋ"</item>
- <item msgid="5997713001067658559">"ਸਿਸਟਮ"</item>
- <item msgid="7858983209929864160">"ਰਿੰਗ ਕਰੋ"</item>
- <item msgid="1850038478268896762">"ਮੀਡੀਆ"</item>
- <item msgid="8265110906352372092">"ਅਲਾਰਮ"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"ਬਲੂਟੁੱਥ"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s। ਅਣਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s। ਥਰਥਰਾਹਟ ਸੈੱਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s। ਮਿਊਟ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ। ਪਹੁੰਚਯੋਗਤਾ ਸੇਵਾਵਾਂ ਮਿਊਟ ਹੋ ਸਕਦੀਆਂ ਹਨ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 78c6102..429fdfb 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -399,7 +399,7 @@
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"Wyłącz oszczędzanie baterii"</string>
<string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> będzie zapisywać wszystko, co wyświetli się na ekranie."</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"Nie pokazuj ponownie"</string>
- <string name="clear_all_notifications_text" msgid="814192889771462828">"Usuń wszystkie"</string>
+ <string name="clear_all_notifications_text" msgid="814192889771462828">"Ukryj wszystkie"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Rozpocznij teraz"</string>
<string name="empty_shade_text" msgid="708135716272867002">"Brak powiadomień"</string>
<string name="device_owned_footer" msgid="3802752663326030053">"Urządzenie może być monitorowane"</string>
@@ -455,6 +455,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Ułatwienia dostępu"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Kliknij, by wyłączyć wyciszenie."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Kliknij, by włączyć wibracje. Ułatwienia dostępu mogą być wyciszone."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 0dbdcb9..828d4d9 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Acessibilidade"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toque para ativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index d037cda..60a1cda 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Acessibilidade"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toque para reativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toque para ativar a vibração. Os serviços de acessibilidade podem ser silenciados."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 0dbdcb9..828d4d9 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Acessibilidade"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Toque para ativar o som."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Toque para configurar para vibrar. É possível que os serviços de acessibilidade sejam silenciados."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index e33ebb5..b418d4a 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -444,18 +444,7 @@
<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="8819536904234337445">"Atingeți pentru a restabili versiunea originală."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Acum folosiți profilul de serviciu"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Apel"</item>
- <item msgid="5997713001067658559">"Sistem"</item>
- <item msgid="7858983209929864160">"Sonerie"</item>
- <item msgid="1850038478268896762">"Conținut media"</item>
- <item msgid="8265110906352372092">"Alarmă"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Atingeți pentru a activa sunetul."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Atingeți pentru a seta vibrarea. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Atingeți pentru a dezactiva sunetul. Sunetul se poate dezactiva pentru serviciile de accesibilitate."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 0fbb0bd..05f0d38 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -457,6 +457,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Специальные возможности"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Нажмите, чтобы включить звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Нажмите, чтобы включить вибрацию. Специальные возможности могут прекратить работу."</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index c4d2378..2db54d0 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -187,7 +187,7 @@
<string name="accessibility_desc_close" msgid="7479755364962766729">"වසන්න"</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>
- <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi සක්රියයි."</string>
+ <string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wifi ක්රියාත්මකයි."</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"ජංගම <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"බැටරිය <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"අහස්යානා අකාරය අක්රියයි."</string>
@@ -203,15 +203,15 @@
<string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"බාධා නොකරන්න ක්රියාත්මක කරන ලදි"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"බ්ලූටූත්."</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"බ්ලූටූත් අක්රියයි."</string>
- <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"බ්ලූටූත් සක්රියයි."</string>
+ <string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"බ්ලූටූත් ක්රියාත්මකයි."</string>
<string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"බ්ලූටූත් සම්බන්ධවෙමින්."</string>
<string name="accessibility_quick_settings_bluetooth_connected" msgid="4306637793614573659">"බ්ලූටූත් සම්බන්ධිතයි."</string>
<string name="accessibility_quick_settings_bluetooth_changed_off" msgid="2730003763480934529">"බ්ලූටූත් අක්රියයි."</string>
- <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"බ්ලූටූත් සක්රියයි."</string>
+ <string name="accessibility_quick_settings_bluetooth_changed_on" msgid="8722351798763206577">"බ්ලූටූත් ක්රියාත්මක කෙරිණි."</string>
<string name="accessibility_quick_settings_location_off" msgid="5119080556976115520">"ස්ථානය වාර්තාකරණය අක්රියයි."</string>
- <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"ස්ථානය වාර්තාකරණය සක්රියයි."</string>
+ <string name="accessibility_quick_settings_location_on" msgid="5809937096590102036">"ස්ථානය වාර්තාකරණය ක්රියාත්මකයි."</string>
<string name="accessibility_quick_settings_location_changed_off" msgid="8526845571503387376">"ස්ථානය වාර්තාකරණය අක්රියයි."</string>
- <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"ස්ථානය වාර්තාකරණය සක්රියයි."</string>
+ <string name="accessibility_quick_settings_location_changed_on" msgid="339403053079338468">"ස්ථානය වාර්තාකරණය ක්රියාත්මක කෙරිණි."</string>
<string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"<xliff:g id="TIME">%s</xliff:g> සඳහා සීනුව සකස් කර ඇත."</string>
<string name="accessibility_quick_settings_close" msgid="3115847794692516306">"පැනලය වහන්න."</string>
<string name="accessibility_quick_settings_more_time" msgid="3659274935356197708">"වේලාව වැඩියෙන්."</string>
@@ -232,7 +232,7 @@
<string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"වැඩ ප්රකාරය ක්රියාත්මක කරන ලදී."</string>
<string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"දත්ත සුරැකුම ක්රියාවිරහිත කරන ලදී."</string>
<string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"දත්ත සුරැකුම ක්රියාත්මක කරන ලදී."</string>
- <string name="accessibility_brightness" msgid="8003681285547803095">"දීප්තිය දර්ශනය කරන්න"</string>
+ <string name="accessibility_brightness" msgid="8003681285547803095">"සංදර්ශක දීප්තිය"</string>
<string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G දත්ත විරාම කර ඇත"</string>
<string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G දත්ත විරාම කර ඇත"</string>
<string name="data_usage_disabled_dialog_mobile_title" msgid="4651001290947318931">"සෙලියුලර් දත්ත විරාම කර ඇත"</string>
@@ -263,7 +263,7 @@
<string name="ethernet_label" msgid="7967563676324087464">"ඊතර නෙට්"</string>
<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_alarms_label" msgid="2559229444312445858">"එලාම පමණි"</string>
<string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"සම්පූර්ණ නිහඬතාව"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"බ්ලූටූත්"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"බ්ලූටූත් (උපාංග <xliff:g id="NUMBER">%d</xliff:g>)"</string>
@@ -356,7 +356,7 @@
<string name="interruption_level_none_with_warning" msgid="5114872171614161084">"සම්පූර්ණ නිහඬතාව. මෙය තිර කියවන්නන්ද නිහඬ කරනු ඇත."</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_alarms" msgid="5226306993448328896">"එලාම පමණි"</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>
@@ -370,8 +370,8 @@
<string name="user_add_user" msgid="5110251524486079492">"පරිශීලකයෙක් එක් කරන්න"</string>
<string name="user_new_user_name" msgid="426540612051178753">"නව පරිශීලකයා"</string>
<string name="guest_nickname" msgid="8059989128963789678">"අමුත්තා"</string>
- <string name="guest_new_guest" msgid="600537543078847803">"ආගන්තුකයා එකතු කරන්න"</string>
- <string name="guest_exit_guest" msgid="7187359342030096885">"අමුත්තාන් ඉවත් කරන්න"</string>
+ <string name="guest_new_guest" msgid="600537543078847803">"අමුත්තා එක් කරන්න"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"අමුත්තා ඉවත් කරන්න"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"අමුත්තාන් ඉවත් කරන්නද?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"මෙම සැසියේ සියළුම යෙදුම් සහ දත්ත මකාවී."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"ඉවත් කරන්න"</string>
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> ධාරිතා සංවාදයයි"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"මුල් තත්ත්වය නැවත ප්රතිසාධනය කිරීමට තට්ටු කරන්න."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"ඔබ ඔබේ කාර්යාල පැතිකඩ භාවිත කරමින් සිටී"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"ඇමතුම"</item>
- <item msgid="5997713001067658559">"පද්ධතිය"</item>
- <item msgid="7858983209929864160">"නාද කරන්න"</item>
- <item msgid="1850038478268896762">"මාධ්ය"</item>
- <item msgid="8265110906352372092">"එලාමය"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"බ්ලූටූත්"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. නිහඬ කිරීම ඉවත් කිරීමට තට්ටු කරන්න."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. කම්පනය කිරීමට තට්ටු කරන්න. ප්රවේශ්යතා සේවා නිහඬ කළ හැකිය."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. නිහඬ කිරීමට තට්ටු කරන්න. ප්රවේශ්යතා සේවා නිහඬ කළ හැකිය."</string>
@@ -602,7 +591,7 @@
<string name="preview" msgid="9077832302472282938">"පෙරදසුන"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"ටයිල් එක් කිරීමට අදින්න"</string>
<string name="drag_to_remove_tiles" msgid="3361212377437088062">"ඉවත් කිරීමට මෙතැනට අදින්න"</string>
- <string name="qs_edit" msgid="2232596095725105230">"සංස්කරණය කරන්න"</string>
+ <string name="qs_edit" msgid="2232596095725105230">"සංස්කරණය"</string>
<string name="tuner_time" msgid="6572217313285536011">"වේලාව"</string>
<string-array name="clock_options">
<item msgid="5965318737560463480">"පැය, මිනිත්තු, සහ තත්පර පෙන්වන්න"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 23daf91..803be7f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -457,6 +457,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Dostupnosť"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Klepnutím zapnite zvuk."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Klepnutím aktivujte režim vibrovania. Služby dostupnosti je možné stlmiť."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 90985e7..0f03de9 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -446,18 +446,7 @@
<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="8819536904234337445">"Dotaknite se, če želite obnoviti prvotno stanje."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Uporabljate delovni profil"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Klic"</item>
- <item msgid="5997713001067658559">"Sistem"</item>
- <item msgid="7858983209929864160">"Zvonjenje"</item>
- <item msgid="1850038478268896762">"Predstavnost"</item>
- <item msgid="8265110906352372092">"Alarm"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Dotaknite se, če želite vklopiti zvok."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Dotaknite se, če želite nastaviti vibriranje. V storitvah za ljudi s posebnimi potrebami bo morda izklopljen zvok."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Dotaknite se, če želite izklopiti zvok. V storitvah za ljudi s posebnimi potrebami bo morda izklopljen zvok."</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 9616c07..c03c0fe 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"Trokit për të restauruar origjinalin."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Po përdor profilin tënd të punës"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Telefono"</item>
- <item msgid="5997713001067658559">"Sistemi"</item>
- <item msgid="7858983209929864160">"Bjeri ziles"</item>
- <item msgid="1850038478268896762">"Media"</item>
- <item msgid="8265110906352372092">"Alarmi"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Trokit për të aktivizuar."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Trokit për ta caktuar te dridhja. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Trokit për të çaktivizuar. Shërbimet e qasshmërisë mund të çaktivizohen."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 667c65d..fd560de 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Приступачност"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Додирните да бисте укључили звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Додирните да бисте подесили на вибрацију. Звук услуга приступачности ће можда бити искључен."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 0a95017..e0c8472 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Tillgänglighet"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Tryck här om du vill slå på ljudet."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tryck här om du vill sätta på vibrationen. Tillgänglighetstjänster kanske inaktiveras."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index afc5ee4..7c89410 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Zana za walio na matatizo ya kuona au kusikia"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Gonga ili urejeshe."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Gonga ili uweke mtetemo. Huenda ikakomesha huduma za zana za walio na matatizo ya kuona au kusikia."</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 99b8439..bd23b43 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"ஒலியளவு செய்தி: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"அசலை மீட்டமைக்க, தட்டவும்."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"பணி சுயவிவரத்தைப் பயன்படுத்துகிறீர்கள்"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"அழைப்பு"</item>
- <item msgid="5997713001067658559">"சாதனம்"</item>
- <item msgid="7858983209929864160">"ரிங்"</item>
- <item msgid="1850038478268896762">"மீடியா"</item>
- <item msgid="8265110906352372092">"அலாரம்"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"புளூடூத்"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. ஒலி இயக்க, தட்டவும்."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. அதிர்விற்கு அமைக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. ஒலியடக்க, தட்டவும். அணுகல்தன்மை சேவைகள் ஒலியடக்கப்படக்கூடும்."</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index c1aeb09b..6ae1e67 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> అనేది వాల్యూమ్ డైలాగ్"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"అసలు దాన్ని పునరుద్ధరించడానికి నొక్కండి."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"మీరు మీ కార్యాలయ ప్రొఫైల్ను ఉపయోగిస్తున్నారు"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"కాల్"</item>
- <item msgid="5997713001067658559">"సిస్టమ్"</item>
- <item msgid="7858983209929864160">"రింగ్"</item>
- <item msgid="1850038478268896762">"మీడియా"</item>
- <item msgid="8265110906352372092">"అలారం"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"బ్లూటూత్"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. అన్మ్యూట్ చేయడానికి నొక్కండి."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. వైబ్రేషన్కు సెట్ చేయడానికి నొక్కండి. ప్రాప్యత సేవలు మ్యూట్ చేయబడవచ్చు."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. మ్యూట్ చేయడానికి నొక్కండి. ప్రాప్యత సేవలు మ్యూట్ చేయబడవచ్చు."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 0c461b4..7e2c00f8 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นช่องโต้ตอบระดับเสียง"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"แตะเพื่อคืนค่าเป็นค่าเดิม"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"คุณกำลังใช้โปรไฟล์งานของคุณ"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"โทร"</item>
- <item msgid="5997713001067658559">"ระบบ"</item>
- <item msgid="7858983209929864160">"ทำให้ส่งเสียง"</item>
- <item msgid="1850038478268896762">"สื่อ"</item>
- <item msgid="8265110906352372092">"การปลุก"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"บลูทูธ"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s แตะเพื่อเปิดเสียง"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s แตะเพื่อตั้งค่าให้สั่น อาจมีการปิดเสียงบริการการเข้าถึง"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s แตะเพื่อปิดเสียง อาจมีการปิดเสียงบริการการเข้าถึง"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index caa9f97..e1e06df 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"I-tap upang i-restore ang orihinal."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Ginagamit mo ang iyong profile sa trabaho"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Tawag"</item>
- <item msgid="5997713001067658559">"System"</item>
- <item msgid="7858983209929864160">"Ipa-ring"</item>
- <item msgid="1850038478268896762">"Media"</item>
- <item msgid="8265110906352372092">"Alarm"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. I-tap upang i-unmute."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. I-tap upang itakda na mag-vibrate. Maaaring i-mute ang mga serbisyo sa Accessibility."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. I-tap upang i-mute. Maaaring i-mute ang mga serbisyo sa Accessibility."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 030c97f..d416fdf 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"Orijinali geri yüklemek için dokunun."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"İş profilinizi kullanıyorsunuz"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Çağrı"</item>
- <item msgid="5997713001067658559">"Sistem"</item>
- <item msgid="7858983209929864160">"Zili Çaldır"</item>
- <item msgid="1850038478268896762">"Medya"</item>
- <item msgid="8265110906352372092">"Alarm"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Sesi açmak için hafifçe dokunun."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Titreşime ayarlamak için hafifçe dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Sesi kapatmak için hafifçe dokunun. Erişilebilirlik hizmetlerinin sesi kapatılabilir."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index c086fff..5db65459 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -457,6 +457,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Спеціальні можливості"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Торкніться, щоб увімкнути звук."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Торкніться, щоб налаштувати вібросигнал. Спеціальні можливості може бути вимкнено."</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index ff46ad3..bc89301 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"<xliff:g id="APP_NAME">%1$s</xliff:g> والیوم ڈائلاگ ہے"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"اصل بحال کرنے کیلئے تھپتھپائیں۔"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"آپ اپنا دفتری پروفائل استعمال کر رہے ہیں۔"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"کال"</item>
- <item msgid="5997713001067658559">"سسٹم"</item>
- <item msgid="7858983209929864160">"رِنگ"</item>
- <item msgid="1850038478268896762">"میڈیا"</item>
- <item msgid="8265110906352372092">"الارم"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"بلوٹوتھ"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s۔ آواز چالو کرنے کیلئے تھپتھپائیں۔"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s۔ ارتعاش پر سیٹ کرنے کیلئے تھپتھپائیں۔ Accessibility سروسز شاید خاموش ہوں۔"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s۔ خاموش کرنے کیلئے تھپتھپائیں۔ Accessibility سروسز شاید خاموش ہوں۔"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index f2d2661..a71b539 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -453,6 +453,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Maxsus imkoniyatlar"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Ovozini yoqish uchun ustiga bosing."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Tebranishni yoqish uchun ustiga bosing. Maxsus imkoniyatlar ishlamasligi mumkin."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 48b1e4f..d0d8216 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -440,18 +440,7 @@
<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="8819536904234337445">"Nhấn để khôi phục ảnh chụp màn hình gốc."</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Bạn đang sử dụng hồ sơ công việc của mình"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"Gọi"</item>
- <item msgid="5997713001067658559">"Hệ thống"</item>
- <item msgid="7858983209929864160">"Chuông"</item>
- <item msgid="1850038478268896762">"Phương tiện"</item>
- <item msgid="8265110906352372092">"Báo thức"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"Bluetooth"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Nhấn để bật tiếng."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Nhấn để đặt chế độ rung. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s. Nhấn để tắt tiếng. Bạn có thể tắt tiếng dịch vụ trợ năng."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 94c3af1..7928bf9 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已用作音量控制对话框"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"点按即可恢复原始设置。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您当前正在使用工作资料"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"通话"</item>
- <item msgid="5997713001067658559">"系统"</item>
- <item msgid="7858983209929864160">"铃声"</item>
- <item msgid="1850038478268896762">"媒体"</item>
- <item msgid="8265110906352372092">"闹钟"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"蓝牙"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s。点按即可取消静音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s。点按即可设为振动,但可能会同时将无障碍服务设为静音。"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。点按即可设为静音,但可能会同时将无障碍服务设为静音。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 5785af9..b4ea6f8 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -442,18 +442,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」為音量對話框"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"輕按即可復原。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用工作設定檔"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"通話"</item>
- <item msgid="5997713001067658559">"系統"</item>
- <item msgid="7858983209929864160">"鈴聲"</item>
- <item msgid="1850038478268896762">"媒體"</item>
- <item msgid="8265110906352372092">"鬧鐘"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"藍牙"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s。輕按即可取消靜音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s。輕按即可設為震動。無障礙功能服務可能已經設為靜音。"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。輕按即可設為靜音。無障礙功能服務可能已經設為靜音。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 6562b39..a6a87f6 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -440,18 +440,7 @@
<string name="volumeui_notification_title" msgid="4906770126345910955">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」現在是預設的音量控制對話方塊。"</string>
<string name="volumeui_notification_text" msgid="8819536904234337445">"輕觸即可恢復原始設定。"</string>
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"您正在使用 Work 設定檔"</string>
- <string-array name="volume_stream_titles">
- <item msgid="5841843895402729630">"通話"</item>
- <item msgid="5997713001067658559">"系統"</item>
- <item msgid="7858983209929864160">"鈴聲"</item>
- <item msgid="1850038478268896762">"媒體"</item>
- <item msgid="8265110906352372092">"鬧鐘"</item>
- <item msgid="5339394737636839168"></item>
- <item msgid="2951313578278086204">"藍牙"</item>
- <item msgid="2919807739709798970"></item>
- <item msgid="150349973435223405"></item>
- <item msgid="6761963760295549099"></item>
- </string-array>
+ <!-- no translation found for volume_stream_titles:10 (8119402510273906841) -->
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s。輕觸即可取消靜音。"</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s。輕觸即可設為震動,但系統可能會將無障礙服務一併設為靜音。"</string>
<string name="volume_stream_content_description_mute" msgid="3625049841390467354">"%1$s。輕觸即可設為靜音,但系統可能會將無障礙服務一併設為靜音。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index e3c419b..324d306 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -451,6 +451,7 @@
<item msgid="2919807739709798970"></item>
<item msgid="150349973435223405"></item>
<item msgid="6761963760295549099"></item>
+ <item msgid="8119402510273906841">"Ukufinyeleleka"</item>
</string-array>
<string name="volume_stream_content_description_unmute" msgid="4436631538779230857">"%1$s. Thepha ukuze ususe ukuthula."</string>
<string name="volume_stream_content_description_vibrate" msgid="1187944970457807498">"%1$s. Thepha ukuze usethe ukudlidliza. Amasevisi okufinyelela angathuliswa."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1b6b04d..a6604cb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -487,6 +487,9 @@
<!-- TrustDrawable: Thickness of the circle -->
<dimen name="trust_circle_thickness">2dp</dimen>
+ <!-- How much two taps can be apart to still be recognized as a double tap on the lockscreen -->
+ <dimen name="double_tap_slop">32dp</dimen>
+
<!-- Margin on the right side of the system icon group on Keyguard. -->
<fraction name="battery_button_height_fraction">10.5%</fraction>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5fec647..bfc26e3 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -840,6 +840,12 @@
<!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
<string name="keyguard_unlock">Swipe up to unlock</string>
+ <!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
+ <string name="do_disclosure_generic">This device is managed</string>
+
+ <!-- Text on keyguard screen indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=40] -->
+ <string name="do_disclosure_with_name">This device is managed by <xliff:g id="organization_name" example="Foo, Inc.">%s</xliff:g></string>
+
<!-- Shows when people have clicked on the phone icon [CHAR LIMIT=60] -->
<string name="phone_hint">Swipe from icon for phone</string>
@@ -1120,7 +1126,6 @@
<item></item> <!-- STREAM_SYSTEM_ENFORCED -->
<item></item> <!-- STREAM_DTMF -->
<item></item> <!-- STREAM_TTS -->
- <item>Accessibility</item> <!-- STREAM_ACCESSIBILITY -->
</string-array>
<string name="volume_stream_muted" translatable="false">%s silent</string>
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 664e886..8fc555f 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -313,7 +313,11 @@
mDataCollector.onNotificationActive();
}
- public void onNotificationDoubleTap() {
+ public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
+ if (FalsingLog.ENABLED) {
+ FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted
+ + " dx=" + dx + " dy=" + dy + " (px)");
+ }
mDataCollector.onNotificationDoubleTap();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 2192b8c..07e1193 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -59,6 +59,8 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -325,6 +327,7 @@
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
+ private boolean mLockWhenSimRemoved;
KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@@ -415,7 +418,7 @@
case ABSENT:
// only force lock screen in case of missing sim if user hasn't
// gone through setup wizard
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (shouldWaitForProvisioning()) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
@@ -426,11 +429,12 @@
resetStateLocked();
}
}
+ onSimNotReadyLocked();
}
break;
case PIN_REQUIRED:
case PUK_REQUIRED:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG,
"INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
@@ -442,7 +446,7 @@
}
break;
case PERM_DISABLED:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
+ "keygaurd isn't showing.");
@@ -452,21 +456,40 @@
+ "show permanently disabled message in lockscreen.");
resetStateLocked();
}
+ onSimNotReadyLocked();
}
break;
case READY:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (mShowing) {
resetStateLocked();
}
+ mLockWhenSimRemoved = true;
}
break;
default:
- if (DEBUG_SIM_STATES) Log.v(TAG, "Ignoring state: " + simState);
+ if (DEBUG_SIM_STATES) Log.v(TAG, "Unspecific state: " + simState);
+ synchronized (KeyguardViewMediator.this) {
+ onSimNotReadyLocked();
+ }
break;
}
}
+ private void onSimNotReadyLocked() {
+ if (isSecure() && mLockWhenSimRemoved) {
+ mLockWhenSimRemoved = false;
+ MetricsLogger.action(mContext,
+ MetricsProto.MetricsEvent.ACTION_LOCK_BECAUSE_SIM_REMOVED, mShowing);
+ if (!mShowing) {
+ if (DEBUG_SIM_STATES) Log.d(TAG, "SIM removed, showing keyguard");
+ doKeyguardLocked(null);
+ } else {
+ resetStateLocked();
+ }
+ }
+ }
+
@Override
public void onFingerprintAuthFailed() {
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
index 7655e6c..790f3f6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java
@@ -438,9 +438,9 @@
SystemServicesProxy ssp = Recents.getSystemServices();
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
boolean screenPinningActive = ssp.isScreenPinningActive();
- boolean isRunningTaskInHomeStack = runningTask != null &&
- SystemServicesProxy.isHomeStack(runningTask.stackId);
- if (runningTask != null && !isRunningTaskInHomeStack && !screenPinningActive) {
+ boolean isRunningTaskInHomeOrRecentsStack = runningTask != null &&
+ ActivityManager.StackId.isHomeOrRecentsStack(runningTask.stackId);
+ if (runningTask != null && !isRunningTaskInHomeOrRecentsStack && !screenPinningActive) {
logDockAttempt(mContext, runningTask.topActivity, runningTask.resizeMode);
if (runningTask.isDockable) {
if (metricsDockAction != -1) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index abde44e..c9c4f2b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -18,6 +18,8 @@
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
+import static android.app.ActivityManager.StackId.isHomeOrRecentsStack;
import static android.view.View.MeasureSpec;
import android.app.ActivityManager;
@@ -460,8 +462,8 @@
// Return early if there is no running task (can't determine affiliated tasks in this case)
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
if (runningTask == null) return;
- // Return early if the running task is in the home stack (optimization)
- if (SystemServicesProxy.isHomeStack(runningTask.stackId)) return;
+ // Return early if the running task is in the home/recents stack (optimization)
+ if (isHomeOrRecentsStack(runningTask.stackId)) return;
// Find the task in the recents list
ArrayList<Task> tasks = focusedStack.getStackTasks();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 2272a72..ea50d89 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -321,7 +321,7 @@
// Remove home/recents/excluded tasks
int minNumTasksToQuery = 10;
int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
- int flags = ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
+ int flags = ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS |
ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK |
ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS |
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
@@ -399,21 +399,23 @@
if (mIam == null) return false;
try {
- ActivityManager.StackInfo stackInfo = mIam.getStackInfo(
+ ActivityManager.StackInfo homeStackInfo = mIam.getStackInfo(
ActivityManager.StackId.HOME_STACK_ID);
ActivityManager.StackInfo fullscreenStackInfo = mIam.getStackInfo(
ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID);
- ComponentName topActivity = stackInfo.topActivity;
- boolean homeStackVisibleNotOccluded = stackInfo.visible;
- if (fullscreenStackInfo != null) {
- boolean isFullscreenStackOccludingHome = fullscreenStackInfo.visible &&
- fullscreenStackInfo.position > stackInfo.position;
- homeStackVisibleNotOccluded &= !isFullscreenStackOccludingHome;
- }
+ ActivityManager.StackInfo recentsStackInfo = mIam.getStackInfo(
+ ActivityManager.StackId.RECENTS_STACK_ID);
+
+ boolean homeStackVisibleNotOccluded = isStackNotOccluded(homeStackInfo,
+ fullscreenStackInfo);
+ boolean recentsStackVisibleNotOccluded = isStackNotOccluded(recentsStackInfo,
+ fullscreenStackInfo);
if (isHomeStackVisible != null) {
isHomeStackVisible.value = homeStackVisibleNotOccluded;
}
- return (homeStackVisibleNotOccluded && topActivity != null
+ ComponentName topActivity = recentsStackInfo != null ?
+ recentsStackInfo.topActivity : null;
+ return (recentsStackVisibleNotOccluded && topActivity != null
&& topActivity.getPackageName().equals(RecentsImpl.RECENTS_PACKAGE)
&& Recents.RECENTS_ACTIVITIES.contains(topActivity.getClassName()));
} catch (RemoteException e) {
@@ -422,6 +424,17 @@
return false;
}
+ private boolean isStackNotOccluded(ActivityManager.StackInfo stackInfo,
+ ActivityManager.StackInfo fullscreenStackInfo) {
+ boolean stackVisibleNotOccluded = stackInfo == null || stackInfo.visible;
+ if (fullscreenStackInfo != null && stackInfo != null) {
+ boolean isFullscreenStackOccludingg = fullscreenStackInfo.visible &&
+ fullscreenStackInfo.position > stackInfo.position;
+ stackVisibleNotOccluded &= !isFullscreenStackOccludingg;
+ }
+ return stackVisibleNotOccluded;
+ }
+
/**
* Returns whether this device has freeform workspaces.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index d789477..0eef864 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -323,7 +323,8 @@
// Create the intent to show the screenshot in gallery
Intent launchIntent = new Intent(Intent.ACTION_VIEW);
launchIntent.setDataAndType(mParams.imageUri, "image/png");
- launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ launchIntent.setFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
final long now = System.currentTimeMillis();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 173f160..d46d267 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -116,6 +116,10 @@
private float mDownY;
private final float mTouchSlop;
+ private float mActivationX;
+ private float mActivationY;
+ private final float mDoubleTapSlop;
+
private OnActivatedListener mOnActivatedListener;
private final Interpolator mSlowOutFastInInterpolator;
@@ -179,6 +183,7 @@
public ActivatableNotificationView(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+ mDoubleTapSlop = context.getResources().getDimension(R.dimen.double_tap_slop);
mSlowOutFastInInterpolator = new PathInterpolator(0.8f, 0.0f, 0.6f, 1.0f);
mSlowOutLinearInInterpolator = new PathInterpolator(0.8f, 0.0f, 1.0f, 1.0f);
setClipChildren(false);
@@ -240,7 +245,6 @@
boolean wasActivated = mActivated;
result = handleTouchEventDimmed(event);
if (wasActivated && result && event.getAction() == MotionEvent.ACTION_UP) {
- mFalsingManager.onNotificationDoubleTap();
removeCallbacks(mTapTimeoutRunnable);
}
} else {
@@ -291,9 +295,21 @@
if (!mActivated) {
makeActive();
postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
+ mActivationX = event.getX();
+ mActivationY = event.getY();
} else {
- if (!performClick()) {
- return false;
+ boolean withinDoubleTapSlop = isWithinDoubleTapSlop(event);
+ mFalsingManager.onNotificationDoubleTap(
+ withinDoubleTapSlop,
+ event.getX() - mActivationX,
+ event.getY() - mActivationY);
+ if (withinDoubleTapSlop) {
+ if (!performClick()) {
+ return false;
+ }
+ } else {
+ makeInactive(true /* animate */);
+ mTrackTouch = false;
}
}
} else {
@@ -401,6 +417,16 @@
&& Math.abs(event.getY() - mDownY) < mTouchSlop;
}
+ private boolean isWithinDoubleTapSlop(MotionEvent event) {
+ if (!mActivated) {
+ // If we're not activated there's no double tap slop to satisfy.
+ return true;
+ }
+
+ return Math.abs(event.getX() - mActivationX) < mDoubleTapSlop
+ && Math.abs(event.getY() - mActivationY) < mDoubleTapSlop;
+ }
+
public void setDimmed(boolean dimmed, boolean fade) {
if (mDimmed != dimmed) {
mDimmed = dimmed;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index f5ca678..414ebec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1073,8 +1073,8 @@
int appUid = -1;
try {
final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
- PackageManager.GET_UNINSTALLED_PACKAGES
- | PackageManager.GET_DISABLED_COMPONENTS);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
if (info != null) {
appname = String.valueOf(pmUser.getApplicationLabel(info));
pkgicon = pmUser.getApplicationIcon(info);
@@ -1643,8 +1643,8 @@
String appname = pkg;
try {
final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
- PackageManager.GET_UNINSTALLED_PACKAGES
- | PackageManager.GET_DISABLED_COMPONENTS);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
if (info != null) {
appname = String.valueOf(pmUser.getApplicationLabel(info));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index a1384dcb..661cc3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1685,6 +1685,9 @@
if (mGuts != null) {
mGuts.setClipBottomAmount(clipBottomAmount);
}
+ if (mChildrenContainer != null) {
+ mChildrenContainer.setClipBottomAmount(clipBottomAmount);
+ }
}
public boolean isMaxExpandHeightInitialized() {
@@ -1863,9 +1866,6 @@
super.applyToView(view);
if (view instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- if (this.isBottomClipped) {
- row.setClipToActualHeight(true);
- }
row.applyChildrenState(mOverallState);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 4b95f07..91abc87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -41,7 +41,7 @@
outline.setRect(translation,
mClipTopAmount,
getWidth() + translation,
- Math.max(getActualHeight(), mClipTopAmount));
+ Math.max(getActualHeight() - mClipBottomAmount, mClipTopAmount));
} else {
outline.setRect(mOutlineRect);
}
@@ -66,6 +66,12 @@
invalidateOutline();
}
+ @Override
+ public void setClipBottomAmount(int clipBottomAmount) {
+ super.setClipBottomAmount(clipBottomAmount);
+ invalidateOutline();
+ }
+
protected void setOutlineAlpha(float alpha) {
if (alpha != mOutlineAlpha) {
mOutlineAlpha = alpha;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 0f5981b..37a900e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -38,7 +38,7 @@
protected OnHeightChangedListener mOnHeightChangedListener;
private int mActualHeight;
protected int mClipTopAmount;
- private float mClipBottomAmount;
+ protected int mClipBottomAmount;
private boolean mDark;
private ArrayList<View> mMatchParentViews = new ArrayList<View>();
private static Rect mClipRect = new Rect();
@@ -241,7 +241,7 @@
return mClipTopAmount;
}
- public float getClipBottomAmount() {
+ public int getClipBottomAmount() {
return mClipBottomAmount;
}
@@ -354,11 +354,8 @@
private void updateClipping() {
if (mClipToActualHeight) {
int top = getClipTopAmount();
- if (top >= getActualHeight()) {
- top = getActualHeight() - 1;
- }
- mClipRect.set(0, top, getWidth(), (int) (getActualHeight() + getExtraBottomPadding()
- - mClipBottomAmount));
+ mClipRect.set(0, top, getWidth(), Math.max(getActualHeight() + getExtraBottomPadding()
+ - mClipBottomAmount, top));
setClipBounds(mClipRect);
} else {
setClipBounds(null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 0ef97152..218c1bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar;
import android.app.ActivityManager;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -36,6 +37,7 @@
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
+import android.view.ViewGroup;
import com.android.internal.app.IBatteryStats;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -58,7 +60,9 @@
private static final long TRANSIENT_FP_ERROR_TIMEOUT = 1300;
private final Context mContext;
+ private final ViewGroup mIndicationArea;
private final KeyguardIndicationTextView mTextView;
+ private final KeyguardIndicationTextView mDisclosure;
private final UserManager mUserManager;
private final IBatteryStats mBatteryInfo;
@@ -78,10 +82,16 @@
private int mChargingWattage;
private String mMessageToShowOnScreenOn;
- public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView,
- LockIcon lockIcon) {
+ private final DevicePolicyManager mDevicePolicyManager;
+
+ public KeyguardIndicationController(Context context, ViewGroup indicationArea,
+ LockIcon lockIcon) {
mContext = context;
- mTextView = textView;
+ mIndicationArea = indicationArea;
+ mTextView = (KeyguardIndicationTextView) indicationArea.findViewById(
+ R.id.keyguard_indication_text);
+ mDisclosure = (KeyguardIndicationTextView) indicationArea.findViewById(
+ R.id.keyguard_indication_enterprise_disclosure);
mLockIcon = lockIcon;
Resources res = context.getResources();
@@ -92,14 +102,39 @@
mBatteryInfo = IBatteryStats.Stub.asInterface(
ServiceManager.getService(BatteryStats.SERVICE_NAME));
+ mDevicePolicyManager = (DevicePolicyManager) context.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor);
context.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM,
new IntentFilter(Intent.ACTION_TIME_TICK), null, null);
+
+ updateDisclosure();
+ }
+
+ private void updateDisclosure() {
+ if (mDevicePolicyManager == null) {
+ return;
+ }
+
+ if (mDevicePolicyManager.isDeviceManaged()) {
+ final CharSequence organizationName =
+ mDevicePolicyManager.getDeviceOwnerOrganizationName();
+ if (organizationName != null) {
+ mDisclosure.switchIndication(mContext.getResources().getString(
+ R.string.do_disclosure_with_name, organizationName));
+ } else {
+ mDisclosure.switchIndication(R.string.do_disclosure_generic);
+ }
+ mDisclosure.setVisibility(View.VISIBLE);
+ } else {
+ mDisclosure.setVisibility(View.GONE);
+ }
}
public void setVisible(boolean visible) {
mVisible = visible;
- mTextView.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mIndicationArea.setVisibility(visible ? View.VISIBLE : View.GONE);
if (visible) {
hideTransientIndication();
updateIndication();
@@ -242,6 +277,13 @@
}
@Override
+ public void onKeyguardVisibilityChanged(boolean showing) {
+ if (showing) {
+ updateDisclosure();
+ }
+ }
+
+ @Override
public void onFingerprintHelp(int msgId, String helpString) {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
if (!updateMonitor.isUnlockingWithFingerprintAllowed()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index add4764..680562a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -156,7 +156,6 @@
mShelfState.alpha = 1.0f;
mShelfState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
mShelfState.shadowAlpha = 1.0f;
- mShelfState.isBottomClipped = false;
mShelfState.hideSensitive = false;
mShelfState.xTranslation = getTranslationX();
if (mNotGoneIndex != -1) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 89defec..daa57c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -107,6 +107,8 @@
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private LockIcon mLockIcon;
+ private ViewGroup mIndicationArea;
+ private TextView mEnterpriseDisclosure;
private TextView mIndicationText;
private ViewGroup mPreviewContainer;
@@ -208,6 +210,9 @@
mRightAffordanceView = (KeyguardAffordanceView) findViewById(R.id.camera_button);
mLeftAffordanceView = (KeyguardAffordanceView) findViewById(R.id.left_button);
mLockIcon = (LockIcon) findViewById(R.id.lock_icon);
+ mIndicationArea = (ViewGroup) findViewById(R.id.keyguard_indication_area);
+ mEnterpriseDisclosure = (TextView) findViewById(
+ R.id.keyguard_indication_enterprise_disclosure);
mIndicationText = (TextView) findViewById(R.id.keyguard_indication_text);
watchForCameraPolicyChanges();
updateCameraVisibility();
@@ -252,13 +257,16 @@
super.onConfigurationChanged(newConfig);
int indicationBottomMargin = getResources().getDimensionPixelSize(
R.dimen.keyguard_indication_margin_bottom);
- MarginLayoutParams mlp = (MarginLayoutParams) mIndicationText.getLayoutParams();
+ MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams();
if (mlp.bottomMargin != indicationBottomMargin) {
mlp.bottomMargin = indicationBottomMargin;
- mIndicationText.setLayoutParams(mlp);
+ mIndicationArea.setLayoutParams(mlp);
}
// Respect font size setting.
+ mEnterpriseDisclosure.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.text_size_small_material));
mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material));
@@ -595,8 +603,8 @@
return mLockIcon;
}
- public View getIndicationView() {
- return mIndicationText;
+ public View getIndicationArea() {
+ return mIndicationArea;
}
@Override
@@ -658,8 +666,8 @@
if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
startFinishDozeAnimationElement(mRightAffordanceView, delay);
}
- mIndicationText.setAlpha(0f);
- mIndicationText.animate()
+ mIndicationArea.setAlpha(0f);
+ mIndicationArea.animate()
.alpha(1f)
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 97df237..a0ea9bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -577,6 +577,7 @@
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);
+ mDeadZone.setDisplayRotation(mCurrentRotation);
// force the low profile & disabled states into compliance
mBarTransitions.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 2895890..03697b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -48,7 +48,7 @@
return mAnimationFilter;
}
}.setDuration(200);
-
+
private static final AnimationProperties ADD_ICON_PROPERTIES = new AnimationProperties() {
private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 523528d..99e98f2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -404,12 +404,9 @@
mKeyguardStatusView.getHeight());
int notificationPadding = Math.max(1, getResources().getDimensionPixelSize(
R.dimen.notification_divider_height));
- final int overflowheight = getResources().getDimensionPixelSize(
- R.dimen.notification_shelf_height);
float shelfSize = mNotificationStackScroller.getNotificationShelf().getIntrinsicHeight()
+ notificationPadding;
- float availableSpace = mNotificationStackScroller.getHeight() - minPadding - overflowheight
- - shelfSize;
+ float availableSpace = mNotificationStackScroller.getHeight() - minPadding - shelfSize;
int count = 0;
for (int i = 0; i < mNotificationStackScroller.getChildCount(); i++) {
ExpandableView child = (ExpandableView) mNotificationStackScroller.getChildAt(i);
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 570d5d4..f16c834 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -1006,14 +1006,14 @@
});
animator.start();
mHeightAnimator = animator;
- mKeyguardBottomArea.getIndicationView().animate()
+ mKeyguardBottomArea.getIndicationArea().animate()
.translationY(-mHintDistance)
.setDuration(250)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.withEndAction(new Runnable() {
@Override
public void run() {
- mKeyguardBottomArea.getIndicationView().animate()
+ mKeyguardBottomArea.getIndicationArea().animate()
.translationY(0)
.setDuration(450)
.setInterpolator(mBounceInterpolator)
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 bbbdc13..2b74c847 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -857,8 +857,7 @@
mKeyguardBottomArea.setActivityStarter(this);
mKeyguardBottomArea.setAssistManager(mAssistManager);
mKeyguardIndicationController = new KeyguardIndicationController(mContext,
- (KeyguardIndicationTextView) mStatusBarWindow.findViewById(
- R.id.keyguard_indication_text),
+ (ViewGroup) mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
mKeyguardBottomArea.getLockIcon());
mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController);
@@ -1873,6 +1872,9 @@
updateQsExpansionEnabled();
mShadeUpdates.check();
+
+ // Let's also update the icons
+ mIconController.updateNotificationIcons(mNotificationData);
}
/**
@@ -2021,7 +2023,6 @@
mNotificationData.filterAndSort();
updateNotificationShade();
- mIconController.updateNotificationIcons(mNotificationData);
}
public void requestNotificationUpdate() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
index 1cad61f..4c879c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeadZone.java
@@ -24,6 +24,7 @@
import android.util.AttributeSet;
import android.util.Slog;
import android.view.MotionEvent;
+import android.view.Surface;
import android.view.View;
import com.android.systemui.R;
@@ -54,6 +55,7 @@
private int mHold, mDecay;
private boolean mVertical;
private long mLastPokeTime;
+ private int mDisplayRotation;
private final Runnable mDebugFlash = new Runnable() {
@Override
@@ -132,7 +134,16 @@
int size = (int) getSize(event.getEventTime());
// In the vertical orientation consume taps along the left edge.
// In horizontal orientation consume taps along the top edge.
- final boolean consumeEvent = mVertical ? event.getX() < size : event.getY() < size;
+ final boolean consumeEvent;
+ if (mVertical) {
+ if (mDisplayRotation == Surface.ROTATION_270) {
+ consumeEvent = event.getX() > getWidth() - size;
+ } else {
+ consumeEvent = event.getX() < size;
+ }
+ } else {
+ consumeEvent = event.getY() < size;
+ }
if (consumeEvent) {
if (CHATTY) {
Slog.v(TAG, "consuming errant click: (" + event.getX() + "," + event.getY() + ")");
@@ -170,7 +181,16 @@
}
final int size = (int) getSize(SystemClock.uptimeMillis());
- can.clipRect(0, 0, mVertical ? size : can.getWidth(), mVertical ? can.getHeight() : size);
+ if (mVertical) {
+ if (mDisplayRotation == Surface.ROTATION_270) {
+ can.clipRect(can.getWidth() - size, 0, can.getWidth(), can.getHeight());
+ } else {
+ can.clipRect(0, 0, size, can.getHeight());
+ }
+ } else {
+ can.clipRect(0, 0, can.getWidth(), size);
+ }
+
final float frac = DEBUG ? (mFlashFrac - 0.5f) + 0.5f : mFlashFrac;
can.drawARGB((int) (frac * 0xFF), 0xDD, 0xEE, 0xAA);
@@ -178,4 +198,8 @@
// crazy aggressive redrawing here, for debugging only
postInvalidateDelayed(100);
}
+
+ public void setDisplayRotation(int rotation) {
+ mDisplayRotation = rotation;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
index 58e6838..7854c98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ExpandableViewState.java
@@ -106,11 +106,6 @@
*/
public int location;
- /**
- * Whether a child in a group is being clipped at the bottom.
- */
- public boolean isBottomClipped;
-
@Override
public void copyFrom(ViewState viewState) {
super.copyFrom(viewState);
@@ -125,7 +120,6 @@
clipTopAmount = svs.clipTopAmount;
notGoneIndex = svs.notGoneIndex;
location = svs.location;
- isBottomClipped = svs.isBottomClipped;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 26e1342..b8f8cb2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -76,6 +76,7 @@
private NotificationViewWrapper mNotificationHeaderWrapper;
private NotificationHeaderUtil mHeaderUtil;
private ViewState mHeaderViewState;
+ private int mClipBottomAmount;
public NotificationChildrenContainer(Context context) {
this(context, null);
@@ -433,7 +434,6 @@
boolean childrenExpanded = !mNotificationParent.isGroupExpansionChanging()
&& mChildrenExpanded;
- int parentHeight = parentState.height;
for (int i = 0; i < childCount; i++) {
ExpandableNotificationRow child = mChildren.get(i);
if (!firstChild) {
@@ -457,20 +457,9 @@
ExpandableViewState childState = resultState.getViewStateForView(child);
int intrinsicHeight = child.getIntrinsicHeight();
- if (childrenExpanded) {
- // When a group is expanded and moving into bottom stack, the bottom visible child
- // adjusts its height to move into it. Children after it are hidden.
- if (updateChildStateForExpandedGroup(child, parentHeight, childState, yPosition)) {
- // Clipping might be deactivated if the view is transforming, however, clipping
- // the child into the bottom stack should take precedent over this.
- childState.isBottomClipped = true;
- }
- } else {
- childState.hidden = false;
- childState.height = intrinsicHeight;
- childState.isBottomClipped = false;
- }
+ childState.height = intrinsicHeight;
childState.yTranslation = yPosition;
+ childState.hidden = false;
// When the group is expanded, the children cast the shadows rather than the parent
// so use the parent's elevation here.
childState.zTranslation = childrenExpanded
@@ -601,6 +590,34 @@
if (mHeaderViewState != null) {
mHeaderViewState.applyToView(mNotificationHeader);
}
+ updateChildrenClipping();
+ }
+
+ private void updateChildrenClipping() {
+ int childCount = mChildren.size();
+ int layoutEnd = mNotificationParent.getActualHeight() - mClipBottomAmount;
+ for (int i = 0; i < childCount; i++) {
+ ExpandableNotificationRow child = mChildren.get(i);
+ if (child.getVisibility() == GONE) {
+ continue;
+ }
+ float childTop = child.getTranslationY();
+ float childBottom = childTop + child.getActualHeight();
+ boolean visible = true;
+ int clipBottomAmount = 0;
+ if (childTop > layoutEnd) {
+ visible = false;
+ } else if (childBottom > layoutEnd) {
+ clipBottomAmount = (int) (childBottom - layoutEnd);
+ }
+
+ boolean isVisible = child.getVisibility() == VISIBLE;
+ if (visible != isVisible) {
+ child.setVisibility(visible ? VISIBLE : INVISIBLE);
+ }
+
+ child.setClipBottomAmount(clipBottomAmount);
+ }
}
/**
@@ -653,6 +670,7 @@
if (mNotificationHeader != null) {
mHeaderViewState.applyToView(mNotificationHeader);
}
+ updateChildrenClipping();
}
public ExpandableNotificationRow getViewAtPosition(float y) {
@@ -889,4 +907,9 @@
}
}
}
+
+ public void setClipBottomAmount(int clipBottomAmount) {
+ mClipBottomAmount = clipBottomAmount;
+ updateChildrenClipping();
+ }
}
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 522e4a9..10d995c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -766,12 +766,14 @@
*/
private float getAppearEndPosition() {
int appearPosition;
+ int minNotificationsForShelf = 1;
if (mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) {
appearPosition = mHeadsUpManager.getTopHeadsUpPinnedHeight();
+ minNotificationsForShelf = 2;
} else {
- appearPosition = getFirstItemMinHeight();
+ appearPosition = 0;
}
- if (getNotGoneChildCount() > 1) {
+ if (getNotGoneChildCount() >= minNotificationsForShelf) {
appearPosition += mShelf.getIntrinsicHeight();
}
return appearPosition + (onKeyguard() ? mTopPadding : mIntrinsicPadding);
@@ -1092,29 +1094,7 @@
@Override
public int getMaxExpandHeight(ExpandableView view) {
- int maxContentHeight = view.getMaxContentHeight();
- if (view.isSummaryWithChildren() && view.getParent() == this) {
- // Faking a measure with the group expanded to simulate how the group would look if
- // it was. Doing a calculation here would be highly non-trivial because of the
- // algorithm
- mGroupExpandedForMeasure = true;
- ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- mGroupManager.toggleGroupExpansion(row.getStatusBarNotification());
- row.setForceUnlocked(true);
- mAmbientState.setLayoutHeight(mMaxLayoutHeight);
- mStackScrollAlgorithm.getStackScrollState(mAmbientState, mCurrentStackScrollState);
- mAmbientState.setLayoutHeight(getLayoutHeight());
- mGroupManager.toggleGroupExpansion(
- row.getStatusBarNotification());
- mGroupExpandedForMeasure = false;
- row.setForceUnlocked(false);
- ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(view);
- if (viewState != null) {
- // The view could have been removed
- return Math.min(viewState.height, maxContentHeight);
- }
- }
- return maxContentHeight;
+ return view.getMaxContentHeight();
}
public void setScrollingEnabled(boolean enable) {
@@ -2126,7 +2106,7 @@
finalTranslationY = (int) ViewState.getFinalTranslationY(lastView);
}
int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
- int finalBottom = finalTranslationY + finalHeight;
+ int finalBottom = finalTranslationY + finalHeight - lastView.getClipBottomAmount();
finalBottom = Math.min(finalBottom, getHeight());
if (mAnimateNextBackgroundBottom
|| mBottomAnimator == null && mCurrentBounds.bottom == finalBottom
@@ -2134,10 +2114,10 @@
// we're ending up at the same location as we are now, lets just skip the animation
bottom = finalBottom;
} else {
- bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight());
+ bottom = (int) (lastView.getTranslationY() + lastView.getActualHeight()
+ - lastView.getClipBottomAmount());
bottom = Math.min(bottom, getHeight());
}
- bottom -= lastView.getClipBottomAmount();
} else {
top = mTopPadding;
bottom = top;
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 1dc346d..7afc7ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -140,7 +140,7 @@
float newNotificationEnd = newYTranslation + newHeight;
boolean isHeadsUp = (child instanceof ExpandableNotificationRow)
&& ((ExpandableNotificationRow) child).isPinned();
- if (newYTranslation < previousNotificationEnd
+ if (!state.inShelf && newYTranslation < previousNotificationEnd
&& (!isHeadsUp || ambientState.isShadeExpanded())) {
// The previous view is overlapping on top, clip!
float overlapAmount = previousNotificationEnd - newYTranslation;
@@ -323,9 +323,6 @@
int childHeight = getMaxAllowedChildHeight(child);
childViewState.yTranslation = currentYPosition;
boolean isDismissView = child instanceof DismissView;
- if (i == 0) {
- updateFirstChildHeight(child, childViewState, childHeight, algorithmState, ambientState);
- }
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
if (isDismissView) {
@@ -450,29 +447,6 @@
}
/**
- * Update the height of the first child i.e clamp it to the bottom stack
- * @param child the child to update
- * @param childViewState the viewstate of the child
- * @param childHeight the height of the child
- * @param algorithmState the algorithm state
- * @param ambientState The ambient state of the algorithm
- */
- protected void updateFirstChildHeight(ExpandableView child, ExpandableViewState childViewState,
- int childHeight, StackScrollAlgorithmState algorithmState,
- AmbientState ambientState) {
-
- int bottomStart= ambientState.getInnerHeight();
- if (algorithmState.visibleChildren.size() > 1) {
- bottomStart -= ambientState.getShelf().getIntrinsicHeight()
- - mPaddingBetweenElements;
- }
- bottomStart += ambientState.getScrollY();
- // Collapse and expand the first child while the shade is being expanded
- childViewState.height = (int) Math.max(Math.min(bottomStart, (float) childHeight),
- child.getCollapsedHeight());
- }
-
- /**
* Calculate the Z positions for all children based on the number of items in both stacks and
* save it in the resultState
* @param resultState The result state to update the zTranslation values
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
index 5393d60..ec0e4cd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogController.java
@@ -78,7 +78,6 @@
AudioSystem.STREAM_SYSTEM_ENFORCED,
AudioSystem.STREAM_TTS,
AudioSystem.STREAM_VOICE_CALL,
- AudioSystem.STREAM_ACCESSIBILITY,
};
private final HandlerThread mWorkerThread;
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 6e17cf4..b03189c 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE" />
+ <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
new file mode 100644
index 0000000..639c8da
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.trust.TrustManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Looper;
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.SubscriptionManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KeyguardIndicationControllerTest extends SysuiTestCase {
+
+ private final String ORGANIZATION_NAME = "organization";
+ private final String DISCLOSURE_WITH_ORGANIZATION_NAME = "managed by organization";
+
+ private Context mContext = mock(Context.class);
+ private DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
+ private ViewGroup mIndicationArea = mock(ViewGroup.class);
+ private KeyguardIndicationTextView mDisclosure = mock(KeyguardIndicationTextView.class);
+
+ private KeyguardIndicationController mController;
+
+ @Before
+ public void setUp() throws Exception {
+ final Resources resources = mock(Resources.class);
+ when(mContext.getResources()).thenReturn(resources);
+ when(mContext.getContentResolver()).thenReturn(mock(ContentResolver.class));
+ when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
+ when(mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)).thenReturn(
+ mock(SubscriptionManager.class));
+ when(mContext.getSystemService(Context.TRUST_SERVICE)).thenReturn(
+ mock(TrustManager.class));
+ when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(
+ mDevicePolicyManager);
+
+ when(resources.getString(R.string.do_disclosure_with_name, ORGANIZATION_NAME))
+ .thenReturn(DISCLOSURE_WITH_ORGANIZATION_NAME);
+
+ when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
+ .thenReturn(mDisclosure);
+ }
+
+ private void createController() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mController = new KeyguardIndicationController(mContext, mIndicationArea, null);
+ }
+
+ @Test
+ public void unmanaged() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.GONE);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void managedNoOwnerName() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void managedOwnerName() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
+ createController();
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+
+ @Test
+ public void updateOnTheFly() {
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ createController();
+
+ final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(null);
+ monitor.onKeyguardVisibilityChanged(true);
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(R.string.do_disclosure_generic);
+ verifyNoMoreInteractions(mDisclosure);
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(true);
+ when(mDevicePolicyManager.getDeviceOwnerOrganizationName()).thenReturn(ORGANIZATION_NAME);
+ monitor.onKeyguardVisibilityChanged(false);
+ monitor.onKeyguardVisibilityChanged(true);
+
+ verify(mDisclosure).setVisibility(View.VISIBLE);
+ verify(mDisclosure).switchIndication(DISCLOSURE_WITH_ORGANIZATION_NAME);
+ verifyNoMoreInteractions(mDisclosure);
+ reset(mDisclosure);
+
+ when(mDevicePolicyManager.isDeviceManaged()).thenReturn(false);
+ monitor.onKeyguardVisibilityChanged(false);
+ monitor.onKeyguardVisibilityChanged(true);
+
+ verify(mDisclosure).setVisibility(View.GONE);
+ verifyNoMoreInteractions(mDisclosure);
+ }
+}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index fc8c675..f08408b 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2232,6 +2232,14 @@
// ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
+ // ACTION: The lockscreen gets shown because the SIM card was removed
+ // SUBTYPE: false: device was previously unlocked, true: device was previously locked
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N-MR2
+ ACTION_LOCK_BECAUSE_SIM_REMOVED = 496;
+
+ // ---- End N-MR2 Constants, all N-MR2 constants go above this line ----
+
// ------- Begin N Keyboard Shortcuts Helper -----
// Keyboard Shortcuts Helper is opened/closed.
KEYBOARD_SHORTCUTS_HELPER = 500;
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 07322fc..8092b4a 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1430,7 +1430,7 @@
synchronized (this) {
try {
ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
reportPowerSaveWhitelistChangedLocked();
updateWhitelistAppIdsLocked();
@@ -2396,7 +2396,7 @@
if (name != null) {
try {
ApplicationInfo ai = pm.getApplicationInfo(name,
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
mPowerSaveWhitelistUserApps.put(ai.packageName,
UserHandle.getAppId(ai.uid));
} catch (PackageManager.NameNotFoundException e) {
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index f5cda0a..72fa1e3 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -41,6 +41,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.TransferPipe;
@@ -63,6 +64,7 @@
private static final boolean DBG = false;
private final Context mContext;
+ private final NetworkScorerAppManager mNetworkScorerAppManager;
private final Map<Integer, INetworkScoreCache> mScoreCaches;
/** Lock used to update mPackageMonitor when scorer package changes occur. */
private final Object mPackageMonitorLock = new Object[0];
@@ -133,7 +135,7 @@
+ ", forceUnbind=" + forceUnbind);
}
final NetworkScorerAppData activeScorer =
- NetworkScorerAppManager.getActiveScorer(mContext);
+ mNetworkScorerAppManager.getActiveScorer();
if (activeScorer == null) {
// Package change has invalidated a scorer, this will also unbind any service
// connection.
@@ -154,7 +156,13 @@
}
public NetworkScoreService(Context context) {
+ this(context, new NetworkScorerAppManager(context));
+ }
+
+ @VisibleForTesting
+ NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager) {
mContext = context;
+ mNetworkScorerAppManager = networkScoreAppManager;
mScoreCaches = new HashMap<>();
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
// TODO: Need to update when we support per-user scorers. http://b/23422763
@@ -173,7 +181,7 @@
String defaultPackage = mContext.getResources().getString(
R.string.config_defaultNetworkScorerPackageName);
if (!TextUtils.isEmpty(defaultPackage)) {
- NetworkScorerAppManager.setActiveScorer(mContext, defaultPackage);
+ mNetworkScorerAppManager.setActiveScorer(defaultPackage);
}
Settings.Global.putInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 1);
}
@@ -194,7 +202,7 @@
private void registerPackageMonitorIfNeeded() {
if (DBG) Log.d(TAG, "registerPackageMonitorIfNeeded");
- NetworkScorerAppData scorer = NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData scorer = mNetworkScorerAppManager.getActiveScorer();
synchronized (mPackageMonitorLock) {
// Unregister the current monitor if needed.
if (mPackageMonitor != null) {
@@ -222,7 +230,7 @@
private void bindToScoringServiceIfNeeded() {
if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded");
- NetworkScorerAppData scorerData = NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData scorerData = mNetworkScorerAppManager.getActiveScorer();
bindToScoringServiceIfNeeded(scorerData);
}
@@ -259,7 +267,7 @@
@Override
public boolean updateScores(ScoredNetwork[] networks) {
- if (!NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid())) {
+ if (!mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid())) {
throw new SecurityException("Caller with UID " + getCallingUid() +
" is not the active scorer.");
}
@@ -298,7 +306,7 @@
public boolean clearScores() {
// Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
// should be allowed to flush all scores.
- if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) ||
+ if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
PackageManager.PERMISSION_GRANTED) {
clearInternal();
@@ -328,7 +336,7 @@
public void disableScoring() {
// Only the active scorer or the system (who can broadcast BROADCAST_NETWORK_PRIVILEGED)
// should be allowed to disable scoring.
- if (NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid()) ||
+ if (mNetworkScorerAppManager.isCallerActiveScorer(getCallingUid()) ||
mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED) ==
PackageManager.PERMISSION_GRANTED) {
// The return value is discarded here because at this point, the call should always
@@ -352,8 +360,8 @@
// only be allowing valid apps to be set as scorers, so failure here should be rare.
clearInternal();
// Get the scorer that is about to be replaced, if any, so we can notify it directly.
- NetworkScorerAppData prevScorer = NetworkScorerAppManager.getActiveScorer(mContext);
- boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName);
+ NetworkScorerAppData prevScorer = mNetworkScorerAppManager.getActiveScorer();
+ boolean result = mNetworkScorerAppManager.setActiveScorer(packageName);
// Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed
// then we'll attempt to restore the previous binding (if any), otherwise an attempt
// will be made to bind to the new scorer.
@@ -411,7 +419,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
- NetworkScorerAppData currentScorer = NetworkScorerAppManager.getActiveScorer(mContext);
+ NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer();
if (currentScorer == null) {
writer.println("Scoring is disabled.");
return;
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 080b46c..698f1eb 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -26,7 +26,6 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
-import android.provider.Settings;
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import android.util.Slog;
@@ -53,15 +52,14 @@
* This data will live across factory resets not initiated via the Settings UI.
* When a device is factory reset through Settings this data is wiped.
*
- * Allows writing one block at a time. Namely, each time
- * {@link android.service.persistentdata.IPersistentDataBlockService}.write(byte[] data)
- * is called, it will overwite the data that was previously written on the block.
+ * Allows writing one block at a time. Namely, each time {@link IPersistentDataBlockService#write}
+ * is called, it will overwrite the data that was previously written on the block.
*
* Clients can query the size of the currently written block via
- * {@link android.service.persistentdata.IPersistentDataBlockService}.getTotalDataSize().
+ * {@link IPersistentDataBlockService#getDataBlockSize}
*
- * Clients can any number of bytes from the currently written block up to its total size by invoking
- * {@link android.service.persistentdata.IPersistentDataBlockService}.read(byte[] data)
+ * Clients can read any number of bytes from the currently written block up to its total size by
+ * invoking {@link IPersistentDataBlockService#read}
*/
public class PersistentDataBlockService extends SystemService {
private static final String TAG = PersistentDataBlockService.class.getSimpleName();
@@ -84,6 +82,7 @@
private int mAllowedUid = -1;
private long mBlockDeviceSize;
+ private boolean mIsWritable = true;
public PersistentDataBlockService(Context context) {
super(context);
@@ -377,6 +376,11 @@
headerAndData.put(data);
synchronized (mLock) {
+ if (!mIsWritable) {
+ IoUtils.closeQuietly(outputStream);
+ return -1;
+ }
+
try {
byte[] checksum = new byte[DIGEST_SIZE_BYTES];
outputStream.write(checksum, 0, DIGEST_SIZE_BYTES);
@@ -451,6 +455,9 @@
if (ret < 0) {
Slog.e(TAG, "failed to wipe persistent partition");
+ } else {
+ mIsWritable = false;
+ Slog.i(TAG, "persistent partition now wiped and unwritable");
}
}
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 11fabb4..55d31c3 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -644,14 +644,8 @@
Slog.e(TAG, "Unable to record last fstrim!");
}
- final boolean shouldBenchmark = shouldBenchmark();
- try {
- // This method must be run on the main (handler) thread,
- // so it is safe to directly call into vold.
- mConnector.execute("fstrim", shouldBenchmark ? "dotrimbench" : "dotrim");
- } catch (NativeDaemonConnectorException ndce) {
- Slog.e(TAG, "Failed to run fstrim!");
- }
+ final int flags = shouldBenchmark() ? StorageManager.FSTRIM_FLAG_BENCHMARK : 0;
+ fstrim(flags);
// invoke the completion callback, if any
// TODO: fstrim is non-blocking, so remove this useless callback
@@ -1956,6 +1950,28 @@
}
}
+ @Override
+ public void fstrim(int flags) {
+ enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
+ waitForReady();
+
+ String cmd;
+ if ((flags & StorageManager.FSTRIM_FLAG_DEEP) != 0) {
+ cmd = "dodtrim";
+ } else {
+ cmd = "dotrim";
+ }
+ if ((flags & StorageManager.FSTRIM_FLAG_BENCHMARK) != 0) {
+ cmd += "bench";
+ }
+
+ try {
+ mConnector.execute("fstrim", cmd);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "Failed to run fstrim: " + e);
+ }
+ }
+
private void remountUidExternalStorage(int uid, int mode) {
waitForReady();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 136e02c..7661127 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -75,6 +75,7 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
+import android.webkit.WebViewZygote;
public final class ActiveServices {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM;
@@ -1704,6 +1705,7 @@
final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
+ String hostingType = "service";
ProcessRecord app;
if (!isolated) {
@@ -1732,13 +1734,17 @@
// in the service any current isolated process it is running in or
// waiting to have come up.
app = r.isolatedProc;
+ if (WebViewZygote.isMultiprocessEnabled()
+ && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
+ hostingType = "webview_service";
+ }
}
// Not running -- get it started, and enqueue this service record
// to be executed when the app comes up.
if (app == null && !permissionsReviewRequired) {
if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
- "service", r.name, false, isolated, false)) == null) {
+ hostingType, r.name, false, isolated, false)) == null) {
String msg = "Unable to launch app "
+ r.appInfo.packageName + "/"
+ r.appInfo.uid + " for service "
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3f73fd2d..6aa0dc9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -200,6 +200,7 @@
import android.os.storage.IStorageManager;
import android.os.storage.StorageManagerInternal;
import android.os.storage.StorageManager;
+import android.provider.Downloads;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionManagerInternal;
@@ -271,10 +272,12 @@
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
import static android.content.pm.PackageManager.GET_PROVIDERS;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
@@ -360,7 +363,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
@@ -3693,10 +3695,18 @@
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
- Process.ProcessStartResult startResult = Process.start(entryPoint,
- app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
- app.info.dataDir, entryPointArgs);
+ Process.ProcessStartResult startResult;
+ if (hostingType.equals("webview_service")) {
+ startResult = Process.startWebView(entryPoint,
+ app.processName, uid, uid, gids, debugFlags, mountExternal,
+ app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
+ app.info.dataDir, entryPointArgs);
+ } else {
+ startResult = Process.start(entryPoint,
+ app.processName, uid, uid, gids, debugFlags, mountExternal,
+ app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
+ app.info.dataDir, entryPointArgs);
+ }
checkTime(startTime, "startProcess: returned from zygote!");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
@@ -8512,6 +8522,12 @@
// Only inspect grants matching package
if (packageName == null || perm.sourcePkg.equals(packageName)
|| perm.targetPkg.equals(packageName)) {
+ // Hacky solution as part of fixing a security bug; ignore
+ // grants associated with DownloadManager so we don't have
+ // to immediately launch it to regrant the permissions
+ if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
+ && !persistable) continue;
+
persistChanged |= perm.revokeModes(persistable
? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
@@ -9175,10 +9191,10 @@
}
}
final ActivityStack stack = tr.getStack();
- if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
- if (stack != null && stack.isHomeStack()) {
+ if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
+ if (stack != null && stack.isHomeOrRecentsStack()) {
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
- "Skipping, home stack task: " + tr);
+ "Skipping, home or recents stack task: " + tr);
continue;
}
}
@@ -9600,8 +9616,8 @@
@Override
public void removeStack(int stackId) {
enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
- if (stackId == HOME_STACK_ID) {
- throw new IllegalArgumentException("Removing home stack is not allowed.");
+ if (StackId.isHomeOrRecentsStack(stackId)) {
+ throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
}
synchronized (this) {
@@ -9829,9 +9845,9 @@
@Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
- if (stackId == HOME_STACK_ID) {
+ if (StackId.isHomeOrRecentsStack(stackId)) {
throw new IllegalArgumentException(
- "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
+ "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
}
synchronized (this) {
long ident = Binder.clearCallingIdentity();
@@ -9846,8 +9862,7 @@
!FORCE_FOCUS, "moveTaskToStack", ANIMATE);
if (result && stackId == DOCKED_STACK_ID) {
// If task moved to docked stack - show recents if needed.
- mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
- "moveTaskToDockedStack");
+ mWindowManager.showRecentApps(false /* fromHome */);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -10031,10 +10046,10 @@
@Override
public void positionTaskInStack(int taskId, int stackId, int position) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
- if (stackId == HOME_STACK_ID) {
+ if (StackId.isHomeOrRecentsStack(stackId)) {
throw new IllegalArgumentException(
"positionTaskInStack: Attempt to change the position of task "
- + taskId + " in/to home stack");
+ + taskId + " in/to home/recents stack");
}
synchronized (this) {
long ident = Binder.clearCallingIdentity();
@@ -10076,22 +10091,6 @@
}
@Override
- public boolean isInHomeStack(int taskId) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
- long ident = Binder.clearCallingIdentity();
- try {
- synchronized (this) {
- final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
- taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
- final ActivityStack stack = tr != null ? tr.getStack() : null;
- return stack != null && stack.isHomeStack();
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- @Override
public int getTaskForActivity(IBinder token, boolean onlyRoot) {
synchronized(this) {
return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
@@ -14430,7 +14429,7 @@
if (dumpPackage != null) {
IPackageManager pm = AppGlobals.getPackageManager();
try {
- dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
+ dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
} catch (RemoteException e) {
}
}
@@ -15407,7 +15406,7 @@
if (dumpPackage != null) {
try {
dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
- MATCH_UNINSTALLED_PACKAGES, 0);
+ MATCH_ANY_USER, 0);
} catch (NameNotFoundException e) {
dumpUid = -1;
}
@@ -18837,8 +18836,8 @@
@Override
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
- if (fromStackId == HOME_STACK_ID) {
- throw new IllegalArgumentException("You can't move tasks from the home stack.");
+ if (StackId.isHomeOrRecentsStack(fromStackId)) {
+ throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
}
synchronized (this) {
final long origId = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index facfeb6..32dec96 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -5,6 +5,8 @@
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
+
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
@@ -78,7 +80,7 @@
if (stack.mStackId == PINNED_STACK_ID) {
stack = mSupervisor.findStackBehind(stack);
}
- if (stack.mStackId == HOME_STACK_ID
+ if (StackId.isHomeOrRecentsStack(stack.mStackId)
|| stack.mStackId == FULLSCREEN_WORKSPACE_STACK_ID) {
mWindowState = WINDOW_STATE_STANDARD;
} else if (stack.mStackId == DOCKED_STACK_ID) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 214a357..d2a560f 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -19,7 +19,9 @@
import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
@@ -1197,10 +1199,11 @@
}
final ActivityStack stack = getStack();
- if (stack.isHomeStack()) {
+ if (stack.isHomeOrRecentsStack()) {
// This is an optimization -- since we never show Home or Recents within Recents itself,
// we can just go ahead and skip taking the screenshot if this is the home stack.
- if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, "\tHome stack");
+ if (DEBUG_SCREENSHOTS) Slog.d(TAG_SCREENSHOTS, stack.getStackId() == HOME_STACK_ID ?
+ "\tHome stack" : "\tRecents stack");
return null;
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 005b8aa..b2adc73 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -22,6 +22,7 @@
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
@@ -690,6 +691,10 @@
return mStackId == HOME_STACK_ID;
}
+ final boolean isHomeOrRecentsStack() {
+ return StackId.isHomeOrRecentsStack(mStackId);
+ }
+
final boolean isDockedStack() {
return mStackId == DOCKED_STACK_ID;
}
@@ -1450,10 +1455,10 @@
return false;
}
- if (!isHomeStack() && r.frontOfTask
- && task.isOverHomeStack() && stackBehindId != HOME_STACK_ID) {
+ if (!isHomeOrRecentsStack() && r.frontOfTask
+ && task.isOverHomeStack() && !StackId.isHomeOrRecentsStack(stackBehindId)) {
// Stack isn't translucent if it's top activity should have the home stack
- // behind it and the stack currently behind it isn't the home stack.
+ // behind it and the stack currently behind it isn't the home or recents stack.
return false;
}
}
@@ -1519,10 +1524,10 @@
}
if (mStackId == FULLSCREEN_WORKSPACE_STACK_ID
- && hasVisibleBehindActivity() && focusedStackId == HOME_STACK_ID
+ && hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(focusedStackId)
&& !focusedStack.topActivity().fullscreen) {
// The fullscreen stack should be visible if it has a visible behind activity behind
- // the home stack that is translucent.
+ // the home or recents stack that is translucent.
return STACK_VISIBLE_ACTIVITY_BEHIND;
}
@@ -1922,7 +1927,7 @@
+ " behindFullscreenActivity=" + behindFullscreenActivity);
// At this point, nothing else needs to be shown in this task.
behindFullscreenActivity = true;
- } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
+ } else if (!isHomeOrRecentsStack() && r.frontOfTask && task.isOverHomeStack()) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Showing home: at " + r
+ " stackInvisible=" + stackInvisible
+ " behindFullscreenActivity=" + behindFullscreenActivity);
@@ -2096,9 +2101,7 @@
if (next == null) {
// There are no more activities!
final String reason = "noMoreActivities";
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack()
- ? HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- if (!mFullscreen && adjustFocusToNextFocusableStackLocked(returnTaskType, reason)) {
+ if (!mFullscreen && adjustFocusToNextFocusableStackLocked(reason)) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen.
return mStackSupervisor.resumeFocusedStackTopActivityLocked(
@@ -2112,7 +2115,7 @@
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
+ mStackSupervisor.resumeHomeStackTask(prev, reason);
}
next.delayedResume = false;
@@ -2147,10 +2150,8 @@
} else if (!isHomeStack()){
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Launching home next");
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
+ mStackSupervisor.resumeHomeStackTask(prev, "prevFinished");
}
}
@@ -2567,7 +2568,7 @@
// activity, set mTaskToReturnTo accordingly.
if (isOnHomeDisplay()) {
ActivityStack lastStack = mStackSupervisor.getLastStack();
- final boolean fromHome = lastStack.isHomeStack();
+ final boolean fromHomeOrRecents = lastStack.isHomeOrRecentsStack();
final boolean fromOnTopLauncher = lastStack.topTask() != null &&
lastStack.topTask().isOnTopLauncher();
if (fromOnTopLauncher) {
@@ -2576,12 +2577,12 @@
// This also makes sure that non-home activities are visible under a transparent
// non-home activity.
task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- } else if (!isHomeStack() && (fromHome || topTask() != task)) {
+ } else if (!isHomeOrRecentsStack() && (fromHomeOrRecents || topTask() != task)) {
// If it's a last task over home - we default to keep its return to type not to
// make underlying task focused when this one will be finished.
int returnToType = isLastTaskOverHome
? task.getTaskToReturnTo() : APPLICATION_ACTIVITY_TYPE;
- if (fromHome && StackId.allowTopTaskToReturnHome(mStackId)) {
+ if (fromHomeOrRecents && StackId.allowTopTaskToReturnHome(mStackId)) {
returnToType = lastStack.topTask() == null
? HOME_ACTIVITY_TYPE : lastStack.topTask().taskType;
}
@@ -2675,7 +2676,7 @@
task.setFrontOfTask();
r.putInHistory();
- if (!isHomeStack() || numActivities() > 0) {
+ if (!isHomeOrRecentsStack() || numActivities() > 0) {
// We want to show the starting preview window if we are
// switching to a new task, or the next activity's process is
// not currently running.
@@ -3114,18 +3115,16 @@
} else {
final TaskRecord task = r.task;
if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
- final int taskToReturnTo = task.getTaskToReturnTo();
-
// For non-fullscreen stack, we want to move the focus to the next visible
// stack to prevent the home screen from moving to the top and obscuring
// other visible stacks.
if (!mFullscreen
- && adjustFocusToNextFocusableStackLocked(taskToReturnTo, myReason)) {
+ && adjustFocusToNextFocusableStackLocked(myReason)) {
return;
}
// Move the home stack to the top if this stack is fullscreen or there is no
// other visible stack.
- if (mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, myReason)) {
+ if (mStackSupervisor.moveHomeStackTaskToTop(myReason)) {
// Activity focus was already adjusted. Nothing else to do...
return;
}
@@ -3137,7 +3136,7 @@
mStackSupervisor.topRunningActivityLocked(), myReason);
}
- private boolean adjustFocusToNextFocusableStackLocked(int taskToReturnTo, String reason) {
+ private boolean adjustFocusToNextFocusableStackLocked(String reason) {
final ActivityStack stack = getNextFocusableStackLocked();
final String myReason = reason + " adjustFocusToNextFocusableStack";
if (stack == null) {
@@ -3146,10 +3145,10 @@
final ActivityRecord top = stack.topRunningActivityLocked();
- if (stack.isHomeStack() && (top == null || !top.visible)) {
+ if (stack.isHomeOrRecentsStack() && (top == null || !top.visible)) {
// If we will be focusing on the home stack next and its current top activity isn't
// visible, then use the task return to value to determine the home task to display next.
- return mStackSupervisor.moveHomeStackTaskToTop(taskToReturnTo, reason);
+ return mStackSupervisor.moveHomeStackTaskToTop(reason);
}
stack.moveToFront(myReason);
@@ -3754,7 +3753,7 @@
"removeActivityFromHistoryLocked: last activity removed from " + this);
if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
task.isOverHomeStack()) {
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo(), reason);
+ mStackSupervisor.moveHomeStackTaskToTop(reason);
}
removeTask(task, reason);
}
@@ -4176,11 +4175,11 @@
mStackSupervisor.invalidateTaskLayers();
}
- void moveHomeStackTaskToTop(int homeStackTaskType) {
+ void moveHomeStackTaskToTop() {
final int top = mTaskHistory.size() - 1;
for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.taskType == homeStackTaskType) {
+ if (task.taskType == HOME_ACTIVITY_TYPE) {
if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
"moveHomeStackTaskToTop: moving " + task);
mTaskHistory.remove(taskNdx);
@@ -4306,7 +4305,7 @@
moveToBack(topTask());
// Resume an activity in the next focusable stack.
- adjustFocusToNextFocusableStackLocked(APPLICATION_ACTIVITY_TYPE, "moveTaskToBack");
+ adjustFocusToNextFocusableStackLocked("moveTaskToBack");
mStackSupervisor.resumeFocusedStackTopActivityLocked();
return true;
}
@@ -4365,9 +4364,8 @@
// Not ready yet!
return false;
}
- final int taskToReturnTo = tr.getTaskToReturnTo();
tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null, "moveTaskToBack");
+ return mStackSupervisor.resumeHomeStackTask(null, "moveTaskToBack");
}
mStackSupervisor.resumeFocusedStackTopActivityLocked();
@@ -4840,9 +4838,7 @@
if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP
&& mStackSupervisor.isFocusedStack(this)) {
String myReason = reason + " leftTaskHistoryEmpty";
- if (mFullscreen
- || !adjustFocusToNextFocusableStackLocked(
- task.getTaskToReturnTo(), myReason)) {
+ if (mFullscreen || !adjustFocusToNextFocusableStackLocked(myReason)) {
mStackSupervisor.moveHomeStackToFront(myReason);
}
}
@@ -4850,7 +4846,7 @@
mStacks.remove(this);
mStacks.add(0, this);
}
- if (!isHomeStack()) {
+ if (!isHomeOrRecentsStack()) {
mActivityContainer.onTaskListEmptyLocked();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 48108fe..e3212c2 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -33,6 +33,7 @@
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -72,7 +73,6 @@
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
@@ -661,13 +661,8 @@
}
/** Returns true if the focus activity was adjusted to the home stack top activity. */
- boolean moveHomeStackTaskToTop(int homeStackTaskType, String reason) {
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps(false /* fromHome */);
- return false;
- }
-
- mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+ boolean moveHomeStackTaskToTop(String reason) {
+ mHomeStack.moveHomeStackTaskToTop();
final ActivityRecord top = getHomeActivity();
if (top == null) {
@@ -677,22 +672,17 @@
return true;
}
- boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
+ boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
if (!mService.mBooting && !mService.mBooted) {
// Not ready yet!
return false;
}
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps(false /* fromHome */);
- return false;
- }
-
if (prev != null) {
prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
}
- mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+ mHomeStack.moveHomeStackTaskToTop();
ActivityRecord r = getHomeActivity();
final String myReason = reason + " resumeHomeStackTask";
@@ -2754,7 +2744,7 @@
final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
- if (!r.isApplicationActivity() && !stack.isHomeStack()) {
+ if (!r.isApplicationActivity() && !stack.isHomeOrRecentsStack()) {
if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping stack: (home activity) " + stack);
continue;
}
@@ -3178,7 +3168,7 @@
stack.moveToFront("switchUserOnHomeDisplay");
} else {
// Stack was moved to another display while user was swapped out.
- resumeHomeStackTask(HOME_ACTIVITY_TYPE, null, "switchUserOnOtherDisplay");
+ resumeHomeStackTask(null, "switchUserOnOtherDisplay");
}
return homeInFront;
}
@@ -4597,9 +4587,9 @@
? new ActivityOptions(bOptions) : null;
final int launchStackId = (activityOptions != null)
? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
- if (launchStackId == HOME_STACK_ID) {
+ if (StackId.isHomeOrRecentsStack(launchStackId)) {
throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
- + taskId + " can't be launch in the home stack.");
+ + taskId + " can't be launch in the home/recents stack.");
}
if (launchStackId == DOCKED_STACK_ID) {
@@ -4609,13 +4599,13 @@
// Defer updating the stack in which recents is until the app transition is done, to
// not run into issues where we still need to draw the task in recents but the
// docked stack is already created.
- deferUpdateBounds(HOME_STACK_ID);
+ deferUpdateBounds(RECENTS_STACK_ID);
mWindowManager.prepareAppTransition(TRANSIT_DOCK_TASK_FROM_RECENTS, false);
}
task = anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
if (task == null) {
- continueUpdateBounds(HOME_STACK_ID);
+ continueUpdateBounds(RECENTS_STACK_ID);
mWindowManager.executeAppTransition();
throw new IllegalArgumentException(
"startActivityFromRecentsInner: Task " + taskId + " not found.");
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index dff7cef..64bf3ad 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -32,6 +32,7 @@
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManager.StackId.isStaticStack;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -589,7 +590,7 @@
}
void startHomeActivityLocked(Intent intent, ActivityInfo aInfo, String reason) {
- mSupervisor.moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
+ mSupervisor.moveHomeStackTaskToTop(reason);
startActivityLocked(null /*caller*/, intent, null /*ephemeralIntent*/,
null /*resolvedType*/, aInfo, null /*rInfo*/, null /*voiceSession*/,
null /*voiceInteractor*/, null /*resultTo*/, null /*resultWho*/,
@@ -1524,8 +1525,8 @@
private void updateTaskReturnToType(
TaskRecord task, int launchFlags, ActivityStack focusedStack) {
- if (focusedStack != null && focusedStack.isHomeStack() && focusedStack.topTask() != null
- && focusedStack.topTask().isOnTopLauncher()) {
+ if (focusedStack != null && focusedStack.isHomeOrRecentsStack()
+ && focusedStack.topTask() != null && focusedStack.topTask().isOnTopLauncher()) {
// Since an on-top launcher will is moved to back when tasks are launched from it,
// those tasks should first try to return to a non-home activity.
// This also makes sure that non-home activities are visible under a transparent
@@ -1869,7 +1870,10 @@
private ActivityStack computeStackFocus(ActivityRecord r, boolean newTask, Rect bounds,
int launchFlags, ActivityOptions aOptions) {
final TaskRecord task = r.task;
- if (!(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
+ if (r.isRecentsActivity()) {
+ return mSupervisor.getStack(RECENTS_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
+ }
+ if (r.isHomeActivity()) {
return mSupervisor.mHomeStack;
}
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 67cac47..0ea78b3 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -1283,7 +1283,7 @@
if (useCheckinFormat) {
List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
- PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_ALL);
+ PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
if (isRealCheckin) {
// For a real checkin, first we want to prefer to use the last complete checkin
// file if there is one.
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index bc9bda2f..6a13d36 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -130,8 +130,8 @@
void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
final ActivityStack stack = task != null ? task.getStack() : null;
- if (stack != null && stack.isHomeStack()) {
- // Never persist the home stack.
+ if (stack != null && stack.isHomeOrRecentsStack()) {
+ // Never persist the home or recents stack.
return;
}
syncPersistentTaskIdsLocked();
@@ -150,7 +150,7 @@
for (int i = size() - 1; i >= 0; i--) {
final TaskRecord task = get(i);
final ActivityStack stack = task.getStack();
- if (task.isPersistable && (stack == null || !stack.isHomeStack())) {
+ if (task.isPersistable && (stack == null || !stack.isHomeOrRecentsStack())) {
// Set of persisted taskIds for task.userId should not be null here
// TODO Investigate why it can happen. For now initialize with an empty set
if (mPersistedTaskIds.get(task.userId) == null) {
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 1ecb2e9..7a62f2c 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -643,7 +643,7 @@
" persistable=" + task.isPersistable);
final ActivityStack stack = task.getStack();
if ((task.isPersistable || task.inRecents)
- && (stack == null || !stack.isHomeStack())) {
+ && (stack == null || !stack.isHomeOrRecentsStack())) {
if (DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
persistentTaskIds.add(task.taskId);
} else {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 86e3ccc..5c352e1 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -64,6 +64,7 @@
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
import static android.content.pm.ActivityInfo.FLAG_ON_TOP_LAUNCHER;
@@ -1068,7 +1069,7 @@
}
boolean isOverHomeStack() {
- return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
+ return mTaskToReturnTo == HOME_ACTIVITY_TYPE;
}
boolean isResizeable() {
@@ -1417,8 +1418,8 @@
try {
ApplicationInfo ai = pm.getApplicationInfo(
checkIntent.getComponent().getPackageName(),
- PackageManager.GET_UNINSTALLED_PACKAGES
- | PackageManager.GET_DISABLED_COMPONENTS, userId);
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS, userId);
if (ai != null) {
effectiveUid = ai.uid;
}
@@ -1685,7 +1686,10 @@
* The task will be moved (and stack focus changed) later if necessary.
*/
int getLaunchStackId() {
- if (!isApplicationTask()) {
+ if (isRecentsTask()) {
+ return RECENTS_STACK_ID;
+ }
+ if (isHomeTask()) {
return HOME_STACK_ID;
}
if (mBounds != null) {
@@ -1707,6 +1711,7 @@
final int stackId = mStack.mStackId;
if (stackId == HOME_STACK_ID
+ || stackId == RECENTS_STACK_ID
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
|| (stackId == DOCKED_STACK_ID && !isResizeable())) {
return isResizeable() ? mStack.mBounds : null;
diff --git a/services/core/java/com/android/server/firewall/SenderPackageFilter.java b/services/core/java/com/android/server/firewall/SenderPackageFilter.java
index 91c9671..2184245 100644
--- a/services/core/java/com/android/server/firewall/SenderPackageFilter.java
+++ b/services/core/java/com/android/server/firewall/SenderPackageFilter.java
@@ -47,7 +47,7 @@
try {
// USER_SYSTEM here is not important. Only app id is used and getPackageUid() will
// return a uid whether the app is installed for a user or not.
- packageUid = pm.getPackageUid(mPackageName, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ packageUid = pm.getPackageUid(mPackageName, PackageManager.MATCH_ANY_USER,
UserHandle.USER_SYSTEM);
} catch (RemoteException ex) {
// handled below
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index c99d8be..f42c5be 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -1820,7 +1820,7 @@
String pkg = args[opti];
try {
filterUid = getContext().getPackageManager().getPackageUid(pkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
} catch (NameNotFoundException ignored) {
pw.println("Invalid package: " + pkg);
return;
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 45f54a9..54366e6 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -95,7 +95,8 @@
import java.util.Date;
import java.util.Map.Entry;
import java.util.Properties;
-
+import java.util.Map;
+import java.util.HashMap;
import libcore.io.IoUtils;
/**
@@ -211,24 +212,18 @@
private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
- // Request ref location
- private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1;
- private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2;
+ //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
+ private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
// ref. location info
private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
- private static final int AGPS_REG_LOCATION_TYPE_MAC = 3;
// set id info
private static final int AGPS_SETID_TYPE_NONE = 0;
private static final int AGPS_SETID_TYPE_IMSI = 1;
private static final int AGPS_SETID_TYPE_MSISDN = 2;
- private static final String PROPERTIES_FILE_PREFIX = "/etc/gps";
- private static final String PROPERTIES_FILE_SUFFIX = ".conf";
- private static final String DEFAULT_PROPERTIES_FILE = PROPERTIES_FILE_PREFIX + PROPERTIES_FILE_SUFFIX;
-
private static final int GPS_GEOFENCE_UNAVAILABLE = 1<<0L;
private static final int GPS_GEOFENCE_AVAILABLE = 1<<1L;
@@ -501,10 +496,6 @@
startNavigating(false);
} else if (action.equals(ALARM_TIMEOUT)) {
hibernate();
- } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) {
- checkSmsSuplInit(intent);
- } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) {
- checkWapSuplInit(intent);
} else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
|| PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)
|| Intent.ACTION_SCREEN_OFF.equals(action)
@@ -557,31 +548,6 @@
}
}
- private void checkSmsSuplInit(Intent intent) {
- SmsMessage[] messages = Intents.getMessagesFromIntent(intent);
- if (messages == null) {
- Log.e(TAG, "Message does not exist in the intent.");
- return;
- }
-
- for (SmsMessage message : messages) {
- if (message != null && message.mWrappedSmsMessage != null) {
- byte[] suplInit = message.getUserData();
- if (suplInit != null) {
- native_agps_ni_message(suplInit, suplInit.length);
- }
- }
- }
- }
-
- private void checkWapSuplInit(Intent intent) {
- byte[] suplInit = intent.getByteArrayExtra("data");
- if (suplInit == null) {
- return;
- }
- native_agps_ni_message(suplInit,suplInit.length);
- }
-
private void updateLowPowerMode() {
// Disable GPS if we are in device idle mode.
boolean disableGps = mPowerManager.isDeviceIdleMode();
@@ -602,23 +568,14 @@
return native_is_supported();
}
+ interface SetCarrierProperty {
+ public boolean set(int value);
+ }
+
private void reloadGpsProperties(Context context, Properties properties) {
if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
loadPropertiesFromResource(context, properties);
- boolean isPropertiesLoadedFromFile = false;
- final String gpsHardware = SystemProperties.get("ro.hardware.gps");
-
- if (!TextUtils.isEmpty(gpsHardware)) {
- final String propFilename =
- PROPERTIES_FILE_PREFIX + "." + gpsHardware + PROPERTIES_FILE_SUFFIX;
- isPropertiesLoadedFromFile =
- loadPropertiesFromFile(propFilename, properties);
- }
- if (!isPropertiesLoadedFromFile) {
- loadPropertiesFromFile(DEFAULT_PROPERTIES_FILE, properties);
- }
- if (DEBUG) Log.d(TAG, "GPS properties reloaded, size = " + properties.size());
String lpp_prof = SystemProperties.get(LPP_PROFILE);
if (!TextUtils.isEmpty(lpp_prof)) {
// override default value of this if lpp_prof is not empty
@@ -636,16 +593,37 @@
Log.e(TAG, "unable to parse C2K_PORT: " + portString);
}
}
-
+ /*
+ * Allow carrier properties to be loaded from a debug configuration file.
+ */
+ loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties);
if (native_is_gnss_configuration_supported()) {
- try {
- // Convert properties to string contents and send it to HAL.
- ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
- properties.store(baos, null);
- native_configuration_update(baos.toString());
- if (DEBUG) Log.d(TAG, "final config = " + baos.toString());
- } catch (IOException ex) {
- Log.e(TAG, "failed to dump properties contents");
+ Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() {
+ {
+ put("SUPL_VER", (val) -> native_set_supl_version(val));
+ put("SUPL_MODE", (val) -> native_set_supl_mode(val));
+ put("SUPL_ES", (val) -> native_set_supl_es(val));
+ put("LPP_PROFILE", (val) -> native_set_lpp_profile(val));
+ put("A_GLONASS_POS_PROTOCOL_SELECT", (val) -> native_set_gnss_pos_protocol_select(val));
+ put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL", (val) -> native_set_emergency_supl_pdn(val));
+ put("GPS_LOCK", (val) -> native_set_gps_lock(val));
+ }
+ };
+
+ for(Entry<String, SetCarrierProperty> entry : map.entrySet()) {
+ String propertyName = entry.getKey();
+ String propertyValueString = properties.getProperty(propertyName);
+ if (propertyValueString != null) {
+ try {
+ int propertyValueInt = Integer.decode(propertyValueString);
+ boolean result = entry.getValue().set(propertyValueInt);
+ if (result == false) {
+ Log.e(TAG, "Unable to set " + propertyName);
+ }
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
+ }
+ }
}
} else if (DEBUG) {
Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not"
@@ -692,7 +670,7 @@
}
} catch (IOException e) {
- Log.w(TAG, "Could not open GPS configuration file " + filename);
+ Log.v(TAG, "Could not open GPS configuration file " + filename);
return false;
}
return true;
@@ -1973,8 +1951,7 @@
String requestorId,
String text,
int requestorIdEncoding,
- int textEncoding,
- String extras // Encoded extra data
+ int textEncoding
)
{
Log.i(TAG, "reportNiNotification: entered");
@@ -2003,28 +1980,6 @@
notification.requestorIdEncoding = requestorIdEncoding;
notification.textEncoding = textEncoding;
- // Process extras, assuming the format is
- // one of more lines of "key = value"
- Bundle bundle = new Bundle();
-
- if (extras == null) extras = "";
- Properties extraProp = new Properties();
-
- try {
- extraProp.load(new StringReader(extras));
- }
- catch (IOException e)
- {
- Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras);
- }
-
- for (Entry<Object, Object> ent : extraProp.entrySet())
- {
- bundle.putString((String) ent.getKey(), (String) ent.getValue());
- }
-
- notification.extras = bundle;
-
mNIHandler.handleNiNotification(notification);
}
@@ -2075,7 +2030,7 @@
* Called from native code to request reference location info
*/
- private void requestRefLocation(int flags) {
+ private void requestRefLocation() {
TelephonyManager phone = (TelephonyManager)
mContext.getSystemService(Context.TELEPHONY_SERVICE);
final int phoneType = phone.getPhoneType();
@@ -2547,5 +2502,12 @@
private native boolean native_stop_navigation_message_collection();
// GNSS Configuration
- private static native void native_configuration_update(String configData);
+ private static native boolean native_set_supl_version(int version);
+ private static native boolean native_set_supl_mode(int mode);
+ private static native boolean native_set_supl_es(int es);
+ private static native boolean native_set_lpp_profile(int lppProfile);
+ private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
+ private static native boolean native_set_gps_lock(int gpsLock);
+ private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
+
}
diff --git a/services/core/java/com/android/server/media/MediaSessionStack.java b/services/core/java/com/android/server/media/MediaSessionStack.java
index 9740935..d8fd6e2 100644
--- a/services/core/java/com/android/server/media/MediaSessionStack.java
+++ b/services/core/java/com/android/server/media/MediaSessionStack.java
@@ -74,7 +74,7 @@
try {
List<ActivityManager.RecentTaskInfo> tasks =
ActivityManager.getService().getRecentTasks(1,
- ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
+ ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS |
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
ActivityManager.RECENT_INCLUDE_PROFILES |
ActivityManager.RECENT_WITH_EXCLUDED, record.getUserId()).getList();
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index c1506b9..533307e 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -2720,7 +2720,7 @@
// update rules for all installed applications
final List<UserInfo> users = mUserManager.getUsers();
final List<ApplicationInfo> apps = pm.getInstalledApplications(
- PackageManager.MATCH_UNINSTALLED_PACKAGES | PackageManager.MATCH_DISABLED_COMPONENTS
+ PackageManager.MATCH_ANY_USER | PackageManager.MATCH_DISABLED_COMPONENTS
| PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4658c046..8ca6086 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -1212,7 +1212,8 @@
// Build list of UIDs that we should clean up
int[] uids = new int[0];
final List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
- PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_DISABLED_COMPONENTS);
+ PackageManager.MATCH_ANY_USER
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
for (ApplicationInfo app : apps) {
final int uid = UserHandle.getUid(userId, app.uid);
uids = ArrayUtils.appendInt(uids, uid);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 84c298b..c78a0f5 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -53,16 +53,17 @@
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.AutomaticZenRule;
+import android.app.backup.BackupManager;
import android.app.IActivityManager;
+import android.app.IOnNotificationChannelCreatedListener;
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.app.Notification;
import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.app.NotificationManager.Policy;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
-import android.app.backup.BackupManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
@@ -224,6 +225,7 @@
private static final long MIN_PACKAGE_OVERRATE_LOG_INTERVAL = 5000; // milliseconds
private IActivityManager mAm;
+ private IPackageManager mPackageManager;
AudioManager mAudioManager;
AudioManagerInternal mAudioManagerInternal;
@Nullable StatusBarManagerInternal mStatusBar;
@@ -718,10 +720,10 @@
if (packageChanged) {
// We cancel notifications for packages which have just been disabled
try {
- final IPackageManager pm = AppGlobals.getPackageManager();
- final int enabled = pm.getApplicationEnabledSetting(pkgName,
+ final int enabled = mPackageManager.getApplicationEnabledSetting(
+ pkgName,
changeUserId != UserHandle.USER_ALL ? changeUserId :
- UserHandle.USER_SYSTEM);
+ UserHandle.USER_SYSTEM);
if (enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|| enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
cancelNotifications = false;
@@ -884,6 +886,7 @@
super(context);
}
+ // TODO - replace these methods with a single VisibleForTesting constructor
@VisibleForTesting
void setAudioManager(AudioManager audioMananger) {
mAudioManager = audioMananger;
@@ -931,6 +934,17 @@
mFallbackVibrationPattern = vibrationPattern;
}
+ @VisibleForTesting
+ void setPackageManager(IPackageManager packageManager) {
+ mPackageManager = packageManager;
+ }
+
+ // TODO: This probably should not be mocked, it's an implementation detail.
+ @VisibleForTesting
+ void setRankingHelper(RankingHelper rankingHelper) {
+ mRankingHelper = rankingHelper;
+ }
+
@Override
public void onStart() {
Resources resources = getContext().getResources();
@@ -940,6 +954,7 @@
DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
mAm = ActivityManager.getService();
+ mPackageManager = AppGlobals.getPackageManager();
mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
@@ -1312,6 +1327,11 @@
scheduleInterruptionFilterChanged(interruptionFilter);
}
+ @VisibleForTesting
+ INotificationManager getBinderService() {
+ return INotificationManager.Stub.asInterface(mService);
+ }
+
private final IBinder mService = new INotificationManager.Stub() {
// Toasts
// ============================================================================
@@ -1529,13 +1549,15 @@
}
@Override
- public void createNotificationChannel(String pkg, NotificationChannel channel) {
+ public void createNotificationChannel(String pkg, NotificationChannel channel,
+ IOnNotificationChannelCreatedListener listener) throws RemoteException {
Preconditions.checkNotNull(channel);
Preconditions.checkNotNull(channel.getId());
Preconditions.checkNotNull(channel.getName());
checkCallerIsSystemOrSameApp(pkg);
mRankingHelper.createNotificationChannel(pkg, Binder.getCallingUid(), channel);
savePolicyFile();
+ listener.onNotificationChannelCreated(channel);
}
@Override
@@ -3906,23 +3928,23 @@
throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
}
- private static void checkCallerIsSystemOrSameApp(String pkg) {
+ private void checkCallerIsSystemOrSameApp(String pkg) {
if (isCallerSystem()) {
return;
}
checkCallerIsSameApp(pkg);
}
- private static void checkCallerIsSameApp(String pkg) {
+ private void checkCallerIsSameApp(String pkg) {
final int uid = Binder.getCallingUid();
try {
- ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
+ ApplicationInfo ai = mPackageManager.getApplicationInfo(
pkg, 0, UserHandle.getCallingUserId());
if (ai == null) {
throw new SecurityException("Unknown package " + pkg);
}
if (!UserHandle.isSameApp(ai.uid, uid)) {
- throw new SecurityException("Calling uid " + uid + " gave package"
+ throw new SecurityException("Calling uid " + uid + " gave package "
+ pkg + " which is owned by uid " + ai.uid);
}
} catch (RemoteException re) {
@@ -4009,7 +4031,7 @@
private boolean isPackageSuspendedForUser(String pkg, int uid) {
int userId = UserHandle.getUserId(uid);
try {
- return AppGlobals.getPackageManager().isPackageSuspendedForUser(pkg, userId);
+ return mPackageManager.isPackageSuspendedForUser(pkg, userId);
} catch (RemoteException re) {
throw new SecurityException("Could not talk to package manager service");
} catch (IllegalArgumentException ex) {
@@ -4510,7 +4532,7 @@
}
public String[] getRequestingPackages() throws RemoteException {
- final ParceledListSlice list = AppGlobals.getPackageManager()
+ final ParceledListSlice list = mPackageManager
.getPackagesHoldingPermissions(PERM, 0 /*flags*/,
ActivityManager.getCurrentUser());
final List<PackageInfo> pkgs = list.getList();
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 29fa754..66fb976 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -595,7 +595,7 @@
if (RULE_INSTANCE_GRACE_PERIOD < (currentTime - rule.creationTime)) {
try {
mPm.getPackageInfo(rule.component.getPackageName(),
- PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ PackageManager.MATCH_ANY_USER);
} catch (PackageManager.NameNotFoundException e) {
newConfig.automaticRules.removeAt(i);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3490503..dc25ce4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -59,11 +59,13 @@
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.MATCH_ALL;
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
+import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
@@ -100,6 +102,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
@@ -3140,6 +3143,11 @@
? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
final PackageUserState state = ps.readUserState(userId);
+ if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
+ && ps.isSystem()) {
+ flags |= MATCH_ANY_USER;
+ }
+
return PackageParser.generatePackageInfo(p, gids, flags,
ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
}
@@ -3221,7 +3229,7 @@
if (p != null) {
return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
}
- if (!matchFactoryOnly && (flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
+ if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
return generatePackageInfo(ps, flags, userId);
}
@@ -3268,7 +3276,7 @@
if (p != null && p.isMatch(flags)) {
return UserHandle.getUid(userId, p.applicationInfo.uid);
}
- if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
+ if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null && ps.isMatch(flags)) {
return UserHandle.getUid(userId, ps.appId);
@@ -3292,9 +3300,11 @@
final PackageParser.Package p = mPackages.get(packageName);
if (p != null && p.isMatch(flags)) {
PackageSetting ps = (PackageSetting) p.mExtras;
+ // TODO: Shouldn't this be checking for package installed state for userId and
+ // return null?
return ps.getPermissionsState().computeGids(userId);
}
- if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
+ if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null && ps.isMatch(flags)) {
return ps.getPermissionsState().computeGids(userId);
@@ -3418,7 +3428,7 @@
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
}
- if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0) {
+ if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
return generateApplicationInfoFromSettingsLPw(packageName, flags, userId);
}
}
@@ -3527,6 +3537,7 @@
* Update given flags when being used to request {@link PackageInfo}.
*/
private int updateFlagsForPackage(int flags, int userId, Object cookie) {
+ final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
boolean triaged = true;
if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
| PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
@@ -3543,6 +3554,18 @@
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
triaged = false;
}
+ if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
+ "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
+ + Debug.getCallers(5));
+ } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
+ && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
+ // If the caller wants all packages and has a restricted profile associated with it,
+ // then match all users. This is to make sure that launchers that need to access work
+ // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
+ // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
+ flags |= PackageManager.MATCH_ANY_USER;
+ }
if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
+ " with flags 0x" + Integer.toHexString(flags), new Throwable());
@@ -6299,7 +6322,7 @@
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForPackage(flags, userId, null);
- final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
+ final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
"get installed packages");
@@ -6383,7 +6406,10 @@
String[] permissions, int flags, int userId) {
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForPackage(flags, userId, permissions);
- final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
+ enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ true /* requireFullPermission */, false /* checkShell */,
+ "get packages holding permissions");
+ final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
// writer
synchronized (mPackages) {
@@ -6391,7 +6417,8 @@
boolean[] tmpBools = new boolean[permissions.length];
if (listUninstalled) {
for (PackageSetting ps : mSettings.mPackages.values()) {
- addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags, userId);
+ addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
+ userId);
}
} else {
for (PackageParser.Package pkg : mPackages.values()) {
@@ -6411,7 +6438,7 @@
public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
flags = updateFlagsForApplication(flags, userId, null);
- final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0;
+ final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
// writer
synchronized (mPackages) {
@@ -6420,11 +6447,16 @@
list = new ArrayList<ApplicationInfo>(mSettings.mPackages.size());
for (PackageSetting ps : mSettings.mPackages.values()) {
ApplicationInfo ai;
+ int effectiveFlags = flags;
+ if (ps.isSystem()) {
+ effectiveFlags |= PackageManager.MATCH_ANY_USER;
+ }
if (ps.pkg != null) {
- ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
+ ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
} else {
- ai = generateApplicationInfoFromSettingsLPw(ps.name, flags, userId);
+ ai = generateApplicationInfoFromSettingsLPw(ps.name, effectiveFlags,
+ userId);
}
if (ai != null) {
list.add(ai);
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 834d343..7938a12 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -51,9 +51,11 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.PrintWriterPrinter;
import com.android.internal.content.PackageHelper;
import com.android.internal.util.SizedInputStream;
+import com.android.server.SystemConfig;
import dalvik.system.DexFile;
@@ -135,6 +137,8 @@
return runSuspend(false);
case "set-home-activity":
return runSetHomeActivity();
+ case "get-privapp-permissions":
+ return runGetPrivappPermissions();
default:
return handleDefaultCommands(cmd);
}
@@ -610,7 +614,7 @@
showUid = true;
break;
case "-u":
- getFlags |= PackageManager.GET_UNINSTALLED_PACKAGES;
+ getFlags |= PackageManager.MATCH_UNINSTALLED_PACKAGES;
break;
case "-3":
listThirdParty = true;
@@ -1164,6 +1168,18 @@
}
}
+ private int runGetPrivappPermissions() {
+ final String pkg = getNextArg();
+ if (pkg == null) {
+ System.err.println("Error: no package specified.");
+ return 1;
+ }
+ ArraySet<String> privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
+ getOutPrintWriter().println(privAppPermissions == null
+ ? "{}" : privAppPermissions.toString());
+ return 0;
+ }
+
private static String checkAbiArgument(String abi) {
if (TextUtils.isEmpty(abi)) {
throw new IllegalArgumentException("Missing ABI argument");
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d558b07..2eb0778 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -259,6 +259,11 @@
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
+ if (si.isFloating()) {
+ si.setRank(0);
+ si.setActivity(null);
+ }
+
if (si.isAlive()) continue;
if (removeList == null) {
@@ -288,6 +293,7 @@
si.setTimestamp(now);
si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
si.setRank(0); // It may still be pinned, so clear the rank.
+ si.setActivity(null);
}
}
if (changed) {
@@ -355,6 +361,7 @@
if (oldShortcut.isPinned()) {
oldShortcut.setRank(0);
+ oldShortcut.setActivity(null);
oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
if (disable) {
oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
@@ -595,6 +602,10 @@
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
+
+ if (si.isFloating()) {
+ continue; // Ignore floating shortcuts, which are not tied to any activities.
+ }
final ComponentName activity = si.getActivity();
if (checked.contains(activity)) {
@@ -1356,6 +1367,10 @@
case TAG_SHORTCUT:
final ShortcutInfo si = parseShortcut(parser, packageName,
shortcutUser.getUserId());
+ // Floating shortcut used to have target activities, but not anymore.
+ if (si.isFloating()) { // Not really needed by just in case.
+ si.setActivity(null);
+ }
// Don't use addShortcut(), we don't need to save the icon.
ret.mShortcuts.put(si.getId(), si);
@@ -1462,7 +1477,6 @@
intents.clear();
intents.add(intentLegacy);
}
-
return new ShortcutInfo(
userId, id, packageName, activityComponent, /* icon =*/ null,
title, titleResId, titleResName, text, textResId, textResName,
@@ -1553,12 +1567,17 @@
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is both dynamic and manifest at the same time.");
}
- if (si.getActivity() == null) {
+ if (!si.isFloating() && si.getActivity() == null) {
failed = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
- + " has null activity.");
+ + " is not floating, but has null activity.");
}
- if ((si.isDynamic() || si.isManifestShortcut()) && !si.isEnabled()) {
+ if (si.isFloating() && si.getActivity() != null) {
+ failed = true;
+ Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " is floating, but has non-null activity.");
+ }
+ if (!si.isFloating() && !si.isEnabled()) {
failed = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " is not floating, but is disabled.");
@@ -1581,7 +1600,7 @@
}
if (failed) {
- throw new IllegalStateException("See logcat for errors");
+ mShortcutUser.mService.verifyError();
}
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index 1f195a7..e59d69f 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -106,27 +106,31 @@
}
return; // Not installed, no need to restore yet.
}
+ boolean blockRestore = false;
if (!mPackageInfo.hasSignatures()) {
s.wtf("Attempted to restore package " + mPackageName + ", user=" + mPackageUserId
+ " but signatures not found in the restore data.");
+ blockRestore = true;
+ }
+ if (!blockRestore) {
+ final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
+ if (!mPackageInfo.canRestoreTo(s, pi)) {
+ // Package is now installed, but can't restore. Let the subclass do the cleanup.
+ blockRestore = true;
+ }
+ }
+ if (blockRestore) {
onRestoreBlocked();
- return;
+ } else {
+ if (ShortcutService.DEBUG) {
+ Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
+ mPackageUserId, getOwnerUserId()));
+ }
+
+ onRestored();
}
- final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
- if (!mPackageInfo.canRestoreTo(s, pi)) {
- // Package is now installed, but can't restore. Let the subclass do the cleanup.
- onRestoreBlocked();
- return;
- }
- if (ShortcutService.DEBUG) {
- Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
- mPackageUserId, getOwnerUserId()));
- }
-
- onRestored();
-
- // Now the package is not shadow.
+ // Either way, it's no longer a shadow.
mPackageInfo.setShadow(false);
s.scheduleSaveUser(mPackageUserId);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 7b877f7..c5c1c0c 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -124,6 +124,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -401,6 +402,9 @@
@VisibleForTesting
ShortcutService(Context context, Looper looper, boolean onlyForPackageManagerApis) {
+ if (DEBUG) {
+ Binder.LOG_RUNTIME_EXCEPTION = true;
+ }
mContext = Preconditions.checkNotNull(context);
LocalServices.addService(ShortcutServiceInternal.class, new LocalService());
mHandler = new Handler(looper);
@@ -1604,7 +1608,7 @@
}
if (!forUpdate) {
- shortcut.enforceMandatoryFields();
+ shortcut.enforceMandatoryFields(/* forPinned= */ false);
Preconditions.checkArgument(
injectIsMainActivity(shortcut.getActivity(), shortcut.getUserId()),
"Cannot publish shortcut: " + shortcut.getActivity() + " is not main activity");
@@ -1752,6 +1756,9 @@
// Note copyNonNullFieldsFrom() does the "updatable with?" check too.
target.copyNonNullFieldsFrom(source);
+ if (target.isFloating()) {
+ target.setActivity(null);
+ }
target.setTimestamp(injectCurrentTimeMillis());
if (replacingIcon) {
@@ -2320,8 +2327,7 @@
return false;
}
if (componentName != null) {
- if (si.getActivity() != null
- && !si.getActivity().equals(componentName)) {
+ if (!Objects.equals(componentName, si.getActivity())) {
return false;
}
}
@@ -3733,6 +3739,16 @@
}
}
+ @VisibleForTesting
+ ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) {
+ synchronized (mLock) {
+ final ShortcutUser user = mUsers.get(userId);
+ if (user == null) return null;
+
+ return user.getAllLaunchersForTest().get(PackageWithUser.of(userId, packageName));
+ }
+ }
+
/**
* Control whether {@link #verifyStates} should be performed. We always perform it during unit
* tests.
@@ -3761,4 +3777,8 @@
forEachLoadedUserLocked(u -> u.forAllPackageItems(ShortcutPackageItem::verifyStates));
}
}
+
+ void verifyError() {
+ Slog.e(TAG, "See logcat for errors");
+ }
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 20afed7..c4241e7 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2716,7 +2716,7 @@
public Bundle getApplicationRestrictionsForUser(String packageName, int userId) {
if (UserHandle.getCallingUserId() != userId
|| !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) {
- checkSystemOrRoot("get application restrictions for other users/apps");
+ checkSystemOrRoot("get application restrictions for other user/app " + packageName);
}
synchronized (mPackagesLock) {
// Read the restrictions from XML
@@ -2751,7 +2751,7 @@
long ident = Binder.clearCallingIdentity();
try {
return mContext.getPackageManager().getApplicationInfo(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES).uid;
+ PackageManager.MATCH_ANY_USER).uid;
} catch (NameNotFoundException nnfe) {
return -1;
} finally {
@@ -3717,4 +3717,23 @@
}
return 0;
}
+
+ /**
+ * Checks if the given user has a managed profile associated with it.
+ * @param userId The parent user
+ * @return
+ */
+ boolean hasManagedProfile(int userId) {
+ synchronized (mUsersLock) {
+ UserInfo userInfo = getUserInfoLU(userId);
+ final int userSize = mUsers.size();
+ for (int i = 0; i < userSize; i++) {
+ UserInfo profile = mUsers.valueAt(i).info;
+ if (userId != profile.id && isProfileOf(userInfo, profile)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 61319cf..7ba95a4 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -291,5 +291,5 @@
// flags declaring we want extra info from the package manager for webview providers
private final static int PACKAGE_FLAGS = PackageManager.GET_META_DATA
| PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING
- | PackageManager.MATCH_UNINSTALLED_PACKAGES;
+ | PackageManager.MATCH_ANY_USER;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 5d739d1..5838a37 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1103,6 +1103,11 @@
return mOrientation;
}
+ /** Returns the app's preferred orientation regardless of its currently visibility state. */
+ int getOrientationIgnoreVisibility() {
+ return mOrientation;
+ }
+
@Override
void checkAppWindowsReadyToShow() {
if (allDrawn == mAppAnimator.allDrawn) {
diff --git a/services/core/java/com/android/server/wm/DragResizeMode.java b/services/core/java/com/android/server/wm/DragResizeMode.java
index 08acf9d..8ab0406 100644
--- a/services/core/java/com/android/server/wm/DragResizeMode.java
+++ b/services/core/java/com/android/server/wm/DragResizeMode.java
@@ -20,6 +20,7 @@
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
/**
* Describes the mode in which a window is drag resizing.
@@ -45,7 +46,8 @@
case DRAG_RESIZE_MODE_DOCKED_DIVIDER:
return stackId == DOCKED_STACK_ID
|| stackId == FULLSCREEN_WORKSPACE_STACK_ID
- || stackId == HOME_STACK_ID;
+ || stackId == HOME_STACK_ID
+ || stackId == RECENTS_STACK_ID;
default:
return false;
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b889db2..d33ae48 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -19,7 +19,7 @@
import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.HOME_STACK_ID;
+
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -526,10 +526,6 @@
return (tokensCount != 0) && mChildren.get(tokensCount - 1).showForAllUsers;
}
- boolean inHomeStack() {
- return mStack != null && mStack.mStackId == HOME_STACK_ID;
- }
-
boolean inFreeformWorkspace() {
return mStack != null && mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 203ba72..a90b615 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1183,7 +1183,7 @@
@Override
public boolean dimFullscreen() {
- return mStackId == HOME_STACK_ID || fillsParent();
+ return StackId.isHomeOrRecentsStack(mStackId) || fillsParent();
}
@Override
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 77da22c..51e8a56 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1415,7 +1415,8 @@
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
// Check if we need to prepare a transition for replacing window first.
- if (atoken != null && !prepareWindowReplacementTransition(atoken)) {
+ if (atoken != null && atoken.isVisible()
+ && !prepareWindowReplacementTransition(atoken)) {
// If not, check if need to set up a dummy transition during display freeze
// so that the unfreeze wait for the apps to draw. This might be needed if
// the app is relaunching.
@@ -2716,7 +2717,7 @@
return SCREEN_ORIENTATION_UNSPECIFIED;
}
- return wtoken.getOrientation();
+ return wtoken.getOrientationIgnoreVisibility();
}
}
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index ac0e622..50a6095 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -73,6 +73,7 @@
libhwbinder \
libutils \
android.hardware.audio.common@2.0 \
+ android.hardware.gnss@1.0 \
android.hardware.light@2.0 \
android.hardware.power@1.0 \
android.hardware.thermal@1.0 \
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index c7d6b95..e46490b 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -22,15 +22,22 @@
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/misc.h>
+#include <utils/AndroidThreads.h>
namespace android {
+static int start_sensor_service(void* /*unused*/) {
+ SensorService::instantiate();
+ return 0;
+}
+
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
- // Start the sensor service
- SensorService::instantiate();
+ // Start the sensor service in a new thread
+ createThreadEtc(start_sensor_service, nullptr,
+ "StartSensorThread", PRIORITY_FOREGROUND);
}
}
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 25e819c..b0a4297 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -18,10 +18,13 @@
#define LOG_NDEBUG 0
+#include <android/hardware/gnss/1.0/IGnss.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+
#include "JNIHelp.h"
#include "jni.h"
-#include "hardware/hardware.h"
-#include "hardware/gps_internal.h"
#include "hardware_legacy/power.h"
#include "utils/Log.h"
#include "utils/misc.h"
@@ -34,6 +37,7 @@
#include <linux/in6.h>
#include <pthread.h>
#include <string.h>
+#include <cinttypes>
static jobject mCallbacksObj = NULL;
@@ -58,978 +62,65 @@
static jmethodID method_reportMeasurementData;
static jmethodID method_reportNavigationMessages;
-static const GpsInterface* sGpsInterface = NULL;
-static const GpsXtraInterface* sGpsXtraInterface = NULL;
-static const AGpsInterface* sAGpsInterface = NULL;
-static const GpsNiInterface* sGpsNiInterface = NULL;
-static const GpsDebugInterface* sGpsDebugInterface = NULL;
-static const AGpsRilInterface* sAGpsRilInterface = NULL;
-static const GpsGeofencingInterface* sGpsGeofencingInterface = NULL;
-static const GpsMeasurementInterface* sGpsMeasurementInterface = NULL;
-static const GpsNavigationMessageInterface* sGpsNavigationMessageInterface = NULL;
-static const GnssConfigurationInterface* sGnssConfigurationInterface = NULL;
+using android::OK;
+using android::sp;
+using android::status_t;
+using android::String16;
-#define GPS_MAX_SATELLITE_COUNT 32
-#define GNSS_MAX_SATELLITE_COUNT 64
+using android::hardware::IPCThreadState;
+using android::hardware::ProcessState;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::hidl_vec;
-// Let these through, with ID remapped down to 1, 2... by offset
-#define GLONASS_SVID_OFFSET 64
-#define GLONASS_SVID_COUNT 24
-#define BEIDOU_SVID_OFFSET 200
-#define BEIDOU_SVID_COUNT 35
+using android::hardware::gnss::V1_0::IAGnss;
+using android::hardware::gnss::V1_0::IAGnssCallback;
+using android::hardware::gnss::V1_0::IAGnssCallback;
+using android::hardware::gnss::V1_0::IAGnssRil;
+using android::hardware::gnss::V1_0::IAGnssRilCallback;
+using android::hardware::gnss::V1_0::IGnss;
+using android::hardware::gnss::V1_0::IGnssCallback;
+using android::hardware::gnss::V1_0::IGnssConfiguration;
+using android::hardware::gnss::V1_0::IGnssDebug;
+using android::hardware::gnss::V1_0::IGnssGeofenceCallback;
+using android::hardware::gnss::V1_0::IGnssGeofencing;
+using android::hardware::gnss::V1_0::IGnssMeasurement;
+using android::hardware::gnss::V1_0::IGnssMeasurementCallback;
+using android::hardware::gnss::V1_0::IGnssNavigationMessage;
+using android::hardware::gnss::V1_0::IGnssNavigationMessageCallback;
+using android::hardware::gnss::V1_0::IGnssNi;
+using android::hardware::gnss::V1_0::IGnssNiCallback;
+using android::hardware::gnss::V1_0::IGnssXtra;
+using android::hardware::gnss::V1_0::IGnssXtraCallback;
-// Let these through, with ID remapped up (33->120 ... 64->151, etc.)
-#define SBAS_SVID_MIN 33
-#define SBAS_SVID_MAX 64
-#define SBAS_SVID_ADD 87
-// Let these through, with no ID remapping
-#define QZSS_SVID_MIN 193
-#define QZSS_SVID_MAX 200
-
-#define SVID_SHIFT_WIDTH 7
-#define CONSTELLATION_TYPE_SHIFT_WIDTH 3
-
-// temporary storage for GPS callbacks
-static GnssSvInfo sGnssSvList[GNSS_MAX_SATELLITE_COUNT];
-static size_t sGnssSvListSize;
-static const char* sNmeaString;
-static int sNmeaStringLength;
+sp<IGnss> gnssHal = nullptr;
+sp<IGnssXtra> gnssXtraIface = nullptr;
+sp<IAGnssRil> agnssRilIface = nullptr;
+sp<IGnssGeofencing> gnssGeofencingIface = nullptr;
+sp<IAGnss> agnssIface = nullptr;
+sp<IGnssDebug> gnssDebugIface = nullptr;
+sp<IGnssConfiguration> gnssConfigurationIface = nullptr;
+sp<IGnssNi> gnssNiIface = nullptr;
+sp<IGnssMeasurement> gnssMeasurementIface = nullptr;
+sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
namespace android {
-static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
- if (env->ExceptionCheck()) {
- ALOGE("An exception was thrown by callback '%s'.", methodName);
- LOGE_EX(env);
- env->ExceptionClear();
- }
-}
-
-static void location_callback(GpsLocation* location)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_reportLocation, location->flags,
- (jdouble)location->latitude, (jdouble)location->longitude,
- (jdouble)location->altitude,
- (jfloat)location->speed, (jfloat)location->bearing,
- (jfloat)location->accuracy, (jlong)location->timestamp);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void status_callback(GpsStatus* status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_reportStatus, status->status);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void sv_status_callback(GpsSvStatus* sv_status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- size_t status_size = sv_status->size;
- // Some drives doesn't set the size field correctly. Assume GpsSvStatus_v1
- // if it doesn't provide a valid size.
- if (status_size == 0) {
- ALOGW("Invalid size of GpsSvStatus found: %zd.", status_size);
- }
- sGnssSvListSize = sv_status->num_svs;
- // Clamp the list size. Legacy GpsSvStatus has only 32 elements in sv_list.
- if (sGnssSvListSize > GPS_MAX_SATELLITE_COUNT) {
- ALOGW("Too many satellites %zd. Clamps to %d.",
- sGnssSvListSize,
- GPS_MAX_SATELLITE_COUNT);
- sGnssSvListSize = GPS_MAX_SATELLITE_COUNT;
- }
- uint32_t ephemeris_mask = sv_status->ephemeris_mask;
- uint32_t almanac_mask = sv_status->almanac_mask;
- uint32_t used_in_fix_mask = sv_status->used_in_fix_mask;
- for (size_t i = 0; i < sGnssSvListSize; i++) {
- GnssSvInfo& info = sGnssSvList[i];
- info.svid = sv_status->sv_list[i].prn;
- // Defacto mapping from the overused API that was designed for GPS-only
- if (info.svid >=1 && info.svid <= 32) {
- info.constellation = GNSS_CONSTELLATION_GPS;
- } else if (info.svid > GLONASS_SVID_OFFSET &&
- info.svid <= GLONASS_SVID_OFFSET + GLONASS_SVID_COUNT) {
- info.constellation = GNSS_CONSTELLATION_GLONASS;
- info.svid -= GLONASS_SVID_OFFSET;
- } else if (info.svid > BEIDOU_SVID_OFFSET &&
- info.svid <= BEIDOU_SVID_OFFSET + BEIDOU_SVID_COUNT) {
- info.constellation = GNSS_CONSTELLATION_BEIDOU;
- info.svid -= BEIDOU_SVID_OFFSET;
- } else if (info.svid >= SBAS_SVID_MIN && info.svid <= SBAS_SVID_MAX) {
- info.constellation = GNSS_CONSTELLATION_SBAS;
- info.svid += SBAS_SVID_ADD;
- } else if (info.svid >= QZSS_SVID_MIN && info.svid <= QZSS_SVID_MAX) {
- info.constellation = GNSS_CONSTELLATION_QZSS;
- } else {
- ALOGD("Unknown constellation type with Svid = %d.", info.svid);
- info.constellation = GNSS_CONSTELLATION_UNKNOWN;
- }
- info.c_n0_dbhz = sv_status->sv_list[i].snr;
- info.elevation = sv_status->sv_list[i].elevation;
- info.azimuth = sv_status->sv_list[i].azimuth;
- info.flags = GNSS_SV_FLAGS_NONE;
- // Only GPS info is valid for these fields, as these masks are just 32 bits, by GPS prn
- if (info.constellation == GNSS_CONSTELLATION_GPS) {
- int32_t this_svid_mask = (1 << (info.svid - 1));
- if ((ephemeris_mask & this_svid_mask) != 0) {
- info.flags |= GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA;
- }
- if ((almanac_mask & this_svid_mask) != 0) {
- info.flags |= GNSS_SV_FLAGS_HAS_ALMANAC_DATA;
- }
- if ((used_in_fix_mask & this_svid_mask) != 0) {
- info.flags |= GNSS_SV_FLAGS_USED_IN_FIX;
- }
- }
- }
- env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void gnss_sv_status_callback(GnssSvStatus* sv_status) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- size_t status_size = sv_status->size;
- // Check the size, and reject the object that has invalid size.
- if (status_size != sizeof(GnssSvStatus)) {
- ALOGE("Invalid size of GnssSvStatus found: %zd.", status_size);
- return;
- }
- sGnssSvListSize = sv_status->num_svs;
- // Clamp the list size
- if (sGnssSvListSize > GNSS_MAX_SATELLITE_COUNT) {
- ALOGD("Too many satellites %zd. Clamps to %d.",
- sGnssSvListSize,
- GNSS_MAX_SATELLITE_COUNT);
- sGnssSvListSize = GNSS_MAX_SATELLITE_COUNT;
- }
- // Copy GNSS SV info into sGnssSvList, if any.
- if (sGnssSvListSize > 0) {
- memcpy(sGnssSvList,
- sv_status->gnss_sv_list,
- sizeof(GnssSvInfo) * sGnssSvListSize);
- }
- env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void nmea_callback(GpsUtcTime timestamp, const char* nmea, int length)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- // The Java code will call back to read these values
- // We do this to avoid creating unnecessary String objects
- sNmeaString = nmea;
- sNmeaStringLength = length;
- env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void set_system_info_callback(const GnssSystemInfo* info) {
- ALOGD("set_system_info_callback: year_of_hw=%d\n", info->year_of_hw);
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
- info->year_of_hw);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void set_capabilities_callback(uint32_t capabilities)
-{
- ALOGD("set_capabilities_callback: %du\n", capabilities);
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void acquire_wakelock_callback()
-{
- acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
-}
-
-static void release_wakelock_callback()
-{
- release_wake_lock(WAKE_LOCK_NAME);
-}
-
-static void request_utc_time_callback()
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg)
-{
- return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg);
-}
-
-GpsCallbacks sGpsCallbacks = {
- sizeof(GpsCallbacks),
- location_callback,
- status_callback,
- sv_status_callback,
- nmea_callback,
- set_capabilities_callback,
- acquire_wakelock_callback,
- release_wakelock_callback,
- create_thread_callback,
- request_utc_time_callback,
- set_system_info_callback,
- gnss_sv_status_callback,
-};
-
-static void xtra_download_request_callback()
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-GpsXtraCallbacks sGpsXtraCallbacks = {
- xtra_download_request_callback,
- create_thread_callback,
-};
-
-static jbyteArray convert_to_ipv4(uint32_t ip, bool net_order)
-{
- if (INADDR_NONE == ip) {
- return NULL;
- }
-
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jbyteArray byteArray = env->NewByteArray(4);
- if (byteArray == NULL) {
- ALOGE("Unable to allocate byte array for IPv4 address");
- return NULL;
- }
-
- jbyte ipv4[4];
- if (net_order) {
- ALOGV("Converting IPv4 address(net_order) %x", ip);
- memcpy(ipv4, &ip, sizeof(ipv4));
- } else {
- ALOGV("Converting IPv4 address(host_order) %x", ip);
- //endianess transparent conversion from int to char[]
- ipv4[0] = (jbyte) (ip & 0xFF);
- ipv4[1] = (jbyte)((ip>>8) & 0xFF);
- ipv4[2] = (jbyte)((ip>>16) & 0xFF);
- ipv4[3] = (jbyte) (ip>>24);
- }
-
- env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*) ipv4);
- return byteArray;
-}
-
-static void agps_status_callback(AGpsStatus* agps_status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jbyteArray byteArray = NULL;
- bool isSupported = false;
-
- size_t status_size = agps_status->size;
- if (status_size == sizeof(AGpsStatus)) {
- ALOGV("AGpsStatus is V3: %zd", status_size);
- switch (agps_status->addr.ss_family)
- {
- case AF_INET:
- {
- struct sockaddr_in *in = (struct sockaddr_in*)&(agps_status->addr);
- uint32_t ipAddr = *(uint32_t*)&(in->sin_addr);
- byteArray = convert_to_ipv4(ipAddr, true /* net_order */);
- if (ipAddr == INADDR_NONE || byteArray != NULL) {
- isSupported = true;
- }
- IF_ALOGD() {
- // log the IP for reference in case there is a bogus value pushed by HAL
- char str[INET_ADDRSTRLEN];
- inet_ntop(AF_INET, &(in->sin_addr), str, INET_ADDRSTRLEN);
- ALOGD("AGPS IP is v4: %s", str);
- }
- }
- break;
- case AF_INET6:
- {
- struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&(agps_status->addr);
- byteArray = env->NewByteArray(16);
- if (byteArray != NULL) {
- env->SetByteArrayRegion(byteArray, 0, 16, (const jbyte *)&(in6->sin6_addr));
- isSupported = true;
- } else {
- ALOGE("Unable to allocate byte array for IPv6 address.");
- }
- IF_ALOGD() {
- // log the IP for reference in case there is a bogus value pushed by HAL
- char str[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &(in6->sin6_addr), str, INET6_ADDRSTRLEN);
- ALOGD("AGPS IP is v6: %s", str);
- }
- }
- break;
- default:
- ALOGE("Invalid ss_family found: %d", agps_status->addr.ss_family);
- break;
- }
- } else if (status_size >= sizeof(AGpsStatus_v2)) {
- ALOGV("AGpsStatus is V2+: %zd", status_size);
- // for back-compatibility reasons we check in v2 that the data structure size is greater or
- // equal to the declared size in gps.h
- uint32_t ipaddr = agps_status->ipaddr;
- ALOGV("AGPS IP is v4: %x", ipaddr);
- byteArray = convert_to_ipv4(ipaddr, false /* net_order */);
- if (ipaddr == INADDR_NONE || byteArray != NULL) {
- isSupported = true;
- }
- } else if (status_size >= sizeof(AGpsStatus_v1)) {
- ALOGV("AGpsStatus is V1+: %zd", status_size);
- // because we have to check for >= with regards to v2, we also need to relax the check here
- // and only make sure that the size is at least what we expect
- isSupported = true;
- } else {
- ALOGE("Invalid size of AGpsStatus found: %zd.", status_size);
- }
-
- if (isSupported) {
- jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
- ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
- env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus, agps_status->type,
- agps_status->status, byteArray);
-
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
- } else {
- ALOGD("Skipping calling method_reportAGpsStatus.");
- }
-
- if (byteArray) {
- env->DeleteLocalRef(byteArray);
- }
-}
-
-AGpsCallbacks sAGpsCallbacks = {
- agps_status_callback,
- create_thread_callback,
-};
-
-static void gps_ni_notify_callback(GpsNiNotification *notification)
-{
- ALOGD("gps_ni_notify_callback\n");
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jstring requestor_id = env->NewStringUTF(notification->requestor_id);
- jstring text = env->NewStringUTF(notification->text);
- jstring extras = env->NewStringUTF(notification->extras);
-
- if (requestor_id && text && extras) {
- env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
- notification->notification_id, notification->ni_type,
- notification->notify_flags, notification->timeout,
- notification->default_response, requestor_id, text,
- notification->requestor_id_encoding,
- notification->text_encoding, extras);
- } else {
- ALOGE("out of memory in gps_ni_notify_callback\n");
- }
-
- if (requestor_id)
- env->DeleteLocalRef(requestor_id);
- if (text)
- env->DeleteLocalRef(text);
- if (extras)
- env->DeleteLocalRef(extras);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-GpsNiCallbacks sGpsNiCallbacks = {
- gps_ni_notify_callback,
- create_thread_callback,
-};
-
-static void agps_request_set_id(uint32_t flags)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_requestSetID, flags);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-static void agps_request_ref_location(uint32_t flags)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- env->CallVoidMethod(mCallbacksObj, method_requestRefLocation, flags);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-}
-
-AGpsRilCallbacks sAGpsRilCallbacks = {
- agps_request_set_id,
- agps_request_ref_location,
- create_thread_callback,
-};
-
-static void gps_geofence_transition_callback(int32_t geofence_id, GpsLocation* location,
- int32_t transition, GpsUtcTime timestamp)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
-
- env->CallVoidMethod(mCallbacksObj, method_reportGeofenceTransition, geofence_id,
- location->flags, (jdouble)location->latitude, (jdouble)location->longitude,
- (jdouble)location->altitude,
- (jfloat)location->speed, (jfloat)location->bearing,
- (jfloat)location->accuracy, (jlong)location->timestamp,
- transition, timestamp);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-static void gps_geofence_status_callback(int32_t status, GpsLocation* location)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jint flags = 0;
- jdouble latitude = 0;
- jdouble longitude = 0;
- jdouble altitude = 0;
- jfloat speed = 0;
- jfloat bearing = 0;
- jfloat accuracy = 0;
- jlong timestamp = 0;
- if (location != NULL) {
- flags = location->flags;
- latitude = location->latitude;
- longitude = location->longitude;
- altitude = location->altitude;
- speed = location->speed;
- bearing = location->bearing;
- accuracy = location->accuracy;
- timestamp = location->timestamp;
- }
-
- env->CallVoidMethod(mCallbacksObj, method_reportGeofenceStatus, status,
- flags, latitude, longitude, altitude, speed, bearing, accuracy, timestamp);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-static void gps_geofence_add_callback(int32_t geofence_id, int32_t status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
- ALOGE("Error in geofence_add_callback: %d\n", status);
- }
- env->CallVoidMethod(mCallbacksObj, method_reportGeofenceAddStatus, geofence_id, status);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-static void gps_geofence_remove_callback(int32_t geofence_id, int32_t status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
- ALOGE("Error in geofence_remove_callback: %d\n", status);
- }
- env->CallVoidMethod(mCallbacksObj, method_reportGeofenceRemoveStatus, geofence_id, status);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-static void gps_geofence_resume_callback(int32_t geofence_id, int32_t status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
- ALOGE("Error in geofence_resume_callback: %d\n", status);
- }
- env->CallVoidMethod(mCallbacksObj, method_reportGeofenceResumeStatus, geofence_id, status);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-static void gps_geofence_pause_callback(int32_t geofence_id, int32_t status)
-{
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (status != GPS_GEOFENCE_OPERATION_SUCCESS) {
- ALOGE("Error in geofence_pause_callback: %d\n", status);
- }
- env->CallVoidMethod(mCallbacksObj, method_reportGeofencePauseStatus, geofence_id, status);
- checkAndClearExceptionFromCallback(env, __FUNCTION__);
-};
-
-GpsGeofenceCallbacks sGpsGeofenceCallbacks = {
- gps_geofence_transition_callback,
- gps_geofence_status_callback,
- gps_geofence_add_callback,
- gps_geofence_remove_callback,
- gps_geofence_pause_callback,
- gps_geofence_resume_callback,
- create_thread_callback,
-};
-
-static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
- int err;
- hw_module_t* module;
-
- method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
- method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
- method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
- method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
- method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
- method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
- method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
- method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
- method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
- "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
- method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
- method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
- method_requestUtcTime = env->GetMethodID(clazz,"requestUtcTime","()V");
- method_reportGeofenceTransition = env->GetMethodID(clazz,"reportGeofenceTransition",
- "(IIDDDFFFJIJ)V");
- method_reportGeofenceStatus = env->GetMethodID(clazz,"reportGeofenceStatus",
- "(IIDDDFFFJ)V");
- method_reportGeofenceAddStatus = env->GetMethodID(clazz,"reportGeofenceAddStatus",
- "(II)V");
- method_reportGeofenceRemoveStatus = env->GetMethodID(clazz,"reportGeofenceRemoveStatus",
- "(II)V");
- method_reportGeofenceResumeStatus = env->GetMethodID(clazz,"reportGeofenceResumeStatus",
- "(II)V");
- method_reportGeofencePauseStatus = env->GetMethodID(clazz,"reportGeofencePauseStatus",
- "(II)V");
- method_reportMeasurementData = env->GetMethodID(
- clazz,
- "reportMeasurementData",
- "(Landroid/location/GnssMeasurementsEvent;)V");
- method_reportNavigationMessages = env->GetMethodID(
- clazz,
- "reportNavigationMessage",
- "(Landroid/location/GnssNavigationMessage;)V");
-
- err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
- if (err == 0) {
- hw_device_t* device;
- err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
- if (err == 0) {
- gps_device_t* gps_device = (gps_device_t *)device;
- sGpsInterface = gps_device->get_gps_interface(gps_device);
- }
- }
- if (sGpsInterface) {
- sGpsXtraInterface =
- (const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);
- sAGpsInterface =
- (const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
- sGpsNiInterface =
- (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
- sGpsDebugInterface =
- (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
- sAGpsRilInterface =
- (const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
- sGpsGeofencingInterface =
- (const GpsGeofencingInterface*)sGpsInterface->get_extension(GPS_GEOFENCING_INTERFACE);
- sGpsMeasurementInterface =
- (const GpsMeasurementInterface*)sGpsInterface->get_extension(GPS_MEASUREMENT_INTERFACE);
- sGpsNavigationMessageInterface =
- (const GpsNavigationMessageInterface*)sGpsInterface->get_extension(
- GPS_NAVIGATION_MESSAGE_INTERFACE);
- sGnssConfigurationInterface =
- (const GnssConfigurationInterface*)sGpsInterface->get_extension(
- GNSS_CONFIGURATION_INTERFACE);
- }
-}
-
-static jboolean android_location_GnssLocationProvider_is_supported(
- JNIEnv* /* env */, jclass /* clazz */)
-{
- return (sGpsInterface != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
- JNIEnv* /* env */, jclass /* clazz */)
-{
- return (sAGpsRilInterface != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
- JNIEnv* /* env */, jclass /* jclazz */)
-{
- return (sGnssConfigurationInterface != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj)
-{
- // this must be set before calling into the HAL library
- if (!mCallbacksObj)
- mCallbacksObj = env->NewGlobalRef(obj);
-
- // fail if the main interface fails to initialize
- if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
- return JNI_FALSE;
-
- // if XTRA initialization fails we will disable it by sGpsXtraInterface to NULL,
- // but continue to allow the rest of the GPS interface to work.
- if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0)
- sGpsXtraInterface = NULL;
- if (sAGpsInterface)
- sAGpsInterface->init(&sAGpsCallbacks);
- if (sGpsNiInterface)
- sGpsNiInterface->init(&sGpsNiCallbacks);
- if (sAGpsRilInterface)
- sAGpsRilInterface->init(&sAGpsRilCallbacks);
- if (sGpsGeofencingInterface)
- sGpsGeofencingInterface->init(&sGpsGeofenceCallbacks);
-
- return JNI_TRUE;
-}
-
-static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */)
-{
- if (sGpsInterface)
- sGpsInterface->cleanup();
-}
-
-static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
- jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
- jint preferred_time)
-{
- if (sGpsInterface) {
- if (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
- preferred_time) == 0) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- }
- else
- return JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */)
-{
- if (sGpsInterface) {
- if (sGpsInterface->start() == 0) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- }
- else
- return JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */)
-{
- if (sGpsInterface) {
- if (sGpsInterface->stop() == 0) {
- return JNI_TRUE;
- } else {
- return JNI_FALSE;
- }
- }
- else
- return JNI_FALSE;
-}
-
-static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
- jobject /* obj */,
- jint flags)
-{
- if (sGpsInterface)
- sGpsInterface->delete_aiding_data(flags);
-}
-
-static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
- jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
- jfloatArray azumArray)
-{
- // this should only be called from within a call to reportSvStatus
- jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
- jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
- jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
- jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
-
- // GNSS SV info.
- for (size_t i = 0; i < sGnssSvListSize; ++i) {
- const GnssSvInfo& info = sGnssSvList[i];
- svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
- (info.constellation << CONSTELLATION_TYPE_SHIFT_WIDTH) |
- info.flags;
- cn0s[i] = info.c_n0_dbhz;
- elev[i] = info.elevation;
- azim[i] = info.azimuth;
- }
-
- env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
- env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
- env->ReleaseFloatArrayElements(elevArray, elev, 0);
- env->ReleaseFloatArrayElements(azumArray, azim, 0);
- return (jint) sGnssSvListSize;
-}
-
-static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
- JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid)
-{
- AGpsRefLocation location;
-
- if (!sAGpsRilInterface) {
- ALOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
- return;
- }
-
- switch(type) {
- case AGPS_REF_LOCATION_TYPE_GSM_CELLID:
- case AGPS_REF_LOCATION_TYPE_UMTS_CELLID:
- location.type = type;
- location.u.cellID.mcc = mcc;
- location.u.cellID.mnc = mnc;
- location.u.cellID.lac = lac;
- location.u.cellID.cid = cid;
- break;
- default:
- ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).",__FUNCTION__,__LINE__);
- return;
- break;
- }
- sAGpsRilInterface->set_ref_location(&location, sizeof(location));
-}
-
-static void android_location_GnssLocationProvider_agps_send_ni_message(JNIEnv* env,
- jobject /* obj */, jbyteArray ni_msg, jint size)
-{
- size_t sz;
-
- if (!sAGpsRilInterface) {
- ALOGE("no AGPS RIL interface in send_ni_message");
- return;
- }
- if (size < 0)
- return;
- sz = (size_t)size;
- jbyte* b = env->GetByteArrayElements(ni_msg, 0);
- sAGpsRilInterface->ni_message((uint8_t *)b,sz);
- env->ReleaseByteArrayElements(ni_msg,b,0);
-}
-
-static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
- jint type, jstring setid_string)
-{
- if (!sAGpsRilInterface) {
- ALOGE("no AGPS RIL interface in agps_set_id");
- return;
- }
-
- const char *setid = env->GetStringUTFChars(setid_string, NULL);
- sAGpsRilInterface->set_set_id(type, setid);
- env->ReleaseStringUTFChars(setid_string, setid);
-}
-
-static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
- jbyteArray nmeaArray, jint buffer_size)
-{
- // this should only be called from within a call to reportNmea
- jbyte* nmea = (jbyte *)env->GetPrimitiveArrayCritical(nmeaArray, 0);
- int length = sNmeaStringLength;
- if (length > buffer_size)
- length = buffer_size;
- memcpy(nmea, sNmeaString, length);
- env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
- return (jint) length;
-}
-
-static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
- jlong time, jlong timeReference, jint uncertainty)
-{
- if (sGpsInterface)
- sGpsInterface->inject_time(time, timeReference, uncertainty);
-}
-
-static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
- jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy)
-{
- if (sGpsInterface)
- sGpsInterface->inject_location(latitude, longitude, accuracy);
-}
-
-static jboolean android_location_GnssLocationProvider_supports_xtra(
- JNIEnv* /* env */, jobject /* obj */)
-{
- return (sGpsXtraInterface != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
- jbyteArray data, jint length)
-{
- if (!sGpsXtraInterface) {
- ALOGE("no XTRA interface in inject_xtra_data");
- return;
- }
-
- jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0);
- sGpsXtraInterface->inject_xtra_data((char *)bytes, length);
- env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
-}
-
-static void android_location_GnssLocationProvider_agps_data_conn_open(
- JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType)
-{
- if (!sAGpsInterface) {
- ALOGE("no AGPS interface in agps_data_conn_open");
- return;
- }
- if (apn == NULL) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
-
- const char *apnStr = env->GetStringUTFChars(apn, NULL);
-
- size_t interface_size = sAGpsInterface->size;
- if (interface_size == sizeof(AGpsInterface)) {
- sAGpsInterface->data_conn_open_with_apn_ip_type(apnStr, apnIpType);
- } else if (interface_size == sizeof(AGpsInterface_v1)) {
- sAGpsInterface->data_conn_open(apnStr);
- } else {
- ALOGE("Invalid size of AGpsInterface found: %zd.", interface_size);
- }
-
- env->ReleaseStringUTFChars(apn, apnStr);
-}
-
-static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
- jobject /* obj */)
-{
- if (!sAGpsInterface) {
- ALOGE("no AGPS interface in agps_data_conn_closed");
- return;
- }
- sAGpsInterface->data_conn_closed();
-}
-
-static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
- jobject /* obj */)
-{
- if (!sAGpsInterface) {
- ALOGE("no AGPS interface in agps_data_conn_failed");
- return;
- }
- sAGpsInterface->data_conn_failed();
-}
-
-static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
- jint type, jstring hostname, jint port)
-{
- if (!sAGpsInterface) {
- ALOGE("no AGPS interface in set_agps_server");
- return;
- }
- const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
- sAGpsInterface->set_server(type, c_hostname, port);
- env->ReleaseStringUTFChars(hostname, c_hostname);
-}
-
-static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
- jobject /* obj */, jint notifId, jint response)
-{
- if (!sGpsNiInterface) {
- ALOGE("no NI interface in send_ni_response");
- return;
- }
-
- sGpsNiInterface->respond(notifId, response);
-}
-
-static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
- jobject /* obj */) {
- jstring result = NULL;
- if (sGpsDebugInterface) {
- const size_t maxLength = 2047;
- char buffer[maxLength+1];
- size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength);
- if (length > maxLength) length = maxLength;
- buffer[length] = 0;
- result = env->NewStringUTF(buffer);
- }
- return result;
-}
-
-static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env, jobject /* obj */,
- jboolean connected, jint type, jboolean roaming, jboolean available, jstring extraInfo, jstring apn)
-{
-
- if (sAGpsRilInterface && sAGpsRilInterface->update_network_state) {
- if (extraInfo) {
- const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL);
- sAGpsRilInterface->update_network_state(connected, type, roaming, extraInfoStr);
- env->ReleaseStringUTFChars(extraInfo, extraInfoStr);
- } else {
- sAGpsRilInterface->update_network_state(connected, type, roaming, NULL);
- }
-
- // update_network_availability callback was not included in original AGpsRilInterface
- if (sAGpsRilInterface->size >= sizeof(AGpsRilInterface)
- && sAGpsRilInterface->update_network_availability) {
- const char *c_apn = env->GetStringUTFChars(apn, NULL);
- sAGpsRilInterface->update_network_availability(available, c_apn);
- env->ReleaseStringUTFChars(apn, c_apn);
- }
- }
-}
-
-static jboolean android_location_GnssLocationProvider_is_geofence_supported(
- JNIEnv* /* env */, jobject /* obj */)
-{
- return (sGpsGeofencingInterface != NULL) ? JNI_TRUE : JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
- jobject /* obj */, jint geofence_id, jdouble latitude, jdouble longitude, jdouble radius,
- jint last_transition, jint monitor_transition, jint notification_responsiveness,
- jint unknown_timer) {
- if (sGpsGeofencingInterface != NULL) {
- sGpsGeofencingInterface->add_geofence_area(geofence_id, latitude, longitude,
- radius, last_transition, monitor_transition, notification_responsiveness,
- unknown_timer);
- return JNI_TRUE;
- } else {
- ALOGE("Geofence interface not available");
- }
- return JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
- jobject /* obj */, jint geofence_id) {
- if (sGpsGeofencingInterface != NULL) {
- sGpsGeofencingInterface->remove_geofence_area(geofence_id);
- return JNI_TRUE;
- } else {
- ALOGE("Geofence interface not available");
- }
- return JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
- jobject /* obj */, jint geofence_id) {
- if (sGpsGeofencingInterface != NULL) {
- sGpsGeofencingInterface->pause_geofence(geofence_id);
- return JNI_TRUE;
- } else {
- ALOGE("Geofence interface not available");
- }
- return JNI_FALSE;
-}
-
-static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
- jobject /* obj */, jint geofence_id, jint monitor_transition) {
- if (sGpsGeofencingInterface != NULL) {
- sGpsGeofencingInterface->resume_geofence(geofence_id, monitor_transition);
- return JNI_TRUE;
- } else {
- ALOGE("Geofence interface not available");
- }
- return JNI_FALSE;
-}
-
template<class T>
class JavaMethodHelper {
- public:
- // Helper function to call setter on a Java object.
- static void callJavaMethod(
+ public:
+ // Helper function to call setter on a Java object.
+ static void callJavaMethod(
JNIEnv* env,
jclass clazz,
jobject object,
const char* method_name,
T value);
- private:
+ private:
static const char *const signature_;
};
@@ -1045,20 +136,20 @@
}
class JavaObject {
- public:
- JavaObject(JNIEnv* env, const char* class_name);
- virtual ~JavaObject();
+ public:
+ JavaObject(JNIEnv* env, const char* class_name);
+ virtual ~JavaObject();
- template<class T>
- void callSetter(const char* method_name, T value);
- template<class T>
- void callSetter(const char* method_name, T* value, size_t size);
- jobject get();
+ template<class T>
+ void callSetter(const char* method_name, T value);
+ template<class T>
+ void callSetter(const char* method_name, T* value, size_t size);
+ jobject get();
- private:
- JNIEnv* env_;
- jclass clazz_;
- jobject object_;
+ private:
+ JNIEnv* env_;
+ jclass clazz_;
+ jobject object_;
};
JavaObject::JavaObject(JNIEnv* env, const char* class_name) : env_(env) {
@@ -1081,7 +172,7 @@
void JavaObject::callSetter(
const char* method_name, uint8_t* value, size_t size) {
jbyteArray array = env_->NewByteArray(size);
- env_->SetByteArrayRegion(array, 0, size, (jbyte*) value);
+ env_->SetByteArrayRegion(array, 0, size, reinterpret_cast<jbyte*>(value));
jmethodID method = env_->GetMethodID(
clazz_,
method_name,
@@ -1095,7 +186,6 @@
}
// Define Java method signatures for all known types.
-
template<>
const char *const JavaMethodHelper<uint8_t>::signature_ = "(B)V";
template<>
@@ -1119,209 +209,460 @@
#define SET(setter, value) object.callSetter("set" # setter, (value))
-// If you want to check if a flag is not set, use SET_IF_NOT(FLAG, setter,
-// value) to do that. SET_IF(!FLAG, setter, value) won't compile.
-//
-// This macros generates compilation error if the provided 'flag' is not a
-// single token. For example, 'GNSS_CLOCK_HAS_BIAS' can be accepted, but
-// '!GNSS_CLOCK_HAS_DRIFT' will fail to compile.
-#define SET_IF(flag, setter, value) do { \
- if (flags & flag) { \
- JavaObject& name_check_##flag = object; \
- name_check_##flag.callSetter("set" # setter, (value)); \
- } \
- } while (false)
-#define SET_IF_NOT(flag, setter, value) do { \
- if (!(flags & flag)) { \
- JavaObject& name_check_##flag = object; \
- name_check_##flag.callSetter("set" # setter, (value)); \
- } \
- } while (false)
+static inline jboolean boolToJbool(bool value) {
+ return value ? JNI_TRUE : JNI_FALSE;
+}
-static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) {
- static uint32_t discontinuity_count_to_handle_old_clock_type = 0;
- JavaObject object(env, "android/location/GnssClock");
- GpsClockFlags flags = clock->flags;
+static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
+ if (env->ExceptionCheck()) {
+ ALOGE("An exception was thrown by callback '%s'.", methodName);
+ LOGE_EX(env);
+ env->ExceptionClear();
+ }
+}
- SET_IF(GPS_CLOCK_HAS_LEAP_SECOND,
- LeapSecond,
- static_cast<int32_t>(clock->leap_second));
+/*
+ * GnssCallback class implements the callback methods for IGnss interface.
+ */
+struct GnssCallback : public IGnssCallback {
+ Return<void> gnssLocationCb(
+ const android::hardware::gnss::V1_0::GnssLocation& location) override;
+ Return<void> gnssStatusCb(const IGnssCallback::GnssStatusValue status) override;
+ Return<void> gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) override;
+ Return<void> gnssNmeaCb(int64_t timestamp, const android::hardware::hidl_string& nmea) override;
+ Return<void> gnssSetCapabilitesCb(uint32_t capabilities) override;
+ Return<void> gnssAcquireWakelockCb() override;
+ Return<void> gnssReleaseWakelockCb() override;
+ Return<void> gnssRequestTimeCb() override;
+ Return<void> gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) override;
- // GnssClock only supports the more effective HW_CLOCK type, so type
- // handling and documentation complexity has been removed. To convert the
- // old GPS_CLOCK types (active only in a limited number of older devices),
- // the GPS time information is handled as an always discontinuous HW clock,
- // with the GPS time information put into the full_bias_ns instead - so that
- // time_ns - full_bias_ns = local estimate of GPS time. Additionally, the
- // sign of full_bias_ns and bias_ns has flipped between GpsClock &
- // GnssClock, so that is also handled below.
- switch (clock->type) {
- case GPS_CLOCK_TYPE_UNKNOWN:
- // Clock type unsupported.
- ALOGE("Unknown clock type provided.");
- break;
- case GPS_CLOCK_TYPE_LOCAL_HW_TIME:
- // Already local hardware time. No need to do anything.
- break;
- case GPS_CLOCK_TYPE_GPS_TIME:
- // GPS time, need to convert.
- flags |= GPS_CLOCK_HAS_FULL_BIAS;
- clock->full_bias_ns = clock->time_ns;
- clock->time_ns = 0;
- SET(HardwareClockDiscontinuityCount,
- discontinuity_count_to_handle_old_clock_type++);
- break;
+ static GnssSvInfo sGnssSvList[static_cast<uint32_t>(
+ android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
+ static size_t sGnssSvListSize;
+
+ static const char* sNmeaString;
+ static size_t sNmeaStringLength;
+};
+
+IGnssCallback::GnssSvInfo GnssCallback::sGnssSvList[static_cast<uint32_t>(
+ android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)];
+const char* GnssCallback::sNmeaString = nullptr;
+size_t GnssCallback::sNmeaStringLength = 0;
+size_t GnssCallback::sGnssSvListSize = 0;
+
+Return<void> GnssCallback::gnssLocationCb(
+ const ::android::hardware::gnss::V1_0::GnssLocation& location) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportLocation,
+ location.gnssLocationFlags,
+ static_cast<jdouble>(location.latitudeDegrees),
+ static_cast<jdouble>(location.longitudeDegrees),
+ static_cast<jdouble>(location.altitudeMeters),
+ static_cast<jfloat>(location.speedMetersPerSec),
+ static_cast<jfloat>(location.bearingDegrees),
+ static_cast<jfloat>(location.accuracyMeters),
+ static_cast<jlong>(location.timestamp));
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssStatusCb(const IGnssCallback::GnssStatusValue status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_reportStatus, status);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssSvStatusCb(const IGnssCallback::GnssSvStatus& svStatus) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+ sGnssSvListSize = svStatus.numSvs;
+ if (sGnssSvListSize > static_cast<uint32_t>(
+ android::hardware::gnss::V1_0::GnssMax::SVS_COUNT)) {
+ ALOGD("Too many satellites %zd. Clamps to %u.", sGnssSvListSize,
+ static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT));
+ sGnssSvListSize = static_cast<uint32_t>(android::hardware::gnss::V1_0::GnssMax::SVS_COUNT);
}
- SET(TimeNanos, clock->time_ns);
- SET_IF(GPS_CLOCK_HAS_TIME_UNCERTAINTY,
- TimeUncertaintyNanos,
- clock->time_uncertainty_ns);
-
- // Definition of sign for full_bias_ns & bias_ns has been changed since N,
- // so flip signs here.
- SET_IF(GPS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, -(clock->full_bias_ns));
- SET_IF(GPS_CLOCK_HAS_BIAS, BiasNanos, -(clock->bias_ns));
-
- SET_IF(GPS_CLOCK_HAS_BIAS_UNCERTAINTY,
- BiasUncertaintyNanos,
- clock->bias_uncertainty_ns);
- SET_IF(GPS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
- SET_IF(GPS_CLOCK_HAS_DRIFT_UNCERTAINTY,
- DriftUncertaintyNanosPerSecond,
- clock->drift_uncertainty_nsps);
-
- return object.get();
-}
-
-static jobject translate_gnss_clock(JNIEnv* env, GnssClock* clock) {
- JavaObject object(env, "android/location/GnssClock");
- GnssClockFlags flags = clock->flags;
-
- SET_IF(GNSS_CLOCK_HAS_LEAP_SECOND,
- LeapSecond,
- static_cast<int32_t>(clock->leap_second));
- SET(TimeNanos, clock->time_ns);
- SET_IF(GNSS_CLOCK_HAS_TIME_UNCERTAINTY,
- TimeUncertaintyNanos,
- clock->time_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_FULL_BIAS, FullBiasNanos, clock->full_bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS, BiasNanos, clock->bias_ns);
- SET_IF(GNSS_CLOCK_HAS_BIAS_UNCERTAINTY,
- BiasUncertaintyNanos,
- clock->bias_uncertainty_ns);
- SET_IF(GNSS_CLOCK_HAS_DRIFT, DriftNanosPerSecond, clock->drift_nsps);
- SET_IF(GNSS_CLOCK_HAS_DRIFT_UNCERTAINTY,
- DriftUncertaintyNanosPerSecond,
- clock->drift_uncertainty_nsps);
-
- SET(HardwareClockDiscontinuityCount, clock->hw_clock_discontinuity_count);
-
- return object.get();
-}
-
-static jobject translate_gps_measurement(JNIEnv* env,
- GpsMeasurement* measurement) {
- JavaObject object(env, "android/location/GnssMeasurement");
- GpsMeasurementFlags flags = measurement->flags;
- SET(Svid, static_cast<int32_t>(measurement->prn));
- if (measurement->prn >= 1 && measurement->prn <= 32) {
- SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS));
- } else {
- ALOGD("Unknown constellation type with Svid = %d.", measurement->prn);
- SET(ConstellationType,
- static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN));
+ // Copy GNSS SV info into sGnssSvList, if any.
+ if (svStatus.numSvs > 0) {
+ memcpy(sGnssSvList, svStatus.gnssSvList.data(), sizeof(GnssSvInfo) * sGnssSvListSize);
}
- SET(TimeOffsetNanos, measurement->time_offset_ns);
- SET(State, static_cast<int32_t>(measurement->state));
- SET(ReceivedSvTimeNanos, measurement->received_gps_tow_ns);
- SET(ReceivedSvTimeUncertaintyNanos,
- measurement->received_gps_tow_uncertainty_ns);
- SET(Cn0DbHz, measurement->c_n0_dbhz);
- SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps);
- SET(PseudorangeRateUncertaintyMetersPerSecond,
- measurement->pseudorange_rate_uncertainty_mps);
- SET(AccumulatedDeltaRangeState,
- static_cast<int32_t>(measurement->accumulated_delta_range_state));
- SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m);
- SET(AccumulatedDeltaRangeUncertaintyMeters,
- measurement->accumulated_delta_range_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
- CarrierFrequencyHz,
- measurement->carrier_frequency_hz);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
- CarrierCycles,
- measurement->carrier_cycles);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE,
- CarrierPhase,
- measurement->carrier_phase);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
- CarrierPhaseUncertainty,
- measurement->carrier_phase_uncertainty);
- SET(MultipathIndicator,
- static_cast<int32_t>(measurement->multipath_indicator));
- SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
- return object.get();
+ env->CallVoidMethod(mCallbacksObj, method_reportSvStatus);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
}
-static jobject translate_gnss_measurement(JNIEnv* env,
- GnssMeasurement* measurement) {
+Return<void> GnssCallback::gnssNmeaCb(
+ int64_t timestamp, const ::android::hardware::hidl_string& nmea) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ /*
+ * The Java code will call back to read these values.
+ * We do this to avoid creating unnecessary String objects.
+ */
+ sNmeaString = nmea.c_str();
+ sNmeaStringLength = nmea.size();
+
+ env->CallVoidMethod(mCallbacksObj, method_reportNmea, timestamp);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssSetCapabilitesCb(uint32_t capabilities) {
+ ALOGD("%s: %du\n", __func__, capabilities);
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_setEngineCapabilities, capabilities);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssAcquireWakelockCb() {
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssReleaseWakelockCb() {
+ release_wake_lock(WAKE_LOCK_NAME);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssRequestTimeCb() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_requestUtcTime);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssCallback::gnssSetSystemInfoCb(const IGnssCallback::GnssSystemInfo& info) {
+ ALOGD("%s: yearOfHw=%d\n", __func__, info.yearOfHw);
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_setGnssYearOfHardware,
+ info.yearOfHw);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+class GnssXtraCallback : public IGnssXtraCallback {
+ Return<void> downloadRequestCb() override;
+};
+
+/*
+ * GnssXtraCallback class implements the callback methods for the IGnssXtra
+ * interface.
+ */
+Return<void> GnssXtraCallback::downloadRequestCb() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_xtraDownloadRequest);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+/*
+ * GnssGeofenceCallback class implements the callback methods for the
+ * IGnssGeofence interface.
+ */
+struct GnssGeofenceCallback : public IGnssGeofenceCallback {
+ // Methods from ::android::hardware::gps::V1_0::IGnssGeofenceCallback follow.
+ Return<void> gnssGeofenceTransitionCb(
+ int32_t geofenceId,
+ const android::hardware::gnss::V1_0::GnssLocation& location,
+ GeofenceTransition transition,
+ hardware::gnss::V1_0::GnssUtcTime timestamp) override;
+ Return<void> gnssGeofenceStatusCb(
+ GeofenceAvailability status,
+ const android::hardware::gnss::V1_0::GnssLocation& location) override;
+ Return<void> gnssGeofenceAddCb(int32_t geofenceId,
+ GeofenceStatus status) override;
+ Return<void> gnssGeofenceRemoveCb(int32_t geofenceId,
+ GeofenceStatus status) override;
+ Return<void> gnssGeofencePauseCb(int32_t geofenceId,
+ GeofenceStatus status) override;
+ Return<void> gnssGeofenceResumeCb(int32_t geofenceId,
+ GeofenceStatus status) override;
+};
+
+Return<void> GnssGeofenceCallback::gnssGeofenceTransitionCb(
+ int32_t geofenceId,
+ const android::hardware::gnss::V1_0::GnssLocation& location,
+ GeofenceTransition transition,
+ hardware::gnss::V1_0::GnssUtcTime timestamp) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofenceTransition,
+ geofenceId,
+ location.gnssLocationFlags,
+ static_cast<jdouble>(location.latitudeDegrees),
+ static_cast<jdouble>(location.longitudeDegrees),
+ static_cast<jdouble>(location.altitudeMeters),
+ static_cast<jfloat>(location.speedMetersPerSec),
+ static_cast<jfloat>(location.bearingDegrees),
+ static_cast<jfloat>(location.accuracyMeters),
+ static_cast<jlong>(location.timestamp),
+ transition,
+ timestamp);
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssGeofenceCallback::gnssGeofenceStatusCb(
+ GeofenceAvailability status,
+ const android::hardware::gnss::V1_0::GnssLocation& location) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofenceStatus,
+ status,
+ location.gnssLocationFlags,
+ static_cast<jdouble>(location.latitudeDegrees),
+ static_cast<jdouble>(location.longitudeDegrees),
+ static_cast<jdouble>(location.altitudeMeters),
+ static_cast<jfloat>(location.speedMetersPerSec),
+ static_cast<jfloat>(location.bearingDegrees),
+ static_cast<jfloat>(location.accuracyMeters),
+ static_cast<jlong>(location.timestamp));
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssGeofenceCallback::gnssGeofenceAddCb(int32_t geofenceId,
+ GeofenceStatus status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
+ ALOGE("%s: Error in adding a Geofence: %d\n", __func__, status);
+ }
+
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofenceAddStatus,
+ geofenceId,
+ status);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssGeofenceCallback::gnssGeofenceRemoveCb(int32_t geofenceId,
+ GeofenceStatus status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
+ ALOGE("%s: Error in removing a Geofence: %d\n", __func__, status);
+ }
+
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofenceRemoveStatus,
+ geofenceId, status);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssGeofenceCallback::gnssGeofencePauseCb(int32_t geofenceId,
+ GeofenceStatus status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
+ ALOGE("%s: Error in pausing Geofence: %d\n", __func__, status);
+ }
+
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofencePauseStatus,
+ geofenceId, status);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> GnssGeofenceCallback::gnssGeofenceResumeCb(int32_t geofenceId,
+ GeofenceStatus status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (status != IGnssGeofenceCallback::GeofenceStatus::OPERATION_SUCCESS) {
+ ALOGE("%s: Error in resuming Geofence: %d\n", __func__, status);
+ }
+
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportGeofenceResumeStatus,
+ geofenceId, status);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+/*
+ * GnssNavigationMessageCallback interface implements the callback methods
+ * required by the IGnssNavigationMessage interface.
+ */
+struct GnssNavigationMessageCallback : public IGnssNavigationMessageCallback {
+ /*
+ * Methods from ::android::hardware::gps::V1_0::IGnssNavigationMessageCallback
+ * follow.
+ */
+ Return<void> gnssNavigationMessageCb(
+ const IGnssNavigationMessageCallback::GnssNavigationMessage& message) override;
+};
+
+Return<void> GnssNavigationMessageCallback::gnssNavigationMessageCb(
+ const IGnssNavigationMessageCallback::GnssNavigationMessage& message) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+ size_t dataLength = message.data.size();
+
+ std::vector<uint8_t> navigationData = message.data;
+ uint8_t* data = &(navigationData[0]);
+ if (dataLength == 0 || data == NULL) {
+ ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data,
+ dataLength);
+ return Void();
+ }
+
+ JavaObject object(env, "android/location/GnssNavigationMessage");
+ SET(Type, static_cast<int32_t>(message.type));
+ SET(Svid, static_cast<int32_t>(message.svid));
+ SET(MessageId, static_cast<int32_t>(message.messageId));
+ SET(SubmessageId, static_cast<int32_t>(message.submessageId));
+ object.callSetter("setData", data, dataLength);
+ SET(Status, static_cast<int32_t>(message.status));
+
+ jobject navigationMessage = object.get();
+ env->CallVoidMethod(mCallbacksObj,
+ method_reportNavigationMessages,
+ navigationMessage);
+ env->DeleteLocalRef(navigationMessage);
+ return Void();
+}
+
+/*
+ * GnssMeasurementCallback implements the callback methods required for the
+ * GnssMeasurement interface.
+ */
+struct GnssMeasurementCallback : public IGnssMeasurementCallback {
+ Return<void> GnssMeasurementCb(const IGnssMeasurementCallback::GnssData& data);
+ private:
+ jobject translateGnssMeasurement(
+ JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement);
+ jobject translateGnssClock(
+ JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock);
+ jobjectArray translateGnssMeasurements(
+ JNIEnv* env,
+ const IGnssMeasurementCallback::GnssMeasurement* measurements,
+ size_t count);
+ void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray);
+};
+
+
+Return<void> GnssMeasurementCallback::GnssMeasurementCb(
+ const IGnssMeasurementCallback::GnssData& data) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+ jobject clock;
+ jobjectArray measurementArray;
+
+ clock = translateGnssClock(env, &data.clock);
+ measurementArray = translateGnssMeasurements(
+ env, data.measurements.data(), data.measurementCount);
+ setMeasurementData(env, clock, measurementArray);
+
+ env->DeleteLocalRef(clock);
+ env->DeleteLocalRef(measurementArray);
+ return Void();
+}
+
+jobject GnssMeasurementCallback::translateGnssMeasurement(
+ JNIEnv* env, const IGnssMeasurementCallback::GnssMeasurement* measurement) {
JavaObject object(env, "android/location/GnssMeasurement");
- GnssMeasurementFlags flags = measurement->flags;
+ uint32_t flags = static_cast<uint32_t>(measurement->flags);
SET(Svid, static_cast<int32_t>(measurement->svid));
SET(ConstellationType, static_cast<int32_t>(measurement->constellation));
- SET(TimeOffsetNanos, measurement->time_offset_ns);
+ SET(TimeOffsetNanos, measurement->timeOffsetNs);
SET(State, static_cast<int32_t>(measurement->state));
- SET(ReceivedSvTimeNanos, measurement->received_sv_time_in_ns);
+ SET(ReceivedSvTimeNanos, measurement->receivedSvTimeInNs);
SET(ReceivedSvTimeUncertaintyNanos,
- measurement->received_sv_time_uncertainty_in_ns);
- SET(Cn0DbHz, measurement->c_n0_dbhz);
- SET(PseudorangeRateMetersPerSecond, measurement->pseudorange_rate_mps);
+ measurement->receivedSvTimeUncertaintyInNs);
+ SET(Cn0DbHz, measurement->cN0DbHz);
+ SET(PseudorangeRateMetersPerSecond, measurement->pseudorangeRateMps);
SET(PseudorangeRateUncertaintyMetersPerSecond,
- measurement->pseudorange_rate_uncertainty_mps);
+ measurement->pseudorangeRateUncertaintyMps);
SET(AccumulatedDeltaRangeState,
- static_cast<int32_t>(measurement->accumulated_delta_range_state));
- SET(AccumulatedDeltaRangeMeters, measurement->accumulated_delta_range_m);
+ (static_cast<int32_t>(measurement->accumulatedDeltaRangeState)));
+ SET(AccumulatedDeltaRangeMeters, measurement->accumulatedDeltaRangeM);
SET(AccumulatedDeltaRangeUncertaintyMeters,
- measurement->accumulated_delta_range_uncertainty_m);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_FREQUENCY,
- CarrierFrequencyHz,
- measurement->carrier_frequency_hz);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_CYCLES,
- CarrierCycles,
- measurement->carrier_cycles);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE,
- CarrierPhase,
- measurement->carrier_phase);
- SET_IF(GNSS_MEASUREMENT_HAS_CARRIER_PHASE_UNCERTAINTY,
- CarrierPhaseUncertainty,
- measurement->carrier_phase_uncertainty);
- SET(MultipathIndicator,
- static_cast<int32_t>(measurement->multipath_indicator));
- SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db);
+ measurement->accumulatedDeltaRangeUncertaintyM);
+
+ if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_FREQUENCY)) {
+ SET(CarrierFrequencyHz, measurement->carrierFrequencyHz);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE)) {
+ SET(CarrierPhase, measurement->carrierPhase);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_CARRIER_PHASE_UNCERTAINTY)) {
+ SET(CarrierPhaseUncertainty, measurement->carrierPhaseUncertainty);
+ }
+
+ SET(MultipathIndicator, static_cast<int32_t>(measurement->multipathIndicator));
+
+ if (flags & static_cast<uint32_t>(GnssMeasurementFlags::HAS_SNR)) {
+ SET(SnrInDb, measurement->snrDb);
+ }
return object.get();
}
-static jobjectArray translate_gps_measurements(JNIEnv* env,
- GpsMeasurement* measurements,
- size_t count) {
+jobject GnssMeasurementCallback::translateGnssClock(
+ JNIEnv* env, const IGnssMeasurementCallback::GnssClock* clock) {
+ JavaObject object(env, "android/location/GnssClock");
+
+ uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags);
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) {
+ SET(LeapSecond, static_cast<int32_t>(clock->leapSecond));
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) {
+ SET(TimeUncertaintyNanos, clock->timeUncertaintyNs);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) {
+ SET(FullBiasNanos, clock->fullBiasNs);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) {
+ SET(BiasNanos, clock->biasNs);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) {
+ SET(BiasUncertaintyNanos, clock->biasUncertaintyNs);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) {
+ SET(DriftNanosPerSecond, clock->driftNsps);
+ }
+
+ if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) {
+ SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps);
+ }
+
+ SET(TimeNanos, clock->timeNs);
+ SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount);
+
+ return object.get();
+}
+
+jobjectArray GnssMeasurementCallback::translateGnssMeasurements(JNIEnv* env,
+ const IGnssMeasurementCallback::GnssMeasurement*
+ measurements, size_t count) {
if (count == 0) {
return NULL;
}
- jclass gnssMeasurementClass = env->FindClass(
- "android/location/GnssMeasurement");
+ jclass gnssMeasurementClass = env->FindClass("android/location/GnssMeasurement");
jobjectArray gnssMeasurementArray = env->NewObjectArray(
count,
gnssMeasurementClass,
NULL /* initialElement */);
for (uint16_t i = 0; i < count; ++i) {
- jobject gnssMeasurement = translate_gps_measurement(
+ jobject gnssMeasurement = translateGnssMeasurement(
env,
&measurements[i]);
env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
@@ -1332,130 +673,789 @@
return gnssMeasurementArray;
}
-static jobjectArray translate_gnss_measurements(JNIEnv* env,
- GnssMeasurement* measurements,
- size_t count) {
- if (count == 0) {
- return NULL;
- }
+void GnssMeasurementCallback::setMeasurementData(JNIEnv* env, jobject clock,
+ jobjectArray measurementArray) {
+ jclass gnssMeasurementsEventClass =
+ env->FindClass("android/location/GnssMeasurementsEvent");
+ jmethodID gnssMeasurementsEventCtor =
+ env->GetMethodID(
+ gnssMeasurementsEventClass,
+ "<init>",
+ "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
- jclass gnssMeasurementClass = env->FindClass(
- "android/location/GnssMeasurement");
- jobjectArray gnssMeasurementArray = env->NewObjectArray(
- count,
- gnssMeasurementClass,
- NULL /* initialElement */);
+ jobject gnssMeasurementsEvent = env->NewObject(gnssMeasurementsEventClass,
+ gnssMeasurementsEventCtor,
+ clock,
+ measurementArray);
- for (uint16_t i = 0; i < count; ++i) {
- jobject gnssMeasurement = translate_gnss_measurement(
- env,
- &measurements[i]);
- env->SetObjectArrayElement(gnssMeasurementArray, i, gnssMeasurement);
- env->DeleteLocalRef(gnssMeasurement);
- }
-
- env->DeleteLocalRef(gnssMeasurementClass);
- return gnssMeasurementArray;
-}
-
-static void set_measurement_data(JNIEnv *env,
- jobject clock,
- jobjectArray measurementArray) {
- jclass gnssMeasurementsEventClass = env->FindClass(
- "android/location/GnssMeasurementsEvent");
- jmethodID gnssMeasurementsEventCtor = env->GetMethodID(
- gnssMeasurementsEventClass,
- "<init>",
- "(Landroid/location/GnssClock;[Landroid/location/GnssMeasurement;)V");
-
- jobject gnssMeasurementsEvent = env->NewObject(
- gnssMeasurementsEventClass,
- gnssMeasurementsEventCtor,
- clock,
- measurementArray);
- env->CallVoidMethod(mCallbacksObj,
- method_reportMeasurementData,
- gnssMeasurementsEvent);
+ env->CallVoidMethod(mCallbacksObj, method_reportMeasurementData,
+ gnssMeasurementsEvent);
checkAndClearExceptionFromCallback(env, __FUNCTION__);
env->DeleteLocalRef(gnssMeasurementsEventClass);
env->DeleteLocalRef(gnssMeasurementsEvent);
}
-static void measurement_callback(GpsData* data) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (data == NULL) {
- ALOGE("Invalid data provided to gps_measurement_callback");
- return;
- }
- if (data->size != sizeof(GpsData)) {
- ALOGE("Invalid GpsData size found in gps_measurement_callback, "
- "size=%zd",
- data->size);
- return;
- }
-
- jobject clock;
- jobjectArray measurementArray;
- clock = translate_gps_clock(env, &data->clock);
- measurementArray = translate_gps_measurements(
- env, data->measurements, data->measurement_count);
- set_measurement_data(env, clock, measurementArray);
-
- env->DeleteLocalRef(clock);
- env->DeleteLocalRef(measurementArray);
-}
-
-static void gnss_measurement_callback(GnssData* data) {
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- if (data == NULL) {
- ALOGE("Invalid data provided to gps_measurement_callback");
- return;
- }
- if (data->size != sizeof(GnssData)) {
- ALOGE("Invalid GnssData size found in gnss_measurement_callback, "
- "size=%zd",
- data->size);
- return;
- }
-
- jobject clock;
- jobjectArray measurementArray;
- clock = translate_gnss_clock(env, &data->clock);
- measurementArray = translate_gnss_measurements(
- env, data->measurements, data->measurement_count);
- set_measurement_data(env, clock, measurementArray);
-
- env->DeleteLocalRef(clock);
- env->DeleteLocalRef(measurementArray);
-}
-
-GpsMeasurementCallbacks sGpsMeasurementCallbacks = {
- sizeof(GpsMeasurementCallbacks),
- measurement_callback,
- gnss_measurement_callback,
+/*
+ * GnssNiCallback implements callback methods required by the IGnssNi interface.
+ */
+struct GnssNiCallback : public IGnssNiCallback {
+ Return<void> niNotifyCb(const IGnssNiCallback::GnssNiNotification& notification)
+ override;
};
+Return<void> GnssNiCallback::niNotifyCb(
+ const IGnssNiCallback::GnssNiNotification& notification) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jstring requestorId = env->NewStringUTF(notification.requestorId.c_str());
+ jstring text = env->NewStringUTF(notification.notificationMessage.c_str());
+
+ if (requestorId && text) {
+ env->CallVoidMethod(mCallbacksObj, method_reportNiNotification,
+ notification.notificationId, notification.niType,
+ notification.notifyFlags, notification.timeoutSec,
+ notification.defaultResponse, requestorId, text,
+ notification.requestorIdEncoding,
+ notification.notificationIdEncoding);
+ } else {
+ ALOGE("%s: OOM Error\n", __func__);
+ }
+
+ if (requestorId) {
+ env->DeleteLocalRef(requestorId);
+ }
+
+ if (text) {
+ env->DeleteLocalRef(text);
+ }
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+/*
+ * AGnssCallback implements callback methods required by the IAGnss interface.
+ */
+struct AGnssCallback : public IAGnssCallback {
+ // Methods from ::android::hardware::gps::V1_0::IAGnssCallback follow.
+ Return<void> agnssStatusIpV6Cb(
+ const IAGnssCallback::AGnssStatusIpV6& agps_status) override;
+
+ Return<void> agnssStatusIpV4Cb(
+ const IAGnssCallback::AGnssStatusIpV4& agps_status) override;
+ private:
+ jbyteArray convertToIpV4(uint32_t ip);
+};
+
+Return<void> AGnssCallback::agnssStatusIpV6Cb(
+ const IAGnssCallback::AGnssStatusIpV6& agps_status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jbyteArray byteArray = NULL;
+ bool isSupported = false;
+
+ byteArray = env->NewByteArray(16);
+ if (byteArray != NULL) {
+ env->SetByteArrayRegion(byteArray, 0, 16,
+ (const jbyte*)(agps_status.ipV6Addr.data()));
+ isSupported = true;
+ } else {
+ ALOGE("Unable to allocate byte array for IPv6 address.");
+ }
+
+ IF_ALOGD() {
+ // log the IP for reference in case there is a bogus value pushed by HAL
+ char str[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, agps_status.ipV6Addr.data(), str, INET6_ADDRSTRLEN);
+ ALOGD("AGPS IP is v6: %s", str);
+ }
+
+ jsize byteArrayLength = byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
+ ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
+ env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
+ agps_status.type, agps_status.status, byteArray);
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+ if (byteArray) {
+ env->DeleteLocalRef(byteArray);
+ }
+
+ return Void();
+}
+
+Return<void> AGnssCallback::agnssStatusIpV4Cb(
+ const IAGnssCallback::AGnssStatusIpV4& agps_status) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jbyteArray byteArray = NULL;
+
+ uint32_t ipAddr = agps_status.ipV4Addr;
+ byteArray = convertToIpV4(ipAddr);
+
+ IF_ALOGD() {
+ /*
+ * log the IP for reference in case there is a bogus value pushed by
+ * HAL.
+ */
+ char str[INET_ADDRSTRLEN];
+ inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
+ ALOGD("AGPS IP is v4: %s", str);
+ }
+
+ jsize byteArrayLength =
+ byteArray != NULL ? env->GetArrayLength(byteArray) : 0;
+ ALOGV("Passing AGPS IP addr: size %d", byteArrayLength);
+ env->CallVoidMethod(mCallbacksObj, method_reportAGpsStatus,
+ agps_status.type, agps_status.status, byteArray);
+
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+
+ if (byteArray) {
+ env->DeleteLocalRef(byteArray);
+ }
+ return Void();
+}
+
+jbyteArray AGnssCallback::convertToIpV4(uint32_t ip) {
+ if (INADDR_NONE == ip) {
+ return NULL;
+ }
+
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ jbyteArray byteArray = env->NewByteArray(4);
+ if (byteArray == NULL) {
+ ALOGE("Unable to allocate byte array for IPv4 address");
+ return NULL;
+ }
+
+ jbyte ipv4[4];
+ ALOGV("Converting IPv4 address byte array (net_order) %x", ip);
+ memcpy(ipv4, &ip, sizeof(ipv4));
+ env->SetByteArrayRegion(byteArray, 0, 4, (const jbyte*)ipv4);
+ return byteArray;
+}
+
+/*
+ * AGnssRilCallback implements the callback methods required by the AGnssRil
+ * interface.
+ */
+struct AGnssRilCallback : IAGnssRilCallback {
+ Return<void> requestSetIdCb(IAGnssRilCallback::ID setIdFlag) override;
+ Return<void> requestRefLocCb() override;
+};
+
+Return<void> AGnssRilCallback::requestSetIdCb(IAGnssRilCallback::ID setIdFlag) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_requestSetID, setIdFlag);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+Return<void> AGnssRilCallback::requestRefLocCb() {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ env->CallVoidMethod(mCallbacksObj, method_requestRefLocation);
+ checkAndClearExceptionFromCallback(env, __FUNCTION__);
+ return Void();
+}
+
+static void android_location_GnssLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
+ method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
+ method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
+ method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
+ method_reportAGpsStatus = env->GetMethodID(clazz, "reportAGpsStatus", "(II[B)V");
+ method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
+ method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
+ method_setGnssYearOfHardware = env->GetMethodID(clazz, "setGnssYearOfHardware", "(I)V");
+ method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
+ method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
+ "(IIIIILjava/lang/String;Ljava/lang/String;II)V");
+ method_requestRefLocation = env->GetMethodID(clazz, "requestRefLocation", "()V");
+ method_requestSetID = env->GetMethodID(clazz, "requestSetID", "(I)V");
+ method_requestUtcTime = env->GetMethodID(clazz, "requestUtcTime", "()V");
+ method_reportGeofenceTransition = env->GetMethodID(clazz, "reportGeofenceTransition",
+ "(IIDDDFFFJIJ)V");
+ method_reportGeofenceStatus = env->GetMethodID(clazz, "reportGeofenceStatus",
+ "(IIDDDFFFJ)V");
+ method_reportGeofenceAddStatus = env->GetMethodID(clazz, "reportGeofenceAddStatus",
+ "(II)V");
+ method_reportGeofenceRemoveStatus = env->GetMethodID(clazz, "reportGeofenceRemoveStatus",
+ "(II)V");
+ method_reportGeofenceResumeStatus = env->GetMethodID(clazz, "reportGeofenceResumeStatus",
+ "(II)V");
+ method_reportGeofencePauseStatus = env->GetMethodID(clazz, "reportGeofencePauseStatus",
+ "(II)V");
+ method_reportMeasurementData = env->GetMethodID(
+ clazz,
+ "reportMeasurementData",
+ "(Landroid/location/GnssMeasurementsEvent;)V");
+ method_reportNavigationMessages = env->GetMethodID(
+ clazz,
+ "reportNavigationMessage",
+ "(Landroid/location/GnssNavigationMessage;)V");
+
+ // TODO(b/31632518)
+ gnssHal = IGnss::getService("gnss");
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->getExtensionXtra([](const sp<IGnssXtra>& xtraIface) {
+ gnssXtraIface = xtraIface;
+ });
+
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to Xtra");
+ }
+
+ result = gnssHal->getExtensionAGnssRil([](const sp<IAGnssRil>& rilIface) {
+ agnssRilIface = rilIface;
+ });
+
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to AGnssRil");
+ }
+
+ result = gnssHal->getExtensionAGnss([](const sp<IAGnss>& assistedGnssIface) {
+ agnssIface = assistedGnssIface;
+ });
+
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to AGnss");
+ }
+
+ result = gnssHal->getExtensionGnssNavigationMessage(
+ [](const sp<IGnssNavigationMessage>& navigationMessageIface) {
+ gnssNavigationMessageIface = navigationMessageIface;
+ });
+
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssNavigationMessage");
+ }
+
+ result = gnssHal->getExtensionGnssMeasurement([](
+ const sp<IGnssMeasurement>& measurementIface) {
+ gnssMeasurementIface = measurementIface;
+ });
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssMeasurement");
+ }
+
+ result = gnssHal->getExtensionGnssDebug([](const sp<IGnssDebug>& debugIface) {
+ gnssDebugIface = debugIface;
+ });
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssDebug");
+ }
+
+ result = gnssHal->getExtensionGnssNi([](const sp<IGnssNi>& niIface) {
+ gnssNiIface = niIface;
+ });
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssNi");
+ }
+
+ result = gnssHal->getExtensionGnssConfiguration([](const sp<IGnssConfiguration>& configIface) {
+ gnssConfigurationIface = configIface;
+ });
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssConfiguration");
+ }
+
+ result = gnssHal->getExtensionGnssGeofencing([](const sp<IGnssGeofencing>& geofenceIface) {
+ gnssGeofencingIface = geofenceIface;
+ });
+ if (!result.getStatus().isOk()) {
+ ALOGD("Unable to get a handle to GnssGeofencing");
+ }
+
+ } else {
+ ALOGE("Unable to get GPS service\n");
+ }
+ ProcessState::self()->setThreadPoolMaxThreadCount(0);
+ ProcessState::self()->startThreadPool();
+}
+
+static jboolean android_location_GnssLocationProvider_is_supported(
+ JNIEnv* /* env */, jclass /* clazz */) {
+ return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
+ JNIEnv* /* env */, jclass /* clazz */) {
+ return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_location_gpsLocationProvider_is_gnss_configuration_supported(
+ JNIEnv* /* env */, jclass /* jclazz */) {
+ return (gnssConfigurationIface != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_init(JNIEnv* env, jobject obj) {
+ /*
+ * This must be set before calling into the HAL library.
+ */
+ if (!mCallbacksObj)
+ mCallbacksObj = env->NewGlobalRef(obj);
+
+ sp<IGnssCallback> gnssCbIface = new GnssCallback();
+ /*
+ * Fail if the main interface fails to initialize
+ */
+ if (gnssHal == nullptr) {
+ ALOGE("Unable to Initialize GNSS HAL\n");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssHal->setCallback(gnssCbIface);
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("SetCallback for Gnss Interface fails\n");
+ return JNI_FALSE;
+ }
+
+ sp<IGnssXtraCallback> gnssXtraCbIface = new GnssXtraCallback();
+ if (gnssXtraIface == nullptr) {
+ ALOGE("Unable to initialize GNSS Xtra interface\n");
+ }
+
+ result = gnssXtraIface->setCallback(gnssXtraCbIface);
+ if ((!result) || (!result.getStatus().isOk())) {
+ gnssXtraIface = nullptr;
+ ALOGE("SetCallback for Gnss Xtra Interface fails\n");
+ }
+
+ sp<IAGnssCallback> aGnssCbIface = new AGnssCallback();
+ if (agnssIface != nullptr) {
+ agnssIface->setCallback(aGnssCbIface);
+ } else {
+ ALOGE("Unable to Initialize AGnss interface\n");
+ }
+
+ sp<IGnssGeofenceCallback> gnssGeofencingCbIface = new GnssGeofenceCallback();
+ if (gnssGeofencingIface != nullptr) {
+ gnssGeofencingIface->setCallback(gnssGeofencingCbIface);
+ } else {
+ ALOGE("Unable to initialize GNSS Geofencing interface\n");
+ }
+
+ sp<IGnssNiCallback> gnssNiCbIface = new GnssNiCallback();
+ if (gnssNiCbIface != nullptr) {
+ gnssNiIface->setCallback(gnssNiCbIface);
+ } else {
+ ALOGE("Unable to initialize GNSS NI interface\n");
+ }
+
+ return JNI_TRUE;
+}
+
+static void android_location_GnssLocationProvider_cleanup(JNIEnv* /* env */, jobject /* obj */) {
+ if (gnssHal != nullptr) {
+ gnssHal->cleanup();
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_position_mode(JNIEnv* /* env */,
+ jobject /* obj */, jint mode, jint recurrence, jint min_interval, jint preferred_accuracy,
+ jint preferred_time) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->setPositionMode(static_cast<IGnss::GnssPositionMode>(mode),
+ static_cast<IGnss::GnssPositionRecurrence>(recurrence),
+ min_interval,
+ preferred_accuracy,
+ preferred_time);
+ if (!result.getStatus().isOk()) {
+ ALOGE("%s: GNSS setPositionMode failed\n", __func__);
+ return JNI_FALSE;
+ } else {
+ return result;
+ }
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_start(JNIEnv* /* env */, jobject /* obj */) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->start();
+ if (!result.getStatus().isOk()) {
+ return JNI_FALSE;
+ } else {
+ return result;
+ }
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_stop(JNIEnv* /* env */, jobject /* obj */) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->stop();
+ if (!result.getStatus().isOk()) {
+ return JNI_FALSE;
+ } else {
+ return result;
+ }
+ } else {
+ return JNI_FALSE;
+ }
+}
+static void android_location_GnssLocationProvider_delete_aiding_data(JNIEnv* /* env */,
+ jobject /* obj */,
+ jint flags) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->deleteAidingData(static_cast<IGnss::GnssAidingData>(flags));
+ if (!result.getStatus().isOk()) {
+ ALOGE("Error in deleting aiding data");
+ }
+ }
+}
+
+/*
+ * This enum is used by the read_sv_status method to combine the svid,
+ * constellation and svFlag fields.
+ */
+enum ShiftWidth: uint8_t {
+ SVID_SHIFT_WIDTH = 7,
+ CONSTELLATION_TYPE_SHIFT_WIDTH = 3
+};
+
+static jint android_location_GnssLocationProvider_read_sv_status(JNIEnv* env, jobject /* obj */,
+ jintArray svidWithFlagArray, jfloatArray cn0Array, jfloatArray elevArray,
+ jfloatArray azumArray) {
+ /*
+ * This method should only be called from within a call to reportSvStatus.
+ */
+ jint* svidWithFlags = env->GetIntArrayElements(svidWithFlagArray, 0);
+ jfloat* cn0s = env->GetFloatArrayElements(cn0Array, 0);
+ jfloat* elev = env->GetFloatArrayElements(elevArray, 0);
+ jfloat* azim = env->GetFloatArrayElements(azumArray, 0);
+
+ /*
+ * Read GNSS SV info.
+ */
+ for (size_t i = 0; i < GnssCallback::sGnssSvListSize; ++i) {
+ const IGnssCallback::GnssSvInfo& info = GnssCallback::sGnssSvList[i];
+ svidWithFlags[i] = (info.svid << SVID_SHIFT_WIDTH) |
+ (static_cast<uint32_t>(info.constellation) << CONSTELLATION_TYPE_SHIFT_WIDTH) |
+ static_cast<uint32_t>(info.svFlag);
+ cn0s[i] = info.cN0Dbhz;
+ elev[i] = info.elevationDegrees;
+ azim[i] = info.azimuthDegrees;
+ }
+
+ env->ReleaseIntArrayElements(svidWithFlagArray, svidWithFlags, 0);
+ env->ReleaseFloatArrayElements(cn0Array, cn0s, 0);
+ env->ReleaseFloatArrayElements(elevArray, elev, 0);
+ env->ReleaseFloatArrayElements(azumArray, azim, 0);
+ return static_cast<jint>(GnssCallback::sGnssSvListSize);
+}
+
+static void android_location_GnssLocationProvider_agps_set_reference_location_cellid(
+ JNIEnv* /* env */, jobject /* obj */, jint type, jint mcc, jint mnc, jint lac, jint cid) {
+ IAGnssRil::AGnssRefLocation location;
+
+ if (agnssRilIface == nullptr) {
+ ALOGE("No AGPS RIL interface in agps_set_reference_location_cellid");
+ return;
+ }
+
+ switch (static_cast<IAGnssRil::AGnssRefLocationType>(type)) {
+ case IAGnssRil::AGnssRefLocationType::GSM_CELLID:
+ case IAGnssRil::AGnssRefLocationType::UMTS_CELLID:
+ location.type = static_cast<IAGnssRil::AGnssRefLocationType>(type);
+ location.cellID.mcc = mcc;
+ location.cellID.mnc = mnc;
+ location.cellID.lac = lac;
+ location.cellID.cid = cid;
+ break;
+ default:
+ ALOGE("Neither a GSM nor a UMTS cellid (%s:%d).", __FUNCTION__, __LINE__);
+ return;
+ break;
+ }
+
+ agnssRilIface->setRefLocation(location);
+}
+
+static void android_location_GnssLocationProvider_agps_set_id(JNIEnv *env, jobject /* obj */,
+ jint type, jstring setid_string) {
+ if (agnssRilIface == nullptr) {
+ ALOGE("no AGPS RIL interface in agps_set_id");
+ return;
+ }
+
+ const char *setid = env->GetStringUTFChars(setid_string, NULL);
+ agnssRilIface->setSetId((IAGnssRil::SetIDType)type, setid);
+ env->ReleaseStringUTFChars(setid_string, setid);
+}
+
+static jint android_location_GnssLocationProvider_read_nmea(JNIEnv* env, jobject /* obj */,
+ jbyteArray nmeaArray, jint buffer_size) {
+ // this should only be called from within a call to reportNmea
+ jbyte* nmea = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(nmeaArray, 0));
+ int length = GnssCallback::sNmeaStringLength;
+ if (length > buffer_size)
+ length = buffer_size;
+ memcpy(nmea, GnssCallback::sNmeaString, length);
+ env->ReleasePrimitiveArrayCritical(nmeaArray, nmea, JNI_ABORT);
+ return (jint) length;
+}
+
+static void android_location_GnssLocationProvider_inject_time(JNIEnv* /* env */, jobject /* obj */,
+ jlong time, jlong timeReference, jint uncertainty) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->injectTime(time, timeReference, uncertainty);
+ if (!result || !result.getStatus().isOk()) {
+ ALOGE("%s: Gnss injectTime() failed", __func__);
+ }
+ }
+}
+
+static void android_location_GnssLocationProvider_inject_location(JNIEnv* /* env */,
+ jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
+ if (gnssHal != nullptr) {
+ auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
+ if (!result || !result.getStatus().isOk()) {
+ ALOGE("%s: Gnss injectLocation() failed", __func__);
+ }
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_supports_xtra(
+ JNIEnv* /* env */, jobject /* obj */) {
+ return (gnssXtraIface != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+static void android_location_GnssLocationProvider_inject_xtra_data(JNIEnv* env, jobject /* obj */,
+ jbyteArray data, jint length) {
+ if (gnssXtraIface == nullptr) {
+ ALOGE("XTRA Interface not supported");
+ return;
+ }
+
+ jbyte* bytes = reinterpret_cast<jbyte *>(env->GetPrimitiveArrayCritical(data, 0));
+ gnssXtraIface->injectXtraData(std::string((const char*)bytes, length));
+ env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
+}
+
+static void android_location_GnssLocationProvider_agps_data_conn_open(
+ JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
+ if (agnssIface == nullptr) {
+ ALOGE("no AGPS interface in agps_data_conn_open");
+ return;
+ }
+ if (apn == NULL) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return;
+ }
+
+ const char *apnStr = env->GetStringUTFChars(apn, NULL);
+
+ auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("%s: Failed to set APN and its IP type", __func__);
+ }
+ env->ReleaseStringUTFChars(apn, apnStr);
+}
+
+static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
+ jobject /* obj */) {
+ if (agnssIface == nullptr) {
+ ALOGE("%s: AGPS interface not supported", __func__);
+ return;
+ }
+
+ auto result = agnssIface->dataConnClosed();
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("%s: Failed to close AGnss data connection", __func__);
+ }
+}
+
+static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
+ jobject /* obj */) {
+ if (agnssIface == nullptr) {
+ ALOGE("%s: AGPS interface not supported", __func__);
+ return;
+ }
+
+ auto result = agnssIface->dataConnFailed();
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
+ }
+}
+
+static void android_location_GnssLocationProvider_set_agps_server(JNIEnv* env, jobject /* obj */,
+ jint type, jstring hostname, jint port) {
+ if (agnssIface == nullptr) {
+ ALOGE("no AGPS interface in set_agps_server");
+ return;
+ }
+
+ const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
+ auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
+ c_hostname,
+ port);
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("%s: Failed to set AGnss host name and port", __func__);
+ }
+
+ env->ReleaseStringUTFChars(hostname, c_hostname);
+}
+
+static void android_location_GnssLocationProvider_send_ni_response(JNIEnv* /* env */,
+ jobject /* obj */, jint notifId, jint response) {
+ if (gnssNiIface == nullptr) {
+ ALOGE("no NI interface in send_ni_response");
+ return;
+ }
+
+ gnssNiIface->respond(notifId, static_cast<IGnssNiCallback::GnssUserResponseType>(response));
+}
+
+static jstring android_location_GnssLocationProvider_get_internal_state(JNIEnv* env,
+ jobject /* obj */) {
+ jstring result = NULL;
+ /*
+ * TODO(b/33089503) : Create a jobject to represent GnssDebug.
+ */
+ if (gnssDebugIface != nullptr) {
+ IGnssDebug::DebugData data;
+ gnssDebugIface->getDebugData([&data](const IGnssDebug::DebugData& debugData) {
+ data = debugData;
+ });
+
+ std::stringstream internalState;
+ if (data.position.valid) {
+ internalState << "Gnss Location Data:: LatitudeDegrees: " << data.position.latitudeDegrees
+ << ", LongitudeDegrees: " << data.position.longitudeDegrees
+ << ", altitudeMeters: " << data.position.altitudeMeters
+ << ", accuracyMeters: " << data.position.accuracyMeters
+ << ", ageSeconds: " << data.position.ageSeconds << std::endl;
+ }
+
+ if (data.time.valid) {
+ internalState << "Gnss Time Data:: timeEstimate: " << data.time.timeEstimate
+ << ", timeUncertaintyNs: " << data.time.timeUncertaintyNs << std::endl;
+ }
+
+ if (data.satelliteDataArray.size() != 0) {
+ internalState << "Satellite Data:: ";
+ }
+
+ for (size_t i = 0; i < data.satelliteDataArray.size(); i++) {
+ internalState << "svid: " << data.satelliteDataArray[i].svid
+ << ", constellation: "
+ << static_cast<uint32_t>(data.satelliteDataArray[i].constellation)
+ << ", ephemerisType: "
+ << static_cast<uint32_t>(data.satelliteDataArray[i].ephemerisType)
+ << ", ephemerisAgeSeconds: "
+ << data.satelliteDataArray[i].ephemerisAgeSeconds << std::endl;
+ }
+ result = env->NewStringUTF(internalState.str().c_str());
+ }
+ return result;
+}
+
+static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
+ jobject /* obj */,
+ jboolean connected,
+ jint type,
+ jboolean roaming,
+ jboolean available,
+ jstring extraInfo,
+ jstring apn) {
+ if (agnssRilIface != nullptr) {
+ auto result = agnssRilIface->updateNetworkState(connected,
+ static_cast<IAGnssRil::NetworkType>(type),
+ roaming);
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("updateNetworkState failed");
+ }
+
+ const char *c_apn = env->GetStringUTFChars(apn, NULL);
+ result = agnssRilIface->updateNetworkAvailability(available, c_apn);
+ if ((!result) || (!result.getStatus().isOk())) {
+ ALOGE("updateNetworkAvailability failed");
+ }
+
+ env->ReleaseStringUTFChars(apn, c_apn);
+ } else {
+ ALOGE("AGnssRilInterface does not exist");
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_is_geofence_supported(
+ JNIEnv* /* env */, jobject /* obj */) {
+ return (gnssGeofencingIface != nullptr) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_add_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofenceId, jdouble latitude, jdouble longitude, jdouble radius,
+ jint last_transition, jint monitor_transition, jint notification_responsiveness,
+ jint unknown_timer) {
+ if (gnssGeofencingIface != nullptr) {
+ auto result = gnssGeofencingIface->addGeofence(
+ geofenceId, latitude, longitude, radius,
+ static_cast<IGnssGeofenceCallback::GeofenceTransition>(last_transition),
+ monitor_transition, notification_responsiveness, unknown_timer);
+ return boolToJbool(result.getStatus().isOk());
+ } else {
+ ALOGE("Geofence Interface not available");
+ }
+ return JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_remove_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofenceId) {
+ if (gnssGeofencingIface != nullptr) {
+ auto result = gnssGeofencingIface->removeGeofence(geofenceId);
+ return boolToJbool(result.getStatus().isOk());
+ } else {
+ ALOGE("Geofence interface not available");
+ }
+ return JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_pause_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofenceId) {
+ if (gnssGeofencingIface != nullptr) {
+ auto result = gnssGeofencingIface->pauseGeofence(geofenceId);
+ return boolToJbool(result.getStatus().isOk());
+ } else {
+ ALOGE("Geofence interface not available");
+ }
+ return JNI_FALSE;
+}
+
+static jboolean android_location_GnssLocationProvider_resume_geofence(JNIEnv* /* env */,
+ jobject /* obj */, jint geofenceId, jint monitor_transition) {
+ if (gnssGeofencingIface != nullptr) {
+ auto result = gnssGeofencingIface->resumeGeofence(geofenceId, monitor_transition);
+ return boolToJbool(result.getStatus().isOk());
+ } else {
+ ALOGE("Geofence interface not available");
+ }
+ return JNI_FALSE;
+}
+
static jboolean android_location_GnssLocationProvider_is_measurement_supported(
- JNIEnv* env,
- jclass clazz) {
- if (sGpsMeasurementInterface != NULL) {
+ JNIEnv* env, jclass clazz) {
+ if (gnssMeasurementIface != nullptr) {
return JNI_TRUE;
}
+
return JNI_FALSE;
}
static jboolean android_location_GnssLocationProvider_start_measurement_collection(
JNIEnv* env,
jobject obj) {
- if (sGpsMeasurementInterface == NULL) {
- ALOGE("Measurement interface is not available.");
+ if (gnssMeasurementIface == nullptr) {
+ ALOGE("GNSS Measurement interface is not available.");
return JNI_FALSE;
}
- int result = sGpsMeasurementInterface->init(&sGpsMeasurementCallbacks);
- if (result != GPS_GEOFENCE_OPERATION_SUCCESS) {
- ALOGE("An error has been found on GpsMeasurementInterface::init, status=%d", result);
+ sp<GnssMeasurementCallback> cbIface = new GnssMeasurementCallback();
+ IGnssMeasurement::GnssMeasurementStatus result = gnssMeasurementIface->setCallback(cbIface);
+ if (result != IGnssMeasurement::GnssMeasurementStatus::SUCCESS) {
+ ALOGE("An error has been found on GnssMeasurementInterface::init, status=%d",
+ static_cast<int32_t>(result));
return JNI_FALSE;
+ } else {
+ ALOGD("gnss measurement infc has been enabled");
}
return JNI_TRUE;
@@ -1464,104 +1464,19 @@
static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
JNIEnv* env,
jobject obj) {
- if (sGpsMeasurementInterface == NULL) {
+ if (gnssMeasurementIface == nullptr) {
ALOGE("Measurement interface not available");
return JNI_FALSE;
}
- sGpsMeasurementInterface->close();
- return JNI_TRUE;
+ auto result = gnssMeasurementIface->close();
+ return boolToJbool(result.getStatus().isOk());
}
-static jobject translate_gps_navigation_message(JNIEnv* env, GpsNavigationMessage* message) {
- size_t dataLength = message->data_length;
- uint8_t* data = message->data;
- if (dataLength == 0 || data == NULL) {
- ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
- return NULL;
- }
- JavaObject object(env, "android/location/GnssNavigationMessage");
- SET(Svid, static_cast<int32_t>(message->prn));
- if (message->prn >=1 && message->prn <= 32) {
- SET(ConstellationType, static_cast<int32_t>(GNSS_CONSTELLATION_GPS));
- // Legacy driver doesn't set the higher byte to constellation type
- // correctly. Set the higher byte to 'GPS'.
- SET(Type, static_cast<int32_t>(message->type | 0x0100));
- } else {
- ALOGD("Unknown constellation type with Svid = %d.", message->prn);
- SET(ConstellationType,
- static_cast<int32_t>(GNSS_CONSTELLATION_UNKNOWN));
- SET(Type, static_cast<int32_t>(GNSS_NAVIGATION_MESSAGE_TYPE_UNKNOWN));
- }
- SET(MessageId, static_cast<int32_t>(message->message_id));
- SET(SubmessageId, static_cast<int32_t>(message->submessage_id));
- object.callSetter("setData", data, dataLength);
- SET(Status, static_cast<int32_t>(message->status));
- return object.get();
-}
-
-static jobject translate_gnss_navigation_message(
- JNIEnv* env, GnssNavigationMessage* message) {
- size_t dataLength = message->data_length;
- uint8_t* data = message->data;
- if (dataLength == 0 || data == NULL) {
- ALOGE("Invalid Navigation Message found: data=%p, length=%zd", data, dataLength);
- return NULL;
- }
- JavaObject object(env, "android/location/GnssNavigationMessage");
- SET(Type, static_cast<int32_t>(message->type));
- SET(Svid, static_cast<int32_t>(message->svid));
- SET(MessageId, static_cast<int32_t>(message->message_id));
- SET(SubmessageId, static_cast<int32_t>(message->submessage_id));
- object.callSetter("setData", data, dataLength);
- SET(Status, static_cast<int32_t>(message->status));
- return object.get();
-}
-
-static void navigation_message_callback(GpsNavigationMessage* message) {
- if (message == NULL) {
- ALOGE("Invalid Navigation Message provided to callback");
- return;
- }
- if (message->size != sizeof(GpsNavigationMessage)) {
- ALOGE("Invalid GpsNavigationMessage size found: %zd", message->size);
- return;
- }
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jobject navigationMessage = translate_gps_navigation_message(env, message);
- env->CallVoidMethod(mCallbacksObj,
- method_reportNavigationMessages,
- navigationMessage);
- env->DeleteLocalRef(navigationMessage);
-}
-
-static void gnss_navigation_message_callback(GnssNavigationMessage* message) {
- if (message == NULL) {
- ALOGE("Invalid Navigation Message provided to callback");
- return;
- }
- if (message->size != sizeof(GnssNavigationMessage)) {
- ALOGE("Invalid GnssNavigationMessage size found: %zd", message->size);
- return;
- }
- JNIEnv* env = AndroidRuntime::getJNIEnv();
- jobject navigationMessage = translate_gnss_navigation_message(env, message);
- env->CallVoidMethod(mCallbacksObj,
- method_reportNavigationMessages,
- navigationMessage);
- env->DeleteLocalRef(navigationMessage);
-}
-
-GpsNavigationMessageCallbacks sGpsNavigationMessageCallbacks = {
- sizeof(GpsNavigationMessageCallbacks),
- navigation_message_callback,
- gnss_navigation_message_callback,
-};
-
static jboolean android_location_GnssLocationProvider_is_navigation_message_supported(
JNIEnv* env,
jclass clazz) {
- if(sGpsNavigationMessageInterface != NULL) {
+ if (gnssNavigationMessageIface != nullptr) {
return JNI_TRUE;
}
return JNI_FALSE;
@@ -1570,14 +1485,18 @@
static jboolean android_location_GnssLocationProvider_start_navigation_message_collection(
JNIEnv* env,
jobject obj) {
- if (sGpsNavigationMessageInterface == NULL) {
+ if (gnssNavigationMessageIface == nullptr) {
ALOGE("Navigation Message interface is not available.");
return JNI_FALSE;
}
- int result = sGpsNavigationMessageInterface->init(&sGpsNavigationMessageCallbacks);
- if (result != GPS_NAVIGATION_MESSAGE_OPERATION_SUCCESS) {
- ALOGE("An error has been found in %s: %d", __FUNCTION__, result);
+ sp<IGnssNavigationMessageCallback> gnssNavigationMessageCbIface =
+ new GnssNavigationMessageCallback();
+ IGnssNavigationMessage::GnssNavigationMessageStatus result =
+ gnssNavigationMessageIface->setCallback(gnssNavigationMessageCbIface);
+
+ if (result != IGnssNavigationMessage::GnssNavigationMessageStatus::SUCCESS) {
+ ALOGE("An error has been found in %s: %d", __FUNCTION__, static_cast<int32_t>(result));
return JNI_FALSE;
}
@@ -1587,127 +1506,255 @@
static jboolean android_location_GnssLocationProvider_stop_navigation_message_collection(
JNIEnv* env,
jobject obj) {
- if (sGpsNavigationMessageInterface == NULL) {
+ if (gnssNavigationMessageIface == nullptr) {
ALOGE("Navigation Message interface is not available.");
return JNI_FALSE;
}
- sGpsNavigationMessageInterface->close();
- return JNI_TRUE;
+ auto result = gnssNavigationMessageIface->close();
+ return boolToJbool(result.getStatus().isOk());
}
-static void android_location_GnssLocationProvider_configuration_update(JNIEnv* env, jobject obj,
- jstring config_content)
-{
- if (!sGnssConfigurationInterface) {
- ALOGE("no GPS configuration interface in configuraiton_update");
- return;
+static jboolean android_location_GnssLocationProvider_set_emergency_supl_pdn(JNIEnv*,
+ jobject,
+ jint emergencySuplPdn) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
}
- const char *data = env->GetStringUTFChars(config_content, NULL);
- ALOGD("GPS configuration:\n %s", data);
- sGnssConfigurationInterface->configuration_update(
- data, env->GetStringUTFLength(config_content));
- env->ReleaseStringUTFChars(config_content, data);
+
+ auto result = gnssConfigurationIface->setEmergencySuplPdn(emergencySuplPdn);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_supl_version(JNIEnv*,
+ jobject,
+ jint version) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+ auto result = gnssConfigurationIface->setSuplVersion(version);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_supl_es(JNIEnv*,
+ jobject,
+ jint suplEs) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssConfigurationIface->setSuplEs(suplEs);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_supl_mode(JNIEnv*,
+ jobject,
+ jint mode) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssConfigurationIface->setSuplMode(mode);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_gps_lock(JNIEnv*,
+ jobject,
+ jint gpsLock) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssConfigurationIface->setGpsLock(gpsLock);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_lpp_profile(JNIEnv*,
+ jobject,
+ jint lppProfile) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssConfigurationIface->setLppProfile(lppProfile);
+
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+static jboolean android_location_GnssLocationProvider_set_gnss_pos_protocol_select(JNIEnv*,
+ jobject,
+ jint gnssPosProtocol) {
+ if (gnssConfigurationIface == nullptr) {
+ ALOGE("no GNSS configuration interface available");
+ return JNI_FALSE;
+ }
+
+ auto result = gnssConfigurationIface->setGlonassPositioningProtocol(gnssPosProtocol);
+ if (result.getStatus().isOk()) {
+ return result;
+ } else {
+ return JNI_FALSE;
+ }
}
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
- {"class_init_native", "()V", (void *)android_location_GnssLocationProvider_class_init_native},
- {"native_is_supported", "()Z", (void*)android_location_GnssLocationProvider_is_supported},
+ {"class_init_native", "()V", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_class_init_native)},
+ {"native_is_supported", "()Z", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_is_supported)},
{"native_is_agps_ril_supported", "()Z",
- (void*)android_location_GnssLocationProvider_is_agps_ril_supported},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
{"native_is_gnss_configuration_supported", "()Z",
- (void*)android_location_gpsLocationProvider_is_gnss_configuration_supported},
- {"native_init", "()Z", (void*)android_location_GnssLocationProvider_init},
- {"native_cleanup", "()V", (void*)android_location_GnssLocationProvider_cleanup},
+ reinterpret_cast<void *>(
+ android_location_gpsLocationProvider_is_gnss_configuration_supported)},
+ {"native_init", "()Z", reinterpret_cast<void *>(android_location_GnssLocationProvider_init)},
+ {"native_cleanup", "()V", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_cleanup)},
{"native_set_position_mode",
"(IIIII)Z",
- (void*)android_location_GnssLocationProvider_set_position_mode},
- {"native_start", "()Z", (void*)android_location_GnssLocationProvider_start},
- {"native_stop", "()Z", (void*)android_location_GnssLocationProvider_stop},
+ reinterpret_cast<void*>(android_location_GnssLocationProvider_set_position_mode)},
+ {"native_start", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_start)},
+ {"native_stop", "()Z", reinterpret_cast<void*>(android_location_GnssLocationProvider_stop)},
{"native_delete_aiding_data",
"(I)V",
- (void*)android_location_GnssLocationProvider_delete_aiding_data},
+ reinterpret_cast<void*>(android_location_GnssLocationProvider_delete_aiding_data)},
{"native_read_sv_status",
"([I[F[F[F)I",
- (void*)android_location_GnssLocationProvider_read_sv_status},
- {"native_read_nmea", "([BI)I", (void*)android_location_GnssLocationProvider_read_nmea},
- {"native_inject_time", "(JJI)V", (void*)android_location_GnssLocationProvider_inject_time},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_read_sv_status)},
+ {"native_read_nmea", "([BI)I", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_read_nmea)},
+ {"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_inject_time)},
{"native_inject_location",
"(DDF)V",
- (void*)android_location_GnssLocationProvider_inject_location},
- {"native_supports_xtra", "()Z", (void*)android_location_GnssLocationProvider_supports_xtra},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_location)},
+ {"native_supports_xtra", "()Z", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_supports_xtra)},
{"native_inject_xtra_data",
"([BI)V",
- (void*)android_location_GnssLocationProvider_inject_xtra_data},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
{"native_agps_data_conn_open",
"(Ljava/lang/String;I)V",
- (void*)android_location_GnssLocationProvider_agps_data_conn_open},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
{"native_agps_data_conn_closed",
"()V",
- (void*)android_location_GnssLocationProvider_agps_data_conn_closed},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
{"native_agps_data_conn_failed",
"()V",
- (void*)android_location_GnssLocationProvider_agps_data_conn_failed},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
{"native_agps_set_id",
"(ILjava/lang/String;)V",
- (void*)android_location_GnssLocationProvider_agps_set_id},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
{"native_agps_set_ref_location_cellid",
"(IIIII)V",
- (void*)android_location_GnssLocationProvider_agps_set_reference_location_cellid},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_agps_set_reference_location_cellid)},
{"native_set_agps_server",
"(ILjava/lang/String;I)V",
- (void*)android_location_GnssLocationProvider_set_agps_server},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_agps_server)},
{"native_send_ni_response",
"(II)V",
- (void*)android_location_GnssLocationProvider_send_ni_response},
- {"native_agps_ni_message",
- "([BI)V",
- (void *)android_location_GnssLocationProvider_agps_send_ni_message},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_send_ni_response)},
{"native_get_internal_state",
"()Ljava/lang/String;",
- (void*)android_location_GnssLocationProvider_get_internal_state},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
{"native_update_network_state",
"(ZIZZLjava/lang/String;Ljava/lang/String;)V",
- (void*)android_location_GnssLocationProvider_update_network_state },
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
{"native_is_geofence_supported",
"()Z",
- (void*) android_location_GnssLocationProvider_is_geofence_supported},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_is_geofence_supported)},
{"native_add_geofence",
"(IDDDIIII)Z",
- (void *)android_location_GnssLocationProvider_add_geofence},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_add_geofence)},
{"native_remove_geofence",
"(I)Z",
- (void *)android_location_GnssLocationProvider_remove_geofence},
- {"native_pause_geofence", "(I)Z", (void *)android_location_GnssLocationProvider_pause_geofence},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_remove_geofence)},
+ {"native_pause_geofence", "(I)Z", reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_pause_geofence)},
{"native_resume_geofence",
"(II)Z",
- (void *)android_location_GnssLocationProvider_resume_geofence},
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_resume_geofence)},
{"native_is_measurement_supported",
"()Z",
- (void*) android_location_GnssLocationProvider_is_measurement_supported},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_is_measurement_supported)},
{"native_start_measurement_collection",
"()Z",
- (void*) android_location_GnssLocationProvider_start_measurement_collection},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_start_measurement_collection)},
{"native_stop_measurement_collection",
"()Z",
- (void*) android_location_GnssLocationProvider_stop_measurement_collection},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_stop_measurement_collection)},
{"native_is_navigation_message_supported",
"()Z",
- (void*) android_location_GnssLocationProvider_is_navigation_message_supported},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_is_navigation_message_supported)},
{"native_start_navigation_message_collection",
"()Z",
- (void*) android_location_GnssLocationProvider_start_navigation_message_collection},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_start_navigation_message_collection)},
{"native_stop_navigation_message_collection",
"()Z",
- (void*) android_location_GnssLocationProvider_stop_navigation_message_collection},
- {"native_configuration_update",
- "(Ljava/lang/String;)V",
- (void*)android_location_GnssLocationProvider_configuration_update},
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_stop_navigation_message_collection)},
+ {"native_set_supl_es",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
+ {"native_set_supl_version",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_version)},
+ {"native_set_supl_mode",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_mode)},
+ {"native_set_lpp_profile",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_lpp_profile)},
+ {"native_set_gnss_pos_protocol_select",
+ "(I)Z",
+ reinterpret_cast<void *>(
+ android_location_GnssLocationProvider_set_gnss_pos_protocol_select)},
+ {"native_set_gps_lock",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_gps_lock)},
+ {"native_set_emergency_supl_pdn",
+ "(I)Z",
+ reinterpret_cast<void *>(android_location_GnssLocationProvider_set_emergency_supl_pdn)},
};
-int register_android_server_location_GnssLocationProvider(JNIEnv* env)
-{
+int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
return jniRegisterNativeMethods(
env,
"com/android/server/location/GnssLocationProvider",
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2f27201..a2af40c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -20,7 +20,7 @@
import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
-import static android.content.pm.PackageManager.GET_UNINSTALLED_PACKAGES;
+import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PROVISIONING_ENTRY_POINT_ADB;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
@@ -7032,7 +7032,8 @@
boolean systemService = false;
try {
ApplicationInfo applicationInfo = mIPackageManager.getApplicationInfo(
- enabledPackage, PackageManager.GET_UNINSTALLED_PACKAGES, userIdToCheck);
+ enabledPackage, PackageManager.MATCH_UNINSTALLED_PACKAGES,
+ userIdToCheck);
systemService = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
} catch (RemoteException e) {
Log.i(LOG_TAG, "Can't talk to package managed", e);
@@ -7787,7 +7788,7 @@
private boolean isSystemApp(IPackageManager pm, String packageName, int userId)
throws RemoteException {
- ApplicationInfo appInfo = pm.getApplicationInfo(packageName, GET_UNINSTALLED_PACKAGES,
+ ApplicationInfo appInfo = pm.getApplicationInfo(packageName, MATCH_UNINSTALLED_PACKAGES,
userId);
if (appInfo == null) {
throw new IllegalArgumentException("The application " + packageName +
@@ -9608,6 +9609,10 @@
Preconditions.checkNotNull(admin);
Preconditions.checkNotNull(caller);
Preconditions.checkNotNull(serviceIntent);
+ Preconditions.checkArgument(
+ serviceIntent.getComponent() != null || serviceIntent.getPackage() != null,
+ "Service intent must be explicit (with a package name or component): "
+ + serviceIntent);
Preconditions.checkNotNull(connection);
Preconditions.checkArgument(mInjector.userHandleGetCallingUserId() != targetUserId,
"target user id must be different from the calling user id");
@@ -9628,9 +9633,8 @@
createCrossUserServiceIntent(serviceIntent, targetPackage, targetUserId);
if (sanitizedIntent == null) {
// Fail, cannot lookup the target service.
- throw new SecurityException("Invalid intent or failed to look up the service");
+ return false;
}
-
// Ask ActivityManager to bind it. Notice that we are binding the service with the
// caller app instead of DevicePolicyManagerService.
return mInjector.getIActivityManager().bindService(
@@ -9885,35 +9889,30 @@
}
/**
- * @param rawIntent Original service intent specified by caller.
- * @param expectedPackageName The expected package name in the incoming intent.
- * @return Intent that have component explicitly set. {@code null} if the incoming intent
- * or target service is invalid.
+ * @param rawIntent Original service intent specified by caller. It must be explicit.
+ * @param expectedPackageName The expected package name of the resolved service.
+ * @return Intent that have component explicitly set. {@code null} if no service is resolved
+ * with the given intent.
+ * @throws SecurityException if the intent is resolved to an invalid service.
*/
private Intent createCrossUserServiceIntent(
@NonNull Intent rawIntent, @NonNull String expectedPackageName,
- @UserIdInt int targetUserId) throws RemoteException {
- if (rawIntent.getComponent() == null && rawIntent.getPackage() == null) {
- Log.e(LOG_TAG, "Service intent must be explicit (with a package name or component): "
- + rawIntent);
- return null;
- }
+ @UserIdInt int targetUserId) throws RemoteException, SecurityException {
ResolveInfo info = mIPackageManager.resolveService(
rawIntent,
rawIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
0, // flags
targetUserId);
if (info == null || info.serviceInfo == null) {
- Log.e(LOG_TAG, "Fail to look up the service: " + rawIntent);
+ Log.e(LOG_TAG, "Fail to look up the service: " + rawIntent
+ + " or user " + targetUserId + " is not running");
return null;
}
if (!expectedPackageName.equals(info.serviceInfo.packageName)) {
- Log.e(LOG_TAG, "Only allow to bind service in " + expectedPackageName);
- return null;
+ throw new SecurityException("Only allow to bind service in " + expectedPackageName);
}
if (info.serviceInfo.exported) {
- Log.e(LOG_TAG, "The service must be unexported.");
- return null;
+ throw new SecurityException("The service must be unexported");
}
// It is the system server to bind the service, it would be extremely dangerous if it
// can be exploited to bind any service. Set the component explicitly to make sure we
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
new file mode 100644
index 0000000..e4a355f
--- /dev/null
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import static junit.framework.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.INotificationManager;
+import android.app.IOnNotificationChannelCreatedListener;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import java.util.concurrent.CountDownLatch;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NotificationManagerServiceTest {
+ private NotificationManagerService mNotificationManagerService;
+ private INotificationManager mBinderService;
+
+ @Before
+ public void setUp() throws Exception {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ mNotificationManagerService = new NotificationManagerService(context);
+
+ // MockPackageManager - default returns ApplicationInfo with matching calling UID
+ final IPackageManager mockPackageManager = mock(IPackageManager.class);
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.uid = Binder.getCallingUid();
+ when(mockPackageManager.getApplicationInfo(any(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ mNotificationManagerService.setPackageManager(mockPackageManager);
+
+ mNotificationManagerService.setRankingHelper(mock(RankingHelper.class));
+ mNotificationManagerService.setHandler(new Handler(context.getMainLooper()));
+
+ // Tests call directly into the Binder.
+ mBinderService = mNotificationManagerService.getBinderService();
+ }
+
+ @Test
+ public void testCreateNotificationChannel_SuccessCallsListener() throws Exception {
+ final NotificationChannel channel =
+ new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
+ final CountDownLatch latch = new CountDownLatch(1);
+ mBinderService.createNotificationChannel("test_pkg", channel,
+ new IOnNotificationChannelCreatedListener.Stub() {
+ @Override public void onNotificationChannelCreated(
+ NotificationChannel channel) {
+ latch.countDown();
+ }});
+ latch.await();
+ }
+
+ @Test
+ public void testCreateNotificationChannel_FailureDoesNotCallListener() throws Exception {
+ try {
+ mBinderService.createNotificationChannel("test_pkg", null,
+ new IOnNotificationChannelCreatedListener.Stub() {
+ @Override public void onNotificationChannelCreated(
+ NotificationChannel channel) {
+ fail("Listener was triggered from failure.");
+ }});
+ fail("Exception should be thrown immediately.");
+ } catch (NullPointerException e) {
+ // pass
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 9f01773..99af9e8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -376,6 +376,7 @@
@Override
boolean injectIsActivityEnabledAndExported(ComponentName activity, @UserIdInt int userId) {
+ assertNotNull(activity);
return mEnabledActivityChecker.test(activity, userId);
}
@@ -416,6 +417,11 @@
// During tests, WTF is fatal.
fail(message + " exception: " + th + "\n" + Log.getStackTraceString(th));
}
+
+ @Override
+ void verifyError() {
+ fail("Verify error");
+ }
}
/** ShortcutManager with injection override methods. */
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
index f773c15..1188bb7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
@@ -27,12 +27,16 @@
import android.util.ArraySet;
import com.android.internal.os.RoSystemProperties;
+import com.android.internal.util.ArrayUtils;
import com.android.server.SystemConfig;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
import static junit.framework.Assert.assertTrue;
@@ -53,27 +57,34 @@
}
/**
- * <p>This test ensures that all signature|privileged permissions are granted to core apps like
- * systemui/settings. If CONTROL_PRIVAPP_PERMISSIONS is set, the test also verifies that
+ * <p>This test ensures that all signature|privileged permissions are granted to priv-apps.
+ * If CONTROL_PRIVAPP_PERMISSIONS_ENFORCE is set, the test also verifies that
* granted permissions are whitelisted in {@link SystemConfig}
*/
@Test
@SmallTest
@Presubmit
public void testPrivAppPermissions() throws PackageManager.NameNotFoundException {
- String[] testPackages = {"com.android.settings", "com.android.shell",
- "com.android.systemui"};
- for (String testPackage : testPackages) {
- testPackagePrivAppPermission(testPackage);
+ List<PackageInfo> installedPackages = mPackageManager
+ .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
+ for (PackageInfo packageInfo : installedPackages) {
+ if (!packageInfo.applicationInfo.isPrivilegedApp()
+ || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(packageInfo.packageName)) {
+ continue;
+ }
+ testPackagePrivAppPermission(packageInfo);
}
+
}
- private void testPackagePrivAppPermission(String testPackage)
+ private void testPackagePrivAppPermission(PackageInfo packageInfo)
throws PackageManager.NameNotFoundException {
- PackageInfo packageInfo = mPackageManager.getPackageInfo(testPackage,
- PackageManager.GET_PERMISSIONS);
+ String packageName = packageInfo.packageName;
ArraySet<String> privAppPermissions = SystemConfig.getInstance()
- .getPrivAppPermissions(testPackage);
+ .getPrivAppPermissions(packageName);
+ if (ArrayUtils.isEmpty(packageInfo.requestedPermissions)) {
+ return;
+ }
for (int i = 0; i < packageInfo.requestedPermissions.length; i++) {
String pName = packageInfo.requestedPermissions[i];
int protectionLevel;
@@ -89,13 +100,14 @@
if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
boolean granted = (packageInfo.requestedPermissionsFlags[i]
& PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0;
- assertTrue("Permission " + pName + " should be granted to " + testPackage, granted);
+ assertTrue("Permission " + pName + " should be granted to " + packageName, granted);
// if privapp permissions are enforced, platform permissions must be whitelisted
// in SystemConfig
if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
assertTrue("Permission " + pName
- + " should be declared in the xml file for package "
- + testPackage,
+ + " should be declared in privapp-permissions-platform.xml "
+ + "or privapp-permissions-<product>.xml file for package "
+ + packageName,
privAppPermissions.contains(pName));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 771ca146..97bcaf0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -1292,7 +1292,43 @@
/* activity =*/ null, /* flags */ 0), getCallingUser());
});
- // TODO More tests: pinned but dynamic.
+ // Make sure floating shortcuts don't match with an activity.
+ // At this point, s1 is dynamic and pinned, so it still has a target activity.
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ assertWith(mLauncherApps.getShortcuts(buildQuery(
+ /* time =*/ 0,
+ CALLING_PACKAGE_2,
+ /* activity =*/ new ComponentName(CALLING_PACKAGE_2,
+ ShortcutActivity2.class.getName()),
+ ShortcutQuery.FLAG_GET_PINNED),
+ getCallingUser()))
+ .haveIds("s3")
+ .areAllPinned()
+ .areAllDynamic()
+ .areAllWithActivity(new ComponentName(CALLING_PACKAGE_2,
+ ShortcutActivity2.class.getName()));
+ });
+
+ // Now remove as a dynamic, making it floating.
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ mManager.removeDynamicShortcuts(list("s3"));
+ assertWith(mManager.getPinnedShortcuts())
+ .selectFloating()
+ .areAllWithNoActivity();
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ // This shouldn't match now.
+ assertWith(mLauncherApps.getShortcuts(buildQuery(
+ /* time =*/ 0,
+ CALLING_PACKAGE_2,
+ /* activity =*/ new ComponentName(CALLING_PACKAGE_2,
+ ShortcutActivity2.class.getName()),
+ ShortcutQuery.FLAG_GET_PINNED),
+ getCallingUser()))
+ .isEmpty();
+ });
+
}
public void testGetShortcuts_shortcutKinds() throws Exception {
@@ -4921,6 +4957,9 @@
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ .getPackageInfo().isShadow());
+
installPackage(USER_0, CALLING_PACKAGE_2);
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
@@ -4929,6 +4968,8 @@
mManager.getPinnedShortcuts()),
"s1", "s2", "s3");
});
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0)
+ .getPackageInfo().isShadow());
installPackage(USER_0, LAUNCHER_1);
runWithCaller(LAUNCHER_1, USER_0, () -> {
@@ -5052,6 +5093,8 @@
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
/* empty */);
});
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+ .getPackageInfo().isShadow());
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5074,6 +5117,8 @@
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
/* empty */);
});
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0)
+ .getPackageInfo().isShadow());
installPackage(USER_0, CALLING_PACKAGE_3);
runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index d25923c..7486858 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -1052,7 +1052,7 @@
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertNull(si.getActivity()); // It's now floating, so no target activity.
assertEquals(null, si.getIcon());
assertEquals("title", si.getTitle());
assertEquals("text", si.getText());
@@ -1116,7 +1116,7 @@
assertEquals(CALLING_PACKAGE_1, si.getPackage());
assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertNull(si.getActivity()); // It's now floating, so no target activity.
assertEquals(null, si.getIcon());
assertEquals(10, si.getTitleResId());
assertEquals("r10", si.getTitleResName());
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 1fe5cb7..6e74deb 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -764,6 +764,12 @@
filter(mList, ShortcutInfo::isPinned));
}
+ public ShortcutListAsserter selectFloating() {
+ return new ShortcutListAsserter(this,
+ filter(mList, (si -> si.isPinned()
+ && !(si.isDynamic() || si.isDeclaredInManifest()))));
+ }
+
public ShortcutListAsserter selectByActivity(ComponentName activity) {
return new ShortcutListAsserter(this,
ShortcutManagerTestUtils.filterByActivity(mList, activity));
@@ -895,6 +901,11 @@
return this;
}
+ public ShortcutListAsserter areAllWithNoActivity() {
+ forAllShortcuts(s -> assertNull("id=" + s.getId(), s.getActivity()));
+ return this;
+ }
+
public ShortcutListAsserter forAllShortcuts(Consumer<ShortcutInfo> sa) {
boolean found = false;
for (int i = 0; i < mList.size(); i++) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7217c3b..515370f 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -791,7 +791,7 @@
int getAppId(String packageName) {
try {
ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
+ PackageManager.MATCH_ANY_USER
| PackageManager.MATCH_DISABLED_COMPONENTS);
return ai.uid;
} catch (NameNotFoundException re) {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c99e22a..c69b7c2 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -324,6 +324,7 @@
private final PhoneAccountHandle mAccountHandle;
private final int mCallCapabilities;
private final int mCallProperties;
+ private final int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private final DisconnectCause mDisconnectCause;
private final long mConnectTimeMillis;
private final GatewayInfo mGatewayInfo;
@@ -536,6 +537,15 @@
}
/**
+ * @return a bitmask of the audio routes available for the call.
+ *
+ * @hide
+ */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
* by {@link android.telecom.DisconnectCause}.
*/
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 2b16722..f601d8b 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -44,8 +44,12 @@
*/
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 |
+ /**
+ * Bit mask of all possible audio routes.
+ *
+ * @hide
+ **/
+ public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
ROUTE_SPEAKER;
private final boolean isMuted;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 2b9a508..7d258a0 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -723,6 +723,7 @@
public void onDestroyed(Connection c) {}
public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
public void onConnectionPropertiesChanged(Connection c, int properties) {}
+ public void onSupportedAudioRoutesChanged(Connection c, int supportedAudioRoutes) {}
public void onVideoProviderChanged(
Connection c, VideoProvider videoProvider) {}
public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
@@ -1485,6 +1486,7 @@
private boolean mRingbackRequested = false;
private int mConnectionCapabilities;
private int mConnectionProperties;
+ private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private VideoProvider mVideoProvider;
private boolean mAudioModeIsVoip;
private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
@@ -1765,6 +1767,15 @@
}
/**
+ * Returns the connection's supported audio routes.
+ *
+ * @hide
+ */
+ public final int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* Sets the value of the {@link #getAddress()} property.
*
* @param address The new address.
@@ -1986,6 +1997,28 @@
}
/**
+ * Sets the supported audio routes.
+ *
+ * @param supportedAudioRoutes the supported audio routes as a bitmask.
+ * See {@link CallAudioState}
+ * @hide
+ */
+ public final void setSupportedAudioRoutes(int supportedAudioRoutes) {
+ if ((supportedAudioRoutes
+ & (CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER)) == 0) {
+ throw new IllegalArgumentException(
+ "supported audio routes must include either speaker or earpiece");
+ }
+
+ if (mSupportedAudioRoutes != supportedAudioRoutes) {
+ mSupportedAudioRoutes = supportedAudioRoutes;
+ for (Listener l : mListeners) {
+ l.onSupportedAudioRoutesChanged(this, mSupportedAudioRoutes);
+ }
+ }
+ }
+
+ /**
* Tears down the Connection object.
*/
public final void destroy() {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index c2a0ff1..b119e16 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1131,6 +1131,7 @@
connection.getState(),
connection.getConnectionCapabilities(),
connection.getConnectionProperties(),
+ connection.getSupportedAudioRoutes(),
connection.getAddress(),
connection.getAddressPresentation(),
connection.getCallerDisplayName(),
@@ -1530,6 +1531,7 @@
connection.getState(),
connection.getConnectionCapabilities(),
connection.getConnectionProperties(),
+ connection.getSupportedAudioRoutes(),
connection.getAddress(),
connection.getAddressPresentation(),
connection.getCallerDisplayName(),
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 1900cb9..a3fce9c 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -39,6 +39,7 @@
private final List<String> mCannedSmsResponses;
private final int mCapabilities;
private final int mProperties;
+ private final int mSupportedAudioRoutes;
private final long mConnectTimeMillis;
private final Uri mHandle;
private final int mHandlePresentation;
@@ -64,6 +65,7 @@
List<String> cannedSmsResponses,
int capabilities,
int properties,
+ int supportedAudioRoutes,
long connectTimeMillis,
Uri handle,
int handlePresentation,
@@ -86,6 +88,7 @@
mCannedSmsResponses = cannedSmsResponses;
mCapabilities = capabilities;
mProperties = properties;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mConnectTimeMillis = connectTimeMillis;
mHandle = handle;
mHandlePresentation = handlePresentation;
@@ -137,6 +140,11 @@
/** Bitmask of properties of the call. */
public int getProperties() { return mProperties; }
+ /** Bitmask of supported routes of the call */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
/** The time that the call switched to the active state. */
public long getConnectTimeMillis() {
return mConnectTimeMillis;
@@ -292,6 +300,7 @@
source.readList(conferenceableCallIds, classLoader);
Bundle intentExtras = source.readBundle(classLoader);
Bundle extras = source.readBundle(classLoader);
+ int supportedAudioRoutes = source.readInt();
return new ParcelableCall(
id,
state,
@@ -299,6 +308,7 @@
cannedSmsResponses,
capabilities,
properties,
+ supportedAudioRoutes,
connectTimeMillis,
handle,
handlePresentation,
@@ -355,6 +365,7 @@
destination.writeList(mConferenceableCallIds);
destination.writeBundle(mIntentExtras);
destination.writeBundle(mExtras);
+ destination.writeInt(mSupportedAudioRoutes);
}
@Override
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index 540f388..e9dba68 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -37,6 +37,7 @@
private final int mState;
private final int mConnectionCapabilities;
private final int mConnectionProperties;
+ private final int mSupportedAudioRoutes;
private final Uri mAddress;
private final int mAddressPresentation;
private final String mCallerDisplayName;
@@ -57,6 +58,7 @@
int state,
int capabilities,
int properties,
+ int supportedAudioRoutes,
Uri address,
int addressPresentation,
String callerDisplayName,
@@ -74,6 +76,7 @@
mState = state;
mConnectionCapabilities = capabilities;
mConnectionProperties = properties;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mAddress = address;
mAddressPresentation = addressPresentation;
mCallerDisplayName = callerDisplayName;
@@ -117,6 +120,10 @@
return mConnectionProperties;
}
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
public Uri getHandle() {
return mAddress;
}
@@ -210,12 +217,14 @@
source.readStringList(conferenceableConnectionIds);
Bundle extras = Bundle.setDefusable(source.readBundle(classLoader), true);
int properties = source.readInt();
+ int supportedAudioRoutes = source.readInt();
return new ParcelableConnection(
phoneAccount,
state,
capabilities,
properties,
+ supportedAudioRoutes,
address,
addressPresentation,
callerDisplayName,
@@ -264,5 +273,6 @@
destination.writeStringList(mConferenceableConnectionIds);
destination.writeBundle(mExtras);
destination.writeInt(mConnectionProperties);
+ destination.writeInt(mSupportedAudioRoutes);
}
}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 0457d63..ca54486 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -17,15 +17,6 @@
package android.telecom;
import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-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.Bundle;
@@ -37,7 +28,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.MissingResourceException;
/**
* Represents a distinct method to place or receive a phone call. Apps which can place calls and
@@ -237,6 +227,7 @@
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
+ private final int mSupportedAudioRoutes;
private final Icon mIcon;
private final Bundle mExtras;
private boolean mIsEnabled;
@@ -246,10 +237,12 @@
* Helper class for creating a {@link PhoneAccount}.
*/
public static class Builder {
+
private PhoneAccountHandle mAccountHandle;
private Uri mAddress;
private Uri mSubscriptionAddress;
private int mCapabilities;
+ private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private int mHighlightColor = NO_HIGHLIGHT_COLOR;
private CharSequence mLabel;
private CharSequence mShortDescription;
@@ -286,6 +279,7 @@
mIsEnabled = phoneAccount.isEnabled();
mExtras = phoneAccount.getExtras();
mGroupId = phoneAccount.getGroupId();
+ mSupportedAudioRoutes = phoneAccount.getSupportedAudioRoutes();
}
/**
@@ -431,6 +425,18 @@
}
/**
+ * Sets the audio routes supported by this {@link PhoneAccount}.
+ *
+ * @param routes bit mask of available routes.
+ * @return The builder.
+ * @hide
+ */
+ public Builder setSupportedAudioRoutes(int routes) {
+ mSupportedAudioRoutes = routes;
+ return this;
+ }
+
+ /**
* Creates an instance of a {@link PhoneAccount} based on the current builder settings.
*
* @return The {@link PhoneAccount}.
@@ -452,6 +458,7 @@
mShortDescription,
mSupportedUriSchemes,
mExtras,
+ mSupportedAudioRoutes,
mIsEnabled,
mGroupId);
}
@@ -468,6 +475,7 @@
CharSequence shortDescription,
List<String> supportedUriSchemes,
Bundle extras,
+ int supportedAudioRoutes,
boolean isEnabled,
String groupId) {
mAccountHandle = account;
@@ -480,6 +488,7 @@
mShortDescription = shortDescription;
mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
mExtras = extras;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mIsEnabled = isEnabled;
mGroupId = groupId;
}
@@ -553,6 +562,17 @@
}
/**
+ * Determines if this {@code PhoneAccount} has routes specified by the passed in bit mask.
+ *
+ * @param route The routes to check.
+ * @return {@code true} if the phone account has the routes.
+ * @hide
+ */
+ public boolean hasAudioRoutes(int routes) {
+ return (mSupportedAudioRoutes & routes) == routes;
+ }
+
+ /**
* A short label describing a {@code PhoneAccount}.
*
* @return A label for this {@code PhoneAccount}.
@@ -592,6 +612,15 @@
}
/**
+ * The audio routes supported by this {@code PhoneAccount}.
+ *
+ * @hide
+ */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* The icon to represent this {@code PhoneAccount}.
*
* @return The icon.
@@ -707,6 +736,7 @@
out.writeByte((byte) (mIsEnabled ? 1 : 0));
out.writeBundle(mExtras);
out.writeString(mGroupId);
+ out.writeInt(mSupportedAudioRoutes);
}
public static final Creator<PhoneAccount> CREATOR
@@ -751,6 +781,7 @@
mIsEnabled = in.readByte() == 1;
mExtras = in.readBundle();
mGroupId = in.readString();
+ mSupportedAudioRoutes = in.readInt();
}
@Override
@@ -760,7 +791,9 @@
.append("] PhoneAccount: ")
.append(mAccountHandle)
.append(" Capabilities: ")
- .append(capabilitiesToString(mCapabilities))
+ .append(capabilitiesToString())
+ .append(" Audio Routes: ")
+ .append(audioRoutesToString())
.append(" Schemes: ");
for (String scheme : mSupportedUriSchemes) {
sb.append(scheme)
@@ -780,7 +813,7 @@
* @param capabilities The capabilities bitmask.
* @return String representation of the capabilities bitmask.
*/
- private String capabilitiesToString(int capabilities) {
+ private String capabilitiesToString() {
StringBuilder sb = new StringBuilder();
if (hasCapabilities(CAPABILITY_SUPPORTS_VIDEO_CALLING)) {
sb.append("SuppVideo ");
@@ -817,4 +850,23 @@
}
return sb.toString();
}
+
+ private String audioRoutesToString() {
+ StringBuilder sb = new StringBuilder();
+
+ if (hasAudioRoutes(CallAudioState.ROUTE_BLUETOOTH)) {
+ sb.append("B");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_EARPIECE)) {
+ sb.append("E");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_SPEAKER)) {
+ sb.append("S");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_WIRED_HEADSET)) {
+ sb.append("W");
+ }
+
+ return sb.toString();
+ }
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index d6a88e8..d7f96a9 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1067,7 +1067,7 @@
* is returned.
* @hide
*/
- public static final String FILTERED_CNAP_NAMES_STRING_ARRAY = "filtered_cnap_names_string_array";
+ public static final String KEY_FILTERED_CNAP_NAMES_STRING_ARRAY = "filtered_cnap_names_string_array";
/**
* The RCS configuration server URL. This URL is used to initiate RCS provisioning.
@@ -1296,7 +1296,7 @@
sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false);
sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
- sDefaults.putStringArray(FILTERED_CNAP_NAMES_STRING_ARRAY, null);
+ sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false);
sDefaults.putBoolean(KEY_PERSIST_LPP_MODE_BOOL, false);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 11d84c1..7a83979 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -20,6 +20,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.Rlog;
+import android.text.TextUtils;
/**
* Contains phone state and service related information.
@@ -590,6 +591,24 @@
}
/**
+ * Get current registered operator name in long alphanumeric format if
+ * available or short otherwise.
+ *
+ * @see #getOperatorAlphaLong
+ * @see #getOperatorAlphaShort
+ *
+ * @return name of operator, null if unregistered or unknown
+ * @hide
+ */
+ public String getOperatorAlpha() {
+ if (TextUtils.isEmpty(mVoiceOperatorAlphaLong)) {
+ return mVoiceOperatorAlphaShort;
+ }
+
+ return mVoiceOperatorAlphaLong;
+ }
+
+ /**
* Get current registered operator numeric id.
*
* In GSM/UMTS, numeric format is 3 digit country code plus 2 or 3 digit
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 457fd88..918ef5e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2275,6 +2275,8 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* OR
* {@link android.Manifest.permission#READ_SMS}
+ * OR
+ * {@link android.Manifest.permission#READ_PHONE_NUMBER}
* <p>
* The default SMS app can also use this.
*/
@@ -2290,6 +2292,8 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* OR
* {@link android.Manifest.permission#READ_SMS}
+ * OR
+ * {@link android.Manifest.permission#READ_PHONE_NUMBER}
* <p>
* The default SMS app can also use this.
*
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index ca2d2e7..6ca59b0 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -91,7 +91,7 @@
while r in raw: raw.remove(r)
self.split = list(raw)
- for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract"]:
+ for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default"]:
while r in raw: raw.remove(r)
self.typ = raw[0]
diff --git a/tools/preload2/src/com/android/preload/Main.java b/tools/preload2/src/com/android/preload/Main.java
index 8e60105..c42a19b 100644
--- a/tools/preload2/src/com/android/preload/Main.java
+++ b/tools/preload2/src/com/android/preload/Main.java
@@ -35,6 +35,7 @@
import com.android.preload.ui.IUI;
import com.android.preload.ui.SequenceUI;
import com.android.preload.ui.SwingUI;
+
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
@@ -42,6 +43,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import javax.swing.Action;
import javax.swing.DefaultListModel;
@@ -89,6 +91,12 @@
+ "android.webkit.WebViewClassic\\$1$" + "|" + "java.lang.ProcessManager$" + "|"
+ "(.*\\$NoPreloadHolder$)";
+ public final static String SCAN_ALL_CMD = "scan-all";
+ public final static String SCAN_PACKAGE_CMD = "scan";
+ public final static String COMPUTE_FILE_CMD = "comp";
+ public final static String EXPORT_CMD = "export";
+ public final static String IMPORT_CMD = "import";
+
/**
* @param args
*/
@@ -148,13 +156,56 @@
Iterator<String> it = Arrays.asList(args).iterator();
it.next(); // --seq
-
+ // Setup
ui.choice("#" + it.next()); // Device.
ui.confirmNo(); // Prepare: no.
- ui.action(ScanPackageAction.class); // Take hprof dump.
- ui.client("system_process"); // Select system server.
- ui.action(ExportAction.class); // Export data.
- ui.output(new File("/tmp/system_server.data")); // Write to file.
+ // Actions
+ try {
+ while (it.hasNext()) {
+ String op = it.next();
+ // Operation: Scan a single package
+ if (SCAN_PACKAGE_CMD.equals(op)) {
+ System.out.println("Scanning package.");
+ ui.action(ScanPackageAction.class);
+ ui.client(it.next());
+ // Operation: Scan all packages
+ } else if (SCAN_ALL_CMD.equals(op)) {
+ System.out.println("Scanning all packages.");
+ ui.action(ScanAllPackagesAction.class);
+ // Operation: Export the output to a file
+ } else if (EXPORT_CMD.equals(op)) {
+ System.out.println("Exporting data.");
+ ui.action(ExportAction.class);
+ ui.output(new File(it.next()));
+ // Operation: Import the input from a file or directory
+ } else if (IMPORT_CMD.equals(op)) {
+ System.out.println("Importing data.");
+ File file = new File(it.next());
+ if (!file.exists()) {
+ throw new RuntimeException(
+ String.format("File does not exist, %s.", file.getAbsolutePath()));
+ } else if (file.isFile()) {
+ ui.action(ImportAction.class);
+ ui.input(file);
+ } else if (file.isDirectory()) {
+ for (File content : file.listFiles()) {
+ ui.action(ImportAction.class);
+ ui.input(content);
+ }
+ }
+ // Operation: Compute preloaded classes with specific threshold
+ } else if (COMPUTE_FILE_CMD.equals(op)) {
+ System.out.println("Compute preloaded classes.");
+ ui.action(ComputeThresholdXAction.class);
+ ui.input(it.next());
+ ui.confirmYes();
+ ui.output(new File(it.next()));
+ }
+ }
+ } catch (NoSuchElementException e) {
+ System.out.println("Failed to parse action sequence correctly.");
+ throw e;
+ }
return main;
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 24cd275..82d41e3 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -685,12 +685,22 @@
/**
* @hide
* A hint about whether or not the network represented by this WifiConfiguration
- * is metered.
+ * is metered. This is hinted at via the meteredHint bit on DHCP results set in
+ * {@link com.android.server.wifi.WifiStateMachine}, or via a network score in
+ * {@link com.android.server.wifi.ExternalScoreEvaluator}.
*/
public boolean meteredHint;
/**
* @hide
+ * Indicates if a user has specified the WifiConfiguration to be metered. Users
+ * can toggle if a network is metered within Settings -> Data Usage -> Network
+ * Restrictions.
+ */
+ public boolean meteredOverride;
+
+ /**
+ * @hide
* Setting this value will force scan results associated with this configuration to
* be included in the bucket of networks that are externally scored.
* If not set, associated scan results will be treated as legacy saved networks and
@@ -1367,6 +1377,7 @@
didSelfAdd = false;
ephemeral = false;
meteredHint = false;
+ meteredOverride = false;
useExternalScores = false;
validatedInternetAccess = false;
mIpConfiguration = new IpConfiguration();
@@ -1470,9 +1481,11 @@
if (this.validatedInternetAccess) sbuf.append(" validatedInternetAccess");
if (this.ephemeral) sbuf.append(" ephemeral");
if (this.meteredHint) sbuf.append(" meteredHint");
+ if (this.meteredOverride) sbuf.append(" meteredOverride");
if (this.useExternalScores) sbuf.append(" useExternalScores");
if (this.didSelfAdd || this.selfAdded || this.validatedInternetAccess
- || this.ephemeral || this.meteredHint || this.useExternalScores) {
+ || this.ephemeral || this.meteredHint || this.meteredOverride
+ || this.useExternalScores) {
sbuf.append("\n");
}
sbuf.append(" KeyMgmt:");
@@ -1897,6 +1910,7 @@
validatedInternetAccess = source.validatedInternetAccess;
ephemeral = source.ephemeral;
meteredHint = source.meteredHint;
+ meteredOverride = source.meteredOverride;
useExternalScores = source.useExternalScores;
if (source.visibility != null) {
visibility = new Visibility(source.visibility);
@@ -1978,6 +1992,7 @@
dest.writeInt(validatedInternetAccess ? 1 : 0);
dest.writeInt(ephemeral ? 1 : 0);
dest.writeInt(meteredHint ? 1 : 0);
+ dest.writeInt(meteredOverride ? 1 : 0);
dest.writeInt(useExternalScores ? 1 : 0);
dest.writeInt(creatorUid);
dest.writeInt(lastConnectUid);
@@ -2049,6 +2064,7 @@
config.validatedInternetAccess = in.readInt() != 0;
config.ephemeral = in.readInt() != 0;
config.meteredHint = in.readInt() != 0;
+ config.meteredOverride = in.readInt() != 0;
config.useExternalScores = in.readInt() != 0;
config.creatorUid = in.readInt();
config.lastConnectUid = in.readInt();
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
index 4aacbae..4b21b15 100644
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.java
+++ b/wifi/java/android/net/wifi/aware/ConfigRequest.java
@@ -22,7 +22,7 @@
/**
* Defines a request object to configure a Wi-Fi Aware network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using
- * {@link WifiAwareManager#attach(android.os.Handler, WifiAwareAttachCallback)}.
+ * {@link WifiAwareManager#attach(WifiAwareAttachCallback, android.os.Handler)}.
* Note that the actual achieved configuration may be different from the
* requested configuration - since different applications may request different
* configurations.
diff --git a/wifi/java/android/net/wifi/aware/LvBufferUtils.java b/wifi/java/android/net/wifi/aware/LvBufferUtils.java
deleted file mode 100644
index 3265243..0000000
--- a/wifi/java/android/net/wifi/aware/LvBufferUtils.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi.aware;
-
-import android.annotation.Nullable;
-
-import libcore.io.Memory;
-
-import java.nio.ByteOrder;
-import java.util.Iterator;
-
-/**
- * Utility class to construct and parse byte arrays using the LV format -
- * Length/Value format. The utilities accept a configuration of the size of
- * the Length field.
- *
- * @hide PROPOSED_AWARE_API
- */
-public class LvBufferUtils {
- private LvBufferUtils() {
- // no reason to ever create this class
- }
-
- /**
- * Utility class to construct byte arrays using the LV format - Length/Value.
- * <p>
- * A constructor is created specifying the size of the Length (L) field.
- * <p>
- * The byte array is either provided (using
- * {@link LvBufferUtils.LvConstructor#wrap(byte[])}) or allocated (using
- * {@link LvBufferUtils.LvConstructor#allocate(int)}).
- * <p>
- * Values are added to the structure using the {@code LvConstructor.put*()}
- * methods.
- * <p>
- * The final byte array is obtained using {@link LvBufferUtils.LvConstructor#getArray()}.
- */
- public static class LvConstructor {
- private TlvBufferUtils.TlvConstructor mTlvImpl;
-
- /**
- * Define a LV constructor with the specified size of the Length (L) field.
- *
- * @param lengthSize Number of bytes used for the Length (L) field.
- * Values of 1 or 2 bytes are allowed.
- */
- public LvConstructor(int lengthSize) {
- mTlvImpl = new TlvBufferUtils.TlvConstructor(0, lengthSize);
- }
-
- /**
- * Set the byte array to be used to construct the LV.
- *
- * @param array Byte array to be formatted.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor wrap(@Nullable byte[] array) {
- mTlvImpl.wrap(array);
- return this;
- }
-
- /**
- * Allocates a new byte array to be used ot construct a LV.
- *
- * @param capacity The size of the byte array to be allocated.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor allocate(int capacity) {
- mTlvImpl.allocate(capacity);
- return this;
- }
-
- /**
- * Copies a byte into the LV array.
- *
- * @param b The byte to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putByte(byte b) {
- mTlvImpl.putByte(0, b);
- return this;
- }
-
- /**
- * Copies a byte array into the LV.
- *
- * @param array The array to be copied into the LV structure.
- * @param offset Start copying from the array at the specified offset.
- * @param length Copy the specified number (length) of bytes from the
- * array.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putByteArray(@Nullable byte[] array, int offset,
- int length) {
- mTlvImpl.putByteArray(0, array, offset, length);
- return this;
- }
-
- /**
- * Copies a byte array into the LV.
- *
- * @param array The array to be copied (in full) into the LV structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putByteArray(int type, @Nullable byte[] array) {
- return putByteArray(array, 0, (array == null) ? 0 : array.length);
- }
-
- /**
- * Places a zero length element (i.e. Length field = 0) into the LV.
- *
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putZeroLengthElement() {
- mTlvImpl.putZeroLengthElement(0);
- return this;
- }
-
- /**
- * Copies short into the LV.
- *
- * @param data The short to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putShort(short data) {
- mTlvImpl.putShort(0, data);
- return this;
- }
-
- /**
- * Copies integer into the LV.
- *
- * @param data The integer to be inserted into the structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putInt(int data) {
- mTlvImpl.putInt(0, data);
- return this;
- }
-
- /**
- * Copies a String's byte representation into the LV.
- *
- * @param data The string whose bytes are to be inserted into the
- * structure.
- * @return The constructor to facilitate chaining
- * {@code ctr.putXXX(..).putXXX(..)}.
- */
- public LvBufferUtils.LvConstructor putString(@Nullable String data) {
- mTlvImpl.putString(0, data);
- return this;
- }
-
- /**
- * Returns the constructed LV formatted byte-array. This array is a copy of the wrapped
- * or allocated array - truncated to just the significant bytes - i.e. those written into
- * the LV.
- *
- * @return The byte array containing the LV formatted structure.
- */
- public byte[] getArray() {
- return mTlvImpl.getArray();
- }
- }
-
- /**
- * Utility class used when iterating over an LV formatted byte-array. Use
- * {@link LvBufferUtils.LvIterable} to iterate over array. A {@link LvBufferUtils.LvElement}
- * represents each entry in a LV formatted byte-array.
- */
- public static class LvElement {
- /**
- * The Length (L) field of the current LV element.
- */
- public int length;
-
- /**
- * The Value (V) field - a raw byte array representing the current LV
- * element where the entry starts at {@link LvBufferUtils.LvElement#offset}.
- */
- public byte[] refArray;
-
- /**
- * The offset to be used into {@link LvBufferUtils.LvElement#refArray} to access the
- * raw data representing the current LV element.
- */
- public int offset;
-
- private LvElement(int length, @Nullable byte[] refArray, int offset) {
- this.length = length;
- this.refArray = refArray;
- this.offset = offset;
- }
-
- /**
- * Utility function to return a byte representation of a LV element of
- * length 1. Note: an attempt to call this function on a LV item whose
- * {@link LvBufferUtils.LvElement#length} is != 1 will result in an exception.
- *
- * @return byte representation of current LV element.
- */
- public byte getByte() {
- if (length != 1) {
- throw new IllegalArgumentException(
- "Accesing a byte from a LV element of length " + length);
- }
- return refArray[offset];
- }
-
- /**
- * Utility function to return a short representation of a LV element of
- * length 2. Note: an attempt to call this function on a LV item whose
- * {@link LvBufferUtils.LvElement#length} is != 2 will result in an exception.
- *
- * @return short representation of current LV element.
- */
- public short getShort() {
- if (length != 2) {
- throw new IllegalArgumentException(
- "Accesing a short from a LV element of length " + length);
- }
- return Memory.peekShort(refArray, offset, ByteOrder.BIG_ENDIAN);
- }
-
- /**
- * Utility function to return an integer representation of a LV element
- * of length 4. Note: an attempt to call this function on a LV item
- * whose {@link LvBufferUtils.LvElement#length} is != 4 will result in an exception.
- *
- * @return integer representation of current LV element.
- */
- public int getInt() {
- if (length != 4) {
- throw new IllegalArgumentException(
- "Accesing an int from a LV element of length " + length);
- }
- return Memory.peekInt(refArray, offset, ByteOrder.BIG_ENDIAN);
- }
-
- /**
- * Utility function to return a String representation of a LV element.
- *
- * @return String representation of the current LV element.
- */
- public String getString() {
- return new String(refArray, offset, length);
- }
- }
-
- /**
- * Utility class to iterate over a LV formatted byte-array.
- */
- public static class LvIterable implements Iterable<LvBufferUtils.LvElement> {
- private final TlvBufferUtils.TlvIterable mTlvIterable;
-
- /**
- * Constructs an LvIterable object - specifying the format of the LV
- * (the size of the Length field), and the byte array whose data is to be parsed.
- *
- * @param lengthSize Number of bytes sued for the Length (L) field.
- * Values values are 1 or 2 bytes.
- * @param array The LV formatted byte-array to parse.
- */
- public LvIterable(int lengthSize, @Nullable byte[] array) {
- mTlvIterable = new TlvBufferUtils.TlvIterable(0, lengthSize, array);
- }
-
- /**
- * Prints out a parsed representation of the LV-formatted byte array.
- * Whenever possible bytes, shorts, and integer are printed out (for
- * fields whose length is 1, 2, or 4 respectively).
- */
- @Override
- public String toString() {
- return mTlvIterable.toString();
- }
-
- /**
- * Returns an iterator to step through a LV formatted byte-array. The
- * individual elements returned by the iterator are {@link LvBufferUtils.LvElement}.
- */
- @Override
- public Iterator<LvBufferUtils.LvElement> iterator() {
- return new Iterator<LvBufferUtils.LvElement>() {
- private Iterator<TlvBufferUtils.TlvElement> mTlvIterator = mTlvIterable.iterator();
-
- @Override
- public boolean hasNext() {
- return mTlvIterator.hasNext();
- }
-
- @Override
- public LvBufferUtils.LvElement next() {
- TlvBufferUtils.TlvElement tlvE = mTlvIterator.next();
-
- return new LvElement(tlvE.length, tlvE.refArray, tlvE.offset);
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- }
- }
-
- /**
- * Validates that a LV array is constructed correctly. I.e. that its specified Length
- * fields correctly fill the specified length (and do not overshoot).
- *
- * @param array The LV array to verify.
- * @param lengthSize The size (in bytes) of the length field. Valid values are 1 or 2.
- * @return A boolean indicating whether the array is valid (true) or invalid (false).
- */
- public static boolean isValid(@Nullable byte[] array, int lengthSize) {
- return TlvBufferUtils.isValid(array, 0, lengthSize);
- }
-}
diff --git a/wifi/java/android/net/wifi/aware/PublishConfig.java b/wifi/java/android/net/wifi/aware/PublishConfig.java
index ba493a0..3925bd7 100644
--- a/wifi/java/android/net/wifi/aware/PublishConfig.java
+++ b/wifi/java/android/net/wifi/aware/PublishConfig.java
@@ -28,6 +28,7 @@
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.List;
/**
* Defines the configuration of a Aware publish session. Built using
@@ -84,7 +85,8 @@
/** @hide */
public final boolean mEnableTerminateNotification;
- private PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
+ /** @hide */
+ public PublishConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int publishType, int publichCount, int ttlSec, boolean enableTerminateNotification) {
mServiceName = serviceName;
mServiceSpecificInfo = serviceSpecificInfo;
@@ -99,9 +101,9 @@
public String toString() {
return "PublishConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
- + ", mTxFilter=" + (new LvBufferUtils.LvIterable(1, mMatchFilter)).toString()
- + ", mPublishType=" + mPublishType + ", mPublishCount=" + mPublishCount
- + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
+ mMatchFilter)).toString() + ", mPublishType=" + mPublishType + ", mPublishCount="
+ + mPublishCount + ", mTtlSec=" + mTtlSec + ", mEnableTerminateNotification="
+ mEnableTerminateNotification + "]";
}
@@ -186,7 +188,7 @@
throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName);
- if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
+ if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
throw new IllegalArgumentException(
"Invalid txFilter configuration - LV fields do not match up to length");
}
@@ -281,18 +283,17 @@
* The match filter for a publish session. Used to determine whether a service
* discovery occurred - in addition to relying on the service name.
* <p>
- * Format is an LV byte array: a single byte Length field followed by L bytes (the value of
- * the Length field) of a value blob.
- * <p>
* Optional. Empty by default.
*
- * @param matchFilter The byte-array containing the LV formatted match filter.
+ * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
+ * array).
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public Builder setMatchFilter(@Nullable byte[] matchFilter) {
- mMatchFilter = matchFilter;
+ public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
+ mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
+ matchFilter).getArray();
return this;
}
diff --git a/wifi/java/android/net/wifi/aware/SubscribeConfig.java b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
index 5e14f8f..bf35445 100644
--- a/wifi/java/android/net/wifi/aware/SubscribeConfig.java
+++ b/wifi/java/android/net/wifi/aware/SubscribeConfig.java
@@ -28,6 +28,7 @@
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.List;
/**
* Defines the configuration of a Aware subscribe session. Built using
@@ -106,7 +107,8 @@
/** @hide */
public final boolean mEnableTerminateNotification;
- private SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
+ /** @hide */
+ public SubscribeConfig(byte[] serviceName, byte[] serviceSpecificInfo, byte[] matchFilter,
int subscribeType, int publichCount, int ttlSec, int matchStyle,
boolean enableTerminateNotification) {
mServiceName = serviceName;
@@ -123,10 +125,11 @@
public String toString() {
return "SubscribeConfig [mServiceName='" + mServiceName + ", mServiceSpecificInfo='" + (
(mServiceSpecificInfo == null) ? "null" : HexEncoding.encode(mServiceSpecificInfo))
- + ", mMatchFilter=" + (new LvBufferUtils.LvIterable(1, mMatchFilter)).toString()
- + ", mSubscribeType=" + mSubscribeType + ", mSubscribeCount=" + mSubscribeCount
- + ", mTtlSec=" + mTtlSec + ", mMatchType=" + mMatchStyle
- + ", mEnableTerminateNotification=" + mEnableTerminateNotification + "]";
+ + ", mMatchFilter=" + (new TlvBufferUtils.TlvIterable(0, 1,
+ mMatchFilter)).toString() + ", mSubscribeType=" + mSubscribeType
+ + ", mSubscribeCount=" + mSubscribeCount + ", mTtlSec=" + mTtlSec + ", mMatchType="
+ + mMatchStyle + ", mEnableTerminateNotification=" + mEnableTerminateNotification
+ + "]";
}
@Override
@@ -213,7 +216,7 @@
throws IllegalArgumentException {
WifiAwareUtils.validateServiceName(mServiceName);
- if (!LvBufferUtils.isValid(mMatchFilter, 1)) {
+ if (!TlvBufferUtils.isValid(mMatchFilter, 0, 1)) {
throw new IllegalArgumentException(
"Invalid matchFilter configuration - LV fields do not match up to length");
}
@@ -313,18 +316,17 @@
* The match filter for a subscribe session. Used to determine whether a service
* discovery occurred - in addition to relying on the service name.
* <p>
- * Format is an LV byte array: a single byte Length field followed by L bytes (the value of
- * the Length field) of a value blob.
- * <p>
* Optional. Empty by default.
*
- * @param matchFilter The byte-array containing the LV formatted match filter.
+ * @param matchFilter A list of match filter entries (each of which is an arbitrary byte
+ * array).
*
* @return The builder to facilitate chaining
* {@code builder.setXXX(..).setXXX(..)}.
*/
- public Builder setMatchFilter(@Nullable byte[] matchFilter) {
- mMatchFilter = matchFilter;
+ public Builder setMatchFilter(@Nullable List<byte[]> matchFilter) {
+ mMatchFilter = new TlvBufferUtils.TlvConstructor(0, 1).allocateAndPut(
+ matchFilter).getArray();
return this;
}
diff --git a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
index 56c9069..29f10e9 100644
--- a/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
+++ b/wifi/java/android/net/wifi/aware/TlvBufferUtils.java
@@ -22,8 +22,10 @@
import java.nio.BufferOverflowException;
import java.nio.ByteOrder;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import java.util.NoSuchElementException;
/**
@@ -32,7 +34,7 @@
* the Type field and the Length field. A Type field size of 0 is allowed -
* allowing usage for LV (no T) array formats.
*
- * @hide PROPOSED_AWARE_API
+ * @hide
*/
public class TlvBufferUtils {
private TlvBufferUtils() {
@@ -111,6 +113,31 @@
}
/**
+ * Creates a TLV array (of the previously specified Type and Length sizes) from the input
+ * list. Allocates an array matching the contents (and required Type and Length
+ * fields), copies the contents, and set the Length fields. The Type field is set to 0.
+ *
+ * @param list A list of fields to be added to the TLV buffer.
+ * @return The constructor of the TLV.
+ */
+ public TlvConstructor allocateAndPut(@Nullable List<byte[]> list) {
+ if (list != null) {
+ int size = 0;
+ for (byte[] field : list) {
+ size += mTypeSize + mLengthSize;
+ if (field != null) {
+ size += field.length;
+ }
+ }
+ allocate(size);
+ for (byte[] field : list) {
+ putByteArray(0, field);
+ }
+ }
+ return this;
+ }
+
+ /**
* Copies a byte into the TLV with the indicated type. For an LV
* formatted structure (i.e. typeLength=0 in {@link TlvConstructor
* TlvConstructor(int, int)} ) the type field is ignored.
@@ -319,6 +346,10 @@
this.length = length;
this.refArray = refArray;
this.offset = offset;
+
+ if (offset + length > refArray.length) {
+ throw new BufferOverflowException();
+ }
}
/**
@@ -393,7 +424,7 @@
* @param typeSize Number of bytes used for the Type (T) field. Valid
* values are 0 (i.e. indicating the format is LV rather than
* TLV), 1, and 2 bytes.
- * @param lengthSize Number of bytes sued for the Length (L) field.
+ * @param lengthSize Number of bytes used for the Length (L) field.
* Values values are 1 or 2 bytes.
* @param array The TLV formatted byte-array to parse.
*/
@@ -450,6 +481,18 @@
}
/**
+ * Returns a List with the raw contents (no types) of the iterator.
+ */
+ public List<byte[]> toList() {
+ List<byte[]> list = new ArrayList<>();
+ for (TlvElement tlv : this) {
+ list.add(Arrays.copyOfRange(tlv.refArray, tlv.offset, tlv.offset + tlv.length));
+ }
+
+ return list;
+ }
+
+ /**
* Returns an iterator to step through a TLV formatted byte-array. The
* individual elements returned by the iterator are {@link TlvElement}.
*/
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
index 072ccab..95d128d 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareCharacteristics.java
@@ -69,8 +69,9 @@
/**
* Returns the maximum length of byte array that can be used to specify a Aware match filter.
- * Restricts the parameters of the {@link PublishConfig.Builder#setMatchFilter(byte[])} and
- * {@link SubscribeConfig.Builder#setMatchFilter(byte[])}.
+ * Restricts the parameters of the
+ * {@link PublishConfig.Builder#setMatchFilter(java.util.List<byte[]>)} and
+ * {@link SubscribeConfig.Builder#setMatchFilter(java.util.List<byte[]>)}.
*
* @return A positive integer, maximum legngth of byte array for Aware discovery match filter.
*/
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
index 01e77da..451d8a5 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoveryBaseSession.java
@@ -140,7 +140,7 @@
* Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} event.
+ * byte[], java.util.List<byte[]>)} event.
* <p>
* Aware messages are not guaranteed delivery. Callbacks on
* {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
@@ -154,7 +154,7 @@
*
* @param peerHandle The peer's handle for the message. Must be a result of an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} or
+ * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same
@@ -187,7 +187,7 @@
* Sends a message to the specified destination. Aware messages are transmitted in the context
* of a discovery session - executed subsequent to a publish/subscribe
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} event.
+ * byte[], java.util.List<byte[]>)} event.
* <p>
* Aware messages are not guaranteed delivery. Callbacks on
* {@link WifiAwareDiscoverySessionCallback} indicate message was transmitted successfully,
@@ -203,7 +203,7 @@
*
* @param peerHandle The peer's handle for the message. Must be a result of an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} or
+ * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} events.
* @param messageId An arbitrary integer used by the caller to identify the message. The same
@@ -220,7 +220,7 @@
/**
* Start a ranging operation with the specified peers. The peer IDs are obtained from an
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} or
+ * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])} operation - can
* only range devices which are part of an ongoing discovery session.
@@ -266,7 +266,7 @@
*
* @param peerHandle The peer's handle obtained through
* {@link WifiAwareDiscoverySessionCallback#onServiceDiscovered(WifiAwareManager.PeerHandle,
- * byte[], byte[])} or
+ * byte[], java.util.List<byte[]>)} or
* {@link WifiAwareDiscoverySessionCallback#onMessageReceived(WifiAwareManager.PeerHandle,
* byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
* from only that peer. A RESPONDER may specified a null - indicating that
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
index 6331c9c..fdf0d01 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareDiscoverySessionCallback.java
@@ -21,6 +21,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
/**
* Base class for Aware session events callbacks. Should be extended by
@@ -130,11 +131,10 @@
* @param serviceSpecificInfo The service specific information (arbitrary
* byte array) provided by the peer as part of its discovery
* configuration.
- * @param matchFilter The filter (Tx on advertiser and Rx on listener) which
- * resulted in this service discovery.
+ * @param matchFilter The filter which resulted in this service discovery.
*/
public void onServiceDiscovered(WifiAwareManager.PeerHandle peerHandle,
- byte[] serviceSpecificInfo, byte[] matchFilter) {
+ byte[] serviceSpecificInfo, List<byte[]> matchFilter) {
/* empty */
}
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index cc24704..029794d 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -45,7 +45,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
+import java.nio.BufferOverflowException;
import java.util.Arrays;
+import java.util.List;
/**
* This class provides the primary API for managing Wi-Fi Aware operations:
@@ -874,12 +876,22 @@
case CALLBACK_SESSION_TERMINATED:
onProxySessionTerminated(msg.arg1);
break;
- case CALLBACK_MATCH:
- mOriginalCallback.onServiceDiscovered(
- new PeerHandle(msg.arg1),
+ case CALLBACK_MATCH: {
+ List<byte[]> matchFilter = null;
+ byte[] arg = msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2);
+ try {
+ matchFilter = new TlvBufferUtils.TlvIterable(0, 1, arg).toList();
+ } catch (BufferOverflowException e) {
+ matchFilter = null;
+ Log.e(TAG, "onServiceDiscovered: invalid match filter byte array '"
+ + new String(HexEncoding.encode(arg))
+ + "' - cannot be parsed: e=" + e);
+ }
+ mOriginalCallback.onServiceDiscovered(new PeerHandle(msg.arg1),
msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE),
- msg.getData().getByteArray(MESSAGE_BUNDLE_KEY_MESSAGE2));
+ matchFilter);
break;
+ }
case CALLBACK_MESSAGE_SEND_SUCCESS:
mOriginalCallback.onMessageSendSucceeded(msg.arg1);
break;
@@ -966,7 +978,7 @@
@Override
public void onMessageReceived(int peerId, byte[] message) {
if (VDBG) {
- Log.v(TAG, "onMessageReceived: peerId='" + peerId);
+ Log.v(TAG, "onMessageReceived: peerId=" + peerId);
}
Message msg = mHandler.obtainMessage(CALLBACK_MESSAGE_RECEIVED);
diff --git a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
index 4b6957b..15641ab 100644
--- a/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/TlvBufferUtilsTest.java
@@ -24,6 +24,10 @@
import org.junit.Test;
import org.junit.rules.ErrorCollector;
+import java.nio.BufferOverflowException;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Unit test harness for TlvBufferUtils class.
*/
@@ -47,9 +51,9 @@
collector.checkThat("tlv11-correct-construction",
tlv11.getArray(), equalTo(new byte[]{0, 1, 2, 2, 3, 0, 1, 2}));
- LvBufferUtils.LvConstructor tlv01 = new LvBufferUtils.LvConstructor(1);
+ TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
tlv01.allocate(15);
- tlv01.putByte((byte) 2);
+ tlv01.putByte(0, (byte) 2);
tlv01.putByteArray(2, new byte[] {
0, 1, 2 });
@@ -60,10 +64,63 @@
TlvBufferUtils.isValid(tlv11.getArray(), 1, 1),
equalTo(true));
collector.checkThat("tlv01-valid",
- LvBufferUtils.isValid(tlv01.getArray(), 1),
+ TlvBufferUtils.isValid(tlv01.getArray(), 0, 1),
equalTo(true));
}
+ /**
+ * Verify that can build a valid TLV from a List of byte[].
+ */
+ @Test
+ public void testTlvListOperations() {
+ byte[] entry1 = { 1, 2, 3 };
+ byte[] entry2 = { 4, 5 };
+ byte[] entry3 = new byte[0];
+ List<byte[]> data = new ArrayList<>();
+ data.add(entry1);
+ data.add(entry2);
+ data.add(entry3);
+ data.add(null); // zero-length should work
+
+ TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
+ tlv01.allocateAndPut(data);
+ byte[] tlvData = tlv01.getArray();
+ List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, tlvData).toList();
+
+ collector.checkThat("tlvData-correct-length", tlvData.length,
+ equalTo(entry1.length + 1 + entry2.length + 1 + entry3.length + 1 + 1));
+ collector.checkThat("parsedList-correct-length", parsedList.size(), equalTo(4));
+ collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(entry1));
+ collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(entry2));
+ collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(entry3));
+ collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
+ }
+
+ /**
+ * Verify that can parse a (correctly formatted) byte array to a list.
+ */
+ @Test
+ public void testTlvParseToList() {
+ byte[] validTlv01 = { 0, 1, 55, 2, 33, 66, 0 };
+
+ List<byte[]> parsedList = new TlvBufferUtils.TlvIterable(0, 1, validTlv01).toList();
+
+ collector.checkThat("parsedList-entry1", parsedList.get(0), equalTo(new byte[0]));
+ collector.checkThat("parsedList-entry2", parsedList.get(1), equalTo(new byte[] { 55 }));
+ collector.checkThat("parsedList-entry3", parsedList.get(2), equalTo(new byte[] { 33, 66 }));
+ collector.checkThat("parsedList-entry4", parsedList.get(3), equalTo(new byte[0]));
+ }
+
+ /**
+ * Verify that an exception is thrown when trying to parse an invalid array.
+ */
+ @Test(expected = BufferOverflowException.class)
+ public void testTlvParseToListError() {
+ byte[] invalidTlv01 = { 0, 1, 55, 2, 55, 66, 3 }; // bad data
+
+ List<byte[]> data = new TlvBufferUtils.TlvIterable(0, 1, invalidTlv01).toList();
+ }
+
@Test
public void testTlvIterate() {
final String ascii = "ABC";
@@ -137,7 +194,7 @@
TlvBufferUtils.isValid(tlv22.getArray(), 2, 2),
equalTo(true));
collector.checkThat("tlv02-valid",
- LvBufferUtils.isValid(tlv02.getArray(), 2),
+ TlvBufferUtils.isValid(tlv02.getArray(), 0, 2),
equalTo(true));
}
@@ -211,15 +268,15 @@
*/
@Test
public void testTlvInvalidByteArray() {
- LvBufferUtils.LvConstructor tlv01 = new LvBufferUtils.LvConstructor(1);
+ TlvBufferUtils.TlvConstructor tlv01 = new TlvBufferUtils.TlvConstructor(0, 1);
tlv01.allocate(15);
- tlv01.putByte((byte) 2);
+ tlv01.putByte(0, (byte) 2);
tlv01.putByteArray(2, new byte[]{0, 1, 2});
byte[] array = tlv01.getArray();
array[0] = 10;
collector.checkThat("tlv01-invalid",
- LvBufferUtils.isValid(array, 1), equalTo(false));
+ TlvBufferUtils.isValid(array, 0, 1), equalTo(false));
}
}
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index e161310..24c0127 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -49,6 +49,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.List;
+
/**
* Unit test harness for WifiAwareManager class.
*/
@@ -276,7 +278,7 @@
final PublishConfig publishConfig = new PublishConfig.Builder().build();
final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
final String string1 = "hey from here...";
- final String string2 = "some other arbitrary string...";
+ final byte[] matchFilter = { 1, 12, 2, 31, 32 };
final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR;
@@ -292,6 +294,8 @@
.forClass(WifiAwarePublishDiscoverySession.class);
ArgumentCaptor<WifiAwareManager.PeerHandle> peerIdCaptor = ArgumentCaptor.forClass(
WifiAwareManager.PeerHandle.class);
+ ArgumentCaptor<List<byte[]>> matchFilterCaptor = ArgumentCaptor.forClass(
+ (Class) List.class);
// (0) connect + success
mDut.attach(mMockLooperHandler, configRequest, mockCallback, null);
@@ -314,8 +318,7 @@
// (3) ...
publishSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
- sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(),
- string2.getBytes());
+ sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -324,13 +327,22 @@
inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
- eq(string1.getBytes()), eq(string2.getBytes()));
- assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId,
- peerHandle.peerId);
+ eq(string1.getBytes()),
+ matchFilterCaptor.capture());
+
+ // note: need to capture/compare elements since the Mockito eq() is a shallow comparator
+ List<byte[]> parsedMatchFilter = new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList();
+ collector.checkThat("match-filter-size", parsedMatchFilter.size(),
+ equalTo(matchFilterCaptor.getValue().size()));
+ collector.checkThat("match-filter-entry0", parsedMatchFilter.get(0),
+ equalTo(matchFilterCaptor.getValue().get(0)));
+ collector.checkThat("match-filter-entry1", parsedMatchFilter.get(1),
+ equalTo(matchFilterCaptor.getValue().get(1)));
+
+ assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
eq(string1.getBytes()));
- assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId,
- peerHandle.peerId);
+ assertEquals(peerIdCaptor.getValue().peerId, peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
@@ -418,7 +430,7 @@
final SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().build();
final WifiAwareManager.PeerHandle peerHandle = new WifiAwareManager.PeerHandle(873);
final String string1 = "hey from here...";
- final String string2 = "some other arbitrary string...";
+ final byte[] matchFilter = { 1, 12, 3, 31, 32 }; // bad data!
final int messageId = 2123;
final int reason = AWARE_STATUS_ERROR;
@@ -456,8 +468,7 @@
// (3) ...
subscribeSession.getValue().sendMessage(peerHandle, messageId, string1.getBytes());
- sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(),
- string2.getBytes());
+ sessionProxyCallback.getValue().onMatch(peerHandle.peerId, string1.getBytes(), matchFilter);
sessionProxyCallback.getValue().onMessageReceived(peerHandle.peerId, string1.getBytes());
sessionProxyCallback.getValue().onMessageSendFail(messageId, reason);
sessionProxyCallback.getValue().onMessageSendSuccess(messageId);
@@ -466,13 +477,11 @@
inOrder.verify(mockAwareService).sendMessage(eq(clientId), eq(sessionId),
eq(peerHandle.peerId), eq(string1.getBytes()), eq(messageId), eq(0));
inOrder.verify(mockSessionCallback).onServiceDiscovered(peerIdCaptor.capture(),
- eq(string1.getBytes()), eq(string2.getBytes()));
- assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId,
- peerHandle.peerId);
+ eq(string1.getBytes()), (List<byte[]>) isNull());
+ assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageReceived(peerIdCaptor.capture(),
eq(string1.getBytes()));
- assertEquals(((WifiAwareManager.PeerHandle) peerIdCaptor.getValue()).peerId,
- peerHandle.peerId);
+ assertEquals((peerIdCaptor.getValue()).peerId, peerHandle.peerId);
inOrder.verify(mockSessionCallback).onMessageSendFailed(eq(messageId));
inOrder.verify(mockSessionCallback).onMessageSendSucceeded(eq(messageId));
@@ -676,8 +685,7 @@
public void testSubscribeConfigBuilder() {
final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = {
- 0, 1, 16, 1, 22 };
+ final byte[] matchFilter = { 1, 16, 1, 22 };
final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
final int subscribeCount = 10;
final int subscribeTtl = 15;
@@ -685,7 +693,8 @@
final boolean enableTerminateNotification = false;
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType)
.setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -709,8 +718,7 @@
public void testSubscribeConfigParcel() {
final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = {
- 0, 1, 16, 1, 22 };
+ final byte[] matchFilter = { 1, 16, 1, 22 };
final int subscribeType = SubscribeConfig.SUBSCRIBE_TYPE_PASSIVE;
final int subscribeCount = 10;
final int subscribeTtl = 15;
@@ -718,7 +726,8 @@
final boolean enableTerminateNotification = true;
SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setSubscribeType(subscribeType)
.setSubscribeCount(subscribeCount).setTtlSec(subscribeTtl).setMatchStyle(matchStyle)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -780,15 +789,15 @@
public void testPublishConfigBuilder() {
final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = {
- 0, 1, 16, 1, 22 };
+ final byte[] matchFilter = { 1, 16, 1, 22 };
final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
final int publishCount = 10;
final int publishTtl = 15;
final boolean enableTerminateNotification = false;
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType)
.setPublishCount(publishCount).setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build();
@@ -809,15 +818,15 @@
public void testPublishConfigParcel() {
final String serviceName = "some_service_or_other";
final String serviceSpecificInfo = "long arbitrary string with some info";
- final byte[] matchFilter = {
- 0, 1, 16, 1, 22 };
+ final byte[] matchFilter = { 1, 16, 1, 22 };
final int publishType = PublishConfig.PUBLISH_TYPE_SOLICITED;
final int publishCount = 10;
final int publishTtl = 15;
final boolean enableTerminateNotification = false;
PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(serviceName)
- .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(matchFilter)
+ .setServiceSpecificInfo(serviceSpecificInfo.getBytes()).setMatchFilter(
+ new TlvBufferUtils.TlvIterable(0, 1, matchFilter).toList())
.setPublishType(publishType)
.setPublishCount(publishCount).setTtlSec(publishTtl)
.setTerminateNotificationEnabled(enableTerminateNotification).build();