Merge "MediaPlayer2: directly pass AudioAttributes to AudioTrack without native parcel conversion"
diff --git a/Android.bp b/Android.bp
index 93e6963..abeeb43 100644
--- a/Android.bp
+++ b/Android.bp
@@ -393,6 +393,9 @@
"core/java/com/android/internal/backup/IObbBackupService.aidl",
"core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl",
"core/java/com/android/internal/inputmethod/IInputMethodPrivilegedOperations.aidl",
+ "core/java/com/android/internal/inputmethod/IMultiClientInputMethod.aidl",
+ "core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl",
+ "core/java/com/android/internal/inputmethod/IMultiClientInputMethodSession.aidl",
"core/java/com/android/internal/net/INetworkWatchlistManager.aidl",
"core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl",
"core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl",
@@ -567,7 +570,6 @@
"telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
"telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
"telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
- "telephony/java/com/android/internal/telephony/IRcs.aidl",
"telephony/java/com/android/internal/telephony/ISms.aidl",
"telephony/java/com/android/internal/telephony/ISub.aidl",
"telephony/java/com/android/internal/telephony/IAns.aidl",
@@ -598,6 +600,7 @@
"telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl",
+ "telephony/java/com/android/internal/telephony/rcs/IRcs.aidl",
"wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl",
"wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl",
"wifi/java/android/net/wifi/ISoftApCallback.aidl",
@@ -1196,6 +1199,7 @@
":openjdk_javadoc_files",
":non_openjdk_javadoc_files",
":android_icu4j_src_files_for_docs",
+ ":conscrypt_public_api_files",
"test-mock/src/**/*.java",
"test-runner/src/**/*.java",
],
@@ -1256,6 +1260,7 @@
":openjdk_javadoc_files",
":non_openjdk_javadoc_files",
":android_icu4j_src_files_for_docs",
+ ":conscrypt_public_api_files",
],
srcs_lib: "framework",
srcs_lib_whitelist_dirs: frameworks_base_subdirs,
diff --git a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
index 434b8e5..bd91112 100644
--- a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
@@ -343,13 +343,14 @@
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final RecordingCanvas c = node.start(
+ final RecordingCanvas c = node.startRecording(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
state.resumeTiming();
textView.onDraw(c);
+ node.endRecording();
}
}
@@ -369,13 +370,14 @@
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final RecordingCanvas c = node.start(
+ final RecordingCanvas c = node.startRecording(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
state.resumeTiming();
textView.onDraw(c);
+ node.endRecording();
}
}
@@ -397,13 +399,14 @@
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final RecordingCanvas c = node.start(
+ final RecordingCanvas c = node.startRecording(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
state.resumeTiming();
textView.onDraw(c);
+ node.endRecording();
}
}
@@ -426,13 +429,14 @@
textView.setText(text);
textView.measure(width, height);
textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
- final RecordingCanvas c = node.start(
+ final RecordingCanvas c = node.startRecording(
textView.getMeasuredWidth(), textView.getMeasuredHeight());
textView.nullLayouts();
Canvas.freeTextLayoutCaches();
state.resumeTiming();
textView.onDraw(c);
+ node.endRecording();
}
}
}
diff --git a/api/current.txt b/api/current.txt
index a5724fe..f736f12 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -1845,6 +1845,10 @@
field public static final int accessibilityActionContextClick = 16908348; // 0x102003c
field public static final int accessibilityActionHideTooltip = 16908357; // 0x1020045
field public static final int accessibilityActionMoveWindow = 16908354; // 0x1020042
+ field public static final int accessibilityActionPageDown = 16908359; // 0x1020047
+ field public static final int accessibilityActionPageLeft = 16908360; // 0x1020048
+ field public static final int accessibilityActionPageRight = 16908361; // 0x1020049
+ field public static final int accessibilityActionPageUp = 16908358; // 0x1020046
field public static final int accessibilityActionScrollDown = 16908346; // 0x102003a
field public static final int accessibilityActionScrollLeft = 16908345; // 0x1020039
field public static final int accessibilityActionScrollRight = 16908347; // 0x102003b
@@ -6184,6 +6188,7 @@
public final class UiAutomation {
method public void adoptShellPermissionIdentity();
+ method public void adoptShellPermissionIdentity(java.lang.String...);
method public void clearWindowAnimationFrameStats();
method public boolean clearWindowContentFrameStats(int);
method public void dropShellPermissionIdentity();
@@ -14624,9 +14629,9 @@
method public final boolean next(android.graphics.Rect);
}
- public class RenderNode {
+ public final class RenderNode {
+ ctor public RenderNode(java.lang.String);
method public int computeApproximateMemoryUsage();
- method public static android.graphics.RenderNode create(java.lang.String);
method public void discardDisplayList();
method public void endRecording();
method public float getAlpha();
@@ -16623,6 +16628,8 @@
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR = 3; // 0x3
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG = 2; // 0x2
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG = 1; // 0x1
+ field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5; // 0x5
+ field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6; // 0x6
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4; // 0x4
field public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB = 0; // 0x0
field public static final int SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME = 1; // 0x1
@@ -20707,6 +20714,51 @@
enum_constant public static final android.icu.text.TimeZoneNames.NameType SHORT_STANDARD;
}
+ public abstract class Transliterator {
+ method public static final android.icu.text.Transliterator createFromRules(java.lang.String, java.lang.String, int);
+ method public void filteredTransliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, boolean);
+ method public final void finishTransliteration(android.icu.text.Replaceable, android.icu.text.Transliterator.Position);
+ method public static final java.util.Enumeration<java.lang.String> getAvailableIDs();
+ method public static final java.util.Enumeration<java.lang.String> getAvailableSources();
+ method public static final java.util.Enumeration<java.lang.String> getAvailableTargets(java.lang.String);
+ method public static final java.util.Enumeration<java.lang.String> getAvailableVariants(java.lang.String, java.lang.String);
+ method public static final java.lang.String getDisplayName(java.lang.String);
+ method public static java.lang.String getDisplayName(java.lang.String, java.util.Locale);
+ method public static java.lang.String getDisplayName(java.lang.String, android.icu.util.ULocale);
+ method public android.icu.text.Transliterator[] getElements();
+ method public final android.icu.text.UnicodeFilter getFilter();
+ method public final java.lang.String getID();
+ method public static final android.icu.text.Transliterator getInstance(java.lang.String);
+ method public static android.icu.text.Transliterator getInstance(java.lang.String, int);
+ method public final android.icu.text.Transliterator getInverse();
+ method public final int getMaximumContextLength();
+ method public final android.icu.text.UnicodeSet getSourceSet();
+ method public android.icu.text.UnicodeSet getTargetSet();
+ method public void setFilter(android.icu.text.UnicodeFilter);
+ method public java.lang.String toRules(boolean);
+ method public final int transliterate(android.icu.text.Replaceable, int, int);
+ method public final void transliterate(android.icu.text.Replaceable);
+ method public final java.lang.String transliterate(java.lang.String);
+ method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, java.lang.String);
+ method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, int);
+ method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position);
+ field public static final int FORWARD = 0; // 0x0
+ field public static final int REVERSE = 1; // 0x1
+ }
+
+ public static class Transliterator.Position {
+ ctor public Transliterator.Position();
+ ctor public Transliterator.Position(int, int, int);
+ ctor public Transliterator.Position(int, int, int, int);
+ ctor public Transliterator.Position(android.icu.text.Transliterator.Position);
+ method public void set(android.icu.text.Transliterator.Position);
+ method public final void validate(int);
+ field public int contextLimit;
+ field public int contextStart;
+ field public int limit;
+ field public int start;
+ }
+
public abstract class UCharacterIterator implements java.lang.Cloneable {
ctor protected UCharacterIterator();
method public java.lang.Object clone() throws java.lang.CloneNotSupportedException;
@@ -24203,6 +24255,8 @@
method public static int getMaxSecurityLevel();
method public int getMaxSessionCount();
method public android.os.PersistableBundle getMetrics();
+ method public java.util.List<byte[]> getOfflineLicenseKeySetIds();
+ method public int getOfflineLicenseState(byte[]);
method public int getOpenSessionCount();
method public byte[] getPropertyByteArray(java.lang.String);
method public java.lang.String getPropertyString(java.lang.String);
@@ -24223,6 +24277,7 @@
method public void releaseSecureStops(byte[]);
method public void removeAllSecureStops();
method public void removeKeys(byte[]);
+ method public void removeOfflineLicense(byte[]);
method public void removeSecureStop(byte[]);
method public void restoreKeys(byte[], byte[]);
method public void setOnEventListener(android.media.MediaDrm.OnEventListener);
@@ -24245,6 +24300,9 @@
field public static final int KEY_TYPE_OFFLINE = 2; // 0x2
field public static final int KEY_TYPE_RELEASE = 3; // 0x3
field public static final int KEY_TYPE_STREAMING = 1; // 0x1
+ field public static final int OFFLINE_LICENSE_INACTIVE = 2; // 0x2
+ field public static final int OFFLINE_LICENSE_STATE_UNKNOWN = 0; // 0x0
+ field public static final int OFFLINE_LICENSE_USABLE = 1; // 0x1
field public static final java.lang.String PROPERTY_ALGORITHMS = "algorithms";
field public static final java.lang.String PROPERTY_DESCRIPTION = "description";
field public static final java.lang.String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
@@ -28687,6 +28745,20 @@
}
+package android.net.ssl {
+
+ public class SSLEngines {
+ method public static boolean isSupportedEngine(javax.net.ssl.SSLEngine);
+ method public static void setUseSessionTickets(javax.net.ssl.SSLEngine, boolean);
+ }
+
+ public class SSLSockets {
+ method public static boolean isSupportedSocket(javax.net.ssl.SSLSocket);
+ method public static void setUseSessionTickets(javax.net.ssl.SSLSocket, boolean);
+ }
+
+}
+
package android.net.wifi {
public class ScanResult implements android.os.Parcelable {
@@ -43035,6 +43107,7 @@
method public int getLevel();
method public int getRsrp();
method public int getRsrq();
+ method public int getRssi();
method public int getRssnr();
method public int getTimingAdvance();
method public void writeToParcel(android.os.Parcel, int);
@@ -47843,6 +47916,7 @@
field public static final int KEYCODE_PLUS = 81; // 0x51
field public static final int KEYCODE_POUND = 18; // 0x12
field public static final int KEYCODE_POWER = 26; // 0x1a
+ field public static final int KEYCODE_PROFILE_SWITCH = 288; // 0x120
field public static final int KEYCODE_PROG_BLUE = 186; // 0xba
field public static final int KEYCODE_PROG_GREEN = 184; // 0xb8
field public static final int KEYCODE_PROG_RED = 183; // 0xb7
@@ -47881,6 +47955,8 @@
field public static final int KEYCODE_SYSTEM_NAVIGATION_UP = 280; // 0x118
field public static final int KEYCODE_T = 48; // 0x30
field public static final int KEYCODE_TAB = 61; // 0x3d
+ field public static final int KEYCODE_THUMBS_DOWN = 287; // 0x11f
+ field public static final int KEYCODE_THUMBS_UP = 286; // 0x11e
field public static final int KEYCODE_TV = 170; // 0xaa
field public static final int KEYCODE_TV_ANTENNA_CABLE = 242; // 0xf2
field public static final int KEYCODE_TV_AUDIO_DESCRIPTION = 252; // 0xfc
@@ -50749,6 +50825,10 @@
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_MOVE_WINDOW;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_AT_MOVEMENT_GRANULARITY;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_NEXT_HTML_ELEMENT;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PAGE_DOWN;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PAGE_LEFT;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PAGE_RIGHT;
+ field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PAGE_UP;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PASTE;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY;
field public static final android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction ACTION_PREVIOUS_HTML_ELEMENT;
@@ -52020,6 +52100,7 @@
public final class TextLinks implements android.os.Parcelable {
method public int apply(android.text.Spannable, int, java.util.function.Function<android.view.textclassifier.TextLinks.TextLink, android.view.textclassifier.TextLinks.TextLinkSpan>);
method public int describeContents();
+ method public android.os.Bundle getExtras();
method public java.util.Collection<android.view.textclassifier.TextLinks.TextLink> getLinks();
method public void writeToParcel(android.os.Parcel, int);
field public static final int APPLY_STRATEGY_IGNORE = 0; // 0x0
@@ -52036,12 +52117,14 @@
method public android.view.textclassifier.TextLinks.Builder addLink(int, int, java.util.Map<java.lang.String, java.lang.Float>);
method public android.view.textclassifier.TextLinks build();
method public android.view.textclassifier.TextLinks.Builder clearTextLinks();
+ method public android.view.textclassifier.TextLinks.Builder setExtras(android.os.Bundle);
}
public static final class TextLinks.Request implements android.os.Parcelable {
method public int describeContents();
method public android.os.LocaleList getDefaultLocales();
method public android.view.textclassifier.TextClassifier.EntityConfig getEntityConfig();
+ method public android.os.Bundle getExtras();
method public java.lang.CharSequence getText();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextLinks.Request> CREATOR;
@@ -52052,6 +52135,7 @@
method public android.view.textclassifier.TextLinks.Request build();
method public android.view.textclassifier.TextLinks.Request.Builder setDefaultLocales(android.os.LocaleList);
method public android.view.textclassifier.TextLinks.Request.Builder setEntityConfig(android.view.textclassifier.TextClassifier.EntityConfig);
+ method public android.view.textclassifier.TextLinks.Request.Builder setExtras(android.os.Bundle);
}
public static final class TextLinks.TextLink implements android.os.Parcelable {
@@ -52076,6 +52160,7 @@
method public float getConfidenceScore(java.lang.String);
method public java.lang.String getEntity(int);
method public int getEntityCount();
+ method public android.os.Bundle getExtras();
method public java.lang.String getId();
method public int getSelectionEndIndex();
method public int getSelectionStartIndex();
@@ -52087,6 +52172,7 @@
ctor public TextSelection.Builder(int, int);
method public android.view.textclassifier.TextSelection build();
method public android.view.textclassifier.TextSelection.Builder setEntityType(java.lang.String, float);
+ method public android.view.textclassifier.TextSelection.Builder setExtras(android.os.Bundle);
method public android.view.textclassifier.TextSelection.Builder setId(java.lang.String);
}
@@ -52094,6 +52180,7 @@
method public int describeContents();
method public android.os.LocaleList getDefaultLocales();
method public int getEndIndex();
+ method public android.os.Bundle getExtras();
method public int getStartIndex();
method public java.lang.CharSequence getText();
method public void writeToParcel(android.os.Parcel, int);
@@ -52104,6 +52191,7 @@
ctor public TextSelection.Request.Builder(java.lang.CharSequence, int, int);
method public android.view.textclassifier.TextSelection.Request build();
method public android.view.textclassifier.TextSelection.Request.Builder setDefaultLocales(android.os.LocaleList);
+ method public android.view.textclassifier.TextSelection.Request.Builder setExtras(android.os.Bundle);
}
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 237d4c4..e0c58b4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1088,6 +1088,7 @@
field public static final java.lang.String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
field public static final java.lang.String EXTRA_UNKNOWN_INSTANT_APP = "android.intent.extra.UNKNOWN_INSTANT_APP";
field public static final java.lang.String EXTRA_VERIFICATION_BUNDLE = "android.intent.extra.VERIFICATION_BUNDLE";
+ field public static final java.lang.String METADATA_SETUP_VERSION = "android.SETUP_VERSION";
}
public class IntentFilter implements android.os.Parcelable {
@@ -5475,6 +5476,7 @@
method public int getDomain();
method public int getRegState();
method public int getRejectCause();
+ method public int getRoamingType();
method public int getTransportType();
method public boolean isEmergencyEnabled();
method public boolean isRoaming();
@@ -5522,7 +5524,9 @@
public class PhoneStateListener {
method public void onRadioPowerStateChanged(int);
+ method public void onSrvccStateChanged(int);
field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
+ field public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
}
public class ServiceState implements android.os.Parcelable {
@@ -5532,6 +5536,10 @@
method public deprecated android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int);
method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int);
method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int);
+ field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
+ field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
+ field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
+ field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
}
public final class SmsManager {
@@ -5755,6 +5763,11 @@
field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0
field public static final int SIM_STATE_LOADED = 10; // 0xa
field public static final int SIM_STATE_PRESENT = 11; // 0xb
+ field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3
+ field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1
+ field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2
+ field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff
+ field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0
}
public final class UiccAccessRule implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index b2cf4c8..6213b17 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -25,6 +25,10 @@
package android.app {
+ public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ method public void onMovedToDisplay(int, android.content.res.Configuration);
+ }
+
public class ActivityManager {
method public void addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int);
method public void alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName);
@@ -710,6 +714,7 @@
public class Environment {
method public static java.io.File buildPath(java.io.File, java.lang.String...);
+ method public static java.io.File getProductDirectory();
method public static java.io.File getStorageDirectory();
}
@@ -1591,7 +1596,8 @@
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable {
method public static java.lang.String actionToString(int);
- field public static final int LAST_KEYCODE = 285; // 0x11d
+ method public final void setDisplayId(int);
+ field public static final int LAST_KEYCODE = 288; // 0x120
}
public final class KeyboardShortcutGroup implements android.os.Parcelable {
@@ -1636,6 +1642,12 @@
method public boolean unregisterFrameCommitCallback(java.lang.Runnable);
}
+ public abstract interface WindowManager implements android.view.ViewManager {
+ method public abstract void setShouldShowIme(int, boolean);
+ method public abstract void setShouldShowWithInsecureKeyguard(int, boolean);
+ method public abstract void setShouldShowSystemDecors(int, boolean);
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 33c274e..00c49e3 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -138,7 +138,8 @@
std::stringstream stream;
for (auto iter = interesting_apks.cbegin(); iter != interesting_apks.cend(); ++iter) {
const std::string idmap_path = Idmap::CanonicalIdmapPathFor(output_directory, *iter);
- if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}), out_error) &&
+ std::stringstream dev_null;
+ if (!Verify(std::vector<std::string>({"--idmap-path", idmap_path}), dev_null) &&
!Create(std::vector<std::string>({
"--target-apk-path",
target_apk_path,
diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java
index 09343f1..c6d717a 100644
--- a/cmds/sm/src/com/android/commands/sm/Sm.java
+++ b/cmds/sm/src/com/android/commands/sm/Sm.java
@@ -101,6 +101,8 @@
runFstrim();
} else if ("set-virtual-disk".equals(op)) {
runSetVirtualDisk();
+ } else if ("set-isolated-storage".equals(op)) {
+ runIsolatedStorage();
} else {
throw new IllegalArgumentException();
}
@@ -278,6 +280,20 @@
StorageManager.DEBUG_VIRTUAL_DISK);
}
+ public void runIsolatedStorage() throws RemoteException {
+ final boolean enableIsolatedStorage = Boolean.parseBoolean(nextArg());
+ // Toggling isolated-storage state will result in a device reboot. So to avoid this command
+ // from erroring out (DeadSystemException), call setDebugFlags() in a separate thread.
+ new Thread(() -> {
+ try {
+ mSm.setDebugFlags(enableIsolatedStorage ? StorageManager.DEBUG_ISOLATED_STORAGE : 0,
+ StorageManager.DEBUG_ISOLATED_STORAGE);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Encountered an error!", e);
+ }
+ }).start();
+ }
+
public void runIdleMaint() throws RemoteException {
final boolean im_run = "run".equals(nextArg());
if (im_run) {
@@ -316,6 +332,8 @@
System.err.println("");
System.err.println(" sm set-emulate-fbe [true|false]");
System.err.println("");
+ System.err.println(" sm set-isolated-storage [true|false]");
+ System.err.println("");
return 1;
}
}
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index f0f5993..eb498f5 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -71,6 +71,9 @@
#define STATS_DATA_DIR "/data/misc/stats-data"
+// Cool down period for writing data to disk to avoid overwriting files.
+#define WRITE_DATA_COOL_DOWN_SEC 5
+
StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap,
const sp<StatsPullerManager>& pullerManager,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
@@ -508,6 +511,16 @@
void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) {
const int64_t timeNs = getElapsedRealtimeNs();
+ // Do not write to disk if we already have in the last few seconds.
+ // This is to avoid overwriting files that would have the same name if we
+ // write twice in the same second.
+ if (static_cast<unsigned long long> (timeNs) <
+ mLastWriteTimeNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
+ ALOGI("Statsd skipping writing data to disk. Already wrote data in last %d seconds",
+ WRITE_DATA_COOL_DOWN_SEC);
+ return;
+ }
+ mLastWriteTimeNs = timeNs;
for (auto& pair : mMetricsManagers) {
WriteDataToDiskLocked(pair.first, timeNs, dumpReportReason);
}
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index ecfd819..a5ce9b6 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -177,6 +177,9 @@
long mLastPullerCacheClearTimeSec = 0;
+ // Last time we wrote data to disk.
+ int64_t mLastWriteTimeNs = 0;
+
#ifdef VERY_VERBOSE_PRINTING
bool mPrintAllLogs = false;
#endif
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index a0d77d6..6617689 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -47,11 +47,9 @@
const int FIELD_ID_ATOM_STATS = 7;
const int FIELD_ID_UIDMAP_STATS = 8;
const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
-// const int FIELD_ID_PULLED_ATOM_STATS = 10; // The proto is written in stats_log_util.cpp
-const int FIELD_ID_LOGGER_ERROR_STATS = 11;
const int FIELD_ID_PERIODIC_ALARM_STATS = 12;
-// const int FIELD_ID_LOG_LOSS_STATS = 14;
const int FIELD_ID_SYSTEM_SERVER_RESTART = 15;
+const int FIELD_ID_LOGGER_ERROR_STATS = 16;
const int FIELD_ID_ATOM_STATS_TAG = 1;
const int FIELD_ID_ATOM_STATS_COUNT = 2;
@@ -59,8 +57,9 @@
const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
const int FIELD_ID_PERIODIC_ALARMS_REGISTERED = 1;
-const int FIELD_ID_LOGGER_STATS_TIME = 1;
-const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2;
+const int FIELD_ID_LOG_LOSS_STATS_TIME = 1;
+const int FIELD_ID_LOG_LOSS_STATS_COUNT = 2;
+const int FIELD_ID_LOG_LOSS_STATS_ERROR = 3;
const int FIELD_ID_CONFIG_STATS_UID = 1;
const int FIELD_ID_CONFIG_STATS_ID = 2;
@@ -181,12 +180,12 @@
noteConfigResetInternalLocked(key);
}
-void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count) {
+void StatsdStats::noteLogLost(int32_t wallClockTimeSec, int32_t count, int32_t lastError) {
lock_guard<std::mutex> lock(mLock);
if (mLogLossStats.size() == kMaxLoggerErrors) {
mLogLossStats.pop_front();
}
- mLogLossStats.push_back(std::make_pair(wallClockTimeSec, count));
+ mLogLossStats.emplace_back(wallClockTimeSec, count, lastError);
}
void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
@@ -564,8 +563,8 @@
}
for (const auto& loss : mLogLossStats) {
- dprintf(out, "Log loss: %lld (wall clock sec) - %d (count)\n", (long long)loss.first,
- loss.second);
+ dprintf(out, "Log loss: %lld (wall clock sec) - %d (count) %d (last error)\n",
+ (long long)loss.mWallClockSec, loss.mCount, loss.mLastError);
}
}
@@ -720,13 +719,11 @@
proto.end(uidMapToken);
for (const auto& error : mLogLossStats) {
- // The logger error stats are not used anymore since we move away from logd.
- // Temporarily use this field to log the log loss timestamp and count
- // TODO(b/80538532) Add a dedicated field in stats_log for this.
uint64_t token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
FIELD_COUNT_REPEATED);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_TIME, error.first);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_ERROR_CODE, error.second);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_TIME, error.mWallClockSec);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_COUNT, error.mCount);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOG_LOSS_STATS_ERROR, error.mLastError);
proto.end(token);
}
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 2008abd..343709a 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -303,7 +303,7 @@
/**
* Records statsd skipped an event.
*/
- void noteLogLost(int32_t wallClockTimeSec, int32_t count);
+ void noteLogLost(int32_t wallClockTimeSec, int32_t count, int lastError);
/**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
@@ -364,8 +364,18 @@
// Maps PullAtomId to its stats. The size is capped by the puller atom counts.
std::map<int, PulledAtomStats> mPulledAtomStats;
+ struct LogLossStats {
+ LogLossStats(int32_t sec, int32_t count, int32_t error)
+ : mWallClockSec(sec), mCount(count), mLastError(error) {
+ }
+ int32_t mWallClockSec;
+ int32_t mCount;
+ // error code defined in linux/errno.h
+ int32_t mLastError;
+ };
+
// Timestamps when we detect log loss, and the number of logs lost.
- std::list<std::pair<int32_t, int32_t>> mLogLossStats;
+ std::list<LogLossStats> mLogLossStats;
std::list<int32_t> mSystemServerRestartSec;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index c8b1cf0..a34df8aa 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -64,21 +64,29 @@
const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
const int FIELD_ID_DIMENSION_LEAF_IN_CONDITION = 5;
// for ValueBucketInfo
-const int FIELD_ID_VALUE_LONG = 7;
-const int FIELD_ID_VALUE_DOUBLE = 8;
+const int FIELD_ID_VALUE_INDEX = 1;
+const int FIELD_ID_VALUE_LONG = 2;
+const int FIELD_ID_VALUE_DOUBLE = 3;
+const int FIELD_ID_VALUES = 9;
const int FIELD_ID_BUCKET_NUM = 4;
const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
// ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently
-ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric,
+ValueMetricProducer::ValueMetricProducer(const ConfigKey& key,
+ const ValueMetric& metric,
const int conditionIndex,
- const sp<ConditionWizard>& wizard, const int pullTagId,
- const int64_t timeBaseNs, const int64_t startTimeNs,
+ const sp<ConditionWizard>& conditionWizard,
+ const int whatMatcherIndex,
+ const sp<EventMatcherWizard>& matcherWizard,
+ const int pullTagId,
+ const int64_t timeBaseNs,
+ const int64_t startTimeNs,
const sp<StatsPullerManager>& pullerManager)
- : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
+ : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, conditionWizard),
+ mWhatMatcherIndex(whatMatcherIndex),
+ mEventMatcherWizard(matcherWizard),
mPullerManager(pullerManager),
- mValueField(metric.value_field()),
mPullTagId(pullTagId),
mIsPulled(pullTagId != -1),
mMinBucketSizeNs(metric.min_bucket_size_nanos()),
@@ -103,6 +111,9 @@
}
mBucketSizeNs = bucketSizeMills * 1000000;
+
+ translateFieldMatcher(metric.value_field(), &mFieldMatchers);
+
if (metric.has_dimensions_in_what()) {
translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat);
mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
@@ -122,9 +133,6 @@
}
}
- if (mValueField.child_size() > 0) {
- mField = mValueField.child(0).field();
- }
mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
HasPositionALL(metric.dimensions_in_condition());
@@ -142,7 +150,7 @@
mCurrentBucketStartTimeNs = startTimeNs;
// Kicks off the puller immediately if condition is true and diff based.
if (mIsPulled && mCondition && mUseDiff) {
- pullLocked(startTimeNs);
+ pullAndMatchEventsLocked(startTimeNs);
}
VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
(long long)mBucketSizeNs, (long long)mTimeBaseNs);
@@ -259,18 +267,27 @@
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
(long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
}
- if (bucket.value.getType() == LONG) {
- protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
- (long long)bucket.value.long_value);
- VLOG("\t bucket [%lld - %lld] count: %lld", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.value.long_value);
- } else if (bucket.value.getType() == DOUBLE) {
- protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
- bucket.value.double_value);
- VLOG("\t bucket [%lld - %lld] count: %.2f", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, bucket.value.double_value);
- } else {
- VLOG("Wrong value type for ValueMetric output: %d", bucket.value.getType());
+ for (int i = 0; i < (int)bucket.valueIndex.size(); i ++) {
+ int index = bucket.valueIndex[i];
+ const Value& value = bucket.values[i];
+ uint64_t valueToken = protoOutput->start(
+ FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_VALUES);
+ protoOutput->write(FIELD_TYPE_INT32 | FIELD_ID_VALUE_INDEX,
+ index);
+ if (value.getType() == LONG) {
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
+ (long long)value.long_value);
+ VLOG("\t bucket [%lld - %lld] value %d: %lld", (long long)bucket.mBucketStartNs,
+ (long long)bucket.mBucketEndNs, index, (long long)value.long_value);
+ } else if (value.getType() == DOUBLE) {
+ protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
+ value.double_value);
+ VLOG("\t bucket [%lld - %lld] value %d: %.2f", (long long)bucket.mBucketStartNs,
+ (long long)bucket.mBucketEndNs, index, value.double_value);
+ } else {
+ VLOG("Wrong value type for ValueMetric output: %d", value.getType());
+ }
+ protoOutput->end(valueToken);
}
protoOutput->end(bucketInfoToken);
}
@@ -297,27 +314,32 @@
// Pull on condition changes.
if (mIsPulled && (mCondition != condition)) {
- pullLocked(eventTimeNs);
+ pullAndMatchEventsLocked(eventTimeNs);
}
// when condition change from true to false, clear diff base
if (mUseDiff && mCondition && !condition) {
for (auto& slice : mCurrentSlicedBucket) {
- slice.second.hasBase = false;
+ for (auto& interval : slice.second) {
+ interval.hasBase = false;
+ }
}
}
mCondition = condition;
}
-void ValueMetricProducer::pullLocked(const int64_t timestampNs) {
+void ValueMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
vector<std::shared_ptr<LogEvent>> allData;
if (mPullerManager->Pull(mPullTagId, timestampNs, &allData)) {
if (allData.size() == 0) {
return;
}
for (const auto& data : allData) {
- onMatchedLogEventLocked(0, *data);
+ if (mEventMatcherWizard->matchLogEvent(
+ *data, mWhatMatcherIndex) == MatchingState::kMatched) {
+ onMatchedLogEventLocked(mWhatMatcherIndex, *data);
+ }
}
}
}
@@ -328,9 +350,9 @@
void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
std::lock_guard<std::mutex> lock(mMutex);
-
if (mCondition) {
if (allData.size() == 0) {
+ VLOG("Data pulled is empty");
return;
}
// For scheduled pulled data, the effective event time is snap to the nearest
@@ -348,9 +370,14 @@
return;
}
for (const auto& data : allData) {
- data->setElapsedTimestampNs(bucketEndTime);
- onMatchedLogEventLocked(0, *data);
+ if (mEventMatcherWizard->matchLogEvent(*data, mWhatMatcherIndex) ==
+ MatchingState::kMatched) {
+ data->setElapsedTimestampNs(bucketEndTime);
+ onMatchedLogEventLocked(mWhatMatcherIndex, *data);
+ }
}
+ } else {
+ VLOG("No need to commit data on condition false.");
}
}
@@ -363,10 +390,12 @@
(unsigned long)mCurrentSlicedBucket.size());
if (verbose) {
for (const auto& it : mCurrentSlicedBucket) {
+ for (const auto& interval : it.second) {
fprintf(out, "\t(what)%s\t(condition)%s (value)%s\n",
it.first.getDimensionKeyInWhat().toString().c_str(),
it.first.getDimensionKeyInCondition().toString().c_str(),
- it.second.value.toString().c_str());
+ interval.value.toString().c_str());
+ }
}
}
}
@@ -391,25 +420,29 @@
return false;
}
-const Value getDoubleOrLong(const Value& value) {
- Value v;
- switch (value.type) {
- case INT:
- v.setLong(value.int_value);
- break;
- case LONG:
- v.setLong(value.long_value);
- break;
- case FLOAT:
- v.setDouble(value.float_value);
- break;
- case DOUBLE:
- v.setDouble(value.double_value);
- break;
- default:
- break;
+bool getDoubleOrLong(const LogEvent& event, const Matcher& matcher, Value& ret) {
+ for (const FieldValue& value : event.getValues()) {
+ if (value.mField.matches(matcher)) {
+ switch (value.mValue.type) {
+ case INT:
+ ret.setLong(value.mValue.int_value);
+ break;
+ case LONG:
+ ret.setLong(value.mValue.long_value);
+ break;
+ case FLOAT:
+ ret.setDouble(value.mValue.float_value);
+ break;
+ case DOUBLE:
+ ret.setDouble(value.mValue.double_value);
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
}
- return v;
+ return false;
}
void ValueMetricProducer::onMatchedLogEventInternalLocked(const size_t matcherIndex,
@@ -436,82 +469,90 @@
if (hitGuardRailLocked(eventKey)) {
return;
}
- Interval& interval = mCurrentSlicedBucket[eventKey];
-
- if (mField > event.size()) {
- VLOG("Failed to extract value field %d from atom %s. %d", mField, event.ToString().c_str(),
- (int)event.size());
- return;
+ vector<Interval>& multiIntervals = mCurrentSlicedBucket[eventKey];
+ if (multiIntervals.size() < mFieldMatchers.size()) {
+ VLOG("Resizing number of intervals to %d", (int)mFieldMatchers.size());
+ multiIntervals.resize(mFieldMatchers.size());
}
- Value value = getDoubleOrLong(event.getValues()[mField - 1].mValue);
- if (mUseDiff) {
- // no base. just update base and return.
- if (!interval.hasBase) {
- interval.base = value;
- interval.hasBase = true;
+ for (int i = 0; i < (int)mFieldMatchers.size(); i++) {
+ const Matcher& matcher = mFieldMatchers[i];
+ Interval& interval = multiIntervals[i];
+ interval.valueIndex = i;
+ Value value;
+ if (!getDoubleOrLong(event, matcher, value)) {
+ VLOG("Failed to get value %d from event %s", i, event.ToString().c_str());
return;
}
- Value diff;
- switch (mValueDirection) {
- case ValueMetric::INCREASING:
- if (value >= interval.base) {
- diff = value - interval.base;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected decreasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- interval.base = value;
- return;
- }
- break;
- case ValueMetric::DECREASING:
- if (interval.base >= value) {
- diff = interval.base - value;
- } else if (mUseAbsoluteValueOnReset) {
- diff = value;
- } else {
- VLOG("Unexpected increasing value");
- StatsdStats::getInstance().notePullDataError(mPullTagId);
- interval.base = value;
- return;
- }
- break;
- case ValueMetric::ANY:
- diff = value - interval.base;
- break;
- default:
- break;
- }
- interval.base = value;
- value = diff;
- }
- if (interval.hasValue) {
- switch (mAggregationType) {
- case ValueMetric::SUM:
- // for AVG, we add up and take average when flushing the bucket
- case ValueMetric::AVG:
- interval.value += value;
- break;
- case ValueMetric::MIN:
- interval.value = std::min(value, interval.value);
- break;
- case ValueMetric::MAX:
- interval.value = std::max(value, interval.value);
- break;
- default:
- break;
+ if (mUseDiff) {
+ // no base. just update base and return.
+ if (!interval.hasBase) {
+ interval.base = value;
+ interval.hasBase = true;
+ return;
+ }
+ Value diff;
+ switch (mValueDirection) {
+ case ValueMetric::INCREASING:
+ if (value >= interval.base) {
+ diff = value - interval.base;
+ } else if (mUseAbsoluteValueOnReset) {
+ diff = value;
+ } else {
+ VLOG("Unexpected decreasing value");
+ StatsdStats::getInstance().notePullDataError(mPullTagId);
+ interval.base = value;
+ return;
+ }
+ break;
+ case ValueMetric::DECREASING:
+ if (interval.base >= value) {
+ diff = interval.base - value;
+ } else if (mUseAbsoluteValueOnReset) {
+ diff = value;
+ } else {
+ VLOG("Unexpected increasing value");
+ StatsdStats::getInstance().notePullDataError(mPullTagId);
+ interval.base = value;
+ return;
+ }
+ break;
+ case ValueMetric::ANY:
+ diff = value - interval.base;
+ break;
+ default:
+ break;
+ }
+ interval.base = value;
+ value = diff;
}
- } else {
- interval.value = value;
- interval.hasValue = true;
+
+ if (interval.hasValue) {
+ switch (mAggregationType) {
+ case ValueMetric::SUM:
+ // for AVG, we add up and take average when flushing the bucket
+ case ValueMetric::AVG:
+ interval.value += value;
+ break;
+ case ValueMetric::MIN:
+ interval.value = std::min(value, interval.value);
+ break;
+ case ValueMetric::MAX:
+ interval.value = std::max(value, interval.value);
+ break;
+ default:
+ break;
+ }
+ } else {
+ interval.value = value;
+ interval.hasValue = true;
+ }
+ interval.sampleSize += 1;
}
- interval.sampleSize += 1;
// TODO: propgate proper values down stream when anomaly support doubles
- long wholeBucketVal = interval.value.long_value;
+ long wholeBucketVal = multiIntervals[0].value.long_value;
auto prev = mCurrentFullBucket.find(eventKey);
if (prev != mCurrentFullBucket.end()) {
wholeBucketVal += prev->second;
@@ -540,7 +581,9 @@
VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
// take base again in future good bucket.
for (auto& slice : mCurrentSlicedBucket) {
- slice.second.hasBase = false;
+ for (auto& interval : slice.second) {
+ interval.hasBase = false;
+ }
}
}
VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
@@ -552,37 +595,38 @@
(int)mCurrentSlicedBucket.size());
int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
- ValueBucket info;
- info.mBucketStartNs = mCurrentBucketStartTimeNs;
- if (eventTimeNs < fullBucketEndTimeNs) {
- info.mBucketEndNs = eventTimeNs;
- } else {
- info.mBucketEndNs = fullBucketEndTimeNs;
- }
+ int64_t bucketEndTime = eventTimeNs < fullBucketEndTimeNs ? eventTimeNs : fullBucketEndTimeNs;
- if (info.mBucketEndNs - mCurrentBucketStartTimeNs >= mMinBucketSizeNs) {
+ if (bucketEndTime - mCurrentBucketStartTimeNs >= mMinBucketSizeNs) {
// The current bucket is large enough to keep.
for (const auto& slice : mCurrentSlicedBucket) {
- if (slice.second.hasValue) {
- // skip the output if the diff is zero
- if (mSkipZeroDiffOutput && mUseDiff && slice.second.value.isZero()) {
- continue;
+ ValueBucket bucket;
+ bucket.mBucketStartNs = mCurrentBucketStartTimeNs;
+ bucket.mBucketEndNs = bucketEndTime;
+ for (const auto& interval : slice.second) {
+ if (interval.hasValue) {
+ // skip the output if the diff is zero
+ if (mSkipZeroDiffOutput && mUseDiff && interval.value.isZero()) {
+ continue;
+ }
+ bucket.valueIndex.push_back(interval.valueIndex);
+ if (mAggregationType != ValueMetric::AVG) {
+ bucket.values.push_back(interval.value);
+ } else {
+ double sum = interval.value.type == LONG ? (double)interval.value.long_value
+ : interval.value.double_value;
+ bucket.values.push_back(Value((double)sum / interval.sampleSize));
+ }
}
- if (mAggregationType != ValueMetric::AVG) {
- info.value = slice.second.value;
- } else {
- double sum = slice.second.value.type == LONG
- ? (double)slice.second.value.long_value
- : slice.second.value.double_value;
- info.value.setDouble(sum / slice.second.sampleSize);
- }
- // it will auto create new vector of ValuebucketInfo if the key is not found.
+ }
+ // it will auto create new vector of ValuebucketInfo if the key is not found.
+ if (bucket.valueIndex.size() > 0) {
auto& bucketList = mPastBuckets[slice.first];
- bucketList.push_back(info);
+ bucketList.push_back(bucket);
}
}
} else {
- mSkippedBuckets.emplace_back(info.mBucketStartNs, info.mBucketEndNs);
+ mSkippedBuckets.emplace_back(mCurrentBucketStartTimeNs, bucketEndTime);
}
if (eventTimeNs > fullBucketEndTimeNs) { // If full bucket, send to anomaly tracker.
@@ -590,7 +634,7 @@
if (mCurrentFullBucket.size() > 0) {
for (const auto& slice : mCurrentSlicedBucket) {
// TODO: fix this when anomaly can accept double values
- mCurrentFullBucket[slice.first] += slice.second.value.long_value;
+ mCurrentFullBucket[slice.first] += slice.second[0].value.long_value;
}
for (const auto& slice : mCurrentFullBucket) {
for (auto& tracker : mAnomalyTrackers) {
@@ -606,7 +650,7 @@
for (auto& tracker : mAnomalyTrackers) {
if (tracker != nullptr) {
// TODO: fix this when anomaly can accept double values
- tracker->addPastBucket(slice.first, slice.second.value.long_value,
+ tracker->addPastBucket(slice.first, slice.second[0].value.long_value,
mCurrentBucketNum);
}
}
@@ -616,14 +660,16 @@
// Accumulate partial bucket.
for (const auto& slice : mCurrentSlicedBucket) {
// TODO: fix this when anomaly can accept double values
- mCurrentFullBucket[slice.first] += slice.second.value.long_value;
+ mCurrentFullBucket[slice.first] += slice.second[0].value.long_value;
}
}
// Reset counters
for (auto& slice : mCurrentSlicedBucket) {
- slice.second.hasValue = false;
- slice.second.sampleSize = 0;
+ for (auto& interval : slice.second) {
+ interval.hasValue = false;
+ interval.sampleSize = 0;
+ }
}
}
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 3416afe..c3912ee 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -23,6 +23,7 @@
#include "../condition/ConditionTracker.h"
#include "../external/PullDataReceiver.h"
#include "../external/StatsPullerManager.h"
+#include "../matchers/EventMatcherWizard.h"
#include "../stats_log_util.h"
#include "MetricProducer.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
@@ -34,13 +35,16 @@
struct ValueBucket {
int64_t mBucketStartNs;
int64_t mBucketEndNs;
- Value value;
+ std::vector<int> valueIndex;
+ std::vector<Value> values;
};
class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
public:
ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric,
- const int conditionIndex, const sp<ConditionWizard>& wizard,
+ const int conditionIndex, const sp<ConditionWizard>& conditionWizard,
+ const int whatMatcherIndex,
+ const sp<EventMatcherWizard>& matcherWizard,
const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs,
const sp<StatsPullerManager>& pullerManager);
@@ -54,7 +58,7 @@
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
if (mIsPulled && mCondition) {
- pullLocked(eventTimeNs - 1);
+ pullAndMatchEventsLocked(eventTimeNs - 1);
}
flushCurrentBucketLocked(eventTimeNs);
mCurrentBucketStartTimeNs = eventTimeNs;
@@ -95,9 +99,14 @@
// Calculate previous bucket end time based on current time.
int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
+ const int mWhatMatcherIndex;
+
+ sp<EventMatcherWizard> mEventMatcherWizard;
+
sp<StatsPullerManager> mPullerManager;
- const FieldMatcher mValueField;
+ // Value fields for matching.
+ std::vector<Matcher> mFieldMatchers;
// tagId for pulled data. -1 if this is not pulled
const int mPullTagId;
@@ -105,10 +114,10 @@
// if this is pulled metric
const bool mIsPulled;
- int mField;
-
- // internal state of a bucket.
+ // internal state of an ongoing aggregation bucket.
typedef struct {
+ // Index in multi value aggregation.
+ int valueIndex;
// Holds current base value of the dimension. Take diff and update if necessary.
Value base;
// Whether there is a base to diff to.
@@ -122,7 +131,7 @@
bool hasValue;
} Interval;
- std::unordered_map<MetricDimensionKey, Interval> mCurrentSlicedBucket;
+ std::unordered_map<MetricDimensionKey, std::vector<Interval>> mCurrentSlicedBucket;
std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket;
@@ -137,7 +146,7 @@
// Util function to check whether the specified dimension hits the guardrail.
bool hitGuardRailLocked(const MetricDimensionKey& newKey);
- void pullLocked(const int64_t timestampNs);
+ void pullAndMatchEventsLocked(const int64_t timestampNs);
static const size_t kBucketSize = sizeof(ValueBucket{});
@@ -156,6 +165,7 @@
const bool mSkipZeroDiffOutput;
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
+ FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 136ba07..47b0376 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -488,9 +488,9 @@
}
}
- sp<MetricProducer> valueProducer =
- new ValueMetricProducer(key, metric, conditionIndex, wizard, pullTagId,
- timeBaseTimeNs, currentTimeNs, pullerManager);
+ sp<MetricProducer> valueProducer = new ValueMetricProducer(
+ key, metric, conditionIndex, wizard, trackerIndex, matcherWizard, pullTagId,
+ timeBaseTimeNs, currentTimeNs, pullerManager);
allMetricProducers.push_back(valueProducer);
}
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
index 9b0691b..6bb8cda 100755
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ b/cmds/statsd/src/socket/StatsSocketListener.cpp
@@ -40,7 +40,6 @@
namespace statsd {
static const int kLogMsgHeaderSize = 28;
-static const int kLibLogTag = 1006;
StatsSocketListener::StatsSocketListener(const sp<LogListener>& listener)
: SocketListener(getLogSocket(), false /*start listen*/), mListener(listener) {
@@ -109,10 +108,11 @@
// TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
if (n == sizeof(android_log_event_int_t)) {
android_log_event_int_t* int_event = reinterpret_cast<android_log_event_int_t*>(ptr);
- if (int_event->header.tag == kLibLogTag && int_event->payload.type == EVENT_TYPE_INT) {
- ALOGE("Found dropped events: %d", int_event->payload.data);
+ if (int_event->payload.type == EVENT_TYPE_INT) {
+ ALOGE("Found dropped events: %d error %d", int_event->payload.data,
+ int_event->header.tag);
StatsdStats::getInstance().noteLogLost((int32_t)getWallClockSec(),
- int_event->payload.data);
+ int_event->payload.data, int_event->header.tag);
return true;
}
}
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 4da3828..5d0f3d1 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -108,12 +108,22 @@
optional int64 value = 3 [deprecated = true];
- oneof values {
- int64 value_long = 7;
+ oneof single_value {
+ int64 value_long = 7 [deprecated = true];
- double value_double = 8;
+ double value_double = 8 [deprecated = true];
}
+ message Value {
+ optional int32 index = 1;
+ oneof value {
+ int64 value_long = 2;
+ double value_double = 3;
+ }
+ }
+
+ repeated Value values = 9;
+
optional int64 bucket_num = 4;
optional int64 start_bucket_elapsed_millis = 5;
@@ -398,4 +408,11 @@
repeated int64 log_loss_stats = 14;
repeated int32 system_restart_sec = 15;
+
+ message LogLossStats {
+ optional int32 detected_time_sec = 1;
+ optional int32 count = 2;
+ optional int32 last_error = 3;
+ }
+ repeated LogLossStats detected_log_loss = 16;
}
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index 095b401..abf1ab1 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -142,23 +142,23 @@
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(0).values_size());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(1).values_size());
EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(2).values_size());
EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(3).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(3).values_size());
EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(4).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(4).values_size());
}
TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
@@ -249,15 +249,15 @@
EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(0).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(0).values_size());
EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(1).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(1).values_size());
EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
EXPECT_EQ(baseTimeNs + 10 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
- EXPECT_TRUE(data.bucket_info(2).has_value_long());
+ EXPECT_EQ(1, data.bucket_info(2).values_size());
}
#else
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index ffa07081..44aa00b 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "src/matchers/SimpleLogMatchingTracker.h"
#include "src/metrics/ValueMetricProducer.h"
#include "src/stats_log_util.h"
#include "metrics_test_helper.h"
@@ -40,6 +41,8 @@
const ConfigKey kConfigKey(0, 12345);
const int tagId = 1;
const int64_t metricId = 123;
+const int64_t atomMatcherId = 678;
+const int logEventMatcherIndex = 0;
const int64_t bucketStartTimeNs = 10000000000;
const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
@@ -60,14 +63,20 @@
metric.mutable_value_field()->add_child()->set_field(2);
int64_t startTimeBase = 11;
-
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// statsd started long ago.
// The metric starts in the middle of the bucket
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- -1, startTimeBase, 22, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, -1, startTimeBase,
+ 22, pullerManager);
EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
@@ -87,13 +96,20 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
// statsd started long ago.
// The metric starts in the middle of the bucket
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- -1, 5, 600 * NS_PER_SEC + NS_PER_SEC/2, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, -1, 5,
+ 600 * NS_PER_SEC + NS_PER_SEC / 2, pullerManager);
EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
@@ -110,6 +126,12 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -127,7 +149,8 @@
}));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -140,7 +163,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
@@ -157,7 +180,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(23, curInterval.base.long_value);
@@ -165,7 +188,7 @@
EXPECT_EQ(12, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -175,7 +198,7 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
@@ -183,7 +206,103 @@
EXPECT_EQ(13, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
+}
+
+/*
+ * Tests pulled atoms with filtering
+ */
+TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ auto keyValue = atomMatcher.add_field_value_matcher();
+ keyValue->set_field(1);
+ keyValue->set_eq_int(3);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
+ event->write(3);
+ event->write(3);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event->write(3);
+ event->write(11);
+ event->init();
+ allData.push_back(event);
+
+ valueProducer.onDataPulled(allData);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval =
+ valueProducer.mCurrentSlicedBucket.begin()->second[0];
+
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ allData.clear();
+ event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
+ event->write(4);
+ event->write(23);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+ // has one slice
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
+ // no events caused flush of bucket
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+
+ allData.clear();
+ event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
+ event->write(3);
+ event->write(36);
+ event->init();
+ allData.push_back(event);
+ valueProducer.onDataPulled(allData);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+
+ // the base was reset
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(36, curInterval.base.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
/*
@@ -197,6 +316,12 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_use_absolute_value_on_reset(true);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -204,7 +329,8 @@
EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -217,7 +343,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
@@ -233,7 +359,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(10, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -248,14 +374,14 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(26, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
/*
@@ -268,6 +394,12 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -275,7 +407,8 @@
EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -288,7 +421,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(11, curInterval.base.long_value);
@@ -304,7 +437,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(10, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
@@ -318,7 +451,7 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -337,6 +470,12 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_condition(StringToId("SCREEN_ON"));
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -364,13 +503,14 @@
return true;
}));
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// startUpdated:false sum:0 start:100
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(100, curInterval.base.long_value);
@@ -388,7 +528,7 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(110, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -399,7 +539,7 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(false, curInterval.hasBase);
@@ -412,10 +552,17 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -453,6 +600,12 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -469,7 +622,8 @@
data->push_back(event);
return true;
}));
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, tagId, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
@@ -486,7 +640,7 @@
valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -497,7 +651,7 @@
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
}
TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
@@ -508,6 +662,12 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_condition(StringToId("SCREEN_ON"));
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -533,7 +693,8 @@
data->push_back(event);
return true;
}));
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
@@ -545,7 +706,7 @@
EXPECT_EQ(bucket2StartTimeNs-50, valueProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucketStartTimeNs, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
EXPECT_FALSE(valueProducer.mCondition);
}
@@ -556,11 +717,18 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -573,7 +741,7 @@
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -581,13 +749,13 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(30, curInterval.value.long_value);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
@@ -597,11 +765,18 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -620,8 +795,8 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(20, curInterval.value.long_value);
shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 30);
@@ -632,7 +807,7 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(50, curInterval.value.long_value);
valueProducer.onConditionChangedLocked(false, bucketStartTimeNs + 35);
@@ -644,13 +819,13 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(50, curInterval.value.long_value);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
TEST(ValueMetricProducerTest, TestAnomalyDetection) {
@@ -669,11 +844,17 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, -1 /*not pulled*/,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
@@ -744,6 +925,12 @@
metric.mutable_value_field()->set_field(tagId);
metric.mutable_value_field()->add_child()->set_field(2);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -751,7 +938,8 @@
EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
// pull 1
@@ -765,7 +953,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// startUpdated:true sum:0 start:11
EXPECT_EQ(true, curInterval.hasBase);
@@ -783,7 +971,7 @@
valueProducer.onDataPulled(allData);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// tartUpdated:false sum:12
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(23, curInterval.base.long_value);
@@ -803,14 +991,14 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// startUpdated:false sum:12
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(36, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
/*
@@ -825,6 +1013,12 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_condition(StringToId("SCREEN_ON"));
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -854,13 +1048,14 @@
return true;
}));
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
@@ -868,7 +1063,7 @@
// pull on bucket boundary come late, condition change happens before it
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(false, curInterval.hasBase);
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(20, curInterval.value.long_value);
@@ -885,7 +1080,7 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(false, curInterval.hasBase);
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(20, curInterval.value.long_value);
@@ -904,6 +1099,12 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_condition(StringToId("SCREEN_ON"));
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return());
@@ -944,13 +1145,14 @@
return true;
}));
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
// startUpdated:false sum:0 start:100
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(100, curInterval.base.long_value);
@@ -959,7 +1161,7 @@
// pull on bucket boundary come late, condition change happens before it
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(false, curInterval.hasBase);
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(20, curInterval.value.long_value);
@@ -967,7 +1169,7 @@
// condition changed to true again, before the pull alarm is delivered
valueProducer.onConditionChanged(true, bucket2StartTimeNs + 25);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(130, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -984,7 +1186,7 @@
allData.push_back(event);
valueProducer.onDataPulled(allData);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(130, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1000,11 +1202,18 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_aggregation_type(ValueMetric::MIN);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1017,7 +1226,7 @@
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1025,13 +1234,13 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
@@ -1042,11 +1251,18 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_aggregation_type(ValueMetric::MAX);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1059,7 +1275,7 @@
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1067,13 +1283,13 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(20, curInterval.value.long_value);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
@@ -1084,11 +1300,18 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_aggregation_type(ValueMetric::AVG);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1102,7 +1325,7 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval;
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(1, curInterval.sampleSize);
@@ -1111,14 +1334,14 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(25, curInterval.value.long_value);
EXPECT_EQ(2, curInterval.sampleSize);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().value.double_value - 12.5) < epsilon);
+ EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().values[0].double_value - 12.5) < epsilon);
}
TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
@@ -1129,11 +1352,18 @@
metric.mutable_value_field()->add_child()->set_field(2);
metric.set_aggregation_type(ValueMetric::SUM);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1146,7 +1376,7 @@
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(10, curInterval.value.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1154,13 +1384,13 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(25, curInterval.value.long_value);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
@@ -1172,11 +1402,18 @@
metric.set_aggregation_type(ValueMetric::MIN);
metric.set_use_diff(true);
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, -1, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1189,7 +1426,7 @@
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(10, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
@@ -1198,7 +1435,7 @@
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(5, curInterval.value.long_value);
@@ -1209,7 +1446,7 @@
event3->init();
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(15, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1220,7 +1457,7 @@
event4->init();
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second[0];
EXPECT_EQ(true, curInterval.hasBase);
EXPECT_EQ(15, curInterval.base.long_value);
EXPECT_EQ(true, curInterval.hasValue);
@@ -1228,7 +1465,7 @@
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
+ EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second.back().values[0].long_value);
}
} // namespace statsd
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0d9a393..851e35b 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -441,40 +441,6 @@
Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
-Landroid/icu/impl/CurrencyData;-><init>()V
-Landroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
-Landroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
-Landroid/icu/impl/IllegalIcuArgumentException;-><init>(Ljava/lang/String;)V
-Landroid/icu/text/ArabicShaping;-><init>(I)V
-Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z
-Landroid/icu/text/ArabicShaping;->isSeenTailFamilyChar(C)I
-Landroid/icu/text/ArabicShaping;->isTailChar(C)Z
-Landroid/icu/text/ArabicShaping;->isYehHamzaChar(C)Z
-Landroid/icu/text/ArabicShaping;->shape(Ljava/lang/String;)Ljava/lang/String;
-Landroid/icu/text/DateFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/DateIntervalFormat;-><init>()V
-Landroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
-Landroid/icu/text/DecimalFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/RuleBasedCollator;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/SpoofChecker$ScriptSet;-><init>()V
-Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V
-Landroid/icu/text/SpoofChecker$ScriptSet;->isFull()Z
-Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V
-Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V
-Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;I)Landroid/icu/text/Transliterator;
-Landroid/icu/text/Transliterator;->transliterate(Landroid/icu/text/Replaceable;Landroid/icu/text/Transliterator$Position;Ljava/lang/String;)V
-Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
-Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/util/PersianCalendar;-><init>(Ljava/util/Locale;)V
-Landroid/icu/util/UResourceBundle;->getBundleInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/util/UResourceBundle;
-Landroid/icu/util/UResourceBundle;->getKey()Ljava/lang/String;
-Landroid/icu/util/UResourceBundle;->getString()Ljava/lang/String;
-Landroid/icu/util/UResourceBundle;->getType()I
-Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
-Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
@@ -1361,15 +1327,11 @@
Landroid/security/IKeystoreService;->generateKey(Ljava/lang/String;Landroid/security/keymaster/KeymasterArguments;[BIILandroid/security/keymaster/KeyCharacteristics;)I
Landroid/security/IKeystoreService;->get(Ljava/lang/String;I)[B
Landroid/security/IKeystoreService;->getState(I)I
-Landroid/security/IKeystoreService;->get_pubkey(Ljava/lang/String;)[B
-Landroid/security/IKeystoreService;->import_key(Ljava/lang/String;[BII)I
Landroid/security/IKeystoreService;->insert(Ljava/lang/String;[BII)I
Landroid/security/IKeystoreService;->is_hardware_backed(Ljava/lang/String;)I
Landroid/security/IKeystoreService;->list(Ljava/lang/String;I)[Ljava/lang/String;
Landroid/security/IKeystoreService;->reset()I
-Landroid/security/IKeystoreService;->sign(Ljava/lang/String;[B)[B
Landroid/security/IKeystoreService;->ungrant(Ljava/lang/String;I)I
-Landroid/security/IKeystoreService;->verify(Ljava/lang/String;[B[B)I
Landroid/security/keymaster/KeymasterBlobArgument;-><init>(ILandroid/os/Parcel;)V
Landroid/security/keymaster/KeymasterBlobArgument;-><init>(I[B)V
Landroid/security/keymaster/KeymasterBlobArgument;->blob:[B
@@ -4250,170 +4212,6 @@
Lcom/android/okhttp/Response;->message:Ljava/lang/String;
Lcom/android/okhttp/Response;->networkResponse:Lcom/android/okhttp/Response;
Lcom/android/okhttp/Response;->protocol:Lcom/android/okhttp/Protocol;
-Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;-><init>()V
-Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;->add(Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V
-Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>(Ljava/io/InputStream;)V
-Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>([B)V
-Lcom/android/org/bouncycastle/asn1/ASN1InputStream;->readObject()Lcom/android/org/bouncycastle/asn1/ASN1Primitive;
-Lcom/android/org/bouncycastle/asn1/ASN1Integer;-><init>(Ljava/math/BigInteger;)V
-Lcom/android/org/bouncycastle/asn1/DERBitString;-><init>([B)V
-Lcom/android/org/bouncycastle/asn1/DEREncodableVector;-><init>()V
-Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(J)V
-Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(Ljava/math/BigInteger;)V
-Lcom/android/org/bouncycastle/asn1/DERNull;->INSTANCE:Lcom/android/org/bouncycastle/asn1/DERNull;
-Lcom/android/org/bouncycastle/asn1/DERObjectIdentifier;-><init>(Ljava/lang/String;)V
-Lcom/android/org/bouncycastle/asn1/DEROctetString;-><init>([B)V
-Lcom/android/org/bouncycastle/asn1/DEROutputStream;-><init>(Ljava/io/OutputStream;)V
-Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>()V
-Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V
-Lcom/android/org/bouncycastle/asn1/DERSet;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V
-Lcom/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers;->sha256WithRSAEncryption:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
-Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;)V
-Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V
-Lcom/android/org/bouncycastle/asn1/x509/Certificate;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/Certificate;
-Lcom/android/org/bouncycastle/asn1/x509/DigestInfo;-><init>(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;[B)V
-Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;
-Lcom/android/org/bouncycastle/asn1/x509/Time;-><init>(Ljava/util/Date;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;-><init>()V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->generateTBSCertificate()Lcom/android/org/bouncycastle/asn1/x509/TBSCertificate;
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setEndDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setIssuer(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSerialNumber(Lcom/android/org/bouncycastle/asn1/ASN1Integer;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSignature(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setStartDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubject(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
-Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubjectPublicKeyInfo(Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;)V
-Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1Sequence;)V
-Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Ljava/lang/String;)V
-Lcom/android/org/bouncycastle/asn1/x509/X509Name;->CN:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
-Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getOIDs()Ljava/util/Vector;
-Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getValues()Ljava/util/Vector;
-Lcom/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers;->ecdsa_with_SHA256:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
-Lcom/android/org/bouncycastle/jce/provider/BouncyCastleProvider;-><init>()V
-Lcom/android/org/bouncycastle/jce/provider/X509CertificateObject;-><init>(Lcom/android/org/bouncycastle/asn1/x509/Certificate;)V
-Lcom/android/org/bouncycastle/jce/X509Principal;-><init>([B)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;-><init>()V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->generate(Ljava/security/PrivateKey;)Ljava/security/cert/X509Certificate;
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Ljavax/security/auth/x500/X500Principal;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotAfter(Ljava/util/Date;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotBefore(Ljava/util/Date;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setPublicKey(Ljava/security/PublicKey;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSerialNumber(Ljava/math/BigInteger;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSignatureAlgorithm(Ljava/lang/String;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
-Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Ljavax/security/auth/x500/X500Principal;)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocols()[Ljava/lang/String;
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getChannelId()[B
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostname()Ljava/lang/String;
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostnameOrIP()Ljava/lang/String;
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getNpnSelectedProtocol()[B
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->getSoWriteTimeout()I
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([Ljava/lang/String;)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setApplicationProtocols([Ljava/lang/String;)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdEnabled(Z)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHandshakeTimeout(I)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V
-Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V
-Lcom/android/org/conscrypt/ClientSessionContext;->getSession(Ljava/lang/String;I)Lcom/android/org/conscrypt/NativeSslSession;
-Lcom/android/org/conscrypt/ClientSessionContext;->setPersistentCache(Lcom/android/org/conscrypt/SSLClientSessionCache;)V
-Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V
-Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V
-Lcom/android/org/conscrypt/FileClientSessionCache$Impl;->getSessionData(Ljava/lang/String;I)[B
-Lcom/android/org/conscrypt/FileClientSessionCache;->usingDirectory(Ljava/io/File;)Lcom/android/org/conscrypt/SSLClientSessionCache;
-Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_pack_X509([J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_unpack_X509_bio(J)[J
-Lcom/android/org/conscrypt/NativeCrypto;->ASN1_TIME_to_Calendar(JLjava/util/Calendar;)V
-Lcom/android/org/conscrypt/NativeCrypto;->BIO_free_all(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_InputStream(Lcom/android/org/conscrypt/OpenSSLBIOInputStream;Z)J
-Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_OutputStream(Ljava/io/OutputStream;)J
-Lcom/android/org/conscrypt/NativeCrypto;->d2i_PKCS7_bio(JI)[J
-Lcom/android/org/conscrypt/NativeCrypto;->d2i_SSL_SESSION([B)J
-Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509([B)J
-Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_bio(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_CRL_bio(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_clear_free(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_new_by_curve_name(Ljava/lang/String;)J
-Lcom/android/org/conscrypt/NativeCrypto;->EC_POINT_clear_free(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_CTX_new()J
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_iv_length(J)I
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_cipherbyname(Ljava/lang/String;)J
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_digestbyname(Ljava/lang/String;)J
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_create()J
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_destroy(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_size(J)I
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_free(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_new_RSA([B[B[B[B[B[B[B[B)J
-Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_ext_oids(JI)[Ljava/lang/String;
-Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_revocationDate(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->i2d_PKCS7([J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->i2d_SSL_SESSION(J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->i2d_X509_REVOKED(J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_PKCS7(JI)[J
-Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509_CRL(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->RAND_bytes([B)V
-Lcom/android/org/conscrypt/NativeCrypto;->RSA_generate_key_ex(I[B)J
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_CTX_new()J
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_cipher(J)Ljava/lang/String;
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_free(J)V
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_time(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_version(J)Ljava/lang/String;
-Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_session_id(J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_dup(J)J
-Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext(JLjava/lang/String;)J
-Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext_oid(JLjava/lang/String;)[B
-Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_serialNumber(J)[B
-Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_print(JJ)V
-Lcom/android/org/conscrypt/NativeCrypto;->X509_supported_extension(J)I
-Lcom/android/org/conscrypt/OpenSSLBIOInputStream;-><init>(Ljava/io/InputStream;Z)V
-Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->getBioContext()J
-Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->release()V
-Lcom/android/org/conscrypt/OpenSSLContextImpl$TLSv12;-><init>()V
-Lcom/android/org/conscrypt/OpenSSLContextImpl;-><init>()V
-Lcom/android/org/conscrypt/OpenSSLContextImpl;->engineGetClientSessionContext()Lcom/android/org/conscrypt/ClientSessionContext;
-Lcom/android/org/conscrypt/OpenSSLContextImpl;->getPreferred()Lcom/android/org/conscrypt/OpenSSLContextImpl;
-Lcom/android/org/conscrypt/OpenSSLKey;-><init>(J)V
-Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey;
-Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY;
-Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey;
-Lcom/android/org/conscrypt/OpenSSLKeyHolder;->getOpenSSLKey()Lcom/android/org/conscrypt/OpenSSLKey;
-Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V
-Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V
-Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;-><init>()V
-Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;->sslParameters:Lcom/android/org/conscrypt/SSLParametersImpl;
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostnameOrIP()Ljava/lang/String;
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getNpnSelectedProtocol()[B
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getSoWriteTimeout()I
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([Ljava/lang/String;)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdEnabled(Z)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHandshakeTimeout(I)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setNpnProtocols([B)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setSoWriteTimeout(I)V
-Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
-Lcom/android/org/conscrypt/OpenSSLX509Certificate;->fromX509PemInputStream(Ljava/io/InputStream;)Lcom/android/org/conscrypt/OpenSSLX509Certificate;
-Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J
-Lcom/android/org/conscrypt/SSLParametersImpl;->getDefault()Lcom/android/org/conscrypt/SSLParametersImpl;
-Lcom/android/org/conscrypt/SSLParametersImpl;->getDefaultX509TrustManager()Ljavax/net/ssl/X509TrustManager;
-Lcom/android/org/conscrypt/SSLParametersImpl;->getX509TrustManager()Ljavax/net/ssl/X509TrustManager;
-Lcom/android/org/conscrypt/SSLParametersImpl;->setEnabledProtocols([Ljava/lang/String;)V
-Lcom/android/org/conscrypt/SSLParametersImpl;->x509TrustManager:Ljavax/net/ssl/X509TrustManager;
-Lcom/android/org/conscrypt/TrustedCertificateStore;-><init>()V
-Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List;
-Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
-Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
-Lcom/android/org/conscrypt/X509PublicKey;-><init>(Ljava/lang/String;[B)V
Lcom/android/server/net/BaseNetworkObserver;-><init>()V
Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V
Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index b6bff9c..14597ee 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -3240,7 +3240,7 @@
android.view.FocusFinder$FocusSorter
android.view.FocusFinder$UserSpecifiedFocusComparator
android.view.FocusFinder$UserSpecifiedFocusComparator$NextFocusGetter
-android.view.FrameInfo
+android.graphics.FrameInfo
android.view.FrameMetrics
android.view.FrameMetricsObserver
android.view.FrameStats
@@ -4117,6 +4117,8 @@
com.android.internal.util.VirtualRefBasePtr
com.android.internal.util.XmlUtils
com.android.internal.util.XmlUtils$WriteMapCallback
+com.android.internal.util.function.HeptConsumer
+com.android.internal.util.function.HeptFunction
com.android.internal.util.function.HexConsumer
com.android.internal.util.function.HexFunction
com.android.internal.util.function.QuadConsumer
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 86ed267..553acc8 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -31,6 +31,7 @@
import android.annotation.RequiresPermission;
import android.annotation.StyleRes;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.VoiceInteractor.Request;
import android.app.admin.DevicePolicyManager;
@@ -2346,6 +2347,7 @@
* @see View#onMovedToDisplay(int, Configuration)
* @hide
*/
+ @TestApi
public void onMovedToDisplay(int displayId, Configuration config) {
}
@@ -4838,6 +4840,7 @@
* their launch had come from the original activity.
* @param intent The Intent to start.
* @param options ActivityOptions or null.
+ * @param permissionToken Token received from the system that permits this call to be made.
* @param ignoreTargetSecurity If true, the activity manager will not check whether the
* caller it is doing the start is, is actually allowed to start the target activity.
* If you set this to true, you must set an explicit component in the Intent and do any
@@ -4846,7 +4849,7 @@
* @hide
*/
public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
- boolean ignoreTargetSecurity, int userId) {
+ IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
@@ -4854,7 +4857,7 @@
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivityAsCaller(
this, mMainThread.getApplicationThread(), mToken, this,
- intent, -1, options, ignoreTargetSecurity, userId);
+ intent, -1, options, permissionToken, ignoreTargetSecurity, userId);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, -1, ar.getResultCode(),
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 7330da3..1cf042f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1751,6 +1751,8 @@
*/
public static class TaskSnapshot implements Parcelable {
+ // Top activity in task when snapshot was taken
+ private final ComponentName mTopActivityComponent;
private final GraphicBuffer mSnapshot;
private final int mOrientation;
private final Rect mContentInsets;
@@ -1765,9 +1767,11 @@
private final int mSystemUiVisibility;
private final boolean mIsTranslucent;
- public TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets,
- boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
- int systemUiVisibility, boolean isTranslucent) {
+ public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
+ int orientation, Rect contentInsets, boolean reducedResolution, float scale,
+ boolean isRealSnapshot, int windowingMode, int systemUiVisibility,
+ boolean isTranslucent) {
+ mTopActivityComponent = topActivityComponent;
mSnapshot = snapshot;
mOrientation = orientation;
mContentInsets = new Rect(contentInsets);
@@ -1780,6 +1784,7 @@
}
private TaskSnapshot(Parcel source) {
+ mTopActivityComponent = ComponentName.readFromParcel(source);
mSnapshot = source.readParcelable(null /* classLoader */);
mOrientation = source.readInt();
mContentInsets = source.readParcelable(null /* classLoader */);
@@ -1792,6 +1797,13 @@
}
/**
+ * @return The top activity component for the task at the point this snapshot was taken.
+ */
+ public ComponentName getTopActivityComponent() {
+ return mTopActivityComponent;
+ }
+
+ /**
* @return The graphic buffer representing the screenshot.
*/
@UnsupportedAppUsage
@@ -1871,6 +1883,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
+ ComponentName.writeToParcel(mTopActivityComponent, dest);
dest.writeParcelable(mSnapshot, 0);
dest.writeInt(mOrientation);
dest.writeParcelable(mContentInsets, 0);
@@ -1886,7 +1899,9 @@
public String toString() {
final int width = mSnapshot != null ? mSnapshot.getWidth() : 0;
final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
- return "TaskSnapshot{mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+ return "TaskSnapshot{"
+ + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
+ + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
+ " mOrientation=" + mOrientation
+ " mContentInsets=" + mContentInsets.toShortString()
+ " mReducedResolution=" + mReducedResolution + " mScale=" + mScale
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 069effd..0e5b976 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -161,13 +161,6 @@
public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
/**
- * Returns a list that contains the memory stats for monitored native processes.
- *
- * The list of the monitored processes is defined in MemoryStatUtil class.
- */
- public abstract List<ProcessMemoryState> getMemoryStateForNativeProcesses();
-
- /**
* Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
* needed.
*/
@@ -277,7 +270,15 @@
public abstract void startProcess(String processName, ApplicationInfo info,
boolean knownToBeDead, String hostingType, ComponentName hostingName);
- /** Starts up the starting activity process for debugging if needed. */
+ /** Starts up the starting activity process for debugging if needed.
+ * This function needs to be called synchronously from WindowManager context so the caller
+ * passes a lock {@code wmLock} and waits to be notified.
+ *
+ * @param wmLock calls {@code notify} on the object to wake up the caller.
+ */
public abstract void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
- ProfilerInfo profilerInfo);
+ ProfilerInfo profilerInfo, Object wmLock);
+
+ /** Checks if process running with given pid has access to full external storage or not */
+ public abstract boolean isAppStorageSandboxed(int pid, int uid);
}
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index b8fe2f1..56ccf6f 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -110,6 +110,32 @@
public static final int RESIZE_MODE_USER_FORCED =
RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED;
+ /**
+ * Extra included on intents that are delegating the call to
+ * ActivityManager#startActivityAsCaller to another app. This token is necessary for that call
+ * to succeed. Type is IBinder.
+ * @hide
+ */
+ public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN";
+
+ /**
+ * Extra included on intents that contain an EXTRA_INTENT, with options that the contained
+ * intent may want to be started with. Type is Bundle.
+ * TODO: remove once the ChooserActivity moves to systemui
+ * @hide
+ */
+ public static final String EXTRA_OPTIONS = "android.app.extra.OPTIONS";
+
+ /**
+ * Extra included on intents that contain an EXTRA_INTENT, use this boolean value for the
+ * parameter of the same name when starting the contained intent.
+ * TODO: remove once the ChooserActivity moves to systemui
+ * @hide
+ */
+ public static final String EXTRA_IGNORE_TARGET_SECURITY =
+ "android.app.extra.EXTRA_IGNORE_TARGET_SECURITY";
+
+
private static int sMaxRecentTasks = -1;
ActivityTaskManager(Context context, Handler handler) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9079f1a..805fb68 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -72,6 +72,7 @@
import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.HardwareRenderer;
import android.graphics.ImageDecoder;
import android.hardware.display.DisplayManagerGlobal;
import android.net.ConnectivityManager;
@@ -5652,7 +5653,7 @@
int uid = Process.myUid();
String[] packages = getPackageManager().getPackagesForUid(uid);
if (packages != null) {
- ThreadedRenderer.setupDiskCache(codeCacheDir);
+ HardwareRenderer.setupDiskCache(codeCacheDir);
RenderScriptCacheDir.setupDiskCache(codeCacheDir);
}
} catch (RemoteException e) {
@@ -5887,7 +5888,8 @@
// Allow renderer debugging features if we're debuggable.
boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
- ThreadedRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
+ HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
+ HardwareRenderer.setPackageName(data.appInfo.packageName);
/**
* Initialize the default http proxy in this process for the reasons we set the time zone.
@@ -5954,7 +5956,7 @@
StrictMode.setThreadPolicyMask(oldMask);
}
} else {
- ThreadedRenderer.setIsolatedProcess(true);
+ HardwareRenderer.setIsolatedProcess(true);
}
// If we use profiles, setup the dex reporter to notify package manager
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index a9819fc..2be5dc9 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2323,7 +2323,7 @@
*/
private static long sum(@NonNull long[] counts, int start, int end) {
long totalCount = 0;
- for (int i = start; i <= end; i++) {
+ for (int i = start; i < end; i++) {
totalCount += counts[i];
}
return totalCount;
diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java
index 0643414..229bee5 100644
--- a/core/java/android/app/DexLoadReporter.java
+++ b/core/java/android/app/DexLoadReporter.java
@@ -87,7 +87,7 @@
}
@Override
- public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) {
+ public void report(List<ClassLoader> classLoadersChain, List<String> classPaths) {
if (classLoadersChain.size() != classPaths.size()) {
Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch");
return;
@@ -113,12 +113,12 @@
registerSecondaryDexForProfiling(dexPathsForRegistration);
}
- private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain,
+ private void notifyPackageManager(List<ClassLoader> classLoadersChain,
List<String> classPaths) {
// Get the class loader names for the binder call.
List<String> classLoadersNames = new ArrayList<>(classPaths.size());
- for (BaseDexClassLoader bdc : classLoadersChain) {
- classLoadersNames.add(bdc.getClass().getName());
+ for (ClassLoader classLoader : classLoadersChain) {
+ classLoadersNames.add(classLoader.getClass().getName());
}
String packageName = ActivityThread.currentPackageName();
try {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e759762..e2312a5 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -475,7 +475,7 @@
* instrumentation at a time. An active instrumentation is one running and
* started from the shell.
*/
- void startDelegateShellPermissionIdentity(int uid);
+ void startDelegateShellPermissionIdentity(int uid, in String[] permissions);
/**
* Method for the shell UID to stop deletating its permission identity to an
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 6f11a76..09b77d5 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -118,7 +118,7 @@
int startActivityAsCaller(in IApplicationThread caller, in String callingPackage,
in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
- boolean ignoreTargetSecurity, int userId);
+ IBinder permissionToken, boolean ignoreTargetSecurity, int userId);
void unhandledBack();
boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
@@ -193,6 +193,20 @@
in ActivityManager.TaskDescription description, in Bitmap thumbnail);
Point getAppTaskThumbnailSize();
boolean releaseActivityInstance(in IBinder token);
+ /**
+ * Only callable from the system. This token grants a temporary permission to call
+ * #startActivityAsCallerWithToken. The token will time out after
+ * START_AS_CALLER_TOKEN_TIMEOUT if it is not used.
+ *
+ * @param delegatorToken The Binder token referencing the system Activity that wants to delegate
+ * the #startActivityAsCaller to another app. The "caller" will be the caller of this
+ * activity's token, not the delegate's caller (which is probably the delegator itself).
+ *
+ * @return Returns a token that can be given to a "delegate" app that may call
+ * #startActivityAsCaller
+ */
+ IBinder requestStartActivityPermissionToken(in IBinder delegatorToken);
+
void releaseSomeActivities(in IApplicationThread app);
Bitmap getTaskDescriptionIcon(in String filename, int userId);
void startInPlaceAnimationOnFrontMostApplication(in Bundle opts);
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl
index ac4bf7d..96da72a 100644
--- a/core/java/android/app/IUiAutomationConnection.aidl
+++ b/core/java/android/app/IUiAutomationConnection.aidl
@@ -47,7 +47,7 @@
in ParcelFileDescriptor source);
void grantRuntimePermission(String packageName, String permission, int userId);
void revokeRuntimePermission(String packageName, String permission, int userId);
- void adoptShellPermissionIdentity(int uid);
+ void adoptShellPermissionIdentity(int uid, in String[] permissions);
void dropShellPermissionIdentity();
// Called from the system process.
oneway void shutdown();
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 1144e26..015bc6c 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1009,7 +1009,7 @@
* from its event processing, though it may <em>not</em> have completely
* finished reacting from the event -- for example, if it needs to update
* its display as a result, it may still be in the process of doing that.
- *
+ *
* @param event The event to send to the current focus.
*/
public void sendKeySync(KeyEvent event) {
@@ -1017,14 +1017,7 @@
long downTime = event.getDownTime();
long eventTime = event.getEventTime();
- int action = event.getAction();
- int code = event.getKeyCode();
- int repeatCount = event.getRepeatCount();
- int metaState = event.getMetaState();
- int deviceId = event.getDeviceId();
- int scancode = event.getScanCode();
int source = event.getSource();
- int flags = event.getFlags();
if (source == InputDevice.SOURCE_UNKNOWN) {
source = InputDevice.SOURCE_KEYBOARD;
}
@@ -1034,12 +1027,14 @@
if (downTime == 0) {
downTime = eventTime;
}
- KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
- deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
+ KeyEvent newEvent = new KeyEvent(event);
+ newEvent.setTime(downTime, eventTime);
+ newEvent.setSource(source);
+ newEvent.setFlags(event.getFlags() | KeyEvent.FLAG_FROM_SYSTEM);
InputManager.getInstance().injectInputEvent(newEvent,
InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
-
+
/**
* Sends an up and down key event sync to the currently focused window.
*
@@ -1902,8 +1897,8 @@
@UnsupportedAppUsage
public ActivityResult execStartActivityAsCaller(
Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options, boolean ignoreTargetSecurity,
- int userId) {
+ Intent intent, int requestCode, Bundle options, IBinder permissionToken,
+ boolean ignoreTargetSecurity, int userId) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
@@ -1934,7 +1929,8 @@
.startActivityAsCaller(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options, ignoreTargetSecurity, userId);
+ requestCode, 0, null, options, permissionToken,
+ ignoreTargetSecurity, userId);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 4f4df5d..df37a02 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5937,8 +5937,9 @@
/**
* @return whether this notification is a foreground service notification
+ * @hide
*/
- private boolean isForegroundService() {
+ public boolean isForegroundService() {
return (flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 713f752..0123551 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -23,6 +23,7 @@
import android.app.admin.IDevicePolicyManager;
import android.app.job.IJobScheduler;
import android.app.job.JobScheduler;
+import android.app.role.RoleManager;
import android.app.slice.SliceManager;
import android.app.timedetector.TimeDetector;
import android.app.timezone.RulesManager;
@@ -152,6 +153,7 @@
import android.telephony.TelephonyManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
+import android.telephony.rcs.RcsManager;
import android.util.ArrayMap;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -546,6 +548,14 @@
return new SubscriptionManager(ctx.getOuterContext());
}});
+ registerService(Context.TELEPHONY_RCS_SERVICE, RcsManager.class,
+ new CachedServiceFetcher<RcsManager>() {
+ @Override
+ public RcsManager createService(ContextImpl ctx) {
+ return new RcsManager();
+ }
+ });
+
registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
new CachedServiceFetcher<CarrierConfigManager>() {
@Override
@@ -1120,6 +1130,14 @@
public PermissionManager createService(ContextImpl ctx) {
return new PermissionManager(ctx.getOuterContext());
}});
+
+ registerService(Context.ROLE_SERVICE, RoleManager.class,
+ new CachedServiceFetcher<RoleManager>() {
+ @Override
+ public RoleManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ return new RoleManager(ctx.getOuterContext());
+ }});
}
/**
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 5a25f5a..3f9627e 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -354,12 +354,17 @@
}
/**
- * Adopt the permission identity of the shell UID. This allows you to call APIs protected
- * permissions which normal apps cannot hold but are granted to the shell UID. If you
- * already adopted the shell permission identity this method would be a no-op.
- * Note that your permission state becomes that of the shell UID and it is not a
- * combination of your and the shell UID permissions.
+ * Adopt the permission identity of the shell UID for all permissions. This allows
+ * you to call APIs protected permissions which normal apps cannot hold but are
+ * granted to the shell UID. If you already adopted all shell permissions by calling
+ * this method or {@link #adoptShellPermissionIdentity(String...)} a subsequent call
+ * would be a no-op. Note that your permission state becomes that of the shell UID
+ * and it is not a combination of your and the shell UID permissions.
+ * <p>
+ * <strong>Note:<strong/> Calling this method adopts all shell permissions and overrides
+ * any subset of adopted permissions via {@link #adoptShellPermissionIdentity(String...)}.
*
+ * @see #adoptShellPermissionIdentity(String...)
* @see #dropShellPermissionIdentity()
*/
public void adoptShellPermissionIdentity() {
@@ -368,7 +373,33 @@
}
try {
// Calling out without a lock held.
- mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid());
+ mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), null);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Error executing adopting shell permission identity!", re);
+ }
+ }
+
+ /**
+ * Adopt the permission identity of the shell UID only for the provided permissions.
+ * This allows you to call APIs protected permissions which normal apps cannot hold
+ * but are granted to the shell UID. If you already adopted the specified shell
+ * permissions by calling this method or {@link #adoptShellPermissionIdentity()} a
+ * subsequent call would be a no-op. Note that your permission state becomes that of the
+ * shell UID and it is not a combination of your and the shell UID permissions.
+ * <p>
+ * <strong>Note:<strong/> Calling this method adopts only the specified shell permissions
+ * and overrides all adopted permissions via {@link #adoptShellPermissionIdentity()}.
+ *
+ * @see #adoptShellPermissionIdentity()
+ * @see #dropShellPermissionIdentity()
+ */
+ public void adoptShellPermissionIdentity(String... permissions) {
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ }
+ try {
+ // Calling out without a lock held.
+ mUiAutomationConnection.adoptShellPermissionIdentity(Process.myUid(), permissions);
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error executing adopting shell permission identity!", re);
}
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index b406d9e..dc2f983 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -18,7 +18,7 @@
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.IAccessibilityServiceClient;
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.graphics.Bitmap;
@@ -279,7 +279,8 @@
}
@Override
- public void adoptShellPermissionIdentity(int uid) throws RemoteException {
+ public void adoptShellPermissionIdentity(int uid, @Nullable String[] permissions)
+ throws RemoteException {
synchronized (mLock) {
throwIfCalledByNotTrustedUidLocked();
throwIfShutdownLocked();
@@ -287,7 +288,7 @@
}
final long identity = Binder.clearCallingIdentity();
try {
- mActivityManager.startDelegateShellPermissionIdentity(uid);
+ mActivityManager.startDelegateShellPermissionIdentity(uid, permissions);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 43f902a..cc4d4b1a 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -61,37 +61,39 @@
* <a href="/guide/topics/text/autofill">Autofill Framework</a> guides.
*/
public class AssistStructure implements Parcelable {
- static final String TAG = "AssistStructure";
+ private static final String TAG = "AssistStructure";
- static final boolean DEBUG_PARCEL = false;
- static final boolean DEBUG_PARCEL_CHILDREN = false;
- static final boolean DEBUG_PARCEL_TREE = false;
+ private static final boolean DEBUG_PARCEL = false;
+ private static final boolean DEBUG_PARCEL_CHILDREN = false;
+ private static final boolean DEBUG_PARCEL_TREE = false;
- static final int VALIDATE_WINDOW_TOKEN = 0x11111111;
- static final int VALIDATE_VIEW_TOKEN = 0x22222222;
+ private static final int VALIDATE_WINDOW_TOKEN = 0x11111111;
+ private static final int VALIDATE_VIEW_TOKEN = 0x22222222;
- boolean mHaveData;
+ private boolean mHaveData;
- ComponentName mActivityComponent;
+ // The task id and component of the activity which this assist structure is for
+ private int mTaskId;
+ private ComponentName mActivityComponent;
private boolean mIsHomeActivity;
private int mFlags;
private int mAutofillFlags;
- final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
+ private final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
- final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
+ private final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>();
- SendChannel mSendChannel;
- IBinder mReceiveChannel;
+ private SendChannel mSendChannel;
+ private IBinder mReceiveChannel;
- Rect mTmpRect = new Rect();
+ private Rect mTmpRect = new Rect();
- boolean mSanitizeOnWrite = false;
+ private boolean mSanitizeOnWrite = false;
private long mAcquisitionStartTime;
private long mAcquisitionEndTime;
- static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
- static final String DESCRIPTOR = "android.app.AssistStructure";
+ private static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1;
+ private static final String DESCRIPTOR = "android.app.AssistStructure";
/** @hide */
public void setAcquisitionStartTime(long acquisitionStartTime) {
@@ -197,7 +199,6 @@
ParcelTransferWriter(AssistStructure as, Parcel out) {
mSanitizeOnWrite = as.mSanitizeOnWrite;
mWriteStructure = as.waitForReady();
- ComponentName.writeToParcel(as.mActivityComponent, out);
out.writeInt(as.mFlags);
out.writeInt(as.mAutofillFlags);
out.writeLong(as.mAcquisitionStartTime);
@@ -353,7 +354,6 @@
void go() {
fetchData();
- mActivityComponent = ComponentName.readFromParcel(mCurParcel);
mFlags = mCurParcel.readInt();
mAutofillFlags = mCurParcel.readInt();
mAcquisitionStartTime = mCurParcel.readLong();
@@ -2129,7 +2129,6 @@
/** @hide */
public AssistStructure(Activity activity, boolean forAutoFill, int flags) {
mHaveData = true;
- mActivityComponent = activity.getComponentName();
mFlags = flags;
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
activity.getActivityToken());
@@ -2145,12 +2144,13 @@
public AssistStructure() {
mHaveData = true;
- mActivityComponent = null;
mFlags = 0;
}
/** @hide */
public AssistStructure(Parcel in) {
+ mTaskId = in.readInt();
+ mActivityComponent = ComponentName.readFromParcel(in);
mIsHomeActivity = in.readInt() == 1;
mReceiveChannel = in.readStrongBinder();
}
@@ -2171,7 +2171,10 @@
Log.i(TAG, "dump(): calling ensureData() first");
ensureData();
}
- Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
+ Log.i(TAG, "Task id: " + mTaskId);
+ Log.i(TAG, "Activity: " + (mActivityComponent != null
+ ? mActivityComponent.flattenToShortString()
+ : null));
Log.i(TAG, "Sanitize on write: " + mSanitizeOnWrite);
Log.i(TAG, "Flags: " + mFlags);
final int N = getWindowNodeCount();
@@ -2283,23 +2286,37 @@
}
/**
- * Return the activity this AssistStructure came from.
+ * Sets the task id is associated with the activity from which this AssistStructure was
+ * generated.
+ * @hide
*/
- public ComponentName getActivityComponent() {
- ensureData();
- return mActivityComponent;
+ public void setTaskId(int taskId) {
+ mTaskId = taskId;
}
/**
- * Called by Autofill server when app forged a different value.
- *
+ * @return The task id for the associated activity.
+ * @hide
+ */
+ public int getTaskId() {
+ return mTaskId;
+ }
+
+ /**
+ * Sets the activity that is associated with this AssistStructure.
* @hide
*/
public void setActivityComponent(ComponentName componentName) {
- ensureData();
mActivityComponent = componentName;
}
+ /**
+ * Return the activity this AssistStructure came from.
+ */
+ public ComponentName getActivityComponent() {
+ return mActivityComponent;
+ }
+
/** @hide */
public int getFlags() {
return mFlags;
@@ -2393,6 +2410,8 @@
@Override
public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(mTaskId);
+ ComponentName.writeToParcel(mActivityComponent, out);
out.writeInt(mIsHomeActivity ? 1 : 0);
if (mHaveData) {
// This object holds its data. We want to write a send channel that the
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index c6e94c7..318dbee 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -24,6 +24,8 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Color;
@@ -622,6 +624,7 @@
}
}
defaultView = inflater.inflate(layoutId, this, false);
+ defaultView.setOnClickListener(this::onDefaultViewClicked);
} else {
Log.w(TAG, "can't inflate defaultView because mInfo is missing");
}
@@ -641,6 +644,19 @@
return defaultView;
}
+ private void onDefaultViewClicked(View view) {
+ if (mInfo != null) {
+ LauncherApps launcherApps = getContext().getSystemService(LauncherApps.class);
+ List<LauncherActivityInfo> activities = launcherApps.getActivityList(
+ mInfo.provider.getPackageName(), mInfo.getProfile());
+ if (!activities.isEmpty()) {
+ LauncherActivityInfo ai = activities.get(0);
+ launcherApps.startMainActivity(ai.getComponentName(), ai.getUser(),
+ RemoteViews.getSourceBounds(view), null);
+ }
+ }
+ }
+
/**
* Inflate and return a view that represents an error state.
*/
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index ed3d455..8777b67 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -27,6 +27,7 @@
import android.net.Uri;
import android.os.Build;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.StrictMode;
import android.text.Html;
@@ -170,6 +171,11 @@
static final String[] MIMETYPES_TEXT_INTENT = new String[] {
ClipDescription.MIMETYPE_TEXT_INTENT };
+ // Constants used in {@link #writeHtmlTextToParcel}.
+ static final int PARCEL_MAX_SIZE_BYTES = 800 * 1024;
+ static final int PARCEL_TYPE_STRING = 0;
+ static final int PARCEL_TYPE_PFD = 1;
+
final ClipDescription mClipDescription;
final Bitmap mIcon;
@@ -225,6 +231,10 @@
* with an alternative HTML formatted representation. You <em>must</em>
* supply a plain text representation in addition to HTML text; coercion
* will not be done from HTML formatted text into plain text.
+ * <p class="note"><strong>Note:</strong> It is strongly recommended to
+ * use content: URI for sharing large clip data. Starting on API 30,
+ * ClipData.Item doesn't accept an HTML text if it's larger than 800KB.
+ * </p>
*/
public Item(CharSequence text, String htmlText) {
mText = text;
@@ -1132,7 +1142,7 @@
for (int i=0; i<N; i++) {
Item item = mItems.get(i);
TextUtils.writeToParcel(item.mText, dest, flags);
- dest.writeString(item.mHtmlText);
+ writeHtmlTextToParcel(item.mHtmlText, dest, flags);
if (item.mIntent != null) {
dest.writeInt(1);
item.mIntent.writeToParcel(dest, flags);
@@ -1159,7 +1169,7 @@
final int N = in.readInt();
for (int i=0; i<N; i++) {
CharSequence text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
- String htmlText = in.readString();
+ String htmlText = readHtmlTextFromParcel(in);
Intent intent = in.readInt() != 0 ? Intent.CREATOR.createFromParcel(in) : null;
Uri uri = in.readInt() != 0 ? Uri.CREATOR.createFromParcel(in) : null;
mItems.add(new Item(text, htmlText, intent, uri));
@@ -1179,4 +1189,61 @@
return new ClipData[size];
}
};
+
+ /**
+ * Helper function for writing an HTML text into a parcel.
+ * If the text size is larger than 400KB, it writes the text to a file descriptor to prevent the
+ * parcel from exceeding 800KB binder size limit. {@link android.os.Binder#checkParcel()}
+ * Otherwise, it directly writes the text into the parcel.
+ * Note: This function is a workaround for existing applications that still use HTML for sharing
+ * large clip data. We will ask application developers to use content: URI instead and remove
+ * this function in API 30.
+ */
+ private static void writeHtmlTextToParcel(String text, Parcel dest, int flags) {
+ byte[] textData = (text != null) ? text.getBytes() : new byte[0];
+ if (textData.length > PARCEL_MAX_SIZE_BYTES / 2
+ && Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
+ try {
+ ParcelFileDescriptor pfd = ParcelFileDescriptor.fromData(textData, null);
+ dest.writeInt(PARCEL_TYPE_PFD);
+ dest.writeParcelable(pfd, flags);
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "Error creating the shared memory area: " + e.toString());
+ }
+ } else {
+ dest.writeInt(PARCEL_TYPE_STRING);
+ dest.writeString(text);
+ }
+ }
+
+ /**
+ * Reads a text written by writeHtmlTextToParcel.
+ */
+ private static String readHtmlTextFromParcel(Parcel in) {
+ if (in.readInt() == PARCEL_TYPE_STRING) {
+ return in.readString();
+ }
+ ParcelFileDescriptor pfd =
+ in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
+ if (pfd == null) {
+ throw new IllegalStateException("Error reading ParcelFileDescriptor from Parcel");
+ }
+ FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+ InputStreamReader reader = new InputStreamReader(fis);
+ StringBuilder builder = new StringBuilder();
+ char[] buffer = new char[4096];
+ int numRead;
+ try {
+ while ((numRead = reader.read(buffer)) != -1) {
+ builder.append(buffer, 0, numRead);
+ }
+ return builder.toString();
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "Error reading data from ParcelFileDescriptor: " + e.toString());
+ } finally {
+ IoUtils.closeQuietly(fis);
+ }
+ }
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2aa32c4..9f8ae0b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4367,6 +4367,13 @@
public static final String APP_BINDING_SERVICE = "app_binding";
/**
+ * Use with {@link #getSystemService(String)} to retrieve an
+ * {@link android.telephony.rcs.RcsManager}.
+ * @hide
+ */
+ public static final String TELEPHONY_RCS_SERVICE = "ircs";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index aa34da8..02f38a7 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1727,10 +1727,14 @@
= "android.intent.extra.UNINSTALL_ALL_USERS";
/**
- * A string associated with a {@link #ACTION_UPGRADE_SETUP} activity
- * describing the last run version of the platform that was setup.
+ * A string that associates with a metadata entry, indicating the last run version of the
+ * platform that was setup.
+ *
+ * @see #ACTION_UPGRADE_SETUP
+ *
* @hide
*/
+ @SystemApi
public static final String METADATA_SETUP_VERSION = "android.SETUP_VERSION";
/**
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6b5c659..48240db 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -27,7 +27,6 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
@@ -1171,11 +1170,11 @@
* system apps.
* @hide
*/
- public static final int HIDDEN_API_ENFORCEMENT_NONE = 0;
+ public static final int HIDDEN_API_ENFORCEMENT_DISABLED = 0;
/**
* No API enforcement, but enable the detection logic and warnings. Observed behaviour is the
- * same as {@link #HIDDEN_API_ENFORCEMENT_NONE} but you may see warnings in the log when APIs
- * are accessed.
+ * same as {@link #HIDDEN_API_ENFORCEMENT_DISABLED} but you may see warnings in the log when
+ * APIs are accessed.
* @hide
* */
public static final int HIDDEN_API_ENFORCEMENT_JUST_WARN = 1;
@@ -1183,14 +1182,10 @@
* Dark grey list enforcement. Enforces the dark grey and black lists
* @hide
*/
- public static final int HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK = 2;
- /**
- * Blacklist enforcement only.
- * @hide
- */
- public static final int HIDDEN_API_ENFORCEMENT_BLACK = 3;
+ public static final int HIDDEN_API_ENFORCEMENT_ENABLED = 2;
- private static final int HIDDEN_API_ENFORCEMENT_MAX = HIDDEN_API_ENFORCEMENT_BLACK;
+ private static final int HIDDEN_API_ENFORCEMENT_MIN = HIDDEN_API_ENFORCEMENT_DEFAULT;
+ private static final int HIDDEN_API_ENFORCEMENT_MAX = HIDDEN_API_ENFORCEMENT_ENABLED;
/**
* Values in this IntDef MUST be kept in sync with enum hiddenapi::EnforcementPolicy in
@@ -1199,17 +1194,16 @@
*/
@IntDef(prefix = { "HIDDEN_API_ENFORCEMENT_" }, value = {
HIDDEN_API_ENFORCEMENT_DEFAULT,
- HIDDEN_API_ENFORCEMENT_NONE,
+ HIDDEN_API_ENFORCEMENT_DISABLED,
HIDDEN_API_ENFORCEMENT_JUST_WARN,
- HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK,
- HIDDEN_API_ENFORCEMENT_BLACK,
+ HIDDEN_API_ENFORCEMENT_ENABLED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface HiddenApiEnforcementPolicy {}
/** @hide */
public static boolean isValidHiddenApiEnforcementPolicy(int policy) {
- return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX;
+ return policy >= HIDDEN_API_ENFORCEMENT_MIN && policy <= HIDDEN_API_ENFORCEMENT_MAX;
}
private int mHiddenApiPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT;
@@ -1749,16 +1743,12 @@
*/
public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() {
if (isAllowedToUseHiddenApis()) {
- return HIDDEN_API_ENFORCEMENT_NONE;
+ return HIDDEN_API_ENFORCEMENT_DISABLED;
}
if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
return mHiddenApiPolicy;
}
- if (targetSdkVersion < Build.VERSION_CODES.P) {
- return HIDDEN_API_ENFORCEMENT_BLACK;
- } else {
- return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK;
- }
+ return HIDDEN_API_ENFORCEMENT_ENABLED;
}
/**
@@ -1777,23 +1767,15 @@
* This will have no effect if this app is not subject to hidden API enforcement, i.e. if it
* is on the package whitelist.
*
- * @param policyPreP configured policy for pre-P apps, or {@link
- * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured.
- * @param policyP configured policy for apps targeting P or later, or {@link
- * #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured.
+ * @param policy configured policy for this app, or {@link #HIDDEN_API_ENFORCEMENT_DEFAULT}
+ * if nothing configured.
* @hide
*/
- public void maybeUpdateHiddenApiEnforcementPolicy(
- @HiddenApiEnforcementPolicy int policyPreP, @HiddenApiEnforcementPolicy int policyP) {
+ public void maybeUpdateHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) {
if (isPackageWhitelistedForHiddenApis()) {
return;
}
- if (targetSdkVersion < Build.VERSION_CODES.P) {
- setHiddenApiEnforcementPolicy(policyPreP);
- } else if (targetSdkVersion >= Build.VERSION_CODES.P) {
- setHiddenApiEnforcementPolicy(policyP);
- }
-
+ setHiddenApiEnforcementPolicy(policy);
}
/**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 4a4de51..a87ee57 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -475,7 +475,7 @@
* @param classPaths the class paths corresponding to the class loaders names from
* {@param classLoadersNames}. The the first element corresponds to the first class loader
* and so on. A classpath is represented as a list of dex files separated by
- * {@code File.pathSeparator}.
+ * {@code File.pathSeparator}, or null if the class loader's classpath is not known.
* The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the loader process
*/
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c1ac061..d3e4045 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5825,16 +5825,16 @@
* {@code android.permission.SUSPEND_APPS} can put any app on the device into a suspended state.
*
* <p>While in this state, the application's notifications will be hidden, any of its started
- * activities will be stopped and it will not be able to show toasts or dialogs or ring the
- * device. When the user tries to launch a suspended app, the system will, instead, show a
+ * activities will be stopped and it will not be able to show toasts or dialogs or play audio.
+ * When the user tries to launch a suspended app, the system will, instead, show a
* dialog to the user informing them that they cannot use this app while it is suspended.
*
* <p>When an app is put into this state, the broadcast action
* {@link Intent#ACTION_MY_PACKAGE_SUSPENDED} will be delivered to any of its broadcast
* receivers that included this action in their intent-filters, <em>including manifest
* receivers.</em> Similarly, a broadcast action {@link Intent#ACTION_MY_PACKAGE_UNSUSPENDED}
- * is delivered when a previously suspended app is taken out of this state.
- * </p>
+ * is delivered when a previously suspended app is taken out of this state. Apps are expected to
+ * use these to gracefully deal with transitions to and from this state.
*
* @return {@code true} if the calling package has been suspended, {@code false} otherwise.
*
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 444ca87..7148b12 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -28,8 +28,8 @@
import android.hardware.camera2.utils.TypeReference;
import android.util.Rational;
-import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -2668,7 +2668,8 @@
/**
* <p>The arrangement of color filters on sensor;
* represents the colors in the top-left 2x2 section of
- * the sensor, in reading order.</p>
+ * the sensor, in reading order, for a Bayer camera, or the
+ * light spectrum it captures for MONOCHROME camera.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB RGGB}</li>
@@ -2676,6 +2677,8 @@
* <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG GBRG}</li>
* <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR BGGR}</li>
* <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB RGB}</li>
+ * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO MONO}</li>
+ * <li>{@link #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR NIR}</li>
* </ul></p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Full capability</b> -
@@ -2688,6 +2691,8 @@
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR
* @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB
+ * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO
+ * @see #SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR
*/
@PublicKey
public static final Key<Integer> SENSOR_INFO_COLOR_FILTER_ARRANGEMENT =
@@ -2919,6 +2924,8 @@
* <p>Some devices may choose to provide a second set of calibration
* information for improved quality, including
* {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2} and its corresponding matrices.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Possible values:</b>
* <ul>
* <li>{@link #SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT DAYLIGHT}</li>
@@ -2981,6 +2988,8 @@
* <p>If this key is present, then {@link CameraCharacteristics#SENSOR_COLOR_TRANSFORM2 android.sensor.colorTransform2},
* {@link CameraCharacteristics#SENSOR_CALIBRATION_TRANSFORM2 android.sensor.calibrationTransform2}, and
* {@link CameraCharacteristics#SENSOR_FORWARD_MATRIX2 android.sensor.forwardMatrix2} will also be present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Range of valid values:</b><br>
* Any value listed in {@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -3006,6 +3015,8 @@
* colorspace) into this camera device's native sensor color
* space under the first reference illuminant
* ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT1 android.sensor.referenceIlluminant1}).</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3029,6 +3040,8 @@
* ({@link CameraCharacteristics#SENSOR_REFERENCE_ILLUMINANT2 android.sensor.referenceIlluminant2}).</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3053,6 +3066,8 @@
* and the CIE XYZ colorspace when calculating this transform will
* match the standard white point for the first reference illuminant
* (i.e. no chromatic adaptation will be applied by this transform).</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3079,6 +3094,8 @@
* (i.e. no chromatic adaptation will be applied by this transform).</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3101,6 +3118,8 @@
* this matrix is chosen so that the standard white point for this reference
* illuminant in the reference sensor colorspace is mapped to D50 in the
* CIE XYZ colorspace.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3125,6 +3144,8 @@
* CIE XYZ colorspace.</p>
* <p>This matrix will only be present if the second reference
* illuminant is present.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* <p><b>Permission {@link android.Manifest.permission#CAMERA } is needed to access this property</b></p>
*
@@ -3153,6 +3174,7 @@
* level values. For raw capture in particular, it is recommended to use
* pixels from {@link CameraCharacteristics#SENSOR_OPTICAL_BLACK_REGIONS android.sensor.opticalBlackRegions} to calculate black
* level values for each frame.</p>
+ * <p>For a MONOCHROME camera device, all of the 2x2 channels must have the same values.</p>
* <p><b>Range of valid values:</b><br>
* >= 0 for each.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index ac00f14..dc6cffc 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -357,7 +357,7 @@
* </p>
*
* <p>MONOCHROME-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}
- * includes {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME})
+ * includes {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME}) devices
* supporting {@link android.graphics.ImageFormat#Y8 Y8} support substituting {@code YUV}
* streams with {@code Y8} in all guaranteed stream combinations for the device's hardware level
* and capabilities.</p>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index ffc2264..402472a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -880,11 +880,15 @@
/**
* <p>The camera device is a monochrome camera that doesn't contain a color filter array,
- * and the pixel values on U and V planes are all 128.</p>
+ * and for YUV_420_888 stream, the pixel values on U and V planes are all 128.</p>
* <p>A MONOCHROME camera must support the guaranteed stream combinations required for
* its device level and capabilities. Additionally, if the monochrome camera device
* supports Y8 format, all mandatory stream combination requirements related to {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888} apply
- * to {@link android.graphics.ImageFormat#Y8 Y8} as well.</p>
+ * to {@link android.graphics.ImageFormat#Y8 Y8} as well. There are no
+ * mandatory stream combination requirements with regard to
+ * {@link android.graphics.ImageFormat#Y8 Y8} for Bayer camera devices.</p>
+ * <p>Starting from Android Q, the SENSOR_INFO_COLOR_FILTER_ARRANGEMENT of a MONOCHROME
+ * camera will be either MONO or NIR.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12;
@@ -937,6 +941,23 @@
*/
public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB = 4;
+ /**
+ * <p>Sensor doesn't have any Bayer color filter.
+ * Such sensor captures visible light in monochrome. The exact weighting and
+ * wavelengths captured is not specified, but generally only includes the visible
+ * frequencies. This value implies a MONOCHROME camera.</p>
+ * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+ */
+ public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO = 5;
+
+ /**
+ * <p>Sensor has a near infrared filter capturing light with wavelength between
+ * roughly 750nm and 1400nm, and the same filter covers the whole sensor array. This
+ * value implies a MONOCHROME camera.</p>
+ * @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
+ */
+ public static final int SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR = 6;
+
//
// Enumeration values for CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 2744e91..8ebaf2f 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -24,8 +24,8 @@
import android.hardware.camera2.impl.SyntheticKey;
import android.hardware.camera2.params.OutputConfiguration;
import android.hardware.camera2.utils.HashCodeHelpers;
-import android.hardware.camera2.utils.TypeReference;
import android.hardware.camera2.utils.SurfaceUtils;
+import android.hardware.camera2.utils.TypeReference;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -2947,8 +2947,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
- * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
- * are ignored.</p>
+ * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+ * control points.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
@@ -3011,8 +3011,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
- * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
- * are ignored.</p>
+ * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+ * control points.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 2b67f3e..3d70c51 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -3417,6 +3417,8 @@
* used to interpolate between the provided color transforms when
* processing raw sensor data.</p>
* <p>The order of the values is R, G, B; where R is in the lowest index.</p>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*/
@PublicKey
@@ -3442,6 +3444,8 @@
* that channel.</p>
* <p>A more detailed description of the noise model can be found in the
* Adobe DNG specification for the NoiseProfile tag.</p>
+ * <p>For a MONOCHROME camera, there is only one color channel. So the noise model coefficients
+ * will only contain one S and one O.</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -3482,6 +3486,8 @@
* <li>R > 1.20 will require strong software correction to produce
* a usuable image (>20% divergence).</li>
* </ul>
+ * <p>Starting from Android Q, this key will not be present for a MONOCHROME camera, even if
+ * the camera device has RAW capability.</p>
* <p><b>Range of valid values:</b><br></p>
* <p>>= 0</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -3592,6 +3598,7 @@
* layout key (see {@link CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT android.sensor.info.colorFilterArrangement}), i.e. the
* nth value given corresponds to the black level offset for the nth
* color channel listed in the CFA.</p>
+ * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values.</p>
* <p>This key will be available if {@link CameraCharacteristics#SENSOR_OPTICAL_BLACK_REGIONS android.sensor.opticalBlackRegions} is available or the
* camera device advertises this key via {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureResultKeys }.</p>
* <p><b>Range of valid values:</b><br>
@@ -3852,6 +3859,17 @@
* <p>As a visualization only, inverting the full-color map to recover an
* image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p>
* <p><img alt="Image of a uniform white wall (inverse shading map)" src="/reference/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+ * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example
+ * shading map for such a camera is defined as:</p>
+ * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ]
+ * android.statistics.lensShadingMap =
+ * [ 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.1, 1.1, 1.1, 1.1, 1.3, 1.3, 1.3, 1.3,
+ * 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1,
+ * 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.2, 1.2,
+ * 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.2, 1.2, 1.2, 1.2, 1.3, 1.3, 1.3, 1.3 ]
+ * </code></pre>
* <p><b>Range of valid values:</b><br>
* Each gain factor is >= 1</p>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
@@ -3894,13 +3912,13 @@
* (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
* pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
* The map is assumed to be bilinearly interpolated between the sample points.</p>
- * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
- * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+ * <p>For a Bayer camera, the channel order is [R, Geven, Godd, B], where Geven is
+ * the green channel for the even rows of a Bayer pattern, and Godd is the odd rows.
* The shading map is stored in a fully interleaved format, and its size
* is provided in the camera static metadata by android.lens.info.shadingMapSize.</p>
* <p>The shading map will generally have on the order of 30-40 rows and columns,
* and will be smaller than 64x64.</p>
- * <p>As an example, given a very small map defined as:</p>
+ * <p>As an example, given a very small map for a Bayer camera defined as:</p>
* <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ]
* android.statistics.lensShadingMap =
* [ 1.3, 1.2, 1.15, 1.2, 1.2, 1.2, 1.15, 1.2,
@@ -3920,6 +3938,17 @@
* image of a gray wall (using bicubic interpolation for visual quality)
* as captured by the sensor gives:</p>
* <p><img alt="Image of a uniform white wall (inverse shading map)" src="/reference/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+ * <p>For a MONOCHROME camera, all of the 2x2 channels must have the same values. An example
+ * shading map for such a camera is defined as:</p>
+ * <pre><code>android.lens.info.shadingMapSize = [ 4, 3 ]
+ * android.statistics.lensShadingMap =
+ * [ 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.1, 1.1, 1.1, 1.1, 1.3, 1.3, 1.3, 1.3,
+ * 1.2, 1.2, 1.2, 1.2, 1.1, 1.1, 1.1, 1.1,
+ * 1.0, 1.0, 1.0, 1.0, 1.2, 1.2, 1.2, 1.2,
+ * 1.3, 1.3, 1.3, 1.3, 1.2, 1.2, 1.2, 1.2,
+ * 1.2, 1.2, 1.2, 1.2, 1.3, 1.3, 1.3, 1.3 ]
+ * </code></pre>
* <p>Note that the RAW image data might be subject to lens shading
* correction not reported on this map. Query
* {@link CameraCharacteristics#SENSOR_INFO_LENS_SHADING_APPLIED android.sensor.info.lensShadingApplied} to see if RAW image data has subject
@@ -4250,8 +4279,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
- * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
- * are ignored.</p>
+ * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+ * control points.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
@@ -4314,8 +4343,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
- * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
- * are ignored.</p>
+ * <p>For devices with MONOCHROME capability, all three channels must have the same set of
+ * control points.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
diff --git a/core/java/android/hardware/camera2/params/BlackLevelPattern.java b/core/java/android/hardware/camera2/params/BlackLevelPattern.java
index 6d6c094..283977f 100644
--- a/core/java/android/hardware/camera2/params/BlackLevelPattern.java
+++ b/core/java/android/hardware/camera2/params/BlackLevelPattern.java
@@ -16,13 +16,17 @@
package android.hardware.camera2.params;
-import java.util.Arrays;
-
import static com.android.internal.util.Preconditions.checkNotNull;
+import java.util.Arrays;
+
/**
* Immutable class to store a 4-element vector of integers corresponding to a 2x2 pattern
* of color channel offsets used for the black level offsets of each color channel.
+ *
+ * For a camera device with
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
+ * MONOCHROME} capability, all 4 elements of the pattern will have the same value.
*/
public final class BlackLevelPattern {
@@ -133,6 +137,12 @@
* {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT}).
* </p>
*
+ * <p>A {@link
+ * android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
+ * MONOCHROME} camera only has one channel. As a result, the returned string will contain 4
+ * identical values.
+ * </p>
+ *
* @return string representation of {@link BlackLevelPattern}
*
* @see android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
diff --git a/core/java/android/hardware/camera2/params/TonemapCurve.java b/core/java/android/hardware/camera2/params/TonemapCurve.java
index 71e68a5..90e6355 100644
--- a/core/java/android/hardware/camera2/params/TonemapCurve.java
+++ b/core/java/android/hardware/camera2/params/TonemapCurve.java
@@ -34,6 +34,10 @@
* use as the tonemapping/contrast/gamma curve when {@link CaptureRequest#TONEMAP_MODE} is
* set to {@link CameraMetadata#TONEMAP_MODE_CONTRAST_CURVE}.</p>
*
+ * <p>For a camera device with
+ * {@link android.hardware.camera2.CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME
+ * MONOCHROME} capability, all 3 channels will contain the same set of control points.
+ *
* <p>The total number of points {@code (Pin, Pout)} for each color channel can be no more than
* {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS}.</p>
*
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 01ef58e..82e765d 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -263,6 +263,7 @@
* @see KeyguardManager#isDeviceLocked()
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
// TODO: Update name and documentation and un-hide the flag. Don't change the value before that.
public static final int VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
@@ -295,6 +296,7 @@
* @see #createVirtualDisplay
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;
/**
@@ -304,6 +306,7 @@
* @see #createVirtualDisplay
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
/** @hide */
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index 007f4bc..dc4f0b7 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -611,6 +611,13 @@
* @hide
*/
public static final int RECOGNITION_STATUS_FAILURE = 2;
+ /**
+ * Recognition event was triggered by a getModelState request, not by the
+ * DSP.
+ *
+ * @hide
+ */
+ public static final int RECOGNITION_STATUS_GET_STATE_RESPONSE = 3;
/**
* A RecognitionEvent is provided by the
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index e970747..402c228 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -133,12 +133,21 @@
public native int stopRecognition(int soundModelHandle);
/**
- * Get the current state of a {@link SoundTrigger.SoundModel}
+ * Get the current state of a {@link SoundTrigger.SoundModel}.
+ * The state will be returned asynchronously as a {@link SoundTrigger#RecognitionEvent}
+ * in the callback registered in the {@link SoundTrigger.startRecognition} method.
* @param soundModelHandle The sound model handle indicating which model's state to return
- * @return - {@link SoundTrigger#RecognitionEvent} in case of success
- * - null in case of an error or if not supported
+ * @return - {@link SoundTrigger#STATUS_OK} in case of success
+ * - {@link SoundTrigger#STATUS_ERROR} in case of unspecified error
+ * - {@link SoundTrigger#STATUS_PERMISSION_DENIED} if the caller does not have
+ * system permission
+ * - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+ * - {@link SoundTrigger#STATUS_BAD_VALUE} if the sound model handle is invalid
+ * - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
+ * service fails
+ * - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
*/
- public native SoundTrigger.RecognitionEvent getModelState(int soundModelHandle);
+ public native int getModelState(int soundModelHandle);
private class NativeEventHandlerDelegate {
private final Handler mHandler;
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
new file mode 100644
index 0000000..b4b541d
--- /dev/null
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright (C) 2018 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.inputmethodservice;
+
+import android.annotation.Nullable;
+import android.annotation.WorkerThread;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.util.Log;
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.ExtractedText;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IMultiClientInputMethodSession;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.InputConnectionWrapper;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Re-dispatches all the incoming per-client events to the specified {@link Looper} thread.
+ *
+ * <p>There are three types of per-client callbacks.</p>
+ *
+ * <ul>
+ * <li>{@link IInputMethodSession} - from the IME client</li>
+ * <li>{@link IMultiClientInputMethodSession} - from MultiClientInputMethodManagerService</li>
+ * <li>{@link InputChannel} - from the IME client</li>
+ * </ul>
+ *
+ * <p>This class serializes all the incoming events among those channels onto
+ * {@link MultiClientInputMethodServiceDelegate.ClientCallback} on the specified {@link Looper}
+ * thread.</p>
+ */
+final class MultiClientInputMethodClientCallbackAdaptor {
+ static final boolean DEBUG = false;
+ static final String TAG = MultiClientInputMethodClientCallbackAdaptor.class.getSimpleName();
+
+ private final Object mSessionLock = new Object();
+ @GuardedBy("mSessionLock")
+ CallbackImpl mCallbackImpl;
+ @GuardedBy("mSessionLock")
+ InputChannel mReadChannel;
+ @GuardedBy("mSessionLock")
+ KeyEvent.DispatcherState mDispatcherState;
+ @GuardedBy("mSessionLock")
+ Handler mHandler;
+ @GuardedBy("mSessionLock")
+ @Nullable
+ InputEventReceiver mInputEventReceiver;
+
+ private final AtomicBoolean mFinished = new AtomicBoolean(false);
+
+ IInputMethodSession.Stub createIInputMethodSession() {
+ synchronized (mSessionLock) {
+ return new InputMethodSessionImpl(
+ mSessionLock, mCallbackImpl, mHandler, mFinished);
+ }
+ }
+
+ IMultiClientInputMethodSession.Stub createIMultiClientInputMethodSession() {
+ synchronized (mSessionLock) {
+ return new MultiClientInputMethodSessionImpl(
+ mSessionLock, mCallbackImpl, mHandler, mFinished);
+ }
+ }
+
+ MultiClientInputMethodClientCallbackAdaptor(
+ MultiClientInputMethodServiceDelegate.ClientCallback clientCallback, Looper looper,
+ KeyEvent.DispatcherState dispatcherState, InputChannel readChannel) {
+ synchronized (mSessionLock) {
+ mCallbackImpl = new CallbackImpl(this, clientCallback);
+ mDispatcherState = dispatcherState;
+ mHandler = new Handler(looper, null, true);
+ mReadChannel = readChannel;
+ mInputEventReceiver = new ImeInputEventReceiver(mReadChannel, mHandler.getLooper(),
+ mFinished, mDispatcherState, mCallbackImpl.mOriginalCallback);
+ }
+ }
+
+ private static final class KeyEventCallbackAdaptor implements KeyEvent.Callback {
+ private final MultiClientInputMethodServiceDelegate.ClientCallback mLocalCallback;
+
+ KeyEventCallbackAdaptor(
+ MultiClientInputMethodServiceDelegate.ClientCallback callback) {
+ mLocalCallback = callback;
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ return mLocalCallback.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ return mLocalCallback.onKeyLongPress(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ return mLocalCallback.onKeyUp(keyCode, event);
+ }
+
+ @Override
+ public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
+ return mLocalCallback.onKeyMultiple(keyCode, event);
+ }
+ }
+
+ private static final class ImeInputEventReceiver extends InputEventReceiver {
+ private final AtomicBoolean mFinished;
+ private final KeyEvent.DispatcherState mDispatcherState;
+ private final MultiClientInputMethodServiceDelegate.ClientCallback mClientCallback;
+ private final KeyEventCallbackAdaptor mKeyEventCallbackAdaptor;
+
+ ImeInputEventReceiver(InputChannel readChannel, Looper looper, AtomicBoolean finished,
+ KeyEvent.DispatcherState dispatcherState,
+ MultiClientInputMethodServiceDelegate.ClientCallback callback) {
+ super(readChannel, looper);
+ mFinished = finished;
+ mDispatcherState = dispatcherState;
+ mClientCallback = callback;
+ mKeyEventCallbackAdaptor = new KeyEventCallbackAdaptor(callback);
+ }
+
+ @Override
+ public void onInputEvent(InputEvent event) {
+ if (mFinished.get()) {
+ // The session has been finished.
+ finishInputEvent(event, false);
+ return;
+ }
+ boolean handled = false;
+ try {
+ if (event instanceof KeyEvent) {
+ final KeyEvent keyEvent = (KeyEvent) event;
+ handled = keyEvent.dispatch(mKeyEventCallbackAdaptor, mDispatcherState,
+ mKeyEventCallbackAdaptor);
+ } else {
+ final MotionEvent motionEvent = (MotionEvent) event;
+ if (motionEvent.isFromSource(InputDevice.SOURCE_CLASS_TRACKBALL)) {
+ handled = mClientCallback.onTrackballEvent(motionEvent);
+ } else {
+ handled = mClientCallback.onGenericMotionEvent(motionEvent);
+ }
+ }
+ } finally {
+ finishInputEvent(event, handled);
+ }
+ }
+ }
+
+ private static final class InputMethodSessionImpl extends IInputMethodSession.Stub {
+ private final Object mSessionLock;
+ @GuardedBy("mSessionLock")
+ private CallbackImpl mCallbackImpl;
+ @GuardedBy("mSessionLock")
+ private Handler mHandler;
+ private final AtomicBoolean mSessionFinished;
+
+ InputMethodSessionImpl(Object lock, CallbackImpl callback, Handler handler,
+ AtomicBoolean sessionFinished) {
+ mSessionLock = lock;
+ mCallbackImpl = callback;
+ mHandler = handler;
+ mSessionFinished = sessionFinished;
+ }
+
+ @Override
+ public void updateExtractedText(int token, ExtractedText text) {
+ reportNotSupported();
+ }
+
+ @Override
+ public void updateSelection(int oldSelStart, int oldSelEnd,
+ int newSelStart, int newSelEnd,
+ int candidatesStart, int candidatesEnd) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ final SomeArgs args = SomeArgs.obtain();
+ args.argi1 = oldSelStart;
+ args.argi2 = oldSelEnd;
+ args.argi3 = newSelStart;
+ args.argi4 = newSelEnd;
+ args.argi5 = candidatesStart;
+ args.argi6 = candidatesEnd;
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::updateSelection, mCallbackImpl, args));
+ }
+ }
+
+ @Override
+ public void viewClicked(boolean focusChanged) {
+ reportNotSupported();
+ }
+
+ @Override
+ public void updateCursor(Rect newCursor) {
+ reportNotSupported();
+ }
+
+ @Override
+ public void displayCompletions(CompletionInfo[] completions) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::displayCompletions, mCallbackImpl, completions));
+ }
+ }
+
+ @Override
+ public void appPrivateCommand(String action, Bundle data) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::appPrivateCommand, mCallbackImpl, action, data));
+ }
+ }
+
+ @Override
+ public void toggleSoftInput(int showFlags, int hideFlags) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::toggleSoftInput, mCallbackImpl, showFlags,
+ hideFlags));
+ }
+ }
+
+ @Override
+ public void finishSession() {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mSessionFinished.set(true);
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::finishSession, mCallbackImpl));
+ mCallbackImpl = null;
+ mHandler = null;
+ }
+ }
+
+ @Override
+ public void updateCursorAnchorInfo(CursorAnchorInfo info) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::updateCursorAnchorInfo, mCallbackImpl, info));
+ }
+ }
+ }
+
+ private static final class MultiClientInputMethodSessionImpl
+ extends IMultiClientInputMethodSession.Stub {
+ private final Object mSessionLock;
+ @GuardedBy("mSessionLock")
+ private CallbackImpl mCallbackImpl;
+ @GuardedBy("mSessionLock")
+ private Handler mHandler;
+ private final AtomicBoolean mSessionFinished;
+
+ MultiClientInputMethodSessionImpl(Object lock, CallbackImpl callback,
+ Handler handler, AtomicBoolean sessionFinished) {
+ mSessionLock = lock;
+ mCallbackImpl = callback;
+ mHandler = handler;
+ mSessionFinished = sessionFinished;
+ }
+
+ @Override
+ public void startInputOrWindowGainedFocus(@Nullable IInputContext inputContext,
+ int missingMethods, @Nullable EditorInfo editorInfo, int controlFlags,
+ @SoftInputModeFlags int softInputMode, int windowHandle) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ final SomeArgs args = SomeArgs.obtain();
+ // TODO(Bug 119211536): Remove dependency on AbstractInputMethodService from ICW
+ final WeakReference<AbstractInputMethodService> fakeIMS =
+ new WeakReference<>(null);
+ args.arg1 = (inputContext == null) ? null
+ : new InputConnectionWrapper(fakeIMS, inputContext, missingMethods,
+ mSessionFinished);
+ args.arg2 = editorInfo;
+ args.argi1 = controlFlags;
+ args.argi2 = softInputMode;
+ args.argi3 = windowHandle;
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::startInputOrWindowGainedFocus, mCallbackImpl, args));
+ }
+ }
+
+ @Override
+ public void showSoftInput(int flags, ResultReceiver resultReceiver) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::showSoftInput, mCallbackImpl, flags,
+ resultReceiver));
+ }
+ }
+
+ @Override
+ public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
+ synchronized (mSessionLock) {
+ if (mCallbackImpl == null || mHandler == null) {
+ return;
+ }
+ mHandler.sendMessage(PooledLambda.obtainMessage(
+ CallbackImpl::hideSoftInput, mCallbackImpl, flags,
+ resultReceiver));
+ }
+ }
+ }
+
+ /**
+ * The maim part of adaptor to {@link MultiClientInputMethodServiceDelegate.ClientCallback}.
+ */
+ @WorkerThread
+ private static final class CallbackImpl {
+ private final MultiClientInputMethodClientCallbackAdaptor mCallbackAdaptor;
+ private final MultiClientInputMethodServiceDelegate.ClientCallback mOriginalCallback;
+ private boolean mFinished = false;
+
+ CallbackImpl(MultiClientInputMethodClientCallbackAdaptor callbackAdaptor,
+ MultiClientInputMethodServiceDelegate.ClientCallback callback) {
+ mCallbackAdaptor = callbackAdaptor;
+ mOriginalCallback = callback;
+ }
+
+ void updateSelection(SomeArgs args) {
+ try {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onUpdateSelection(args.argi1, args.argi2, args.argi3,
+ args.argi4, args.argi5, args.argi6);
+ } finally {
+ args.recycle();
+ }
+ }
+
+ void displayCompletions(CompletionInfo[] completions) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onDisplayCompletions(completions);
+ }
+
+ void appPrivateCommand(String action, Bundle data) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onAppPrivateCommand(action, data);
+ }
+
+ void toggleSoftInput(int showFlags, int hideFlags) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onToggleSoftInput(showFlags, hideFlags);
+ }
+
+ void finishSession() {
+ if (mFinished) {
+ return;
+ }
+ mFinished = true;
+ mOriginalCallback.onFinishSession();
+ synchronized (mCallbackAdaptor.mSessionLock) {
+ mCallbackAdaptor.mDispatcherState = null;
+ if (mCallbackAdaptor.mReadChannel != null) {
+ mCallbackAdaptor.mReadChannel.dispose();
+ mCallbackAdaptor.mReadChannel = null;
+ }
+ mCallbackAdaptor.mInputEventReceiver = null;
+ }
+ }
+
+ void updateCursorAnchorInfo(CursorAnchorInfo info) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onUpdateCursorAnchorInfo(info);
+ }
+
+ void startInputOrWindowGainedFocus(SomeArgs args) {
+ try {
+ if (mFinished) {
+ return;
+ }
+ final InputConnectionWrapper inputConnection = (InputConnectionWrapper) args.arg1;
+ final EditorInfo editorInfo = (EditorInfo) args.arg2;
+ final int startInputFlags = args.argi1;
+ final int softInputMode = args.argi2;
+ final int windowHandle = args.argi3;
+ mOriginalCallback.onStartInputOrWindowGainedFocus(inputConnection, editorInfo,
+ startInputFlags, softInputMode, windowHandle);
+ } finally {
+ args.recycle();
+ }
+ }
+
+ void showSoftInput(int flags, ResultReceiver resultReceiver) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onShowSoftInput(flags, resultReceiver);
+ }
+
+ void hideSoftInput(int flags, ResultReceiver resultReceiver) {
+ if (mFinished) {
+ return;
+ }
+ mOriginalCallback.onHideSoftInput(flags, resultReceiver);
+ }
+ }
+
+ private static void reportNotSupported() {
+ if (DEBUG) {
+ Log.d(TAG, Debug.getCaller() + " is not supported");
+ }
+ }
+}
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java
new file mode 100644
index 0000000..0604f6a6
--- /dev/null
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegate.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2018 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.inputmethodservice;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.ResultReceiver;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.inputmethod.CompletionInfo;
+import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+
+import com.android.internal.inputmethod.StartInputFlags;
+
+/**
+ * Defines all the public APIs and interfaces that are necessary to implement multi-client IMEs.
+ *
+ * <p>Actual implementation is further delegated to
+ * {@link MultiClientInputMethodServiceDelegateImpl}.</p>
+ *
+ * @hide
+ */
+public final class MultiClientInputMethodServiceDelegate {
+ // @SdkConstant(SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE =
+ "android.inputmethodservice.MultiClientInputMethodService";
+
+ /**
+ * Special value that is guaranteed to be not used for IME client ID.
+ */
+ public static final int INVALID_CLIENT_ID = -1;
+
+ /**
+ * Special value that is guaranteed to be not used for window handle.
+ */
+ public static final int INVALID_WINDOW_HANDLE = -1;
+
+ private final MultiClientInputMethodServiceDelegateImpl mImpl;
+
+ /**
+ * Top-level callbacks for this {@link MultiClientInputMethodServiceDelegate}.
+ */
+ public interface ServiceCallback {
+ /**
+ * Called when this {@link MultiClientInputMethodServiceDelegate} is recognized by the
+ * system and privileged operations like {@link #createInputMethodWindowToken(int)} are
+ * ready to be called.
+ */
+ void initialized();
+
+ /**
+ * Called when a new IME client is recognized by the system.
+ *
+ * <p>Once the IME receives this callback, the IME can start interacting with the IME client
+ * by calling {@link #acceptClient(int, ClientCallback, KeyEvent.DispatcherState, Looper)}.
+ * </p>
+ *
+ * @param clientId ID of the client.
+ * @param uid UID of the IME client.
+ * @param pid PID of the IME client.
+ * @param selfReportedDisplayId display ID reported from the IME client. Since the system
+ * does not validate this display ID, and at any time the IME client can lose the
+ * access to this display ID, the IME needs to call
+ * {@link #isUidAllowedOnDisplay(int, int)} to check whether the IME client still
+ * has access to this display or not.
+ */
+ void addClient(int clientId, int uid, int pid, int selfReportedDisplayId);
+
+ /**
+ * Called when an IME client is being destroyed.
+ *
+ * @param clientId ID of the client.
+ */
+ void removeClient(int clientId);
+ }
+
+ /**
+ * Per-client callbacks.
+ */
+ public interface ClientCallback {
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#sendAppPrivateCommand(View, String, Bundle)}.
+ *
+ * @param action Name of the command to be performed.
+ * @param data Any data to include with the command.
+ * @see android.inputmethodservice.InputMethodService#onAppPrivateCommand(String, Bundle)
+ */
+ void onAppPrivateCommand(String action, Bundle data);
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#displayCompletions(View, CompletionInfo[])}.
+ *
+ * @param completions Completion information provided from the IME client.
+ * @see android.inputmethodservice.InputMethodService#onDisplayCompletions(CompletionInfo[])
+ */
+ void onDisplayCompletions(CompletionInfo[] completions);
+
+ /**
+ * Called when this callback session is closed. No further callback should not happen on
+ * this callback object.
+ */
+ void onFinishSession();
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(IBinder, int)} or
+ * {@link android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(IBinder, int,
+ * ResultReceiver)}.
+ *
+ * @param flags The flag passed by the client.
+ * @param resultReceiver The {@link ResultReceiver} passed by the client.
+ * @see android.inputmethodservice.InputMethodService#onWindowHidden()
+ */
+ void onHideSoftInput(int flags, ResultReceiver resultReceiver);
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#showSoftInput(View, int)} or {@link
+ * android.view.inputmethod.InputMethodManager#showSoftInput(View, int, ResultReceiver)}.
+ *
+ * @param flags The flag passed by the client.
+ * @param resultReceiver The {@link ResultReceiver} passed by the client.
+ * @see android.inputmethodservice.InputMethodService#onWindowShown()
+ */
+ void onShowSoftInput(int flags, ResultReceiver resultReceiver);
+
+ /**
+ * A generic callback when {@link InputConnection} is being established.
+ *
+ * @param inputConnection The {@link InputConnection} to be established.
+ * @param editorInfo The {@link EditorInfo} reported from the IME client.
+ * @param startInputFlags Any combinations of {@link StartInputFlags}.
+ * @param softInputMode SoftWindowMode specified to this window.
+ * @param targetWindowHandle A unique Window token.
+ * @see android.inputmethodservice.InputMethodService#onStartInput(EditorInfo, boolean)
+ */
+ void onStartInputOrWindowGainedFocus(
+ @Nullable InputConnection inputConnection,
+ @Nullable EditorInfo editorInfo,
+ @StartInputFlags int startInputFlags,
+ @SoftInputModeFlags int softInputMode,
+ int targetWindowHandle);
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#toggleSoftInput(int, int)}.
+ *
+ * @param showFlags The flag passed by the client.
+ * @param hideFlags The flag passed by the client.
+ * @see android.inputmethodservice.InputMethodService#onToggleSoftInput(int, int)
+ */
+ void onToggleSoftInput(int showFlags, int hideFlags);
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#updateCursorAnchorInfo(View,
+ * CursorAnchorInfo)}.
+ *
+ * @param info The {@link CursorAnchorInfo} passed by the client.
+ * @see android.inputmethodservice.InputMethodService#onUpdateCursorAnchorInfo(
+ * CursorAnchorInfo)
+ */
+ void onUpdateCursorAnchorInfo(CursorAnchorInfo info);
+
+ /**
+ * Called when the associated IME client called {@link
+ * android.view.inputmethod.InputMethodManager#updateSelection(View, int, int, int, int)}.
+ *
+ * @param oldSelStart The previous selection start index.
+ * @param oldSelEnd The previous selection end index.
+ * @param newSelStart The new selection start index.
+ * @param newSelEnd The new selection end index.
+ * @param candidatesStart The new candidate start index.
+ * @param candidatesEnd The new candidate end index.
+ * @see android.inputmethodservice.InputMethodService#onUpdateSelection(int, int, int, int,
+ * int, int)
+ */
+ void onUpdateSelection(int oldSelStart, int oldSelEnd, int newSelStart, int newSelEnd,
+ int candidatesStart, int candidatesEnd);
+
+ /**
+ * Called to give a chance for the IME to intercept generic motion events before they are
+ * processed by the application.
+ *
+ * @param event {@link MotionEvent} that is about to be handled by the IME client.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onGenericMotionEvent(MotionEvent)
+ */
+ boolean onGenericMotionEvent(MotionEvent event);
+
+ /**
+ * Called to give a chance for the IME to intercept key down events before they are
+ * processed by the application.
+ *
+ * @param keyCode The value in {@link KeyEvent#getKeyCode()}.
+ * @param event {@link KeyEvent} for this key down event.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onKeyDown(int, KeyEvent)
+ */
+ boolean onKeyDown(int keyCode, KeyEvent event);
+
+ /**
+ * Called to give a chance for the IME to intercept key long press events before they are
+ * processed by the application.
+ *
+ * @param keyCode The value in {@link KeyEvent#getKeyCode()}.
+ * @param event {@link KeyEvent} for this key long press event.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onKeyLongPress(int, KeyEvent)
+ */
+ boolean onKeyLongPress(int keyCode, KeyEvent event);
+
+ /**
+ * Called to give a chance for the IME to intercept key multiple events before they are
+ * processed by the application.
+ *
+ * @param keyCode The value in {@link KeyEvent#getKeyCode()}.
+ * @param event {@link KeyEvent} for this key multiple event.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onKeyMultiple(int, int, KeyEvent)
+ */
+ boolean onKeyMultiple(int keyCode, KeyEvent event);
+
+ /**
+ * Called to give a chance for the IME to intercept key up events before they are processed
+ * by the application.
+ *
+ * @param keyCode The value in {@link KeyEvent#getKeyCode()}.
+ * @param event {@link KeyEvent} for this key up event.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onKeyUp(int, KeyEvent)
+ */
+ boolean onKeyUp(int keyCode, KeyEvent event);
+
+ /**
+ * Called to give a chance for the IME to intercept generic motion events before they are
+ * processed by the application.
+ *
+ * @param event {@link MotionEvent} that is about to be handled by the IME client.
+ * @return {@code true} to tell the IME client that the IME handled this event.
+ * @see android.inputmethodservice.InputMethodService#onTrackballEvent(MotionEvent)
+ */
+ boolean onTrackballEvent(MotionEvent event);
+ }
+
+ private MultiClientInputMethodServiceDelegate(Context context,
+ ServiceCallback serviceCallback) {
+ mImpl = new MultiClientInputMethodServiceDelegateImpl(context, serviceCallback);
+ }
+
+ /**
+ * Must be called by the multi-client IME implementer to create
+ * {@link MultiClientInputMethodServiceDelegate}.
+ *
+ * @param context {@link Context} with which the delegate should interact with the system.
+ * @param serviceCallback {@link ServiceCallback} to receive service-level callbacks.
+ * @return A new instance of {@link MultiClientInputMethodServiceDelegate}.
+ */
+ public static MultiClientInputMethodServiceDelegate create(Context context,
+ ServiceCallback serviceCallback) {
+ return new MultiClientInputMethodServiceDelegate(context, serviceCallback);
+ }
+
+ /**
+ * Must be called by the multi-client IME service when {@link android.app.Service#onDestroy()}
+ * is called.
+ */
+ public void onDestroy() {
+ mImpl.onDestroy();
+ }
+
+ /**
+ * Must be called by the multi-client IME service when
+ * {@link android.app.Service#onBind(Intent)} is called.
+ *
+ * @param intent {@link Intent} passed to {@link android.app.Service#onBind(Intent)}.
+ * @return An {@link IBinder} object that needs to be returned from
+ * {@link android.app.Service#onBind(Intent)}.
+ */
+ public IBinder onBind(Intent intent) {
+ return mImpl.onBind(intent);
+ }
+
+ /**
+ * Must be called by the multi-client IME service when
+ * {@link android.app.Service#onUnbind(Intent)} is called.
+ *
+ * @param intent {@link Intent} passed to {@link android.app.Service#onUnbind(Intent)}.
+ * @return A boolean value that needs to be returned from
+ * {@link android.app.Service#onUnbind(Intent)}.
+ */
+ public boolean onUnbind(Intent intent) {
+ return mImpl.onUnbind(intent);
+ }
+
+ /**
+ * Must be called by the multi-client IME service to create a special window token for IME
+ * window.
+ *
+ * <p>This method is available only after {@link ServiceCallback#initialized()}.</p>
+ *
+ * @param displayId display ID on which the IME window will be shown.
+ * @return Window token to be specified to the IME window/
+ */
+ public IBinder createInputMethodWindowToken(int displayId) {
+ return mImpl.createInputMethodWindowToken(displayId);
+ }
+
+ /**
+ * Must be called by the multi-client IME service to notify the system when the IME is ready to
+ * accept callback events from the specified IME client.
+ *
+ * @param clientId The IME client ID specified in
+ * {@link ServiceCallback#addClient(int, int, int, int)}.
+ * @param clientCallback The {@link ClientCallback} to receive callback events from this IME
+ * client.
+ * @param dispatcherState {@link KeyEvent.DispatcherState} to be used when receiving key-related
+ * callbacks in {@link ClientCallback}.
+ * @param looper {@link Looper} on which {@link ClientCallback} will be called back.
+ */
+ public void acceptClient(int clientId, ClientCallback clientCallback,
+ KeyEvent.DispatcherState dispatcherState, Looper looper) {
+ mImpl.acceptClient(clientId, clientCallback, dispatcherState, looper);
+ }
+
+ /**
+ * Must be called by the multi-client IME service to notify the system when the IME is ready to
+ * interact with the window in the IME client.
+ *
+ * @param clientId The IME client ID specified in
+ * {@link ServiceCallback#addClient(int, int, int, int)}.
+ * @param targetWindowHandle The window handle specified in
+ * {@link ClientCallback#onStartInputOrWindowGainedFocus}.
+ * @param imeWindowToken The IME window token returned from
+ * {@link #createInputMethodWindowToken(int)}.
+ */
+ public void reportImeWindowTarget(int clientId, int targetWindowHandle,
+ IBinder imeWindowToken) {
+ mImpl.reportImeWindowTarget(clientId, targetWindowHandle, imeWindowToken);
+ }
+
+ /**
+ * Can be called by the multi-client IME service to check if the given {@code uid} is allowed
+ * to access to {@code displayId}.
+ *
+ * @param displayId Display ID to be queried.
+ * @param uid UID to be queried.
+ * @return {@code true} if {@code uid} is allowed to access to {@code displayId}.
+ */
+ public boolean isUidAllowedOnDisplay(int displayId, int uid) {
+ return mImpl.isUidAllowedOnDisplay(displayId, uid);
+ }
+}
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java
new file mode 100644
index 0000000..bbe3a7f
--- /dev/null
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodServiceDelegateImpl.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2018 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.inputmethodservice;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Looper;
+import android.util.Log;
+import android.view.InputChannel;
+import android.view.KeyEvent;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IMultiClientInputMethod;
+import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.MultiClientInputMethodPrivilegedOperations;
+
+import java.lang.annotation.Retention;
+import java.lang.ref.WeakReference;
+
+final class MultiClientInputMethodServiceDelegateImpl {
+ private static final String TAG = "MultiClientInputMethodServiceDelegateImpl";
+
+ private final Object mLock = new Object();
+
+ @Retention(SOURCE)
+ @IntDef({InitializationPhase.INSTANTIATED,
+ InitializationPhase.ON_BIND_CALLED,
+ InitializationPhase.INITIALIZE_CALLED,
+ InitializationPhase.ON_UNBIND_CALLED,
+ InitializationPhase.ON_DESTROY_CALLED})
+ private @interface InitializationPhase {
+ int INSTANTIATED = 1;
+ int ON_BIND_CALLED = 2;
+ int INITIALIZE_CALLED = 3;
+ int ON_UNBIND_CALLED = 4;
+ int ON_DESTROY_CALLED = 5;
+ }
+
+ @GuardedBy("mLock")
+ @InitializationPhase
+ private int mInitializationPhase;
+
+ private final MultiClientInputMethodPrivilegedOperations mPrivOps =
+ new MultiClientInputMethodPrivilegedOperations();
+
+ private final MultiClientInputMethodServiceDelegate.ServiceCallback mServiceCallback;
+
+ private final Context mContext;
+
+ MultiClientInputMethodServiceDelegateImpl(Context context,
+ MultiClientInputMethodServiceDelegate.ServiceCallback serviceCallback) {
+ mInitializationPhase = InitializationPhase.INSTANTIATED;
+ mContext = context;
+ mServiceCallback = serviceCallback;
+ }
+
+ void onDestroy() {
+ synchronized (mLock) {
+ switch (mInitializationPhase) {
+ case InitializationPhase.INSTANTIATED:
+ case InitializationPhase.ON_UNBIND_CALLED:
+ mInitializationPhase = InitializationPhase.ON_DESTROY_CALLED;
+ break;
+ default:
+ Log.e(TAG, "unexpected state=" + mInitializationPhase);
+ break;
+ }
+ }
+ }
+
+ private static final class ServiceImpl extends IMultiClientInputMethod.Stub {
+ private final WeakReference<MultiClientInputMethodServiceDelegateImpl> mImpl;
+
+ ServiceImpl(MultiClientInputMethodServiceDelegateImpl service) {
+ mImpl = new WeakReference<>(service);
+ }
+
+ @Override
+ public void initialize(IMultiClientInputMethodPrivilegedOperations privOps) {
+ final MultiClientInputMethodServiceDelegateImpl service = mImpl.get();
+ if (service == null) {
+ return;
+ }
+ synchronized (service.mLock) {
+ switch (service.mInitializationPhase) {
+ case InitializationPhase.ON_BIND_CALLED:
+ service.mPrivOps.set(privOps);
+ service.mInitializationPhase = InitializationPhase.INITIALIZE_CALLED;
+ service.mServiceCallback.initialized();
+ break;
+ default:
+ Log.e(TAG, "unexpected state=" + service.mInitializationPhase);
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void addClient(int clientId, int uid, int pid, int selfReportedDisplayId) {
+ final MultiClientInputMethodServiceDelegateImpl service = mImpl.get();
+ if (service == null) {
+ return;
+ }
+ service.mServiceCallback.addClient(clientId, uid, pid, selfReportedDisplayId);
+ }
+
+ @Override
+ public void removeClient(int clientId) {
+ final MultiClientInputMethodServiceDelegateImpl service = mImpl.get();
+ if (service == null) {
+ return;
+ }
+ service.mServiceCallback.removeClient(clientId);
+ }
+ }
+
+ IBinder onBind(Intent intent) {
+ synchronized (mLock) {
+ switch (mInitializationPhase) {
+ case InitializationPhase.INSTANTIATED:
+ mInitializationPhase = InitializationPhase.ON_BIND_CALLED;
+ return new ServiceImpl(this);
+ default:
+ Log.e(TAG, "unexpected state=" + mInitializationPhase);
+ break;
+ }
+ }
+ return null;
+ }
+
+ boolean onUnbind(Intent intent) {
+ synchronized (mLock) {
+ switch (mInitializationPhase) {
+ case InitializationPhase.ON_BIND_CALLED:
+ case InitializationPhase.INITIALIZE_CALLED:
+ mInitializationPhase = InitializationPhase.ON_UNBIND_CALLED;
+ mPrivOps.dispose();
+ break;
+ default:
+ Log.e(TAG, "unexpected state=" + mInitializationPhase);
+ break;
+ }
+ }
+ return false;
+ }
+
+ IBinder createInputMethodWindowToken(int displayId) {
+ return mPrivOps.createInputMethodWindowToken(displayId);
+ }
+
+ void acceptClient(int clientId,
+ MultiClientInputMethodServiceDelegate.ClientCallback clientCallback,
+ KeyEvent.DispatcherState dispatcherState, Looper looper) {
+ final InputChannel[] channels = InputChannel.openInputChannelPair("MSIMS-session");
+ final InputChannel writeChannel = channels[0];
+ final InputChannel readChannel = channels[1];
+ try {
+ final MultiClientInputMethodClientCallbackAdaptor callbackAdaptor =
+ new MultiClientInputMethodClientCallbackAdaptor(clientCallback, looper,
+ dispatcherState, readChannel);
+ mPrivOps.acceptClient(clientId, callbackAdaptor.createIInputMethodSession(),
+ callbackAdaptor.createIMultiClientInputMethodSession(), writeChannel);
+ } finally {
+ writeChannel.dispose();
+ }
+ }
+
+ void reportImeWindowTarget(int clientId, int targetWindowHandle, IBinder imeWindowToken) {
+ mPrivOps.reportImeWindowTarget(clientId, targetWindowHandle, imeWindowToken);
+ }
+
+ boolean isUidAllowedOnDisplay(int displayId, int uid) {
+ return mPrivOps.isUidAllowedOnDisplay(displayId, uid);
+ }
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0c4a0b3e..0c1aae8 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -199,6 +199,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static File getProductDirectory() {
return DIR_PRODUCT_ROOT;
}
@@ -468,6 +469,14 @@
}
/**
+ * Returns location of packages cache directory.
+ * {@hide}
+ */
+ public static File getPackageCacheDirectory() {
+ return new File(getDataSystemDirectory(), "package_cache");
+ }
+
+ /**
* Return the primary shared/external storage directory. This directory may
* not currently be accessible if it has been mounted by the user on their
* computer, has been removed from the device, or some other problem has
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 0b90f54..1f47f93 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1156,11 +1156,16 @@
public static @Nullable File createDir(File baseDir, String name) {
final File dir = new File(baseDir, name);
+ return createDir(dir) ? dir : null;
+ }
+
+ /** @hide */
+ public static boolean createDir(File dir) {
if (dir.exists()) {
- return dir.isDirectory() ? dir : null;
+ return dir.isDirectory();
}
- return dir.mkdir() ? dir : null;
+ return dir.mkdir();
}
/**
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index b25707a..8c5c415 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -37,8 +37,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.util.HashSet;
-import java.util.Set;
/** @hide */
public class GraphicsEnvironment {
@@ -70,7 +68,7 @@
public void setup(Context context, Bundle coreSettings) {
setupGpuLayers(context, coreSettings);
setupAngle(context, coreSettings);
- chooseDriver(context);
+ chooseDriver(context, coreSettings);
}
/**
@@ -312,11 +310,12 @@
/**
* Choose whether the current process should use the builtin or an updated driver.
*/
- private static void chooseDriver(Context context) {
+ private static void chooseDriver(Context context, Bundle coreSettings) {
String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
}
+
// To minimize risk of driver updates crippling the device beyond user repair, never use an
// updated driver for privileged or non-updated system apps. Presumably pre-installed apps
// were tested thoroughly with the pre-installed driver.
@@ -325,12 +324,16 @@
if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
return;
}
- Set<String> whitelist = loadWhitelist(context, driverPackageName);
- // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed
- // updatable graphics driver is supposed to be a place holder and contains no graphics
- // driver and whitelist.
- if (whitelist == null || whitelist.isEmpty()) {
+ String applicationPackageName = context.getPackageName();
+ String devOptInApplicationName = coreSettings.getString(
+ Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
+ boolean devOptIn = applicationPackageName.equals(devOptInApplicationName);
+ boolean whitelisted = onWhitelist(context, driverPackageName, ai.packageName);
+ if (!devOptIn && !whitelisted) {
+ if (DEBUG) {
+ Log.w(TAG, applicationPackageName + " is not on the whitelist.");
+ }
return;
}
@@ -342,12 +345,6 @@
Log.w(TAG, "driver package '" + driverPackageName + "' not installed");
return;
}
- if (!whitelist.contains(context.getPackageName())) {
- if (DEBUG) {
- Log.w(TAG, context.getPackageName() + " is not on the whitelist.");
- }
- return;
- }
// O drivers are restricted to the sphal linker namespace, so don't try to use
// packages unless they declare they're compatible with that restriction.
@@ -413,10 +410,18 @@
return null;
}
- private static Set<String> loadWhitelist(Context context, String driverPackageName) {
+ private static boolean onWhitelist(Context context, String driverPackageName,
+ String applicationPackageName) {
String whitelistName = SystemProperties.get(PROPERTY_GFX_DRIVER_WHITELIST);
+
+ // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed
+ // updatable graphics driver is supposed to be a place holder and contains no graphics
+ // driver and whitelist.
if (whitelistName == null || whitelistName.isEmpty()) {
- return null;
+ if (DEBUG) {
+ Log.w(TAG, "No whitelist found.");
+ }
+ return false;
}
try {
Context driverContext = context.createPackageContext(driverPackageName,
@@ -424,11 +429,11 @@
AssetManager assets = driverContext.getAssets();
InputStream stream = assets.open(whitelistName);
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- Set<String> whitelist = new HashSet<>();
- for (String line; (line = reader.readLine()) != null; ) {
- whitelist.add(line);
+ for (String packageName; (packageName = reader.readLine()) != null; ) {
+ if (packageName.equals(applicationPackageName)) {
+ return true;
+ }
}
- return whitelist;
} catch (PackageManager.NameNotFoundException e) {
if (DEBUG) {
Log.w(TAG, "driver package '" + driverPackageName + "' not installed");
@@ -438,7 +443,7 @@
Log.w(TAG, "Failed to load whitelist driver package, abort.");
}
}
- return null;
+ return false;
}
private static native int getCanLoadSystemLibraries();
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 70688fd..126588a 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -881,9 +881,9 @@
@Override
public void close() throws IOException {
try {
- mPfd.close();
- } finally {
super.close();
+ } finally {
+ mPfd.close();
}
}
@@ -932,9 +932,9 @@
@Override
public void close() throws IOException {
try {
- mPfd.close();
- } finally {
super.close();
+ } finally {
+ mPfd.close();
}
}
}
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 33b2676..bf988ae 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -188,6 +188,6 @@
void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) = 78;
void runIdleMaintenance() = 79;
void abortIdleMaintenance() = 80;
- String translateAppToSystem(String path, String packageName, int userId) = 81;
- String translateSystemToApp(String path, String packageName, int userId) = 82;
+ String translateAppToSystem(String path, int pid, int uid) = 81;
+ String translateSystemToApp(String path, int pid, int uid) = 82;
}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index c91cda6..8a36a78 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -225,6 +225,8 @@
public static final int DEBUG_SDCARDFS_FORCE_OFF = 1 << 4;
/** {@hide} */
public static final int DEBUG_VIRTUAL_DISK = 1 << 5;
+ /** {@hide} */
+ public static final int DEBUG_ISOLATED_STORAGE = 1 << 6;
/** {@hide} */
public static final int FLAG_STORAGE_DE = IInstalld.FLAG_STORAGE_DE;
@@ -1546,13 +1548,13 @@
*
* @hide
*/
- public File translateAppToSystem(File file, String packageName) {
+ public File translateAppToSystem(File file, int pid, int uid) {
// We can only translate absolute paths
if (!file.isAbsolute()) return file;
try {
return new File(mStorageManager.translateAppToSystem(file.getAbsolutePath(),
- packageName, mContext.getUserId()));
+ pid, uid));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1564,13 +1566,13 @@
*
* @hide
*/
- public File translateSystemToApp(File file, String packageName) {
+ public File translateSystemToApp(File file, int pid, int uid) {
// We can only translate absolute paths
if (!file.isAbsolute()) return file;
try {
return new File(mStorageManager.translateSystemToApp(file.getAbsolutePath(),
- packageName, mContext.getUserId()));
+ pid, uid));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8e4de9f..f840792 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9174,6 +9174,13 @@
public static final String DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT
= "enable_freeform_support";
+ /**
+ * Whether to enable experimental desktop mode on secondary displays.
+ * @hide
+ */
+ public static final String DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS =
+ "force_desktop_mode_on_external_displays";
+
/**
* Whether user has enabled development settings.
*/
@@ -11752,6 +11759,13 @@
public static final String ANGLE_ENABLED_APP = "angle_enabled_app";
/**
+ * App that is selected to use updated graphics driver.
+ * @hide
+ */
+ public static final String UPDATED_GFX_DRIVER_DEV_OPT_IN_APP =
+ "updated_gfx_driver_dev_opt_in_app";
+
+ /**
* Ordered GPU debug layer list for Vulkan
* i.e. <layer1>:<layer2>:...:<layerN>
* @hide
@@ -12622,27 +12636,14 @@
"hidden_api_access_log_sampling_rate";
/**
- * Hidden API enforcement policy for apps targeting SDK versions prior to the latest
- * version.
+ * Hidden API enforcement policy for apps.
*
* Values correspond to @{@link
* android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy}
*
* @hide
*/
- public static final String HIDDEN_API_POLICY_PRE_P_APPS =
- "hidden_api_policy_pre_p_apps";
-
- /**
- * Hidden API enforcement policy for apps targeting the current SDK version.
- *
- * Values correspond to @{@link
- * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy}
- *
- * @hide
- */
- public static final String HIDDEN_API_POLICY_P_APPS =
- "hidden_api_policy_p_apps";
+ public static final String HIDDEN_API_POLICY = "hidden_api_policy";
/**
* Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 56e6aea..64eae0c 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1462,6 +1462,7 @@
private @UserSentiment int mUserSentiment = USER_SENTIMENT_NEUTRAL;
private boolean mHidden;
private boolean mAudiblyAlerted;
+ private boolean mNoisy;
private ArrayList<Notification.Action> mSmartActions;
private ArrayList<CharSequence> mSmartReplies;
@@ -1636,6 +1637,11 @@
return mAudiblyAlerted;
}
+ /** @hide */
+ public boolean isNoisy() {
+ return mNoisy;
+ }
+
/**
* @hide
*/
@@ -1646,7 +1652,8 @@
NotificationChannel channel, ArrayList<String> overridePeople,
ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
int userSentiment, boolean hidden, boolean audiblyAlerted,
- ArrayList<Notification.Action> smartActions, ArrayList<CharSequence> smartReplies) {
+ boolean noisy, ArrayList<Notification.Action> smartActions,
+ ArrayList<CharSequence> smartReplies) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1663,6 +1670,7 @@
mUserSentiment = userSentiment;
mHidden = hidden;
mAudiblyAlerted = audiblyAlerted;
+ mNoisy = noisy;
mSmartActions = smartActions;
mSmartReplies = smartReplies;
}
@@ -1715,6 +1723,7 @@
private ArrayMap<String, Integer> mUserSentiment;
private ArrayMap<String, Boolean> mHidden;
private ArrayMap<String, Boolean> mAudiblyAlerted;
+ private ArrayMap<String, Boolean> mNoisy;
private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
@@ -1746,7 +1755,8 @@
getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
getShowBadge(key), getUserSentiment(key), getHidden(key),
- getAudiblyAlerted(key), getSmartActions(key), getSmartReplies(key));
+ getAudiblyAlerted(key), getNoisy(key), getSmartActions(key),
+ getSmartReplies(key));
return rank >= 0;
}
@@ -1894,6 +1904,16 @@
return audiblyAlerted == null ? false : audiblyAlerted.booleanValue();
}
+ private boolean getNoisy(String key) {
+ synchronized (this) {
+ if (mNoisy == null) {
+ buildNoisyLocked();
+ }
+ }
+ Boolean noisy = mNoisy.get(key);
+ return noisy == null ? false : noisy.booleanValue();
+ }
+
private ArrayList<Notification.Action> getSmartActions(String key) {
synchronized (this) {
if (mSmartActions == null) {
@@ -2034,6 +2054,11 @@
}
// Locked by 'this'
+ private void buildNoisyLocked() {
+ mNoisy = buildBooleanMapFromBundle(mRankingUpdate.getNoisy());
+ }
+
+ // Locked by 'this'
private void buildSmartActions() {
Bundle smartActions = mRankingUpdate.getSmartActions();
mSmartActions = new ArrayMap<>(smartActions.size());
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index b561bfd..f80df93 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -40,13 +40,14 @@
private final Bundle mSmartActions;
private final Bundle mSmartReplies;
private final Bundle mAudiblyAlerted;
+ private final Bundle mNoisy;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
- Bundle smartReplies, Bundle audiblyAlerted) {
+ Bundle smartReplies, Bundle audiblyAlerted, Bundle noisy) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
@@ -63,6 +64,7 @@
mSmartActions = smartActions;
mSmartReplies = smartReplies;
mAudiblyAlerted = audiblyAlerted;
+ mNoisy = noisy;
}
public NotificationRankingUpdate(Parcel in) {
@@ -83,6 +85,7 @@
mSmartActions = in.readBundle();
mSmartReplies = in.readBundle();
mAudiblyAlerted = in.readBundle();
+ mNoisy = in.readBundle();
}
@Override
@@ -108,6 +111,7 @@
out.writeBundle(mSmartActions);
out.writeBundle(mSmartReplies);
out.writeBundle(mAudiblyAlerted);
+ out.writeBundle(mNoisy);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -184,4 +188,8 @@
public Bundle getAudiblyAlerted() {
return mAudiblyAlerted;
}
+
+ public Bundle getNoisy() {
+ return mNoisy;
+ }
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index b047ef7..bad26ed 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -44,8 +44,8 @@
DEFAULT_FLAGS = new HashMap<>();
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
- DEFAULT_FLAGS.put("settings_dynamic_homepage", "false");
- DEFAULT_FLAGS.put("settings_mobile_network_v2", "false");
+ DEFAULT_FLAGS.put("settings_dynamic_homepage", "true");
+ DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
DEFAULT_FLAGS.put("settings_data_usage_v2", "false");
DEFAULT_FLAGS.put("settings_seamless_transfer", "false");
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index a872776..96ef8ba 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -21,6 +21,7 @@
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.graphics.FrameInfo;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
import android.os.Handler;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 719a401..4ead34e 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -218,6 +218,7 @@
* @see #getFlags
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
/**
@@ -230,6 +231,7 @@
* @see #supportsSystemDecorations
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6;
/**
@@ -384,6 +386,7 @@
*
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY
public static final int REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY = 0;
/**
* Indicates that when display is removed, all its stacks and tasks will be removed, all
@@ -391,6 +394,7 @@
*
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
public static final int REMOVE_MODE_DESTROY_CONTENT = 1;
/**
@@ -451,6 +455,19 @@
}
/**
+ * Gets the display unique id.
+ * <p>
+ * Unique id is different from display id because physical displays have stable unique id across
+ * reboots.
+ *
+ * @see com.android.service.display.DisplayDevice#hasStableUniqueId().
+ * @hide
+ */
+ public String getUniqueId() {
+ return mDisplayInfo.uniqueId;
+ }
+
+ /**
* Returns true if this display is still valid, false if the display has been removed.
*
* If the display is invalid, then the methods of this class will
@@ -881,6 +898,7 @@
* @see #REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY
* @see #REMOVE_MODE_DESTROY_CONTENT
*/
+ // TODO (b/114338689): Remove the method and use IWindowManager#getRemoveContentMode
public int getRemoveMode() {
return mDisplayInfo.removeMode;
}
@@ -891,6 +909,7 @@
* @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
* @hide
*/
+ // TODO (b/114338689): Remove the method and use IWindowManager#shouldShowSystemDecors
public boolean supportsSystemDecorations() {
return (mDisplayInfo.flags & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0;
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 34bcbdd..43de1f8 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -266,6 +266,7 @@
*
* @see Display#getRemoveMode()
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode
public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
diff --git a/core/java/android/view/FrameMetricsObserver.java b/core/java/android/view/FrameMetricsObserver.java
index 597089b..0f38e84 100644
--- a/core/java/android/view/FrameMetricsObserver.java
+++ b/core/java/android/view/FrameMetricsObserver.java
@@ -40,8 +40,9 @@
@UnsupportedAppUsage
private FrameMetrics mFrameMetrics;
- /* package */ Window.OnFrameMetricsAvailableListener mListener;
- /* package */ VirtualRefBasePtr mNative;
+ /* pacage */ Window.OnFrameMetricsAvailableListener mListener;
+ /** @hide */
+ public VirtualRefBasePtr mNative;
/**
* Creates a FrameMetricsObserver
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5c07f44..c836c9e 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -432,4 +432,120 @@
* @param displayId The id of the display.
*/
void dontOverrideDisplayInfo(int displayId);
+
+ /**
+ * Gets the windowing mode of the display.
+ *
+ * @param displayId The id of the display.
+ * @return {@link WindowConfiguration.WindowingMode}
+ */
+ int getWindowingMode(int displayId);
+
+ /**
+ * Sets the windowing mode of the display.
+ *
+ * @param displayId The id of the display.
+ * @param mode {@link WindowConfiguration.WindowingMode}
+ */
+ void setWindowingMode(int displayId, int mode);
+
+ /**
+ * Gets current remove content mode of the display.
+ * <p>
+ * What actions should be performed with the display's content when it is removed. Default
+ * behavior for public displays in this case is to move all activities to the primary display
+ * and make it focused. For private display is to destroy all activities.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @return The remove content mode of the display.
+ * @see WindowManager#REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY
+ * @see WindowManager#REMOVE_CONTENT_MODE_DESTROY
+ */
+ int getRemoveContentMode(int displayId);
+
+ /**
+ * Sets the remove content mode of the display.
+ * <p>
+ * This mode indicates what actions should be performed with the display's content when it is
+ * removed.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @param mode Remove content mode.
+ * @see WindowManager#REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY
+ * @see WindowManager#REMOVE_CONTENT_MODE_DESTROY
+ */
+ void setRemoveContentMode(int displayId, int mode);
+
+ /**
+ * Indicates that the display should show its content when non-secure keyguard is shown.
+ * <p>
+ * This flag identifies secondary displays that will continue showing content if keyguard can be
+ * dismissed without entering credentials.
+ * </p><p>
+ * An example of usage is a virtual display which content is displayed on external hardware
+ * display that is not visible to the system directly.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @return {@code true} if the display should show its content when non-secure keyguard is
+ * shown.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ */
+ boolean shouldShowWithInsecureKeyguard(int displayId);
+
+ /**
+ * Sets that the display should show its content when non-secure keyguard is shown.
+ *
+ * @param displayId The id of the display.
+ * @param shouldShow Indicates that the display should show its content when non-secure keyguard
+ * is shown.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ */
+ void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow);
+
+ /**
+ * Indicates the display should show system decors.
+ * <p>
+ * System decors include status bar, navigation bar, launcher.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @return {@code true} if the display should show system decors.
+ */
+ boolean shouldShowSystemDecors(int displayId);
+
+ /**
+ * Sets that the display should show system decors.
+ * <p>
+ * System decors include status bar, navigation bar, launcher.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @param shouldShow Indicates that the display should show system decors.
+ */
+ void setShouldShowSystemDecors(int displayId, boolean shouldShow);
+
+ /**
+ * Indicates that the display should show IME.
+ *
+ * @param displayId The id of the display.
+ * @return {@code true} if the display should show IME.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ */
+ boolean shouldShowIme(int displayId);
+
+ /**
+ * Sets that the display should show IME.
+ *
+ * @param displayId The id of the display.
+ * @param shouldShow Indicates that the display should show IME.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ */
+ void setShouldShowIme(int displayId, boolean shouldShow);
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 7e5c149..0739516 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -814,13 +814,19 @@
public static final int KEYCODE_ALL_APPS = 284;
/** Key code constant: Refresh key. */
public static final int KEYCODE_REFRESH = 285;
+ /** Key code constant: Thumbs up key. Apps can use this to let user upvote content. */
+ public static final int KEYCODE_THUMBS_UP = 286;
+ /** Key code constant: Thumbs down key. Apps can use this to let user downvote content. */
+ public static final int KEYCODE_THUMBS_DOWN = 287;
+ /** Key code constant: Consumed by system to switch current viewer profile. */
+ public static final int KEYCODE_PROFILE_SWITCH = 288;
/**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@TestApi
- public static final int LAST_KEYCODE = KEYCODE_REFRESH;
+ public static final int LAST_KEYCODE = KEYCODE_PROFILE_SWITCH;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
@@ -1972,6 +1978,7 @@
}
/** @hide */
+ @TestApi
@Override
public final void setDisplayId(int displayId) {
mDisplayId = displayId;
@@ -2036,6 +2043,16 @@
}
/**
+ * Modifies the flags of the event.
+ *
+ * @param newFlags New flags for the event, replacing the entire value.
+ * @hide
+ */
+ public final void setFlags(int newFlags) {
+ mFlags = newFlags;
+ }
+
+ /**
* Returns the flags for this key event.
*
* @see #FLAG_WOKE_HERE
@@ -2536,6 +2553,20 @@
}
/**
+ * Modifies the down time and the event time of the event.
+ *
+ * @param downTime The new down time (in {@link android.os.SystemClock#uptimeMillis}) of the
+ * event.
+ * @param eventTime The new event time (in {@link android.os.SystemClock#uptimeMillis}) of the
+ * event.
+ * @hide
+ */
+ public final void setTime(long downTime, long eventTime) {
+ mDownTime = downTime;
+ mEventTime = eventTime;
+ }
+
+ /**
* Retrieve the time of the most recent key down event,
* in the {@link android.os.SystemClock#uptimeMillis} time base. If this
* is a down event, this will be the same as {@link #getEventTime()}.
diff --git a/core/java/android/view/TextureLayer.java b/core/java/android/view/TextureLayer.java
index d89d634..46dd436 100644
--- a/core/java/android/view/TextureLayer.java
+++ b/core/java/android/view/TextureLayer.java
@@ -18,6 +18,7 @@
import android.annotation.Nullable;
import android.graphics.Bitmap;
+import android.graphics.HardwareRenderer;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
@@ -32,10 +33,10 @@
* @hide
*/
public final class TextureLayer {
- private ThreadedRenderer mRenderer;
+ private HardwareRenderer mRenderer;
private VirtualRefBasePtr mFinalizer;
- private TextureLayer(ThreadedRenderer renderer, long deferredUpdater) {
+ private TextureLayer(HardwareRenderer renderer, long deferredUpdater) {
if (renderer == null || deferredUpdater == 0) {
throw new IllegalArgumentException("Either hardware renderer: " + renderer
+ " or deferredUpdater: " + deferredUpdater + " is invalid");
@@ -139,7 +140,8 @@
mRenderer.pushLayerUpdate(this);
}
- static TextureLayer adoptTextureLayer(ThreadedRenderer renderer, long layer) {
+ /** @hide */
+ public static TextureLayer adoptTextureLayer(HardwareRenderer renderer, long layer) {
return new TextureLayer(renderer, layer);
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index f0f4c1c..bac0154 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,36 +16,24 @@
package android.view;
-import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.UnsupportedAppUsage;
-import android.app.ActivityManager;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Bitmap;
+import android.graphics.HardwareRenderer;
import android.graphics.Point;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.Trace;
-import android.util.Log;
import android.view.Surface.OutOfResourcesException;
import android.view.View.AttachInfo;
import android.view.animation.AnimationUtils;
import com.android.internal.R;
-import com.android.internal.util.VirtualRefBasePtr;
-import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
/**
* Threaded renderer that proxies the rendering to a render thread. Most calls
@@ -66,15 +54,7 @@
*
* @hide
*/
-public final class ThreadedRenderer {
- private static final String LOG_TAG = "ThreadedRenderer";
-
- /**
- * Name of the file that holds the shaders cache.
- */
- private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
- private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
-
+public final class ThreadedRenderer extends HardwareRenderer {
/**
* System property used to enable or disable threaded rendering profiling.
* The default value of this property is assumed to be false.
@@ -271,21 +251,6 @@
}
/**
- * Sets the directory to use as a persistent storage for threaded rendering
- * resources.
- *
- * @param cacheDir A directory the current process can write to
- *
- * @hide
- */
- @UnsupportedAppUsage
- public static void setupDiskCache(File cacheDir) {
- ThreadedRenderer.setupShadersDiskCache(
- new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
- new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
- }
-
- /**
* Creates a threaded renderer using OpenGL.
*
* @param translucent True if the surface is translucent, false otherwise
@@ -300,55 +265,10 @@
return renderer;
}
- /**
- * Invoke this method when the system is running out of memory. This
- * method will attempt to recover as much memory as possible, based on
- * the specified hint.
- *
- * @param level Hint about the amount of memory that should be trimmed,
- * see {@link android.content.ComponentCallbacks}
- */
- public static void trimMemory(int level) {
- nTrimMemory(level);
- }
-
- public static void overrideProperty(@NonNull String name, @NonNull String value) {
- if (name == null || value == null) {
- throw new IllegalArgumentException("name and value must be non-null");
- }
- nOverrideProperty(name, value);
- }
-
- // Keep in sync with DrawFrameTask.h SYNC_* flags
- // Nothing interesting to report
- private static final int SYNC_OK = 0;
- // Needs a ViewRoot invalidate
- private static final int SYNC_INVALIDATE_REQUIRED = 1 << 0;
- // Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
- private static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
- // setStopped is true, drawing is false
- // TODO: Remove this and SYNC_LOST_SURFACE_REWARD_IF_FOUND?
- // This flag isn't really used as there's nothing that we care to do
- // in response, so it really just exists to differentiate from LOST_SURFACE
- // but possibly both can just be deleted.
- private static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
- private static final int SYNC_FRAME_DROPPED = 1 << 3;
-
private static final String[] VISUALIZERS = {
PROFILE_PROPERTY_VISUALIZE_BARS,
};
- private static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
- private static final int FLAG_DUMP_RESET = 1 << 1;
- private static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
-
- @IntDef(flag = true, prefix = { "FLAG_DUMP_" }, value = {
- FLAG_DUMP_FRAMESTATS,
- FLAG_DUMP_RESET
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface DumpFlags {}
-
// Size of the rendered content.
private int mWidth, mHeight;
@@ -362,51 +282,37 @@
// Whether the surface has insets. Used to protect opacity.
private boolean mHasInsets;
- // Light and shadow properties specified by the theme.
+ // Light properties specified by the theme.
private final float mLightY;
private final float mLightZ;
private final float mLightRadius;
- private final int mAmbientShadowAlpha;
- private final int mSpotShadowAlpha;
- private long mNativeProxy;
private boolean mInitialized = false;
- private RenderNode mRootNode;
private boolean mRootNodeNeedsUpdate;
private boolean mEnabled;
private boolean mRequested = true;
- private boolean mIsOpaque = false;
ThreadedRenderer(Context context, boolean translucent, String name) {
+ super();
+ setName(name);
+ setOpaque(!translucent);
+
final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
- mAmbientShadowAlpha =
- (int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
- mSpotShadowAlpha = (int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
+ float ambientShadowAlpha = a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0);
+ float spotShadowAlpha = a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0);
a.recycle();
-
- long rootNodePtr = nCreateRootRenderNode();
- mRootNode = RenderNode.adopt(rootNodePtr);
- mRootNode.setClipToBounds(false);
- mIsOpaque = !translucent;
- mNativeProxy = nCreateProxy(translucent, rootNodePtr);
- nSetName(mNativeProxy, name);
-
- ProcessInitializer.sInstance.init(context, mNativeProxy);
-
- loadSystemProperties();
+ setLightSourceAlpha(ambientShadowAlpha, spotShadowAlpha);
}
- /**
- * Destroys the threaded rendering context.
- */
- void destroy() {
+ @Override
+ public void destroy() {
mInitialized = false;
updateEnabledState(null);
- nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
+ super.destroy();
}
/**
@@ -464,7 +370,7 @@
boolean status = !mInitialized;
mInitialized = true;
updateEnabledState(surface);
- nInitialize(mNativeProxy, surface);
+ setSurface(surface);
return status;
}
@@ -505,26 +411,18 @@
*/
void updateSurface(Surface surface) throws OutOfResourcesException {
updateEnabledState(surface);
- nUpdateSurface(mNativeProxy, surface);
+ setSurface(surface);
}
- /**
- * Halts any current rendering into the surface. Use this if it is unclear whether
- * or not the surface used by the ThreadedRenderer will be changing. It
- * Suspends any rendering into the surface, but will not do any destruction.
- *
- * Any subsequent draws will override the pause, resuming normal operation.
- */
- boolean pauseSurface(Surface surface) {
- return nPauseSurface(mNativeProxy, surface);
- }
-
- /**
- * Hard stops or resumes rendering into the surface. This flag is used to
- * determine whether or not it is safe to use the given surface *at all*
- */
- void setStopped(boolean stopped) {
- nSetStopped(mNativeProxy, stopped);
+ @Override
+ public void setSurface(Surface surface) {
+ // TODO: Do we ever pass a non-null but isValid() = false surface?
+ // This is here to be super conservative for ViewRootImpl
+ if (surface != null && surface.isValid()) {
+ super.setSurface(surface);
+ } else {
+ super.setSurface(null);
+ }
}
/**
@@ -535,7 +433,7 @@
*/
void destroyHardwareResources(View view) {
destroyResources(view);
- nDestroyHardwareResources(mNativeProxy);
+ destroyHardwareResources();
}
private static void destroyResources(View view) {
@@ -543,14 +441,6 @@
}
/**
- * Detaches the layer's surface texture from the GL context and releases
- * the texture id
- */
- void detachSurfaceTexture(long hardwareLayer) {
- nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
- }
-
- /**
* Sets up the renderer for drawing.
*
* @param width The width of the drawing surface.
@@ -581,8 +471,6 @@
}
mRootNode.setLeftTopRightBottom(-mInsetLeft, -mInsetTop, mSurfaceWidth, mSurfaceHeight);
- nSetup(mNativeProxy, mLightRadius,
- mAmbientShadowAlpha, mSpotShadowAlpha);
setLightCenter(attachInfo);
}
@@ -598,27 +486,7 @@
attachInfo.mDisplay.getRealSize(displaySize);
final float lightX = displaySize.x / 2f - attachInfo.mWindowLeft;
final float lightY = mLightY - attachInfo.mWindowTop;
-
- nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
- }
-
- /**
- * Change the ThreadedRenderer's opacity
- */
- void setOpaque(boolean opaque) {
- mIsOpaque = opaque && !mHasInsets;
- nSetOpaque(mNativeProxy, mIsOpaque);
- }
-
- boolean isOpaque() {
- return mIsOpaque;
- }
-
- /**
- * Enable/disable wide gamut rendering on this renderer.
- */
- void setWideGamut(boolean wideGamut) {
- nSetWideGamut(mNativeProxy, wideGamut);
+ setLightSourceGeometry(lightX, lightY, mLightZ, mLightRadius);
}
/**
@@ -663,18 +531,12 @@
break;
}
}
- nDumpProfileInfo(mNativeProxy, fd, flags);
+ dumpProfileInfo(fd, flags);
}
- /**
- * Loads system properties used by the renderer. This method is invoked
- * whenever system properties are modified. Implementations can use this
- * to trigger live updates of the renderer based on properties.
- *
- * @return True if a property has changed.
- */
- boolean loadSystemProperties() {
- boolean changed = nLoadSystemProperties(mNativeProxy);
+ @Override
+ public boolean loadSystemProperties() {
+ boolean changed = super.loadSystemProperties();
if (changed) {
invalidateRoot();
}
@@ -695,72 +557,27 @@
updateViewTreeDisplayList(view);
if (mRootNodeNeedsUpdate || !mRootNode.hasDisplayList()) {
- RecordingCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
+ RecordingCanvas canvas = mRootNode.startRecording(mSurfaceWidth, mSurfaceHeight);
try {
final int saveCount = canvas.save();
canvas.translate(mInsetLeft, mInsetTop);
callbacks.onPreDraw(canvas);
- canvas.insertReorderBarrier();
+ canvas.enableZ();
canvas.drawRenderNode(view.updateDisplayListIfDirty());
- canvas.insertInorderBarrier();
+ canvas.disableZ();
callbacks.onPostDraw(canvas);
canvas.restoreToCount(saveCount);
mRootNodeNeedsUpdate = false;
} finally {
- mRootNode.end(canvas);
+ mRootNode.endRecording();
}
}
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
/**
- * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
- * rendernode of the UI thread.
- * @param node The node to add.
- * @param placeFront If true, the render node will be placed in front of the content node,
- * otherwise behind the content node.
- */
- @UnsupportedAppUsage
- public void addRenderNode(RenderNode node, boolean placeFront) {
- nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
- }
-
- /**
- * Only especially added render nodes can be removed.
- * @param node The node which was added via addRenderNode which should get removed again.
- */
- @UnsupportedAppUsage
- public void removeRenderNode(RenderNode node) {
- nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
- }
-
- /**
- * Draws a particular render node. If the node is not the content node, only the additional
- * nodes will get drawn and the content remains untouched.
- * @param node The node to be drawn.
- */
- @UnsupportedAppUsage
- public void drawRenderNode(RenderNode node) {
- nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
- }
-
- /**
- * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
- * will be prevented to overdraw this area. It will be synchronized with the draw call.
- * This should be updated in the content view's draw call.
- * @param left The left side of the protected bounds.
- * @param top The top side of the protected bounds.
- * @param right The right side of the protected bounds.
- * @param bottom The bottom side of the protected bounds.
- */
- @UnsupportedAppUsage
- public void setContentDrawBounds(int left, int top, int right, int bottom) {
- nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
- }
-
- /**
* Interface used to receive callbacks whenever a view is drawn by
* a threaded renderer instance.
*/
@@ -819,11 +636,10 @@
attachInfo.mPendingAnimatingRenderNodes = null;
}
- final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
if (frameDrawingCallback != null) {
- nSetFrameCallback(mNativeProxy, frameDrawingCallback);
+ setFrameCallback(frameDrawingCallback);
}
- int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
+ int syncResult = syncAndDrawFrame(choreographer.mFrameInfo);
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
setEnabled(false);
attachInfo.mViewRootImpl.mSurface.release();
@@ -831,207 +647,40 @@
// if it is still needed or do nothing if we are no longer drawing
attachInfo.mViewRootImpl.invalidate();
}
- if ((syncResult & SYNC_INVALIDATE_REQUIRED) != 0) {
+ if ((syncResult & SYNC_REDRAW_REQUESTED) != 0) {
attachInfo.mViewRootImpl.invalidate();
}
}
- void setFrameCompleteCallback(FrameCompleteCallback callback) {
- nSetFrameCompleteCallback(mNativeProxy, callback);
- }
-
- static void invokeFunctor(long functor, boolean waitForCompletion) {
- nInvokeFunctor(functor, waitForCompletion);
- }
-
- /**
- * Creates a new hardware layer. A hardware layer built by calling this
- * method will be treated as a texture layer, instead of as a render target.
- *
- * @return A hardware layer
- */
- TextureLayer createTextureLayer() {
- long layer = nCreateTextureLayer(mNativeProxy);
- return TextureLayer.adoptTextureLayer(this, layer);
- }
-
-
- void buildLayer(RenderNode node) {
- if (node.hasDisplayList()) {
- nBuildLayer(mNativeProxy, node.mNativeRenderNode);
- }
- }
-
-
- boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
- return nCopyLayerInto(mNativeProxy,
- layer.getDeferredLayerUpdater(), bitmap);
- }
-
- /**
- * Indicates that the specified hardware layer needs to be updated
- * as soon as possible.
- *
- * @param layer The hardware layer that needs an update
- */
- void pushLayerUpdate(TextureLayer layer) {
- nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
- }
-
- /**
- * Tells the HardwareRenderer that the layer is destroyed. The renderer
- * should remove the layer from any update queues.
- */
- void onLayerDestroyed(TextureLayer layer) {
- nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
- }
-
- /**
- * Blocks until all previously queued work has completed.
- */
- void fence() {
- nFence(mNativeProxy);
- }
-
- /**
- * Prevents any further drawing until draw() is called. This is a signal
- * that the contents of the RenderNode tree are no longer safe to play back.
- * In practice this usually means that there are Functor pointers in the
- * display list that are no longer valid.
- */
- void stopDrawing() {
- nStopDrawing(mNativeProxy);
- }
-
- /**
- * Called by {@link ViewRootImpl} when a new performTraverals is scheduled.
- */
- public void notifyFramePending() {
- nNotifyFramePending(mNativeProxy);
- }
-
-
- void registerAnimatingRenderNode(RenderNode animator) {
- nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
- }
-
- void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
- nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
- animator.getAnimatorNativePtr());
- }
-
- public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
- if (srcRect == null) {
- // Empty rect means entire surface
- return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
- } else {
- return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
- srcRect.right, srcRect.bottom, bitmap);
- }
- }
-
- /**
- * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
- * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
- * not the RenderNode from a View.
- **/
- @UnsupportedAppUsage
- public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
- return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
- }
-
- /**
- * Sets whether or not high contrast text rendering is enabled. The setting is global
- * but only affects content rendered after the change is made.
- */
- public static void setHighContrastText(boolean highContrastText) {
- nSetHighContrastText(highContrastText);
- }
-
- /**
- * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
- */
- public static void setIsolatedProcess(boolean isIsolated) {
- nSetIsolatedProcess(isIsolated);
- }
-
- /**
- * If set extra graphics debugging abilities will be enabled such as dumping skp
- */
- public static void setDebuggingEnabled(boolean enable) {
- nSetDebuggingEnabled(enable);
- }
-
- void allocateBuffers(Surface surface) {
- nAllocateBuffers(mNativeProxy, surface);
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- nDeleteProxy(mNativeProxy);
- mNativeProxy = 0;
- } finally {
- super.finalize();
- }
- }
-
/** The root of everything */
public @NonNull RenderNode getRootNode() {
return mRootNode;
}
- private boolean mForceDark = false;
-
- /**
- * Whether or not the force-dark feature should be used for this renderer.
- */
- public boolean setForceDark(boolean enable) {
- if (mForceDark != enable) {
- mForceDark = enable;
- nSetForceDark(mNativeProxy, enable);
- return true;
- }
- return false;
- }
-
/**
* Basic synchronous renderer. Currently only used to render the Magnifier, so use with care.
* TODO: deduplicate against ThreadedRenderer.
*
* @hide
*/
- public static class SimpleRenderer {
- private final RenderNode mRootNode;
- private long mNativeProxy;
- private final float mLightY, mLightZ;
- private Surface mSurface;
- private final FrameInfo mFrameInfo = new FrameInfo();
+ public static class SimpleRenderer extends HardwareRenderer {
+ private final float mLightY, mLightZ, mLightRadius;
public SimpleRenderer(final Context context, final String name, final Surface surface) {
+ super();
+ setName(name);
+ setOpaque(false);
+ setSurface(surface);
final TypedArray a = context.obtainStyledAttributes(null, R.styleable.Lighting, 0, 0);
mLightY = a.getDimension(R.styleable.Lighting_lightY, 0);
mLightZ = a.getDimension(R.styleable.Lighting_lightZ, 0);
- final float lightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
+ mLightRadius = a.getDimension(R.styleable.Lighting_lightRadius, 0);
final int ambientShadowAlpha =
(int) (255 * a.getFloat(R.styleable.Lighting_ambientShadowAlpha, 0) + 0.5f);
final int spotShadowAlpha =
(int) (255 * a.getFloat(R.styleable.Lighting_spotShadowAlpha, 0) + 0.5f);
a.recycle();
-
- final long rootNodePtr = nCreateRootRenderNode();
- mRootNode = RenderNode.adopt(rootNodePtr);
- mRootNode.setClipToBounds(false);
- mNativeProxy = nCreateProxy(true /* translucent */, rootNodePtr);
- nSetName(mNativeProxy, name);
-
- ProcessInitializer.sInstance.init(context, mNativeProxy);
- nLoadSystemProperties(mNativeProxy);
-
- nSetup(mNativeProxy, lightRadius, ambientShadowAlpha, spotShadowAlpha);
-
- mSurface = surface;
- nUpdateSurface(mNativeProxy, surface);
+ setLightSourceAlpha(ambientShadowAlpha, spotShadowAlpha);
}
/**
@@ -1045,7 +694,7 @@
final float lightX = displaySize.x / 2f - windowLeft;
final float lightY = mLightY - windowTop;
- nSetLightCenter(mNativeProxy, lightX, lightY, mLightZ);
+ setLightSourceGeometry(lightX, lightY, mLightZ, mLightRadius);
}
public RenderNode getRootNode() {
@@ -1057,222 +706,10 @@
*/
public void draw(final FrameDrawingCallback callback) {
final long vsync = AnimationUtils.currentAnimationTimeMillis() * 1000000L;
- mFrameInfo.setVsync(vsync, vsync);
- mFrameInfo.addFlags(1 << 2 /* VSYNC */);
if (callback != null) {
- nSetFrameCallback(mNativeProxy, callback);
+ setFrameCallback(callback);
}
- nSyncAndDrawFrame(mNativeProxy, mFrameInfo.mFrameInfo, mFrameInfo.mFrameInfo.length);
- }
-
- /**
- * Destroy the renderer.
- */
- public void destroy() {
- mSurface = null;
- nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- nDeleteProxy(mNativeProxy);
- mNativeProxy = 0;
- } finally {
- super.finalize();
- }
+ syncAndDrawFrame(vsync);
}
}
-
- /**
- * Interface used to receive callbacks when a frame is being drawn.
- */
- public interface FrameDrawingCallback {
- /**
- * Invoked during a frame drawing.
- *
- * @param frame The id of the frame being drawn.
- */
- void onFrameDraw(long frame);
- }
-
- /**
- * Interface used to be notified when a frame has finished rendering
- */
- public interface FrameCompleteCallback {
- /**
- * Invoked after a frame draw
- *
- * @param frameNr The id of the frame that was drawn.
- */
- void onFrameComplete(long frameNr);
- }
-
- private static class ProcessInitializer {
- static ProcessInitializer sInstance = new ProcessInitializer();
-
- private boolean mInitialized = false;
-
- private Context mAppContext;
- private IGraphicsStats mGraphicsStatsService;
- private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
- @Override
- public void onRotateGraphicsStatsBuffer() throws RemoteException {
- rotateBuffer();
- }
- };
-
- private ProcessInitializer() {}
-
- synchronized void init(Context context, long renderProxy) {
- if (mInitialized) return;
- mInitialized = true;
- mAppContext = context.getApplicationContext();
-
- initSched(renderProxy);
-
- if (mAppContext != null) {
- initGraphicsStats();
- }
- }
-
- private void initSched(long renderProxy) {
- try {
- int tid = nGetRenderThreadTid(renderProxy);
- ActivityManager.getService().setRenderThread(tid);
- } catch (Throwable t) {
- Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
- }
- }
-
- private void initGraphicsStats() {
- try {
- IBinder binder = ServiceManager.getService("graphicsstats");
- if (binder == null) return;
- mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
- requestBuffer();
- } catch (Throwable t) {
- Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
- }
- }
-
- private void rotateBuffer() {
- nRotateProcessStatsBuffer();
- requestBuffer();
- }
-
- private void requestBuffer() {
- try {
- final String pkg = mAppContext.getApplicationInfo().packageName;
- ParcelFileDescriptor pfd = mGraphicsStatsService
- .requestBufferForProcess(pkg, mGraphicsStatsCallback);
- nSetProcessStatsBuffer(pfd.getFd());
- pfd.close();
- } catch (Throwable t) {
- Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
- }
- }
- }
-
- void addFrameMetricsObserver(FrameMetricsObserver observer) {
- long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
- observer.mNative = new VirtualRefBasePtr(nativeObserver);
- }
-
- void removeFrameMetricsObserver(FrameMetricsObserver observer) {
- nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
- observer.mNative = null;
- }
-
- /** b/68769804: For low FPS experiments. */
- public static void setFPSDivisor(int divisor) {
- nHackySetRTAnimationsEnabled(divisor <= 1);
- }
-
- /**
- * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
- * called before any OpenGL context is created.
- *
- * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
- */
- public static void setContextPriority(int priority) {
- nSetContextPriority(priority);
- }
-
- /** Not actually public - internal use only. This doc to make lint happy */
- public static native void disableVsync();
-
- static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
-
- private static native void nRotateProcessStatsBuffer();
- private static native void nSetProcessStatsBuffer(int fd);
- private static native int nGetRenderThreadTid(long nativeProxy);
-
- private static native long nCreateRootRenderNode();
- private static native long nCreateProxy(boolean translucent, long rootRenderNode);
- private static native void nDeleteProxy(long nativeProxy);
-
- private static native boolean nLoadSystemProperties(long nativeProxy);
- private static native void nSetName(long nativeProxy, String name);
-
- private static native void nInitialize(long nativeProxy, Surface window);
- private static native void nUpdateSurface(long nativeProxy, Surface window);
- private static native boolean nPauseSurface(long nativeProxy, Surface window);
- private static native void nSetStopped(long nativeProxy, boolean stopped);
- private static native void nSetup(long nativeProxy,
- float lightRadius, int ambientShadowAlpha, int spotShadowAlpha);
- private static native void nSetLightCenter(long nativeProxy,
- float lightX, float lightY, float lightZ);
- private static native void nSetOpaque(long nativeProxy, boolean opaque);
- private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
- private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
- private static native void nDestroy(long nativeProxy, long rootRenderNode);
- private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
- private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
-
- private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
-
- private static native long nCreateTextureLayer(long nativeProxy);
- private static native void nBuildLayer(long nativeProxy, long node);
- private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
- private static native void nPushLayerUpdate(long nativeProxy, long layer);
- private static native void nCancelLayerUpdate(long nativeProxy, long layer);
- private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
-
- private static native void nDestroyHardwareResources(long nativeProxy);
- private static native void nTrimMemory(int level);
- private static native void nOverrideProperty(String name, String value);
-
- private static native void nFence(long nativeProxy);
- private static native void nStopDrawing(long nativeProxy);
- private static native void nNotifyFramePending(long nativeProxy);
-
- private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
- @DumpFlags int dumpFlags);
-
- private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
- boolean placeFront);
- private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
- private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
- private static native void nSetContentDrawBounds(long nativeProxy, int left,
- int top, int right, int bottom);
- private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
- private static native void nSetFrameCompleteCallback(long nativeProxy,
- FrameCompleteCallback callback);
-
- private static native long nAddFrameMetricsObserver(long nativeProxy, FrameMetricsObserver observer);
- private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
-
- private static native int nCopySurfaceInto(Surface surface,
- int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
-
- private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
- private static native void nSetHighContrastText(boolean enabled);
- // For temporary experimentation b/66945974
- private static native void nHackySetRTAnimationsEnabled(boolean enabled);
- private static native void nSetDebuggingEnabled(boolean enabled);
- private static native void nSetIsolatedProcess(boolean enabled);
- private static native void nSetContextPriority(int priority);
- private static native void nAllocateBuffers(long nativeProxy, Surface window);
- private static native void nSetForceDark(long nativeProxy, boolean enabled);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 453d788..7ba027f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24122,7 +24122,7 @@
* @param outShadowSize A {@link android.graphics.Point} containing the width and height
* of the shadow image. Your application must set {@link android.graphics.Point#x} to the
* desired width and must set {@link android.graphics.Point#y} to the desired height of the
- * image.
+ * image. Since Android P, the width and height must be positive values.
*
* @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
* shadow image that should be underneath the touch point during the drag and drop
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index dd1f640..a23d68b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -46,6 +46,8 @@
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.FrameInfo;
+import android.graphics.HardwareRenderer.FrameDrawingCallback;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Point;
@@ -84,7 +86,6 @@
import android.util.TypedValue;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl.Transaction;
-import android.view.ThreadedRenderer.FrameDrawingCallback;
import android.view.View.AttachInfo;
import android.view.View.FocusDirection;
import android.view.View.MeasureSpec;
@@ -2148,7 +2149,7 @@
// relayoutWindow may decide to destroy mSurface. As that decision
// happens in WindowManager service, we need to be defensive here
// and stop using the surface in case it gets destroyed.
- if (mAttachInfo.mThreadedRenderer.pauseSurface(mSurface)) {
+ if (mAttachInfo.mThreadedRenderer.pause()) {
// Animations were running so we need to push a frame
// to resume them
mDirty.set(0, 0, mWidth, mHeight);
@@ -2266,7 +2267,7 @@
& View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
// Don't pre-allocate if transparent regions
// are requested as they may not be needed
- mAttachInfo.mThreadedRenderer.allocateBuffers(mSurface);
+ mAttachInfo.mThreadedRenderer.allocateBuffers();
}
} catch (OutOfResourcesException e) {
handleOutOfResourcesException(e);
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2d77cb4..8d8a370 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -315,6 +315,36 @@
@interface TransitionFlags {}
/**
+ * Remove content mode: Indicates remove content mode is currently not defined.
+ * @hide
+ */
+ int REMOVE_CONTENT_MODE_UNDEFINED = 0;
+
+ /**
+ * Remove content mode: Indicates that when display is removed, all its activities will be moved
+ * to the primary display and the topmost activity should become focused.
+ * @hide
+ */
+ int REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY = 1;
+
+ /**
+ * Remove content mode: Indicates that when display is removed, all its stacks and tasks will be
+ * removed, all activities will be destroyed according to the usual lifecycle.
+ * @hide
+ */
+ int REMOVE_CONTENT_MODE_DESTROY = 2;
+
+ /**
+ * @hide
+ */
+ @IntDef(prefix = { "REMOVE_CONTENT_MODE_" }, value = {
+ REMOVE_CONTENT_MODE_UNDEFINED,
+ REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
+ REMOVE_CONTENT_MODE_DESTROY,
+ })
+ @interface RemoveContentMode {}
+
+ /**
* Exception that is thrown when trying to add view whose
* {@link LayoutParams} {@link LayoutParams#token}
* is invalid.
@@ -422,6 +452,47 @@
@RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
public Region getCurrentImeTouchRegion();
+ /**
+ * Sets that the display should show its content when non-secure keyguard is shown.
+ *
+ * @param displayId Display ID.
+ * @param shouldShow Indicates that the display should show its content when non-secure keyguard
+ * is shown.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ * @hide
+ */
+ @TestApi
+ default void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
+ }
+
+ /**
+ * Sets that the display should show system decors.
+ * <p>
+ * System decors include status bar, navigation bar, launcher.
+ * </p>
+ *
+ * @param displayId The id of the display.
+ * @param shouldShow Indicates that the display should show system decors.
+ * @hide
+ */
+ @TestApi
+ default void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
+ }
+
+ /**
+ * Sets that the display should show IME.
+ *
+ * @param displayId Display ID.
+ * @param shouldShow Indicates that the display should show IME.
+ * @see KeyguardManager#isDeviceSecure()
+ * @see KeyguardManager#isDeviceLocked()
+ * @hide
+ */
+ @TestApi
+ default void setShouldShowIme(int displayId, boolean shouldShow) {
+ }
+
public static class LayoutParams extends ViewGroup.LayoutParams implements Parcelable {
/**
* X position for this window. With the default gravity it is ignored.
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index 2339d35..a102f6c 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -157,4 +157,30 @@
}
return null;
}
+
+ @Override
+ public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .setShouldShowWithInsecureKeyguard(displayId, shouldShow);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
+ try {
+ WindowManagerGlobal.getWindowManagerService()
+ .setShouldShowSystemDecors(displayId, shouldShow);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
+ public void setShouldShowIme(int displayId, boolean shouldShow) {
+ try {
+ WindowManagerGlobal.getWindowManagerService().setShouldShowIme(displayId, shouldShow);
+ } catch (RemoteException e) {
+ }
+ }
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index e129091..d7c8aed 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3838,6 +3838,14 @@
return "ACTION_SCROLL_DOWN";
case R.id.accessibilityActionScrollRight:
return "ACTION_SCROLL_RIGHT";
+ case R.id.accessibilityActionPageDown:
+ return "ACTION_PAGE_DOWN";
+ case R.id.accessibilityActionPageUp:
+ return "ACTION_PAGE_UP";
+ case R.id.accessibilityActionPageLeft:
+ return "ACTION_PAGE_LEFT";
+ case R.id.accessibilityActionPageRight:
+ return "ACTION_PAGE_RIGHT";
case R.id.accessibilityActionSetProgress:
return "ACTION_SET_PROGRESS";
case R.id.accessibilityActionContextClick:
@@ -4368,6 +4376,30 @@
new AccessibilityAction(R.id.accessibilityActionScrollRight);
/**
+ * Action to move to the page above.
+ */
+ public static final AccessibilityAction ACTION_PAGE_UP =
+ new AccessibilityAction(R.id.accessibilityActionPageUp);
+
+ /**
+ * Action to move to the page below.
+ */
+ public static final AccessibilityAction ACTION_PAGE_DOWN =
+ new AccessibilityAction(R.id.accessibilityActionPageDown);
+
+ /**
+ * Action to move to the page left.
+ */
+ public static final AccessibilityAction ACTION_PAGE_LEFT =
+ new AccessibilityAction(R.id.accessibilityActionPageLeft);
+
+ /**
+ * Action to move to the page right.
+ */
+ public static final AccessibilityAction ACTION_PAGE_RIGHT =
+ new AccessibilityAction(R.id.accessibilityActionPageRight);
+
+ /**
* Action that context clicks the node.
*/
public static final AccessibilityAction ACTION_CONTEXT_CLICK =
diff --git a/core/java/android/view/textclassifier/ModelFileManager.java b/core/java/android/view/textclassifier/ModelFileManager.java
index adea125..896b516 100644
--- a/core/java/android/view/textclassifier/ModelFileManager.java
+++ b/core/java/android/view/textclassifier/ModelFileManager.java
@@ -74,10 +74,9 @@
* @param localeList the required locales, use {@code null} if there is no preference.
*/
public ModelFile findBestModelFile(@Nullable LocaleList localeList) {
- // Specified localeList takes priority over the system default, so it is listed first.
final String languages = localeList == null || localeList.isEmpty()
? LocaleList.getDefault().toLanguageTags()
- : localeList.toLanguageTags() + "," + LocaleList.getDefault().toLanguageTags();
+ : localeList.toLanguageTags();
final List<Locale.LanguageRange> languageRangeList = Locale.LanguageRange.parse(languages);
ModelFile bestModel = null;
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 2fc7422..50801a2 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -90,6 +90,10 @@
"entity_list_not_editable";
private static final String ENTITY_LIST_EDITABLE =
"entity_list_editable";
+ private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
+ "in_app_conversation_action_types_default";
+ private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
+ "notification_conversation_action_types_default";
private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
private static final boolean SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
@@ -111,6 +115,18 @@
.add(TextClassifier.TYPE_DATE)
.add(TextClassifier.TYPE_DATE_TIME)
.add(TextClassifier.TYPE_FLIGHT_NUMBER).toString();
+ private static final String CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES =
+ new StringJoiner(ENTITY_LIST_DELIMITER)
+ .add(ConversationActions.TYPE_TEXT_REPLY)
+ .add(ConversationActions.TYPE_CREATE_REMINDER)
+ .add(ConversationActions.TYPE_CALL_PHONE)
+ .add(ConversationActions.TYPE_OPEN_URL)
+ .add(ConversationActions.TYPE_SEND_EMAIL)
+ .add(ConversationActions.TYPE_SEND_SMS)
+ .add(ConversationActions.TYPE_TRACK_FLIGHT)
+ .add(ConversationActions.TYPE_VIEW_CALENDAR)
+ .add(ConversationActions.TYPE_VIEW_MAP)
+ .toString();
private final boolean mSystemTextClassifierEnabled;
private final boolean mLocalTextClassifierEnabled;
@@ -126,6 +142,8 @@
private final List<String> mEntityListDefault;
private final List<String> mEntityListNotEditable;
private final List<String> mEntityListEditable;
+ private final List<String> mInAppConversationActionTypesDefault;
+ private final List<String> mNotificationConversationActionTypesDefault;
private TextClassificationConstants(@Nullable String settings) {
final KeyValueListParser parser = new KeyValueListParser(',');
@@ -177,6 +195,12 @@
mEntityListEditable = parseEntityList(parser.getString(
ENTITY_LIST_EDITABLE,
ENTITY_LIST_DEFAULT_VALUE));
+ mInAppConversationActionTypesDefault = parseEntityList(parser.getString(
+ IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
+ mNotificationConversationActionTypesDefault = parseEntityList(parser.getString(
+ NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
}
/** Load from a settings string. */
@@ -240,6 +264,14 @@
return mEntityListEditable;
}
+ public List<String> getInAppConversationActionTypes() {
+ return mInAppConversationActionTypesDefault;
+ }
+
+ public List<String> getNotificationConversationActionTypes() {
+ return mNotificationConversationActionTypesDefault;
+ }
+
private static List<String> parseEntityList(String listStr) {
return Collections.unmodifiableList(Arrays.asList(listStr.split(ENTITY_LIST_DELIMITER)));
}
@@ -261,6 +293,9 @@
pw.printPair("getEntityListDefault", mEntityListDefault);
pw.printPair("getEntityListNotEditable", mEntityListNotEditable);
pw.printPair("getEntityListEditable", mEntityListEditable);
+ pw.printPair("getInAppConversationActionTypes", mInAppConversationActionTypesDefault);
+ pw.printPair("getNotificationConversationActionTypes",
+ mNotificationConversationActionTypesDefault);
pw.decreaseIndent();
pw.println();
}
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index e675744..524f709 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -48,6 +48,9 @@
/**
* Interface for providing text classification related features.
+ * <p>
+ * The TextClassifier may be used to understand the meaning of text, as well as generating predicted
+ * next actions based on the text.
*
* <p><strong>NOTE: </strong>Unless otherwise stated, methods of this interface are blocking
* operations. Call on a worker thread.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 159bfaa..798a820 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -40,11 +40,13 @@
import android.provider.Browser;
import android.provider.CalendarContract;
import android.provider.ContactsContract;
+import android.text.TextUtils;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
+import com.google.android.textclassifier.ActionsSuggestionsModel;
import com.google.android.textclassifier.AnnotatorModel;
import com.google.android.textclassifier.LangIdModel;
@@ -90,6 +92,11 @@
private static final File UPDATED_LANG_ID_MODEL_FILE =
new File("/data/misc/textclassifier/lang_id.model");
+ // Actions
+ private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model";
+ private static final File UPDATED_ACTIONS_MODEL =
+ new File("/data/misc/textclassifier/actions_suggestions.model");
+
private final Context mContext;
private final TextClassifier mFallback;
private final GenerateLinksLogger mGenerateLinksLogger;
@@ -101,6 +108,8 @@
private AnnotatorModel mAnnotatorImpl;
@GuardedBy("mLock") // Do not access outside this lock.
private LangIdModel mLangIdImpl;
+ @GuardedBy("mLock") // Do not access outside this lock.
+ private ActionsSuggestionsModel mActionsImpl;
private final Object mLoggerLock = new Object();
@GuardedBy("mLoggerLock") // Do not access outside this lock.
@@ -110,6 +119,7 @@
private final ModelFileManager mAnnotatorModelFileManager;
private final ModelFileManager mLangIdModelFileManager;
+ private final ModelFileManager mActionsModelFileManager;
public TextClassifierImpl(
Context context, TextClassificationConstants settings, TextClassifier fallback) {
@@ -131,6 +141,13 @@
UPDATED_LANG_ID_MODEL_FILE,
fd -> -1, // TODO: Replace this with LangIdModel.getVersion(fd)
fd -> ModelFileManager.ModelFile.LANGUAGE_INDEPENDENT));
+ mActionsModelFileManager = new ModelFileManager(
+ new ModelFileManager.ModelFileSupplierImpl(
+ FACTORY_MODEL_DIR,
+ ACTIONS_FACTORY_MODEL_FILENAME_REGEX,
+ UPDATED_ACTIONS_MODEL,
+ ActionsSuggestionsModel::getVersion,
+ ActionsSuggestionsModel::getLocales));
}
public TextClassifierImpl(Context context, TextClassificationConstants settings) {
@@ -346,10 +363,69 @@
return mFallback.detectLanguage(request);
}
+ @Override
+ public ConversationActions suggestConversationActions(ConversationActions.Request request) {
+ Preconditions.checkNotNull(request);
+ Utils.checkMainThread();
+ try {
+ ActionsSuggestionsModel actionsImpl = getActionsImpl();
+ if (actionsImpl == null) {
+ // Actions model is optional, fallback if it is not available.
+ return mFallback.suggestConversationActions(request);
+ }
+ List<ActionsSuggestionsModel.ConversationMessage> nativeMessages = new ArrayList<>();
+ for (ConversationActions.Message message : request.getConversation()) {
+ if (TextUtils.isEmpty(message.getText())) {
+ continue;
+ }
+ // TODO: We need to map the Person object to user id.
+ int userId = 1;
+ nativeMessages.add(
+ new ActionsSuggestionsModel.ConversationMessage(
+ userId, message.getText().toString()));
+ }
+ ActionsSuggestionsModel.Conversation nativeConversation =
+ new ActionsSuggestionsModel.Conversation(nativeMessages.toArray(
+ new ActionsSuggestionsModel.ConversationMessage[0]));
+
+ ActionsSuggestionsModel.ActionSuggestion[] nativeSuggestions =
+ actionsImpl.suggestActions(nativeConversation, null);
+
+ Collection<String> expectedTypes = resolveActionTypesFromRequest(request);
+ List<ConversationActions.ConversationAction> conversationActions = new ArrayList<>();
+ int maxSuggestions = Math.min(request.getMaxSuggestions(), nativeSuggestions.length);
+ for (int i = 0; i < maxSuggestions; i++) {
+ ActionsSuggestionsModel.ActionSuggestion nativeSuggestion = nativeSuggestions[i];
+ String actionType = nativeSuggestion.getActionType();
+ if (!expectedTypes.contains(actionType)) {
+ continue;
+ }
+ conversationActions.add(
+ new ConversationActions.ConversationAction.Builder(actionType)
+ .setTextReply(nativeSuggestion.getResponseText())
+ .setConfidenceScore(nativeSuggestion.getScore())
+ .build());
+ }
+ return new ConversationActions(conversationActions);
+ } catch (Throwable t) {
+ // Avoid throwing from this method. Log the error.
+ Log.e(LOG_TAG, "Error suggesting conversation actions.", t);
+ }
+ return mFallback.suggestConversationActions(request);
+ }
+
+ private Collection<String> resolveActionTypesFromRequest(ConversationActions.Request request) {
+ List<String> defaultActionTypes =
+ request.getHints().contains(ConversationActions.HINT_FOR_NOTIFICATION)
+ ? mSettings.getNotificationConversationActionTypes()
+ : mSettings.getInAppConversationActionTypes();
+ return request.getTypeConfig().resolveTypes(defaultActionTypes);
+ }
+
private AnnotatorModel getAnnotatorImpl(LocaleList localeList)
throws FileNotFoundException {
synchronized (mLock) {
- localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
+ localeList = localeList == null ? LocaleList.getDefault() : localeList;
final ModelFileManager.ModelFile bestModel =
mAnnotatorModelFileManager.findBestModelFile(localeList);
if (bestModel == null) {
@@ -386,7 +462,7 @@
synchronized (mLock) {
if (mLangIdImpl == null) {
final ModelFileManager.ModelFile bestModel =
- mLangIdModelFileManager.findBestModelFile(LocaleList.getEmptyLocaleList());
+ mLangIdModelFileManager.findBestModelFile(null);
if (bestModel == null) {
throw new FileNotFoundException("No LangID model is found");
}
@@ -404,6 +480,30 @@
}
}
+ @Nullable
+ private ActionsSuggestionsModel getActionsImpl() throws FileNotFoundException {
+ synchronized (mLock) {
+ if (mActionsImpl == null) {
+ // TODO: Use LangID to determine the locale we should use here?
+ final ModelFileManager.ModelFile bestModel =
+ mActionsModelFileManager.findBestModelFile(LocaleList.getDefault());
+ if (bestModel == null) {
+ return null;
+ }
+ final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
+ new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
+ try {
+ if (pfd != null) {
+ mActionsImpl = new ActionsSuggestionsModel(pfd.getFd());
+ }
+ } finally {
+ maybeCloseAndLogError(pfd);
+ }
+ }
+ return mActionsImpl;
+ }
+ }
+
private String createId(String text, int start, int end) {
synchronized (mLock) {
return SelectionSessionLogger.createId(text, start, end, mContext,
@@ -471,11 +571,19 @@
}
printWriter.decreaseIndent();
printWriter.println("LangID model file(s):");
+ printWriter.increaseIndent();
for (ModelFileManager.ModelFile modelFile :
mLangIdModelFileManager.listModelFiles()) {
printWriter.println(modelFile.toString());
}
printWriter.decreaseIndent();
+ printWriter.println("Actions model file(s):");
+ printWriter.increaseIndent();
+ for (ModelFileManager.ModelFile modelFile :
+ mActionsModelFileManager.listModelFiles()) {
+ printWriter.println(modelFile.toString());
+ }
+ printWriter.decreaseIndent();
printWriter.printPair("mFallback", mFallback);
printWriter.decreaseIndent();
printWriter.println();
diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java
index b31438f..02aee50 100644
--- a/core/java/android/view/textclassifier/TextLinks.java
+++ b/core/java/android/view/textclassifier/TextLinks.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
+import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
@@ -92,10 +93,12 @@
private final String mFullText;
private final List<TextLink> mLinks;
+ private final Bundle mExtras;
- private TextLinks(String fullText, ArrayList<TextLink> links) {
+ private TextLinks(String fullText, ArrayList<TextLink> links, Bundle extras) {
mFullText = fullText;
mLinks = Collections.unmodifiableList(links);
+ mExtras = extras;
}
/**
@@ -116,6 +119,18 @@
}
/**
+ * Returns the extended data.
+ *
+ * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
+ * prefer to hold a reference to the returned bundle rather than frequently calling this
+ * method.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras.deepCopy();
+ }
+
+ /**
* Annotates the given text with the generated links. It will fail if the provided text doesn't
* match the original text used to create the TextLinks.
*
@@ -158,6 +173,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mFullText);
dest.writeTypedList(mLinks);
+ dest.writeBundle(mExtras);
}
public static final Parcelable.Creator<TextLinks> CREATOR =
@@ -176,6 +192,7 @@
private TextLinks(Parcel in) {
mFullText = in.readString();
mLinks = in.createTypedArrayList(TextLink.CREATOR);
+ mExtras = in.readBundle();
}
/**
@@ -304,18 +321,21 @@
@Nullable private final TextClassifier.EntityConfig mEntityConfig;
private final boolean mLegacyFallback;
private String mCallingPackageName;
+ private final Bundle mExtras;
private Request(
CharSequence text,
LocaleList defaultLocales,
TextClassifier.EntityConfig entityConfig,
boolean legacyFallback,
- String callingPackageName) {
+ String callingPackageName,
+ Bundle extras) {
mText = text;
mDefaultLocales = defaultLocales;
mEntityConfig = entityConfig;
mLegacyFallback = legacyFallback;
mCallingPackageName = callingPackageName;
+ mExtras = extras;
}
/**
@@ -362,6 +382,18 @@
}
/**
+ * Returns the extended data.
+ *
+ * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
+ * prefer to hold a reference to the returned bundle rather than frequently calling this
+ * method.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras.deepCopy();
+ }
+
+ /**
* A builder for building TextLinks requests.
*/
public static final class Builder {
@@ -372,6 +404,7 @@
@Nullable private TextClassifier.EntityConfig mEntityConfig;
private boolean mLegacyFallback = true; // Use legacy fall back by default.
private String mCallingPackageName;
+ @Nullable private Bundle mExtras;
public Builder(@NonNull CharSequence text) {
mText = Preconditions.checkNotNull(text);
@@ -431,15 +464,25 @@
}
/**
+ * Sets the extended data.
+ *
+ * @return this builder
+ */
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds and returns the request object.
*/
@NonNull
public Request build() {
return new Request(
mText, mDefaultLocales, mEntityConfig,
- mLegacyFallback, mCallingPackageName);
+ mLegacyFallback, mCallingPackageName,
+ mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
}
-
}
/**
@@ -469,6 +512,7 @@
mEntityConfig.writeToParcel(dest, flags);
}
dest.writeString(mCallingPackageName);
+ dest.writeBundle(mExtras);
}
public static final Parcelable.Creator<Request> CREATOR =
@@ -491,6 +535,7 @@
? null : TextClassifier.EntityConfig.CREATOR.createFromParcel(in);
mLegacyFallback = true;
mCallingPackageName = in.readString();
+ mExtras = in.readBundle();
}
}
@@ -575,6 +620,7 @@
public static final class Builder {
private final String mFullText;
private final ArrayList<TextLink> mLinks;
+ private Bundle mExtras;
/**
* Create a new TextLinks.Builder.
@@ -622,13 +668,24 @@
}
/**
+ * Sets the extended data.
+ *
+ * @return this builder
+ */
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Constructs a TextLinks instance.
*
* @return the constructed TextLinks
*/
@NonNull
public TextLinks build() {
- return new TextLinks(mFullText, mLinks);
+ return new TextLinks(mFullText, mLinks,
+ mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
}
}
}
diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java
index 52d01ea..f236915 100644
--- a/core/java/android/view/textclassifier/TextSelection.java
+++ b/core/java/android/view/textclassifier/TextSelection.java
@@ -20,6 +20,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,13 +42,16 @@
private final int mEndIndex;
private final EntityConfidence mEntityConfidence;
@Nullable private final String mId;
+ private final Bundle mExtras;
private TextSelection(
- int startIndex, int endIndex, Map<String, Float> entityConfidence, String id) {
+ int startIndex, int endIndex, Map<String, Float> entityConfidence, String id,
+ Bundle extras) {
mStartIndex = startIndex;
mEndIndex = endIndex;
mEntityConfidence = new EntityConfidence(entityConfidence);
mId = id;
+ mExtras = extras;
}
/**
@@ -103,6 +107,18 @@
return mId;
}
+ /**
+ * Returns the extended data.
+ *
+ * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
+ * prefer to hold a reference to the returned bundle rather than frequently calling this
+ * method.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras.deepCopy();
+ }
+
@Override
public String toString() {
return String.format(
@@ -120,6 +136,8 @@
private final int mEndIndex;
private final Map<String, Float> mEntityConfidence = new ArrayMap<>();
@Nullable private String mId;
+ @Nullable
+ private Bundle mExtras;
/**
* Creates a builder used to build {@link TextSelection} objects.
@@ -160,12 +178,23 @@
}
/**
+ * Sets the extended data.
+ *
+ * @return this builder
+ */
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds and returns {@link TextSelection} object.
*/
@NonNull
public TextSelection build() {
return new TextSelection(
- mStartIndex, mEndIndex, mEntityConfidence, mId);
+ mStartIndex, mEndIndex, mEntityConfidence, mId,
+ mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
}
}
@@ -179,18 +208,21 @@
private final int mEndIndex;
@Nullable private final LocaleList mDefaultLocales;
private final boolean mDarkLaunchAllowed;
+ private final Bundle mExtras;
private Request(
CharSequence text,
int startIndex,
int endIndex,
LocaleList defaultLocales,
- boolean darkLaunchAllowed) {
+ boolean darkLaunchAllowed,
+ Bundle extras) {
mText = text;
mStartIndex = startIndex;
mEndIndex = endIndex;
mDefaultLocales = defaultLocales;
mDarkLaunchAllowed = darkLaunchAllowed;
+ mExtras = extras;
}
/**
@@ -238,6 +270,18 @@
}
/**
+ * Returns the extended data.
+ *
+ * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
+ * prefer to hold a reference to the returned bundle rather than frequently calling this
+ * method.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras.deepCopy();
+ }
+
+ /**
* A builder for building TextSelection requests.
*/
public static final class Builder {
@@ -248,6 +292,7 @@
@Nullable private LocaleList mDefaultLocales;
private boolean mDarkLaunchAllowed;
+ private Bundle mExtras;
/**
* @param text text providing context for the selected text (which is specified by the
@@ -296,12 +341,23 @@
}
/**
+ * Sets the extended data.
+ *
+ * @return this builder
+ */
+ public Builder setExtras(@Nullable Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds and returns the request object.
*/
@NonNull
public Request build() {
return new Request(mText, mStartIndex, mEndIndex,
- mDefaultLocales, mDarkLaunchAllowed);
+ mDefaultLocales, mDarkLaunchAllowed,
+ mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
}
}
@@ -319,6 +375,7 @@
if (mDefaultLocales != null) {
mDefaultLocales.writeToParcel(dest, flags);
}
+ dest.writeBundle(mExtras);
}
public static final Parcelable.Creator<Request> CREATOR =
@@ -340,6 +397,7 @@
mEndIndex = in.readInt();
mDefaultLocales = in.readInt() == 0 ? null : LocaleList.CREATOR.createFromParcel(in);
mDarkLaunchAllowed = false;
+ mExtras = in.readBundle();
}
}
@@ -354,6 +412,7 @@
dest.writeInt(mEndIndex);
mEntityConfidence.writeToParcel(dest, flags);
dest.writeString(mId);
+ dest.writeBundle(mExtras);
}
public static final Parcelable.Creator<TextSelection> CREATOR =
@@ -374,5 +433,6 @@
mEndIndex = in.readInt();
mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in);
mId = in.readString();
+ mExtras = in.readBundle();
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c31f17a..4523d3b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -16,13 +16,8 @@
package com.android.internal.app;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.annotation.NonNull;
import android.app.Activity;
import android.app.ActivityManager;
-import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -56,7 +51,6 @@
import android.service.chooser.IChooserTargetResult;
import android.service.chooser.IChooserTargetService;
import android.text.TextUtils;
-import android.util.FloatProperty;
import android.util.Log;
import android.util.Slog;
import android.view.LayoutInflater;
@@ -66,8 +60,6 @@
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
@@ -76,10 +68,9 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.ResolverActivity;
-import com.android.internal.app.ResolverActivity.TargetInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+
import com.google.android.collect.Lists;
import java.io.File;
@@ -847,7 +838,7 @@
}
@Override
- public boolean startAsCaller(Activity activity, Bundle options, int userId) {
+ public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
final Intent intent = getBaseIntentToSend();
if (intent == null) {
return false;
@@ -866,8 +857,7 @@
final boolean ignoreTargetSecurity = mSourceInfo != null
&& mSourceInfo.getResolvedComponentName().getPackageName()
.equals(mChooserTarget.getComponentName().getPackageName());
- activity.startActivityAsCaller(intent, options, ignoreTargetSecurity, userId);
- return true;
+ return activity.startAsCallerImpl(intent, options, ignoreTargetSecurity, userId);
}
@Override
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index c0c689c..764c0cf 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -53,5 +53,5 @@
/** For both ...Intent and ...Service based usage */
boolean isRecognitionActive(in ParcelUuid parcelUuid);
- SoundTrigger.RecognitionEvent getModelState(in ParcelUuid parcelUuid);
+ int getModelState(in ParcelUuid soundModelId);
}
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 8cfe1c1..d13bcf2 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.app.Activity;
-import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.ActivityThread;
import android.app.AppGlobals;
@@ -38,7 +37,9 @@
import android.os.UserManager;
import android.util.Slog;
import android.widget.Toast;
+
import com.android.internal.annotations.VisibleForTesting;
+
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -106,7 +107,7 @@
final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY,
targetUserId);
try {
- startActivityAsCaller(newIntent, null, false, targetUserId);
+ startActivityAsCaller(newIntent, null, null, false, targetUserId);
} catch (RuntimeException e) {
int launchedFromUid = -1;
String launchedFromPackage = "?";
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index fd38917..0f88722 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -46,6 +46,7 @@
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.PatternMatcher;
import android.os.RemoteException;
import android.os.StrictMode;
@@ -859,6 +860,37 @@
}
}
+
+ boolean startAsCallerImpl(Intent intent, Bundle options, boolean ignoreTargetSecurity,
+ int userId) {
+ // Pass intent to delegate chooser activity with permission token.
+ // TODO: This should move to a trampoline Activity in the system when the ChooserActivity
+ // moves into systemui
+ try {
+ // TODO: Once this is a small springboard activity, it can move off the UI process
+ // and we can move the request method to ActivityManagerInternal.
+ IBinder permissionToken = ActivityTaskManager.getService()
+ .requestStartActivityPermissionToken(getActivityToken());
+ final Intent chooserIntent = new Intent();
+ final ComponentName delegateActivity = ComponentName.unflattenFromString(
+ Resources.getSystem().getString(R.string.config_chooserActivity));
+ chooserIntent.setClassName(delegateActivity.getPackageName(),
+ delegateActivity.getClassName());
+ chooserIntent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, permissionToken);
+
+ // TODO: These extras will change as chooser activity moves into systemui
+ chooserIntent.putExtra(Intent.EXTRA_INTENT, intent);
+ chooserIntent.putExtra(ActivityTaskManager.EXTRA_OPTIONS, options);
+ chooserIntent.putExtra(ActivityTaskManager.EXTRA_IGNORE_TARGET_SECURITY,
+ ignoreTargetSecurity);
+ chooserIntent.putExtra(Intent.EXTRA_USER_ID, userId);
+ startActivity(chooserIntent);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ return true;
+ }
+
public void onActivityStarted(TargetInfo cti) {
// Do nothing
}
@@ -1183,9 +1215,8 @@
}
@Override
- public boolean startAsCaller(Activity activity, Bundle options, int userId) {
- activity.startActivityAsCaller(mResolvedIntent, options, false, userId);
- return true;
+ public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
+ return activity.startAsCallerImpl(mResolvedIntent, options, false, userId);
}
@Override
@@ -1244,7 +1275,7 @@
* @param userId userId to start as or {@link UserHandle#USER_NULL} for activity's caller
* @return true if the start completed successfully
*/
- boolean startAsCaller(Activity activity, Bundle options, int userId);
+ boolean startAsCaller(ResolverActivity activity, Bundle options, int userId);
/**
* Start the activity referenced by this target as a given user.
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/core/java/com/android/internal/inputmethod/IMultiClientInputMethod.aidl
similarity index 60%
copy from telephony/java/com/android/internal/telephony/IRcs.aidl
copy to core/java/com/android/internal/inputmethod/IMultiClientInputMethod.aidl
index ede8695..2f782ba 100644
--- a/telephony/java/com/android/internal/telephony/IRcs.aidl
+++ b/core/java/com/android/internal/inputmethod/IMultiClientInputMethod.aidl
@@ -14,8 +14,13 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package com.android.internal.inputmethod;
-interface IRcs {
- void deleteThread(int threadId);
-}
\ No newline at end of file
+import android.os.IBinder;
+import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
+
+oneway interface IMultiClientInputMethod {
+ void initialize(in IMultiClientInputMethodPrivilegedOperations privOps);
+ void addClient(int clientId, int uid, int pid, int selfReportedDisplayId);
+ void removeClient(int clientId);
+}
diff --git a/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl
new file mode 100644
index 0000000..69d9ccc
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodPrivilegedOperations.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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.inputmethod;
+
+import android.view.InputChannel;
+import com.android.internal.view.IInputMethodSession;
+import com.android.internal.inputmethod.IMultiClientInputMethodSession;
+
+/**
+ * Defines priviledged operations that only the current MSIMS is allowed to call.
+ * Actual operations are implemented and handled by MultiClientInputMethodManagerService.
+ */
+interface IMultiClientInputMethodPrivilegedOperations {
+ IBinder createInputMethodWindowToken(int displayId);
+ void deleteInputMethodWindowToken(IBinder token);
+ void acceptClient(int clientId, in IInputMethodSession session,
+ in IMultiClientInputMethodSession multiClientSession, in InputChannel writeChannel);
+ void reportImeWindowTarget(int clientId, int targetWindowHandle, in IBinder imeWindowToken);
+ boolean isUidAllowedOnDisplay(int displayId, int uid);
+}
diff --git a/core/java/com/android/internal/inputmethod/IMultiClientInputMethodSession.aidl b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodSession.aidl
new file mode 100644
index 0000000..b40e82c
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/IMultiClientInputMethodSession.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 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.inputmethod;
+
+import android.os.ResultReceiver;
+import android.view.inputmethod.EditorInfo;
+import com.android.internal.view.IInputContext;
+
+oneway interface IMultiClientInputMethodSession {
+ void startInputOrWindowGainedFocus(
+ in IInputContext inputContext, int missingMethods, in EditorInfo attribute,
+ int controlFlags, int softInputMode, int targetWindowHandle);
+ void showSoftInput(int flags, in ResultReceiver resultReceiver);
+ void hideSoftInput(int flags, in ResultReceiver resultReceiver);
+}
diff --git a/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java b/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java
new file mode 100644
index 0000000..9220117
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/MultiClientInputMethodPrivilegedOperations.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2018 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.inputmethod;
+
+import android.annotation.AnyThread;
+import android.annotation.Nullable;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.InputChannel;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.view.IInputMethodSession;
+
+/**
+ * A utility class to take care of boilerplate code around IPCs.
+ *
+ * <p>Note: All public methods are designed to be thread-safe.</p>
+ */
+public class MultiClientInputMethodPrivilegedOperations {
+ private static final String TAG = "MultiClientInputMethodPrivilegedOperations";
+
+ private static final class OpsHolder {
+ @Nullable
+ @GuardedBy("this")
+ private IMultiClientInputMethodPrivilegedOperations mPrivOps;
+
+ /**
+ * Sets {@link IMultiClientInputMethodPrivilegedOperations}.
+ *
+ * <p>This method can be called only once.</p>
+ *
+ * @param privOps Binder interface to be set.
+ */
+ @AnyThread
+ public synchronized void set(IMultiClientInputMethodPrivilegedOperations privOps) {
+ if (mPrivOps != null) {
+ throw new IllegalStateException(
+ "IMultiClientInputMethodPrivilegedOperations must be set at most once."
+ + " privOps=" + privOps);
+ }
+ mPrivOps = privOps;
+ }
+
+ /**
+ * A simplified version of {@link android.os.Debug#getCaller()}.
+ *
+ * @return method name of the caller.
+ */
+ @AnyThread
+ private static String getCallerMethodName() {
+ final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+ if (callStack.length <= 4) {
+ return "<bottom of call stack>";
+ }
+ return callStack[4].getMethodName();
+ }
+
+ @AnyThread
+ public synchronized void dispose() {
+ mPrivOps = null;
+ }
+
+ @AnyThread
+ @Nullable
+ public synchronized IMultiClientInputMethodPrivilegedOperations getAndWarnIfNull() {
+ if (mPrivOps == null) {
+ Log.e(TAG, getCallerMethodName() + " is ignored."
+ + " Call it within attachToken() and InputMethodService.onDestroy()");
+ }
+ return mPrivOps;
+ }
+ }
+ private final OpsHolder mOps = new OpsHolder();
+
+ /**
+ * Sets {@link IMultiClientInputMethodPrivilegedOperations}.
+ *
+ * <p>This method can be called only once.</p>
+ *
+ * @param privOps Binder interface to be set.
+ */
+ @AnyThread
+ public void set(IMultiClientInputMethodPrivilegedOperations privOps) {
+ mOps.set(privOps);
+ }
+
+ /**
+ * Disposes internal Binder proxy so that the real Binder object can be garbage collected.
+ */
+ @AnyThread
+ public void dispose() {
+ mOps.dispose();
+ }
+
+ /**
+
+ * Calls {@link IMultiClientInputMethodPrivilegedOperations#createInputMethodWindowToken(int)}.
+ *
+ * @param displayId display ID on which the IME window will be shown.
+ * @return Window token to be specified to the IME window.
+ */
+ @AnyThread
+ public IBinder createInputMethodWindowToken(int displayId) {
+ IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return null;
+ }
+ try {
+ return ops.createInputMethodWindowToken(displayId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Calls {@link
+ * IMultiClientInputMethodPrivilegedOperations#deleteInputMethodWindowToken(IBinder)}.
+ *
+ * @param token Window token that is to be deleted.
+ */
+ @AnyThread
+ public void deleteInputMethodWindowToken(IBinder token) {
+ IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return;
+ }
+ try {
+ ops.deleteInputMethodWindowToken(token);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Calls {@link IMultiClientInputMethodPrivilegedOperations#acceptClient(int,
+ * IInputMethodSession, IMultiClientInputMethodSession, InputChannel)}.
+ *
+ * @param clientId client ID to be accepted.
+ * @param session {@link IInputMethodSession} that is also used for traditional IME protocol.
+ * @param multiClientSession {@link IMultiClientInputMethodSession} that defines new callbacks
+ * for multi-client scenarios.
+ * @param writeChannel {@link InputChannel} that is also used for traditional IME protocol.
+ */
+ @AnyThread
+ public void acceptClient(int clientId, IInputMethodSession session,
+ IMultiClientInputMethodSession multiClientSession, InputChannel writeChannel) {
+ final IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return;
+ }
+ try {
+ ops.acceptClient(clientId, session, multiClientSession, writeChannel);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Calls {@link IMultiClientInputMethodPrivilegedOperations#reportImeWindowTarget(int, int,
+ * IBinder)}.
+ *
+ * @param clientId client ID about which new IME target window is reported.
+ * @param targetWindowHandle integer handle of the target window.
+ * @param imeWindowToken {@link IBinder} window token of the IME window.
+ */
+ @AnyThread
+ public void reportImeWindowTarget(int clientId, int targetWindowHandle,
+ IBinder imeWindowToken) {
+ final IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return;
+ }
+ try {
+ ops.reportImeWindowTarget(clientId, targetWindowHandle, imeWindowToken);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Calls {@link IMultiClientInputMethodPrivilegedOperations#isUidAllowedOnDisplay(int, int)}.
+ *
+ * @param displayId display ID to be verified.
+ * @param uid UID to be verified.
+ * @return {@code true} when {@code uid} is allowed to access to {@code displayId}.
+ */
+ @AnyThread
+ public boolean isUidAllowedOnDisplay(int displayId, int uid) {
+ final IMultiClientInputMethodPrivilegedOperations ops = mOps.getAndWarnIfNull();
+ if (ops == null) {
+ return false;
+ }
+ try {
+ return ops.isUidAllowedOnDisplay(displayId, uid);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+}
diff --git a/core/java/com/android/internal/os/KernelCpuProcStringReader.java b/core/java/com/android/internal/os/KernelCpuProcStringReader.java
new file mode 100644
index 0000000..22435ae
--- /dev/null
+++ b/core/java/com/android/internal/os/KernelCpuProcStringReader.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2018 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.os.StrictMode;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.CharBuffer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Reads human-readable cpu time proc files.
+ *
+ * It is implemented as singletons for built-in kernel proc files. Get___Instance() method will
+ * return corresponding reader instance. In order to prevent frequent GC, it reuses the same char[]
+ * to store data read from proc files.
+ *
+ * A KernelCpuProcStringReader instance keeps an error counter. When the number of read errors
+ * within that instance accumulates to 5, this instance will reject all further read requests.
+ *
+ * Data fetched within last 500ms is considered fresh, since the reading lifecycle can take up to
+ * 100ms. KernelCpuProcStringReader always tries to use cache if it is fresh and valid, but it can
+ * be disabled through a parameter.
+ *
+ * A KernelCpuProcReader instance is thread-safe. It acquires a write lock when reading the proc
+ * file, releases it right after, then acquires a read lock before returning a ProcFileIterator.
+ * Caller is responsible for closing ProcFileIterator (also auto-closable) after reading, otherwise
+ * deadlock will occur.
+ */
+public class KernelCpuProcStringReader {
+ private static final String TAG = KernelCpuProcStringReader.class.getSimpleName();
+ private static final int ERROR_THRESHOLD = 5;
+ // Data read within the last 500ms is considered fresh.
+ private static final long FRESHNESS = 500L;
+ private static final int MAX_BUFFER_SIZE = 1024 * 1024;
+
+ private static final String PROC_UID_FREQ_TIME = "/proc/uid_time_in_state";
+ private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_concurrent_active_time";
+ private static final String PROC_UID_CLUSTER_TIME = "/proc/uid_concurrent_policy_time";
+
+ private static final KernelCpuProcStringReader FREQ_TIME_READER =
+ new KernelCpuProcStringReader(PROC_UID_FREQ_TIME);
+ private static final KernelCpuProcStringReader ACTIVE_TIME_READER =
+ new KernelCpuProcStringReader(PROC_UID_ACTIVE_TIME);
+ private static final KernelCpuProcStringReader CLUSTER_TIME_READER =
+ new KernelCpuProcStringReader(PROC_UID_CLUSTER_TIME);
+
+ public static KernelCpuProcStringReader getFreqTimeReaderInstance() {
+ return FREQ_TIME_READER;
+ }
+
+ public static KernelCpuProcStringReader getActiveTimeReaderInstance() {
+ return ACTIVE_TIME_READER;
+ }
+
+ public static KernelCpuProcStringReader getClusterTimeReaderInstance() {
+ return CLUSTER_TIME_READER;
+ }
+
+ private int mErrors = 0;
+ private final Path mFile;
+ private char[] mBuf;
+ private int mSize;
+ private long mLastReadTime = 0;
+ private final ReentrantReadWriteLock mLock = new ReentrantReadWriteLock();
+ private final ReentrantReadWriteLock.ReadLock mReadLock = mLock.readLock();
+ private final ReentrantReadWriteLock.WriteLock mWriteLock = mLock.writeLock();
+
+ public KernelCpuProcStringReader(String file) {
+ mFile = Paths.get(file);
+ }
+
+ /**
+ * @see #open(boolean) Default behavior is trying to use cache.
+ */
+ public ProcFileIterator open() {
+ return open(false);
+ }
+
+ /**
+ * Opens the proc file and buffers all its content, which can be traversed through a
+ * ProcFileIterator.
+ *
+ * This method will tolerate at most 5 errors. After that, it will always return null. This is
+ * to save resources and to prevent log spam.
+ *
+ * This method is thread-safe. It first checks if there are other threads holding read/write
+ * lock. If there are, it assumes data is fresh and reuses the data.
+ *
+ * A read lock is automatically acquired when a valid ProcFileIterator is returned. Caller MUST
+ * call {@link ProcFileIterator#close()} when it is done to release the lock.
+ *
+ * @param ignoreCache If true, ignores the cache and refreshes the data anyway.
+ * @return A {@link ProcFileIterator} to iterate through the file content, or null if there is
+ * error.
+ */
+ public ProcFileIterator open(boolean ignoreCache) {
+ if (mErrors >= ERROR_THRESHOLD) {
+ return null;
+ }
+
+ if (ignoreCache) {
+ mWriteLock.lock();
+ } else {
+ mReadLock.lock();
+ if (dataValid()) {
+ return new ProcFileIterator(mSize);
+ }
+ mReadLock.unlock();
+ mWriteLock.lock();
+ if (dataValid()) {
+ // Recheck because another thread might have written data just before we did.
+ mReadLock.lock();
+ mWriteLock.unlock();
+ return new ProcFileIterator(mSize);
+ }
+ }
+
+ // At this point, write lock is held and data is invalid.
+ int total = 0;
+ int curr;
+ mSize = 0;
+ final int oldMask = StrictMode.allowThreadDiskReadsMask();
+ try (BufferedReader r = Files.newBufferedReader(mFile)) {
+ if (mBuf == null) {
+ mBuf = new char[1024];
+ }
+ while ((curr = r.read(mBuf, total, mBuf.length - total)) >= 0) {
+ total += curr;
+ if (total == mBuf.length) {
+ // Hit the limit. Resize buffer.
+ if (mBuf.length == MAX_BUFFER_SIZE) {
+ mErrors++;
+ Slog.e(TAG, "Proc file too large: " + mFile);
+ return null;
+ }
+ mBuf = Arrays.copyOf(mBuf, Math.min(mBuf.length << 1, MAX_BUFFER_SIZE));
+ }
+ }
+ mSize = total;
+ mLastReadTime = SystemClock.elapsedRealtime();
+ // ReentrantReadWriteLock allows lock downgrading.
+ mReadLock.lock();
+ return new ProcFileIterator(total);
+ } catch (FileNotFoundException e) {
+ mErrors++;
+ Slog.w(TAG, "File not found. It's normal if not implemented: " + mFile);
+ } catch (IOException e) {
+ mErrors++;
+ Slog.e(TAG, "Error reading: " + mFile, e);
+ } finally {
+ StrictMode.setThreadPolicyMask(oldMask);
+ mWriteLock.unlock();
+ }
+ return null;
+ }
+
+ private boolean dataValid() {
+ return mSize > 0 && (SystemClock.elapsedRealtime() - mLastReadTime < FRESHNESS);
+ }
+
+ /**
+ * An autoCloseable iterator to iterate through a string proc file line by line. User must call
+ * close() when finish using to prevent deadlock.
+ */
+ public class ProcFileIterator implements AutoCloseable {
+ private final int mSize;
+ private int mPos;
+
+ public ProcFileIterator(int size) {
+ mSize = size;
+ }
+
+ /**
+ * Fetches the next line. Note that all subsequent return values share the same char[]
+ * under the hood.
+ *
+ * @return A {@link java.nio.CharBuffer} containing the next line without the new line
+ * symbol.
+ */
+ public CharBuffer nextLine() {
+ if (mPos >= mSize) {
+ return null;
+ }
+ int i = mPos;
+ // Move i to the next new line symbol, which is always '\n' in Android.
+ while (i < mSize && mBuf[i] != '\n') {
+ i++;
+ }
+ int start = mPos;
+ mPos = i + 1;
+ return CharBuffer.wrap(mBuf, start, i - start);
+ }
+
+ /**
+ * Fetches the next line, converts all numbers into long, and puts into the given long[].
+ * To avoid GC, caller should try to use the same array for all calls. All non-numeric
+ * chars are treated as delimiters. All numbers are non-negative.
+ *
+ * @param array An array to store the parsed numbers.
+ * @return The number of elements written to the given array. -1 if there is no more line.
+ */
+ public int nextLineAsArray(long[] array) {
+ CharBuffer buf = nextLine();
+ if (buf == null) {
+ return -1;
+ }
+ int count = 0;
+ long num = -1;
+ char c;
+
+ while (buf.remaining() > 0 && count < array.length) {
+ c = buf.get();
+ if (num < 0) {
+ if (isNumber(c)) {
+ num = c - '0';
+ }
+ } else {
+ if (isNumber(c)) {
+ num = num * 10 + c - '0';
+ } else {
+ array[count++] = num;
+ num = -1;
+ }
+ }
+ }
+ if (num >= 0) {
+ array[count++] = num;
+ }
+ return count;
+ }
+
+ /** Total size of the proc file in chars. */
+ public int size() {
+ return mSize;
+ }
+
+ /** Must call close at the end to release the read lock! Or use try-with-resources. */
+ public void close() {
+ mReadLock.unlock();
+ }
+
+ private boolean isNumber(char c) {
+ return c >= '0' && c <= '9';
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index 6b277a0..7c82a7e 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -173,7 +173,7 @@
}
}
} catch (IOException e) {
- Slog.w(TAG, "Failed to iterate over thread paths", e);
+ // Expected when a process finishes
return null;
}
diff --git a/core/java/com/android/internal/os/ProcStatsUtil.java b/core/java/com/android/internal/os/ProcStatsUtil.java
index 3d4df89..0002447f 100644
--- a/core/java/com/android/internal/os/ProcStatsUtil.java
+++ b/core/java/com/android/internal/os/ProcStatsUtil.java
@@ -32,6 +32,8 @@
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED)
public final class ProcStatsUtil {
+ private static final boolean DEBUG = false;
+
private static final String TAG = "ProcStatsUtil";
/**
@@ -141,7 +143,9 @@
}
return byteStream.toString();
} catch (IOException e) {
- Slog.w(TAG, "Failed to open proc file", e);
+ if (DEBUG) {
+ Slog.d(TAG, "Failed to open proc file", e);
+ }
return null;
} finally {
StrictMode.setThreadPolicy(savedPolicy);
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/core/java/com/android/internal/util/function/HeptConsumer.java
similarity index 71%
copy from telephony/java/com/android/internal/telephony/IRcs.aidl
copy to core/java/com/android/internal/util/function/HeptConsumer.java
index ede8695..171b0f2 100644
--- a/telephony/java/com/android/internal/telephony/IRcs.aidl
+++ b/core/java/com/android/internal/util/function/HeptConsumer.java
@@ -14,8 +14,15 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package com.android.internal.util.function;
-interface IRcs {
- void deleteThread(int threadId);
-}
\ No newline at end of file
+import java.util.function.Consumer;
+
+/**
+ * A 7-argument {@link Consumer}
+ *
+ * @hide
+ */
+public interface HeptConsumer<A, B, C, D, E, F, G> {
+ void accept(A a, B b, C c, D d, E e, F f, G g);
+}
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/core/java/com/android/internal/util/function/HeptFunction.java
similarity index 71%
copy from telephony/java/com/android/internal/telephony/IRcs.aidl
copy to core/java/com/android/internal/util/function/HeptFunction.java
index ede8695..7aa4345 100644
--- a/telephony/java/com/android/internal/telephony/IRcs.aidl
+++ b/core/java/com/android/internal/util/function/HeptFunction.java
@@ -14,8 +14,15 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package com.android.internal.util.function;
-interface IRcs {
- void deleteThread(int threadId);
-}
\ No newline at end of file
+import java.util.function.Function;
+
+/**
+ * A 7-argument {@link Function}
+ *
+ * @hide
+ */
+public interface HeptFunction<A, B, C, D, E, F, G, R> {
+ R apply(A a, B b, C c, D d, E e, F f, G g);
+}
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/core/java/com/android/internal/util/function/HeptPredicate.java
similarity index 71%
copy from telephony/java/com/android/internal/telephony/IRcs.aidl
copy to core/java/com/android/internal/util/function/HeptPredicate.java
index ede8695..531e53a 100644
--- a/telephony/java/com/android/internal/telephony/IRcs.aidl
+++ b/core/java/com/android/internal/util/function/HeptPredicate.java
@@ -14,8 +14,15 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package com.android.internal.util.function;
-interface IRcs {
- void deleteThread(int threadId);
-}
\ No newline at end of file
+import java.util.function.Predicate;
+
+/**
+ * A 7-argument {@link Predicate}
+ *
+ * @hide
+ */
+public interface HeptPredicate<A, B, C, D, E, F, G> {
+ boolean test(A a, B b, C c, D d, E e, F f, G g);
+}
diff --git a/core/java/com/android/internal/util/function/pooled/OmniFunction.java b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
index 9378869..4ffe441 100755
--- a/core/java/com/android/internal/util/function/pooled/OmniFunction.java
+++ b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
@@ -18,6 +18,8 @@
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
+import com.android.internal.util.function.HeptConsumer;
+import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.QuadConsumer;
@@ -37,59 +39,61 @@
*
* @hide
*/
-abstract class OmniFunction<A, B, C, D, E, F, R> implements
+abstract class OmniFunction<A, B, C, D, E, F, G, R> implements
PooledFunction<A, R>, BiFunction<A, B, R>, TriFunction<A, B, C, R>,
QuadFunction<A, B, C, D, R>, QuintFunction<A, B, C, D, E, R>,
- HexFunction<A, B, C, D, E, F, R>, PooledConsumer<A>, BiConsumer<A, B>,
- TriConsumer<A, B, C>, QuadConsumer<A, B, C, D>, QuintConsumer<A, B, C, D, E>,
- HexConsumer<A, B, C, D, E, F>, PooledPredicate<A>, BiPredicate<A, B>,
+ HexFunction<A, B, C, D, E, F, R>, HeptFunction<A, B, C, D, E, F, G, R>,
+ PooledConsumer<A>, BiConsumer<A, B>, TriConsumer<A, B, C>, QuadConsumer<A, B, C, D>,
+ QuintConsumer<A, B, C, D, E>, HexConsumer<A, B, C, D, E, F>,
+ HeptConsumer<A, B, C, D, E, F, G>,
+ PooledPredicate<A>, BiPredicate<A, B>,
PooledSupplier<R>, PooledRunnable, ThrowingRunnable, ThrowingSupplier<R>,
PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble {
- abstract R invoke(A a, B b, C c, D d, E e, F f);
+ abstract R invoke(A a, B b, C c, D d, E e, F f, G g);
@Override
public R apply(A o, B o2) {
- return invoke(o, o2, null, null, null, null);
+ return invoke(o, o2, null, null, null, null, null);
}
@Override
public R apply(A o) {
- return invoke(o, null, null, null, null, null);
+ return invoke(o, null, null, null, null, null, null);
}
- abstract public <V> OmniFunction<A, B, C, D, E, F, V> andThen(
+ public abstract <V> OmniFunction<A, B, C, D, E, F, G, V> andThen(
Function<? super R, ? extends V> after);
- abstract public OmniFunction<A, B, C, D, E, F, R> negate();
+ public abstract OmniFunction<A, B, C, D, E, F, G, R> negate();
@Override
public void accept(A o, B o2) {
- invoke(o, o2, null, null, null, null);
+ invoke(o, o2, null, null, null, null, null);
}
@Override
public void accept(A o) {
- invoke(o, null, null, null, null, null);
+ invoke(o, null, null, null, null, null, null);
}
@Override
public void run() {
- invoke(null, null, null, null, null, null);
+ invoke(null, null, null, null, null, null, null);
}
@Override
public R get() {
- return invoke(null, null, null, null, null, null);
+ return invoke(null, null, null, null, null, null, null);
}
@Override
public boolean test(A o, B o2) {
- return (Boolean) invoke(o, o2, null, null, null, null);
+ return (Boolean) invoke(o, o2, null, null, null, null, null);
}
@Override
public boolean test(A o) {
- return (Boolean) invoke(o, null, null, null, null, null);
+ return (Boolean) invoke(o, null, null, null, null, null, null);
}
@Override
@@ -104,42 +108,52 @@
@Override
public R apply(A a, B b, C c) {
- return invoke(a, b, c, null, null, null);
+ return invoke(a, b, c, null, null, null, null);
}
@Override
public void accept(A a, B b, C c) {
- invoke(a, b, c, null, null, null);
+ invoke(a, b, c, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d) {
- return invoke(a, b, c, d, null, null);
+ return invoke(a, b, c, d, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e) {
- return invoke(a, b, c, d, e, null);
+ return invoke(a, b, c, d, e, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f) {
- return invoke(a, b, c, d, e, f);
+ return invoke(a, b, c, d, e, f, null);
+ }
+
+ @Override
+ public R apply(A a, B b, C c, D d, E e, F f, G g) {
+ return invoke(a, b, c, d, e, f, g);
}
@Override
public void accept(A a, B b, C c, D d) {
- invoke(a, b, c, d, null, null);
+ invoke(a, b, c, d, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e) {
- invoke(a, b, c, d, e, null);
+ invoke(a, b, c, d, e, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f) {
- invoke(a, b, c, d, e, f);
+ invoke(a, b, c, d, e, f, null);
+ }
+
+ @Override
+ public void accept(A a, B b, C c, D d, E e, F f, G g) {
+ invoke(a, b, c, d, e, f, g);
}
@Override
@@ -153,5 +167,5 @@
}
@Override
- abstract public OmniFunction<A, B, C, D, E, F, R> recycleOnUse();
+ public abstract OmniFunction<A, B, C, D, E, F, G, R> recycleOnUse();
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
index 15698cc..af3c752 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
@@ -21,6 +21,8 @@
import android.os.Message;
+import com.android.internal.util.function.HeptConsumer;
+import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.QuadConsumer;
@@ -174,7 +176,7 @@
Consumer<? super A> function,
A arg1) {
return acquire(PooledLambdaImpl.sPool,
- function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null);
+ function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null);
}
/**
@@ -190,7 +192,7 @@
Predicate<? super A> function,
A arg1) {
return acquire(PooledLambdaImpl.sPool,
- function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null);
+ function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null);
}
/**
@@ -206,7 +208,7 @@
Function<? super A, ? extends R> function,
A arg1) {
return acquire(PooledLambdaImpl.sPool,
- function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null);
+ function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null);
}
/**
@@ -236,7 +238,7 @@
A arg1) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null);
+ function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -255,7 +257,7 @@
BiConsumer<? super A, ? super B> function,
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null);
+ function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null);
}
/**
@@ -272,7 +274,7 @@
BiPredicate<? super A, ? super B> function,
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
+ function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null);
}
/**
@@ -289,7 +291,7 @@
BiFunction<? super A, ? super B, ? extends R> function,
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
+ function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null);
}
/**
@@ -306,7 +308,7 @@
BiConsumer<? super A, ? super B> function,
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null);
}
/**
@@ -323,7 +325,7 @@
BiPredicate<? super A, ? super B> function,
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null);
}
/**
@@ -340,7 +342,7 @@
BiFunction<? super A, ? super B, ? extends R> function,
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null);
}
/**
@@ -357,7 +359,7 @@
BiConsumer<? super A, ? super B> function,
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null);
}
/**
@@ -374,7 +376,7 @@
BiPredicate<? super A, ? super B> function,
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null);
}
/**
@@ -391,7 +393,7 @@
BiFunction<? super A, ? super B, ? extends R> function,
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
- function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null);
+ function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null);
}
/**
@@ -422,7 +424,7 @@
A arg1, B arg2) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null);
+ function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -442,7 +444,7 @@
TriConsumer<? super A, ? super B, ? super C> function,
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
+ function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -460,7 +462,7 @@
TriFunction<? super A, ? super B, ? super C, ? extends R> function,
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
+ function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -478,7 +480,7 @@
TriConsumer<? super A, ? super B, ? super C> function,
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -496,7 +498,7 @@
TriFunction<? super A, ? super B, ? super C, ? extends R> function,
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -514,7 +516,7 @@
TriConsumer<? super A, ? super B, ? super C> function,
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -532,7 +534,7 @@
TriFunction<? super A, ? super B, ? super C, ? extends R> function,
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -550,7 +552,7 @@
TriConsumer<? super A, ? super B, ? super C> function,
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -568,7 +570,7 @@
TriFunction<? super A, ? super B, ? super C, ? extends R> function,
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
- function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null);
+ function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null);
}
/**
@@ -600,7 +602,7 @@
A arg1, B arg2, C arg3) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null);
+ function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -621,7 +623,7 @@
QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -640,7 +642,7 @@
QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -659,7 +661,7 @@
QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -678,7 +680,7 @@
QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -697,7 +699,7 @@
QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -716,7 +718,7 @@
QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -735,7 +737,7 @@
QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -754,7 +756,7 @@
QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -773,7 +775,7 @@
QuadConsumer<? super A, ? super B, ? super C, ? super D> function,
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -792,7 +794,7 @@
QuadFunction<? super A, ? super B, ? super C, ? super D, ? extends R> function,
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
- function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null);
}
/**
@@ -825,7 +827,7 @@
A arg1, B arg2, C arg3, D arg4) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null);
+ function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -847,7 +849,7 @@
QuintConsumer<? super A, ? super B, ? super C, ? super D, ? super E> function,
A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
- function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null);
+ function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null);
}
/**
@@ -867,7 +869,7 @@
QuintFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? extends R>
function, A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
- function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null);
+ function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null);
}
/**
@@ -902,7 +904,7 @@
A arg1, B arg2, C arg3, D arg4, E arg5) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null);
+ function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -925,7 +927,7 @@
HexConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F> function,
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
- function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6);
+ function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null);
}
/**
@@ -946,7 +948,7 @@
HexFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
- function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6);
+ function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null);
}
/**
@@ -982,7 +984,91 @@
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
- function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6);
+ function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null);
+ return Message.obtain().setCallback(callback.recycleOnUse());
+ }
+ }
+
+ /**
+ * {@link PooledRunnable} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @return a {@link PooledRunnable}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7) }
+ */
+ static <A, B, C, D, E, F, G> PooledRunnable obtainRunnable(
+ HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ }
+
+ /**
+ * {@link PooledSupplier} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @return a {@link PooledSupplier}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7) }
+ */
+ static <A, B, C, D, E, F, G, R> PooledSupplier<R> obtainSupplier(
+ HeptFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? extends R> function,
+ A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ }
+
+ /**
+ * Factory of {@link Message}s that contain an
+ * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+ * {@link Message#getCallback internal callback}.
+ *
+ * The callback is equivalent to one obtainable via
+ * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+ *
+ * Note that using this method with {@link android.os.Handler#handleMessage}
+ * is more efficient than the alternative of {@link android.os.Handler#post}
+ * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+ * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+ *
+ * You may optionally set a {@link Message#what} for the message if you want to be
+ * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+ * there's no need to do so
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+ * arg7) } when handled
+ */
+ static <A, B, C, D, E, F, G> Message obtainMessage(
+ HeptConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
+ synchronized (Message.sPoolSync) {
+ PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+ function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index 565ae11..eea1e5f 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -24,6 +24,9 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.BitUtils;
+import com.android.internal.util.function.HeptConsumer;
+import com.android.internal.util.function.HeptFunction;
+import com.android.internal.util.function.HeptPredicate;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.HexPredicate;
@@ -51,12 +54,12 @@
* @hide
*/
final class PooledLambdaImpl<R> extends OmniFunction<Object,
- Object, Object, Object, Object, Object, R> {
+ Object, Object, Object, Object, Object, Object, R> {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "PooledLambdaImpl";
- private static final int MAX_ARGS = 5;
+ private static final int MAX_ARGS = 7;
private static final int MAX_POOL_SIZE = 50;
@@ -122,7 +125,7 @@
/**
* Bit schema:
- * AAAABCDEEEEEEFFFFFF
+ * AAAAAAABCDEEEEEEFFFFFF
*
* Where:
* A - whether {@link #mArgs arg} at corresponding index was specified at
@@ -158,17 +161,17 @@
}
@Override
- R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) {
+ R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) {
checkNotRecycled();
if (DEBUG) {
Log.i(LOG_TAG, this + ".invoke("
+ commaSeparateFirstN(
- new Object[] { a1, a2, a3, a4, a5, a6 },
+ new Object[] { a1, a2, a3, a4, a5, a6, a7 },
LambdaType.decodeArgCount(getFlags(MASK_EXPOSED_AS)))
+ ")");
}
final boolean notUsed = fillInArg(a1) && fillInArg(a2) && fillInArg(a3)
- && fillInArg(a4) && fillInArg(a5) && fillInArg(a6);
+ && fillInArg(a4) && fillInArg(a5) && fillInArg(a6) && fillInArg(a7);
int argCount = LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE));
if (argCount != LambdaType.MASK_ARG_COUNT) {
for (int i = 0; i < argCount; i++) {
@@ -333,6 +336,27 @@
}
}
}
+
+ case 7: {
+ switch (returnType) {
+ case LambdaType.ReturnType.VOID: {
+ ((HeptConsumer) mFunc).accept(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6));
+ return null;
+ }
+ case LambdaType.ReturnType.BOOLEAN: {
+ return (R) (Object) ((HeptPredicate) mFunc).test(popArg(0),
+ popArg(1), popArg(2), popArg(3),
+ popArg(4), popArg(5), popArg(6));
+ }
+ case LambdaType.ReturnType.OBJECT: {
+ return (R) ((HeptFunction) mFunc).apply(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6));
+ }
+ }
+ }
}
throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType));
}
@@ -396,7 +420,7 @@
*/
static <E extends PooledLambda> E acquire(Pool pool, Object func,
int fNumArgs, int numPlaceholders, int fReturnType,
- Object a, Object b, Object c, Object d, Object e, Object f) {
+ Object a, Object b, Object c, Object d, Object e, Object f, Object g) {
PooledLambdaImpl r = acquire(pool);
if (DEBUG) {
Log.i(LOG_TAG,
@@ -411,6 +435,7 @@
+ ", d = " + d
+ ", e = " + e
+ ", f = " + f
+ + ", g = " + g
+ ")");
}
r.mFunc = func;
@@ -423,6 +448,7 @@
setIfInBounds(r.mArgs, 3, d);
setIfInBounds(r.mArgs, 4, e);
setIfInBounds(r.mArgs, 5, f);
+ setIfInBounds(r.mArgs, 6, g);
return (E) r;
}
@@ -448,12 +474,12 @@
}
@Override
- public OmniFunction<Object, Object, Object, Object, Object, Object, R> negate() {
+ public OmniFunction<Object, Object, Object, Object, Object, Object, Object, R> negate() {
throw new UnsupportedOperationException();
}
@Override
- public <V> OmniFunction<Object, Object, Object, Object, Object, Object, V> andThen(
+ public <V> OmniFunction<Object, Object, Object, Object, Object, Object, Object, V> andThen(
Function<? super R, ? extends V> after) {
throw new UnsupportedOperationException();
}
@@ -474,7 +500,7 @@
}
@Override
- public OmniFunction<Object, Object, Object, Object, Object, Object, R> recycleOnUse() {
+ public OmniFunction<Object, Object, Object, Object, Object, Object, Object, R> recycleOnUse() {
if (DEBUG) Log.i(LOG_TAG, this + ".recycleOnUse()");
mFlags |= FLAG_RECYCLE_ON_USE;
return this;
@@ -519,10 +545,10 @@
* Contract for encoding a supported lambda type in {@link #MASK_BIT_COUNT} bits
*/
static class LambdaType {
- public static final int MASK_ARG_COUNT = 0b111;
- public static final int MASK_RETURN_TYPE = 0b111000;
+ public static final int MASK_ARG_COUNT = 0b1111;
+ public static final int MASK_RETURN_TYPE = 0b1110000;
public static final int MASK = MASK_ARG_COUNT | MASK_RETURN_TYPE;
- public static final int MASK_BIT_COUNT = 6;
+ public static final int MASK_BIT_COUNT = 7;
static int encode(int argCount, int returnType) {
return mask(MASK_ARG_COUNT, argCount) | mask(MASK_RETURN_TYPE, returnType);
@@ -557,6 +583,7 @@
case 4: return "Quad";
case 5: return "Quint";
case 6: return "Hex";
+ case 7: return "Hept";
default: throw new IllegalArgumentException("" + argCount);
}
}
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index ec8e8da..901cfe3 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -54,6 +54,7 @@
ResultCode.ERROR_NO_EDITOR,
ResultCode.ERROR_DISPLAY_ID_MISMATCH,
ResultCode.ERROR_INVALID_DISPLAY_ID,
+ ResultCode.ERROR_INVALID_CLIENT,
})
public @interface ResultCode {
/**
@@ -158,6 +159,10 @@
* display.
*/
int ERROR_INVALID_DISPLAY_ID = 14;
+ /**
+ * Indicates that the client is not recognized by the system.
+ */
+ int ERROR_INVALID_CLIENT = 15;
}
@ResultCode
@@ -287,6 +292,8 @@
return "ERROR_DISPLAY_ID_MISMATCH";
case ResultCode.ERROR_INVALID_DISPLAY_ID:
return "ERROR_INVALID_DISPLAY_ID";
+ case ResultCode.ERROR_INVALID_CLIENT:
+ return "ERROR_INVALID_CLIENT";
default:
return "Unknown(" + result + ")";
}
@@ -343,4 +350,9 @@
*/
public static final InputBindResult INVALID_DISPLAY_ID =
error(ResultCode.ERROR_INVALID_DISPLAY_ID);
+
+ /**
+ * Predefined error object for {@link ResultCode#ERROR_INVALID_CLIENT}.
+ */
+ public static final InputBindResult INVALID_CLIENT = error(ResultCode.ERROR_INVALID_CLIENT);
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index c96aaba..bdd5f83 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -240,7 +240,7 @@
],
shared_libs: [
- "libbpf",
+ "libbpf_android",
"libnetdbpf",
"libnetdutils",
"libmemtrack",
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index b417a56..98bc735 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -788,61 +788,18 @@
return status;
}
-static jobject
+static jint
android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz,
jint jHandle)
{
+ jint status = SOUNDTRIGGER_STATUS_OK;
ALOGV("getModelState");
sp<SoundTrigger> module = getSoundTrigger(env, thiz);
if (module == NULL) {
- return NULL;
+ return SOUNDTRIGGER_STATUS_ERROR;
}
- sp<IMemory> memory;
- jint status = module->getModelState(jHandle, memory);
- if (status != 0 || memory == NULL) {
- ALOGW("getModelState, failed to get model state, status: %d", status);
- return NULL;
- }
- struct sound_trigger_recognition_event* event =
- (struct sound_trigger_recognition_event *)memory->pointer();
- if (event == NULL) {
- return NULL;
- }
- if (event->type != SOUND_MODEL_TYPE_GENERIC) {
- ALOGW("getModelState, unsupported model type: %d", event->type);
- return NULL;
- }
-
- jbyteArray jData = NULL;
- if (event->data_size) {
- jData = env->NewByteArray(event->data_size);
- jbyte *nData = env->GetByteArrayElements(jData, NULL);
- memcpy(nData, (char *)event + event->data_offset, event->data_size);
- env->ReleaseByteArrayElements(jData, nData, 0);
- }
-
- jobject jAudioFormat = NULL;
- if (event->trigger_in_data || event->capture_available) {
- jAudioFormat = env->NewObject(gAudioFormatClass,
- gAudioFormatCstor,
- audioFormatFromNative(event->audio_config.format),
- event->audio_config.sample_rate,
- inChannelMaskFromNative(event->audio_config.channel_mask));
-
- }
- jobject jEvent = NULL;
- jEvent = env->NewObject(gGenericRecognitionEventClass, gGenericRecognitionEventCstor,
- event->status, event->model, event->capture_available,
- event->capture_session, event->capture_delay_ms,
- event->capture_preamble_ms, event->trigger_in_data,
- jAudioFormat, jData);
- if (jAudioFormat != NULL) {
- env->DeleteLocalRef(jAudioFormat);
- }
- if (jData != NULL) {
- env->DeleteLocalRef(jData);
- }
- return jEvent;
+ status = module->getModelState(jHandle);
+ return status;
}
static const JNINativeMethod gMethods[] = {
@@ -875,7 +832,7 @@
"(I)I",
(void *)android_hardware_SoundTrigger_stopRecognition},
{"getModelState",
- "(I)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;",
+ "(I)I",
(void *)android_hardware_SoundTrigger_getModelState},
};
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index c977437..29051f1 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -892,6 +892,13 @@
cfaOut[3] = 0;
break;
}
+ // MONO and NIR are degenerate case of RGGB pattern: only Red channel
+ // will be used.
+ case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO:
+ case ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR: {
+ cfaOut[0] = 0;
+ break;
+ }
default: {
return BAD_VALUE;
}
@@ -1063,6 +1070,8 @@
uint32_t preWidth = 0;
uint32_t preHeight = 0;
+ uint8_t colorFilter = 0;
+ bool isBayer = true;
{
// Check dimensions
camera_metadata_entry entry =
@@ -1083,10 +1092,25 @@
"either the preCorrectionActiveArraySize or the pixelArraySize.");
return nullptr;
}
+
+ camera_metadata_entry colorFilterEntry =
+ characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
+ colorFilter = colorFilterEntry.data.u8[0];
+ camera_metadata_entry capabilitiesEntry =
+ characteristics.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
+ size_t capsCount = capabilitiesEntry.count;
+ uint8_t* caps = capabilitiesEntry.data.u8;
+ if (std::find(caps, caps+capsCount, ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME)
+ != caps+capsCount) {
+ isBayer = false;
+ } else if (colorFilter == ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_MONO ||
+ colorFilter == ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_NIR) {
+ jniThrowException(env, "java/lang/AssertionError",
+ "A camera device with MONO/NIR color filter must have MONOCHROME capability.");
+ return nullptr;
+ }
}
-
-
writer->addIfd(TIFF_IFD_0);
status_t err = OK;
@@ -1094,9 +1118,12 @@
const uint32_t samplesPerPixel = 1;
const uint32_t bitsPerSample = BITS_PER_SAMPLE;
- OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_RGGB;
+ OpcodeListBuilder::CfaLayout opcodeCfaLayout = OpcodeListBuilder::CFA_NONE;
uint8_t cfaPlaneColor[3] = {0, 1, 2};
- uint8_t cfaEnum = -1;
+ camera_metadata_entry cfaEntry =
+ characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
+ BAIL_IF_EMPTY_RET_NULL_SP(cfaEntry, env, TAG_CFAPATTERN, writer);
+ uint8_t cfaEnum = cfaEntry.data.u8[0];
// TODO: Greensplit.
// TODO: Add remaining non-essential tags
@@ -1141,12 +1168,20 @@
{
// Set photometric interpretation
- uint16_t interpretation = 32803; // CFA
+ uint16_t interpretation = isBayer ? 32803 /* CFA */ :
+ 34892; /* Linear Raw */;
BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_PHOTOMETRICINTERPRETATION, 1,
&interpretation, TIFF_IFD_0), env, TAG_PHOTOMETRICINTERPRETATION, writer);
}
{
+ uint16_t repeatDim[2] = {2, 2};
+ if (!isBayer) {
+ repeatDim[0] = repeatDim[1] = 1;
+ }
+ BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim,
+ TIFF_IFD_0), env, TAG_BLACKLEVELREPEATDIM, writer);
+
// Set blacklevel tags, using dynamic black level if available
camera_metadata_entry entry =
results.find(ANDROID_SENSOR_DYNAMIC_BLACK_LEVEL);
@@ -1165,14 +1200,9 @@
blackLevelRational[i * 2] = static_cast<uint32_t>(entry.data.i32[i]);
blackLevelRational[i * 2 + 1] = 1;
}
-
}
- BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, 4, blackLevelRational,
- TIFF_IFD_0), env, TAG_BLACKLEVEL, writer);
-
- uint16_t repeatDim[2] = {2, 2};
- BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVELREPEATDIM, 2, repeatDim,
- TIFF_IFD_0), env, TAG_BLACKLEVELREPEATDIM, writer);
+ BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_BLACKLEVEL, repeatDim[0]*repeatDim[1],
+ blackLevelRational, TIFF_IFD_0), env, TAG_BLACKLEVEL, writer);
}
{
@@ -1189,21 +1219,15 @@
TIFF_IFD_0), env, TAG_PLANARCONFIGURATION, writer);
}
- {
+ // All CFA pattern tags are not necessary for monochrome cameras.
+ if (isBayer) {
// Set CFA pattern dimensions
uint16_t repeatDim[2] = {2, 2};
BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAREPEATPATTERNDIM, 2, repeatDim,
TIFF_IFD_0), env, TAG_CFAREPEATPATTERNDIM, writer);
- }
- {
// Set CFA pattern
- camera_metadata_entry entry =
- characteristics.find(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
- BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_CFAPATTERN, writer);
-
const int cfaLength = 4;
- cfaEnum = entry.data.u8[0];
uint8_t cfa[cfaLength];
if ((err = convertCFA(cfaEnum, /*out*/cfa)) != OK) {
jniThrowExceptionFmt(env, "java/lang/IllegalStateException",
@@ -1214,15 +1238,11 @@
env, TAG_CFAPATTERN, writer);
opcodeCfaLayout = convertCFAEnumToOpcodeLayout(cfaEnum);
- }
- {
// Set CFA plane color
BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFAPLANECOLOR, 3, cfaPlaneColor,
TIFF_IFD_0), env, TAG_CFAPLANECOLOR, writer);
- }
- {
// Set CFA layout
uint16_t cfaLayout = 1;
BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_CFALAYOUT, 1, &cfaLayout, TIFF_IFD_0),
@@ -1442,7 +1462,7 @@
}
bool singleIlluminant = false;
- {
+ if (isBayer) {
// Set calibration illuminants
camera_metadata_entry entry1 =
characteristics.find(ANDROID_SENSOR_REFERENCE_ILLUMINANT1);
@@ -1464,7 +1484,7 @@
}
}
- {
+ if (isBayer) {
// Set color transforms
camera_metadata_entry entry1 =
characteristics.find(ANDROID_SENSOR_COLOR_TRANSFORM1);
@@ -1497,7 +1517,7 @@
}
}
- {
+ if (isBayer) {
// Set calibration transforms
camera_metadata_entry entry1 =
characteristics.find(ANDROID_SENSOR_CALIBRATION_TRANSFORM1);
@@ -1531,7 +1551,7 @@
}
}
- {
+ if (isBayer) {
// Set forward transforms
camera_metadata_entry entry1 =
characteristics.find(ANDROID_SENSOR_FORWARD_MATRIX1);
@@ -1565,7 +1585,7 @@
}
}
- {
+ if (isBayer) {
// Set camera neutral
camera_metadata_entry entry =
results.find(ANDROID_SENSOR_NEUTRAL_COLOR_POINT);
@@ -1632,8 +1652,8 @@
camera_metadata_entry entry =
results.find(ANDROID_SENSOR_NOISE_PROFILE);
- const status_t numPlaneColors = 3;
- const status_t numCfaChannels = 4;
+ const status_t numPlaneColors = isBayer ? 3 : 1;
+ const status_t numCfaChannels = isBayer ? 4 : 1;
uint8_t cfaOut[numCfaChannels];
if ((err = convertCFA(cfaEnum, /*out*/cfaOut)) != OK) {
@@ -1710,42 +1730,44 @@
}
}
+ // Hot pixel map is specific to bayer camera per DNG spec.
+ if (isBayer) {
+ // Set up bad pixel correction list
+ camera_metadata_entry entry3 = characteristics.find(ANDROID_STATISTICS_HOT_PIXEL_MAP);
- // Set up bad pixel correction list
- camera_metadata_entry entry3 = characteristics.find(ANDROID_STATISTICS_HOT_PIXEL_MAP);
-
- if ((entry3.count % 2) != 0) {
- ALOGE("%s: Hot pixel map contains odd number of values, cannot map to pairs!",
- __FUNCTION__);
- jniThrowRuntimeException(env, "failed to add hotpixel map.");
- return nullptr;
- }
-
- // Adjust the bad pixel coordinates to be relative to the origin of the active area DNG tag
- std::vector<uint32_t> v;
- for (size_t i = 0; i < entry3.count; i += 2) {
- int32_t x = entry3.data.i32[i];
- int32_t y = entry3.data.i32[i + 1];
- x -= static_cast<int32_t>(xmin);
- y -= static_cast<int32_t>(ymin);
- if (x < 0 || y < 0 || static_cast<uint32_t>(x) >= width ||
- static_cast<uint32_t>(y) >= height) {
- continue;
- }
- v.push_back(x);
- v.push_back(y);
- }
- const uint32_t* badPixels = &v[0];
- uint32_t badPixelCount = v.size();
-
- if (badPixelCount > 0) {
- err = builder.addBadPixelListForMetadata(badPixels, badPixelCount, opcodeCfaLayout);
-
- if (err != OK) {
- ALOGE("%s: Could not add hotpixel map.", __FUNCTION__);
+ if ((entry3.count % 2) != 0) {
+ ALOGE("%s: Hot pixel map contains odd number of values, cannot map to pairs!",
+ __FUNCTION__);
jniThrowRuntimeException(env, "failed to add hotpixel map.");
return nullptr;
}
+
+ // Adjust the bad pixel coordinates to be relative to the origin of the active area DNG tag
+ std::vector<uint32_t> v;
+ for (size_t i = 0; i < entry3.count; i += 2) {
+ int32_t x = entry3.data.i32[i];
+ int32_t y = entry3.data.i32[i + 1];
+ x -= static_cast<int32_t>(xmin);
+ y -= static_cast<int32_t>(ymin);
+ if (x < 0 || y < 0 || static_cast<uint32_t>(x) >= width ||
+ static_cast<uint32_t>(y) >= height) {
+ continue;
+ }
+ v.push_back(x);
+ v.push_back(y);
+ }
+ const uint32_t* badPixels = &v[0];
+ uint32_t badPixelCount = v.size();
+
+ if (badPixelCount > 0) {
+ err = builder.addBadPixelListForMetadata(badPixels, badPixelCount, opcodeCfaLayout);
+
+ if (err != OK) {
+ ALOGE("%s: Could not add hotpixel map.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to add hotpixel map.");
+ return nullptr;
+ }
+ }
}
if (builder.getCount() > 0) {
@@ -1960,10 +1982,12 @@
tagsToMove.add(TAG_BLACKLEVELREPEATDIM);
tagsToMove.add(TAG_SAMPLESPERPIXEL);
tagsToMove.add(TAG_PLANARCONFIGURATION);
- tagsToMove.add(TAG_CFAREPEATPATTERNDIM);
- tagsToMove.add(TAG_CFAPATTERN);
- tagsToMove.add(TAG_CFAPLANECOLOR);
- tagsToMove.add(TAG_CFALAYOUT);
+ if (isBayer) {
+ tagsToMove.add(TAG_CFAREPEATPATTERNDIM);
+ tagsToMove.add(TAG_CFAPATTERN);
+ tagsToMove.add(TAG_CFAPLANECOLOR);
+ tagsToMove.add(TAG_CFALAYOUT);
+ }
tagsToMove.add(TAG_XRESOLUTION);
tagsToMove.add(TAG_YRESOLUTION);
tagsToMove.add(TAG_RESOLUTIONUNIT);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index f512ce4..b8139a7 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -556,18 +556,18 @@
proxy->setWideGamut(true);
}
proxy->setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
- proxy->initialize(surface);
+ proxy->setSurface(surface);
// Shadows can't be used via this interface, so just set the light source
// to all 0s.
- proxy->setup(0, 0, 0);
- proxy->setLightCenter((Vector3){0, 0, 0});
+ proxy->setLightAlpha(0, 0);
+ proxy->setLightGeometry((Vector3){0, 0, 0}, 0);
return (jlong) proxy;
}
static void setSurface(JNIEnv* env, jclass clazz, jlong rendererPtr, jlong surfacePtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr);
sp<Surface> surface(reinterpret_cast<Surface*>(surfacePtr));
- proxy->updateSurface(surface);
+ proxy->setSurface(surface);
}
static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) {
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 7a5b604..702741e 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -686,31 +686,20 @@
env->ReleaseStringUTFChars(jname, name);
}
-static void android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jobject jsurface) {
- RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
- proxy->initialize(surface);
-}
-
-static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
+static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz,
jlong proxyPtr, jobject jsurface) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
sp<Surface> surface;
if (jsurface) {
surface = android_view_Surface_getSurface(env, jsurface);
}
- proxy->updateSurface(surface);
+ proxy->setSurface(surface);
}
-static jboolean android_view_ThreadedRenderer_pauseSurface(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jobject jsurface) {
+static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
+ jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- sp<Surface> surface;
- if (jsurface) {
- surface = android_view_Surface_getSurface(env, jsurface);
- }
- return proxy->pauseSurface(surface);
+ return proxy->pause();
}
static void android_view_ThreadedRenderer_setStopped(JNIEnv* env, jobject clazz,
@@ -719,16 +708,16 @@
proxy->setStopped(stopped);
}
-static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz, jlong proxyPtr,
- jfloat lightRadius, jint ambientShadowAlpha, jint spotShadowAlpha) {
+static void android_view_ThreadedRenderer_setLightAlpha(JNIEnv* env, jobject clazz, jlong proxyPtr,
+ jfloat ambientShadowAlpha, jfloat spotShadowAlpha) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->setup(lightRadius, ambientShadowAlpha, spotShadowAlpha);
+ proxy->setLightAlpha((uint8_t) (255 * ambientShadowAlpha), (uint8_t) (255 * spotShadowAlpha));
}
-static void android_view_ThreadedRenderer_setLightCenter(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ) {
+static void android_view_ThreadedRenderer_setLightGeometry(JNIEnv* env, jobject clazz,
+ jlong proxyPtr, jfloat lightX, jfloat lightY, jfloat lightZ, jfloat lightRadius) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->setLightCenter((Vector3){lightX, lightY, lightZ});
+ proxy->setLightGeometry((Vector3){lightX, lightY, lightZ}, lightRadius);
}
static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
@@ -990,13 +979,12 @@
{
ContextFactory factory;
RenderProxy proxy{true, renderNode, &factory};
- proxy.loadSystemProperties();
proxy.setSwapBehavior(SwapBehavior::kSwap_discardBuffer);
- proxy.initialize(surface);
+ proxy.setSurface(surface);
// Shadows can't be used via this interface, so just set the light source
// to all 0s.
- proxy.setup(0, 0, 0);
- proxy.setLightCenter((Vector3){0, 0, 0});
+ proxy.setLightAlpha(0, 0);
+ proxy.setLightGeometry((Vector3){0, 0, 0}, 0);
nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
UiFrameInfoBuilder(proxy.frameInfo())
.setVsync(vsync, vsync)
@@ -1058,10 +1046,9 @@
}
static void android_view_ThreadedRenderer_allocateBuffers(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jobject jsurface) {
+ jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- sp<Surface> surface = android_view_Surface_getSurface(env, jsurface);
- proxy->allocateBuffers(surface);
+ proxy->allocateBuffers();
}
static void android_view_ThreadedRenderer_setForceDark(JNIEnv* env, jobject clazz,
@@ -1118,7 +1105,7 @@
// JNI Glue
// ----------------------------------------------------------------------------
-const char* const kClassPathName = "android/view/ThreadedRenderer";
+const char* const kClassPathName = "android/graphics/HardwareRenderer";
static const JNINativeMethod gMethods[] = {
{ "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
@@ -1129,12 +1116,11 @@
{ "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
{ "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
{ "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName },
- { "nInitialize", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_initialize },
- { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
- { "nPauseSurface", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_pauseSurface },
+ { "nSetSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_setSurface },
+ { "nPause", "(J)Z", (void*) android_view_ThreadedRenderer_pause },
{ "nSetStopped", "(JZ)V", (void*) android_view_ThreadedRenderer_setStopped },
- { "nSetup", "(JFII)V", (void*) android_view_ThreadedRenderer_setup },
- { "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
+ { "nSetLightAlpha", "(JFF)V", (void*) android_view_ThreadedRenderer_setLightAlpha },
+ { "nSetLightGeometry", "(JFFFF)V", (void*) android_view_ThreadedRenderer_setLightGeometry },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
{ "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
{ "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
@@ -1161,9 +1147,9 @@
{ "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
{ "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
{ "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
- { "nSetFrameCallback", "(JLandroid/view/ThreadedRenderer$FrameDrawingCallback;)V",
+ { "nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCallback},
- { "nSetFrameCompleteCallback", "(JLandroid/view/ThreadedRenderer$FrameCompleteCallback;)V",
+ { "nSetFrameCompleteCallback", "(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCompleteCallback },
{ "nAddFrameMetricsObserver",
"(JLandroid/view/FrameMetricsObserver;)J",
@@ -1182,7 +1168,7 @@
{ "nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled },
{ "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess },
{ "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority },
- { "nAllocateBuffers", "(JLandroid/view/Surface;)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
+ { "nAllocateBuffers", "(J)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
{ "nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark },
};
@@ -1215,12 +1201,12 @@
env, metricsClass, "mTimingData", "[J");
jclass frameCallbackClass = FindClassOrDie(env,
- "android/view/ThreadedRenderer$FrameDrawingCallback");
+ "android/graphics/HardwareRenderer$FrameDrawingCallback");
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,
"onFrameDraw", "(J)V");
jclass frameCompleteClass = FindClassOrDie(env,
- "android/view/ThreadedRenderer$FrameCompleteCallback");
+ "android/graphics/HardwareRenderer$FrameCompleteCallback");
gFrameCompleteCallback.onFrameComplete = GetMethodIDOrDie(env, frameCompleteClass,
"onFrameComplete", "(J)V");
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index b3ff4db..b708735 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -175,7 +175,7 @@
}
}
s.tag = rawTag >> 32;
- if (limitTag != -1 && s.tag != limitTag) {
+ if (limitTag != -1 && s.tag != static_cast<uint32_t>(limitTag)) {
//ALOGI("skipping due to tag: %s", buffer);
continue;
}
@@ -188,7 +188,7 @@
if (sscanf(pos, "%u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
&s.uid, &s.set, &s.rxBytes, &s.rxPackets,
&s.txBytes, &s.txPackets) == 6) {
- if (limitUid != -1 && limitUid != s.uid) {
+ if (limitUid != -1 && static_cast<uint32_t>(limitUid) != s.uid) {
//ALOGI("skipping due to uid: %s", buffer);
continue;
}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 69ebb59..72892fa 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -270,6 +270,7 @@
optional SettingProto enable_freeform_windows_support = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto force_rtl = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto emulate_display_cutout = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto force_desktop_mode_on_external_displays = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Development development = 39;
@@ -404,6 +405,9 @@
// Ordered GPU debug layer list for GLES
// i.e. <layer1>:<layer2>:...:<layerN>
optional SettingProto debug_layers_gles = 5;
+ // App opt in to load updated graphics driver instead of
+ // native graphcis driver through developer options.
+ optional SettingProto updated_gfx_driver_dev_opt_in_app = 6;
}
optional Gpu gpu = 59;
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index f8acc33..6e661e1 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -72,11 +72,6 @@
// List of the accessibility services to which the user has granted
// permission to put the device into touch exploration mode.
optional SettingProto touch_exploration_granted_accessibility_services = 31;
- reserved 32; // minimum_ui_timeout_enabled
- reserved 33; // minimum_ui_timeout_ms
- optional SettingProto non_interactive_ui_timeout_ms = 34 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto interactive_ui_timeout_ms = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
-
}
optional Accessibility accessibility = 2;
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 54f0934..e83a2bf 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -609,6 +609,17 @@
repeated Constraint unsatisfied_constraints = 9;
optional bool is_doze_whitelisted = 10;
+ message ImplicitConstraints {
+ // The device isn't Dozing or this job will be in the foreground. This
+ // implicit constraint must be satisfied for the job to run.
+ optional bool is_not_dozing = 1;
+ // The job is not restricted from running in the background (due to
+ // Battery Saver). This implicit constraint must be satisfied for the
+ // job to run.
+ optional bool is_not_restricted_in_bg = 2;
+ }
+ optional ImplicitConstraints implicit_constraints = 25;
+
enum TrackingController {
TRACKING_BATTERY = 0;
TRACKING_CONNECTIVITY = 1;
@@ -662,4 +673,6 @@
optional int64 last_failed_run_time = 23;
optional int64 internal_flags = 24;
+
+ // Next tag: 26
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 093a860..2976879 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2211,6 +2211,12 @@
android:protectionLevel="signature" />
<uses-permission android:name="android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS" />
+ <!-- Allows an application to start an activity as another app, provided that app has been
+ granted a permissionToken from the ActivityManagerService.
+ @hide -->
+ <permission android:name="android.permission.START_ACTIVITY_AS_CALLER"
+ android:protectionLevel="signature" />
+
<!-- @deprecated The {@link android.app.ActivityManager#restartPackage}
API is no longer supported. -->
<permission android:name="android.permission.RESTART_PACKAGES"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9ba991b..8afbf66 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>-Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-oproepe | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>-VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Af"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Verkies Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Verkies mobiel"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Gee die program toegang tot ekstra liggingverskaffer-bevele. Dit kan die program dalk toelaat om in te meng met die werking van die GPS of ander liggingbronne."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"kry net op die voorgrond toegang tot presiese ligging"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Hierdie program kan jou presiese ligging kry net wanneer dit op die voorgrond is. Hierdie liggingdienste moet aangeskakel wees en op jou foon beskikbaar wees sodat die program hulle kan gebruik. Dit kan veroorsaak dat meer batterykrag gebruik word."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"verkry toegang tot benaderde ligging (netwerkgegrond)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Hierdie program kan jou ligging kry op grond van jou netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke. Hierdie liggingdienste moet aangeskakel en op jou tablet beskikbaar wees sodat die program hulle kan gebruik."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Hierdie program kan jou ligging kry op grond van jou netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke. Hierdie liggingdienste moet aangeskakel en op jou TV beskikbaar wees sodat die program hulle kan gebruik."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Hierdie program kan jou ligging kry op grond van jou netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke. Hierdie liggingdienste moet aangeskakel en op jou foon beskikbaar wees sodat die program hulle kan gebruik."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"kry benaderde ligging (netwerkgegrond) net op die voorgrond"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou tablet beskikbaar is."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou TV beskikbaar is."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Hierdie program kan jou ligging kry op grond van netwerkhulpbronne soos selfoontorings en Wi-Fi-netwerke, maar net wanneer die program op die voorgrond is. Die program kan hierdie liggingdienste net gebruik as hulle aangeskakel is en op jou foon beskikbaar is."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"kry ligging op die agtergrond"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"As dit bo en behalwe toegang tot die benaderde of presiese ligging verleen word, kan die program die ligging kry terwyl dit op die agtergrond werk."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"verander jou klankinstellings"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-versoek is na USSD-versoek toe verander"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Na nuwe SS-versoek toe verander"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Werkprofiel"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Vou uit"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Vou in"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"wissel uitvou-aksie"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5b2286b..b9be6af 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"የWiFi ጥሪ አደራረግ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ጠፍቷል"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ተመርጧል"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"የተንቀሳቃሽ ስልክ ተመራጭ ነው"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"መተግበሪያው ተጨማሪ የአካባቢ አቅራቢ ትእዛዞችን እንዲደርስ ይፈቅድለታል። ይሄ መተግበሪያው በጂፒኤስ ወይም ሌላ የአካባቢ ምንጮች ስራ ላይ ጣልቃ እንዲገባ ሊፈቅድለት ይችላል።"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"መዳረሻ ከፊት ለፊት ብቻ ትክክለኛ ነው"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ይህ መተግበሪያ ከፊት ላይ ሆኖ ሲበራ ብቻ ትክክለኛውን መገኛ አካባቢ ማግኘት ይችላል። እነዚህ የመገኛ አካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ስልክ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ግምታዊ አካባቢን መድረስ (በአውታረ መረብ ላይ የተመሰረተ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ከመሳሰሉ የአውታረ መረብ ምንጮች ላይ በመመርኮዝ የእርስዎን መገኛ አካባቢ ማግኘት ይችላል። እነዚህ የመገኛ አካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ጡባዊ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ከመሳሰሉ የአውታረ መረብ ምንጮች ላይ በመመርኮዝ የእርስዎን መገኛ አካባቢ ማግኘት ይችላል። እነዚህ የመገኛ አካባቢ አገልግሎቶች እርስዎ መጠቀም እንዲችሉ ሊበሩ እና በእርስዎ ቴሌቪዥን ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ከመሳሰሉ የአውታረ መረብ ምንጮች ላይ በመመርኮዝ የእርስዎን መገኛ አካባቢ ማግኘት ይችላል። እነዚህ የመገኛ አካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ስልክ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ግምታዊ አካባቢ (በአውታረ መረብ ላይ የተመሠረተ) ከፊት ላይ ሲሆን ብቻ መድረስ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ጡባዊ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ቴሌቪዥን ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ይህ መተግበሪያ እንደ የሕዋስ ማማዎች እና የWi-Fi አውታረ መረቦች ባሉ የአውታረ መረብ ምንጮች ላይ በመመስረት የእርስዎን አካባቢ ማግኘት ይችላል፣ ነገር ግን መተግበሪያው ከፊት ሲሆን ብቻ። እነዚህ የአካባቢ አገልግሎቶች መተግበሪያው መጠቀም እንዲችል ሊበሩ እና በእርስዎ ስልክ ላይ ሊገኙ የሚችሉ መሆን አለባቸው።"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"አካባቢን በበስተጀርባ ድረስ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ይህ ከግምታዊ ወይም ትክክለኛ አካባቢ በተጨማሪ ከተሰጠ መተግበሪያው በበስተጀርባ እያሄደ ሳለ አካባቢውን መድረስ ይችላል።"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"የድምፅ ቅንብሮችን ለውጥ"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"የSS ጥያቄ ወደ የUSSD ጥያቄ ተለውጧል"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"ወደ አዲስ የSS ጥያቄ ተለውጧል"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"የስራ መገለጫ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ዘርጋ"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ሰብስብ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ዝርጋታን ቀያይር"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 9a48e14..ecc24ca 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -140,6 +140,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"شبكة Wi-Fi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"الاتصال عبر شبكة WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"شبكة VoWifi التابعة لـ <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"إيقاف"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"شبكة Wi-Fi مفضّلة"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"شبكة بيانات الجوال مفضَّلة"</string>
@@ -429,10 +437,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"للسماح للتطبيق بالدخول إلى أوامر إضافية لموفر الموقع. قد يتيح هذا للتطبيق التداخل مع تشغيل تقنية نظام تحديد المواقع العالمي (GPS) أو مصادر الموقع الأخرى."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"الوصول إلى الموقع الجغرافي الدقيق في الواجهة الأمامية فقط"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"لا يمكن لهذا التطبيق معرفة موقعك الجغرافي بالضبط إلا عندما يعمل في الخلفية. ويجب تفعيل خدمات الموقع الجغرافي هذه وأن تكون متاحة على الهاتف حتى يتمكن التطبيق من استخدامها. وقد يؤدي هذا إلى زيادة استهلاك طاقة البطارية."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"الوصول إلى الموقع التقريبي (استنادًا إلى الشبكة)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"يمكن لهذا التطبيق معرفة موقعك من خلال مصادر الشبكات مثل أبراج الجوّال وشبكات Wi-Fi. ويجب تشغيل خدمات المواقع هذه وأن تكون متاحة على الجهاز اللوحي حتى يتمكن التطبيق من استخدامها."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"يمكن لهذا التطبيق معرفة موقعك من خلال مصادر الشبكات مثل أبراج الجوّال وشبكات Wi-Fi. ويجب تشغيل خدمات المواقع هذه وأن تكون متاحة على جهاز التلفزيون حتى يتمكن التطبيق من استخدامها."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"يمكن لهذا التطبيق معرفة موقعك من خلال مصادر الشبكات مثل أبراج الجوّال وشبكات Wi-Fi. ويجب تشغيل خدمات المواقع هذه وأن تكون متاحة على الهاتف حتى يتمكن التطبيق من استخدامها."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"الوصول إلى الموقع الجغرافي التقريبي (بالاعتماد على الشبكة) في الخلفية فقط"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"يمكن لهذا التطبيق معرفة موقعك مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi ولكن يجب أن يعمل في الخلفية. ويجب تفعيل خدمات المواقع هذه وتوفّرها على جهازك اللوحي كي يتمكن التطبيق من استخدامها."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"يمكن لهذا التطبيق معرفة موقعك مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi ولكن يجب أن يعمل في الخلفية. ويجب تفعيل خدمات المواقع هذه وتوفّرها على جهاز التلفزيون كي يتمكن التطبيق من استخدامها."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"يمكن لهذا التطبيق معرفة موقعك مستعينًا بمصادر الشبكات مثل الأبراج الخلوية وشبكات Wi-Fi ولكن يجب أن يعمل في الخلفية. ويجب تفعيل خدمات المواقع هذه وتوفّرها على هاتفك كي يتمكن التطبيق من استخدامها."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"الوصول إلى الموقع الجغرافي في الخلفية"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"إذا تمّ منح إذن التطبيق هذا بالإضافة إلى الموقع الجغرافي التقريبي أو الدقيق، يمكن للتطبيق الوصول إلى الموقع الجغرافي أثناء تشغيله في الخلفية."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"تغيير إعداداتك الصوتية"</string>
@@ -1504,7 +1512,7 @@
<string name="forward_intent_to_work" msgid="621480743856004612">"أنت تستخدم هذا التطبيق في ملفك الشخصي للعمل"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"طريقة الإرسال"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"مزامنة"</string>
- <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الدخول"</string>
+ <string name="accessibility_binding_label" msgid="4148120742096474641">"إمكانية الوصول"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"الخلفية"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"تغيير الخلفية"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"برنامج تلقّي الإشعارات الصوتية"</string>
@@ -1957,6 +1965,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"تم تغيير طلب SS إلى طلب USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"تم التغيير إلى طلب SS الجديد."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"الملف الشخصي للعمل"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"توسيع"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"تصغير"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"تبديل التوسيع"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 4df7643..b897e24 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ৱাই-ফাই"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ৱাই- ফাই কলিং | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"অফ হৈ আছে"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ৱাই-ফাইক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ম\'বাইলক অগ্ৰাধিকাৰ দিয়া হৈছে"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"অৱস্থানৰ অতিৰিক্ত নির্দেশনাসমূহত প্ৰৱেশ কৰিবলৈ এপক অনুমতি দিয়ে। ইয়ে এপটোক জিপিএছ বা অন্য অৱস্থান উৎসসমূহৰ কাৰ্যকলাপত হস্তক্ষেপ কৰাৰ সুযোগ দিব পাৰে।"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"কেৱল অগ্ৰভূমিত অৱস্থানৰ সঠিক তথ্য় পাওক"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"এই এপটোৱে যেতিয়া ই নেপথ্যত চলি থাকে তেতিয়া আপোনাৰ সঠিক অৱস্থান নিৰ্ণয় কৰিব পাৰে। এপটোৱে ব্যৱহাৰ কৰিব পৰাকৈ এই অৱস্থান সেৱাসমূহ অন হৈ থাকিবই লাগিব আৰু আপোনাৰ ফ\'নত উপলব্ধ হ\'ব লাগিব। ইয়াৰ ফলত বেটাৰিৰ খৰচ বাঢ়িব পাৰে।"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"অনুমানিক অৱস্থান (নেটৱর্ক ভিত্তিক) ব্যৱহাৰ কৰিব পাৰে"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱর্কৰ দৰে নেটৱর্কৰ উৎসসমূহক ভিত্তি কৰি এই এপটোৱে আপোনাৰ অৱস্থান নিৰ্ণয় কৰিব পাৰে। এই অৱস্থানৰ সেৱাসমূহ অন হৈ থাকিলে আৰু আপোনাৰ টেবলেটটোত উপলব্ধ হ\'লেহে এপটোৱে সেইবোৰ ব্যৱহাৰ কৰিবলৈ সক্ষম হ\'ব।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱর্কৰ দৰে নেটৱর্কৰ উৎসসমূহক ভিত্তি কৰি এই এপটোৱে আপোনাৰ অৱস্থান নিৰ্ণয় কৰিব পাৰে। এই অৱস্থানৰ সেৱাসমূহ অন হৈ থাকিলে আৰু আপোনাৰ টিভিত উপলব্ধ হ\'লেহে এপটোৱে সেইবোৰ ব্যৱহাৰ কৰিবলৈ সক্ষম হ\'ব।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"এই এপটোৱে ম\'বাইলৰ টাৱাৰ আৰু ৱাই-ফাইৰ নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্কৰ উৎসসমূহক ভিত্তি কৰি আপোনাৰ অৱস্থান চিনাক্ত কৰিব পাৰে। সেই অৱস্থান সেৱাসমূহ আপোনাৰ ফ\'নত সক্ষম অৱস্থাত থাকিলেহে এপটোৱে সেইবোৰ ব্যৱহাৰ কৰিব পাৰিব।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"কেৱল অগ্ৰভূমিত থকা অৱস্থাতহে আনুমানিক অৱস্থানৰ (নেটৱৰ্কৰ ওপৰত ভিত্তি কৰি) এক্সেছ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"এই এপটোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্ক উৎসৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান জানিব পাৰে। এপটোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ\'লে সেইবোৰ অন হৈ থকাৰ লগতে আপোনাৰ টেবলেটত থাকিবই লাগিব।"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"এই এপটোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্ক উৎসৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান জানিব পাৰে। এপটোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ\'লে সেইবোৰ অন হৈ থকাৰ লগতে আপোনাৰ টিভিত থাকিবই লাগিব।"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"এই এপটোৱে অগ্ৰভূমিত থকা অৱস্থাতহে চেল টাৱাৰ আৰু ৱাই-ফাই নেটৱৰ্ক আদিৰ দৰে নেটৱৰ্ক উৎসৰ ওপৰত ভিত্তি কৰি আপোনাৰ অৱস্থান জানিব পাৰে। এপটোৱে এই অৱস্থান সেৱাসমূহ ব্যৱহাৰ কৰিবলৈ হ\'লে সেইবোৰ অন হৈ থকাৰ লগতে আপোনাৰ ফ\'নত থাকিবই লাগিব।"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"নেপথ্যত চলি থকা সময়ত অৱস্থানৰ এক্সেছ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ইয়াৰ উপৰিও যদি ইয়াক আনুমানিক বা সঠিক অৱস্থানৰ এক্সেছ দিয়া হয়, তেন্তে উক্ত এপে নেপথ্যত চলি থকাৰ সময়ত অৱস্থানৰ এক্সেছ লাভ কৰিব পাৰে।"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"আপোনাৰ অডিঅ\' ছেটিংসমূহ সলনি কৰক"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS অনুৰোধ USSD অনুৰোধলৈ সলনি কৰা হ\'ল"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"নতুন SS অনুৰোধলৈ সলনি কৰা হ\'ল"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"কৰ্মস্থানৰ প্ৰ\'ফাইল"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"বিস্তাৰ কৰক"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"সংকুচিত কৰক"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"সম্প্ৰসাৰণ ট’গল কৰক"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 4bb6c1f..3f3d685 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi Zəngi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Deaktiv"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi tərcih edilir"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tərcih"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tətbiqə ekstra məkan provayder əmrlərinə girişə imkan verir. Bu, tətbiqə GPS və ya digər lokal mənbələrlə əməliyyata müdaxiləyə imkan verə bilər."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"yalnız ön planda dəqiq məkana daxil olun"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Bu tətbiq yalnız ön fonda olduqda dəqiq məkanınızı əldə edə bilər. Tətbiqin bunlardan istifadə etməsi üçün bu məkan xidmətləri aktiv edilməlidir və telefonda əlçatan olmalıdır. Bu, batareya sərfiyyatını artıra bilər."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"təxmini məkana (şəbəkə əsaslı) giriş"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Bu tətbiq mobil qüllələr və Wi-Fi şəbəkələri kimi şəbəkə mənbələrinin əassında əkanınızı əldə edə bilər. Bu məkan xidmətləri aktiv edilməlidir və planşetdə tətbiq tərəfindən istifadə üçün əlçatan olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Bu tətbiq mobil qüllələr və Wi-Fi şəbəkələri kimi şəbəkə mənbələrinin əassında əkanınızı əldə edə bilər. Bu məkan xidmətləri aktiv edilməlidir və TV\'də tətbiq tərəfindən istifadə üçün əlçatan olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Bu tətbiq mobil qüllələr və Wi-Fi şəbəkələri kimi şəbəkə mənbələrinin əassında əkanınızı əldə edə bilər. Bu məkan xidmətləri aktiv edilməlidir və telefonda tətbiq tərəfindən istifadə üçün əlçatan olmalıdır."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"yalnız ön planda təxmini məkana (şəbəkəyə əsaslanan) giriş"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Bu tətbiq baza stansiyaları və Wi-Fi şəbəkələri kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə edə bilməsi üçün bu məkan xidmətləri aktiv edilməli və planşetdə əlçatan olmalıdır."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Bu tətbiq baza stansiyaları və Wi-Fi kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə edə bilməsi üçün bu məkan xidmətləri aktiv edilməli və TV-də əlçatan olmalıdır."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Bu tətbiq baza stansiyaları və Wi-Fi kimi şəbəkə mənbələrinə əsaslanaraq məkanınızı əldə edə bilər. Bu, yalnız tətbiq ön planda olduqda mümkündür. Tətbiqin istifadə edə bilməsi üçün bu məkan xidmətləri aktiv edilməli və telefonda əlçatan olmalıdır."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"arxa fonda məkan girişi"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Bu, təqribi və ya dəqiq məkan girişinə əlavə olaraq verilərsə, tətbiq arxa fonda işləyərkən məkana daxil ola bilər."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"audio ayarlarınızı dəyişir"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS sorğusu USSD sorğusuna dəyişdirildi"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Yeni SS sorğusuna dəyişdirildi"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"İş profili"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Genişləndirin"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Yığcamlaşdırın"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"keçid genişlənməsi"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index e650f2d..ca2c823 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pozivanje preko Wi-Fi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Želim mobilne podatke"</string>
@@ -213,7 +221,7 @@
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Sat će se ugasiti."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Telefon će se isključiti."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Da li želite da isključite telefon?"</string>
- <string name="reboot_safemode_title" msgid="7054509914500140361">"Ponovo pokreni sistem u bezbednom režimu"</string>
+ <string name="reboot_safemode_title" msgid="7054509914500140361">"Restartuj sistem u bezbednom režimu"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"Da li želite da ponovo pokrenete sistem u bezbednom režimu? Ovo će onemogućiti sve instalirane aplikacije nezavisnih proizvođača. One će biti vraćene kada ponovo pokrenete sistem."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Nedavno"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Nema nedavnih aplikacija."</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Omogućava aplikaciji da pristupa dodatnim komandama davaoca usluga lokacije. To može da omogući aplikaciji da utiče na rad GPS-a ili drugih izvora lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"pristup preciznoj lokaciji samo u prvom planu"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ova aplikacija može da odredi vašu tačnu lokaciju samo kada radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na telefonu da bi aplikacija mogla da ih koristi. To može da poveća potrošnju baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"pristup približnoj lokaciji (utvrđena preko mreže)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže. Ove usluge lokacije moraju da budu uključene i dostupne na tabletu da bi aplikacija mogla da ih koristi."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže. Ove usluge lokacije moraju da budu uključene i dostupne na TV-u da bi aplikacija mogla da ih koristi."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže. Ove usluge lokacije moraju da budu uključene i dostupne na telefonu da bi aplikacija mogla da ih koristi."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"pristup približnoj lokaciji (utvrđenoj preko mreže) samo u prvom planu"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na tabletu da bi aplikacija mogla da ih koristi"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na televizoru da bi aplikacija mogla da ih koristi."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ova aplikacija može da pristupi vašoj lokaciji pomoću izvora mreže, kao što su mobilni predajnici i Wi-Fi mreže, ali samo kada aplikacija radi u prvom planu. Ove usluge lokacije moraju da budu uključene i dostupne na telefonu da bi aplikacija mogla da ih koristi."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"pristup lokaciji u pozadini"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ako se pored približnog ili preciznog pristupa lokacija odobri i ovaj, aplikacija može da pristupa lokaciji dok je pokrenuta u pozadini."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"promena audio podešavanja"</string>
@@ -507,11 +515,11 @@
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja ekrana"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Dozvoljava aplikaciji da onemogući zaključavanje tastature i sve povezane bezbednosne mere sa lozinkama. Na primer, telefon onemogućava zaključavanje tastature pri prijemu dolaznog telefonskog poziva, a zatim ga ponovo omogućava po završetku poziva."</string>
<string name="permlab_useBiometric" msgid="8837753668509919318">"koristi biometrijski hardver"</string>
- <string name="permdesc_useBiometric" msgid="8389855232721612926">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu autentičnosti"</string>
+ <string name="permdesc_useBiometric" msgid="8389855232721612926">"Dozvoljava aplikaciji da koristi biometrijski hardver za potvrdu identiteta"</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"upravljaj hardverom za otiske prstiju"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Dozvoljava aplikaciji da aktivira metode za dodavanje i brisanje šablona otisaka prstiju koji će se koristiti."</string>
<string name="permlab_useFingerprint" msgid="3150478619915124905">"koristi hardver za otiske prstiju"</string>
- <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Dozvoljava aplikaciji da koristi hardver za otiske prstiju radi potvrde autentičnosti"</string>
+ <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Dozvoljava aplikaciji da koristi hardver za otiske prstiju radi potvrde identiteta"</string>
<string name="permlab_audioRead" msgid="6617225220728465565">"čitanje muzičke kolekcije"</string>
<string name="permdesc_audioRead" msgid="5034032570243484805">"Dozvoljava aplikaciji da čita muzičku kolekciju."</string>
<string name="permlab_audioWrite" msgid="2661772059799779292">"izmena muzičke kolekcije"</string>
@@ -898,7 +906,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"Fabričko testiranje nije uspelo"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"Radnja FACTORY_TEST je podržana samo za pakete instalirane u direktorijumu /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Nije pronađen nijedan paket koji obezbeđuje radnju FACTORY_TEST."</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"Ponovo pokreni"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"Restartuj"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"Na stranici na adresi „<xliff:g id="TITLE">%s</xliff:g>“ piše:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Potvrda navigacije"</string>
@@ -1318,7 +1326,7 @@
<string name="sim_done_button" msgid="827949989369963775">"Gotovo"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM kartica je dodata"</string>
<string name="sim_added_message" msgid="6599945301141050216">"Restartujte uređaj da biste mogli da pristupite mobilnoj mreži."</string>
- <string name="sim_restart_button" msgid="4722407842815232347">"Ponovo pokreni"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Restartuj"</string>
<string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Aktivirajte mobilnu uslugu"</string>
<string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Preuzmite aplikaciju mobilnog operatera da biste aktivirali novi SIM"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Preuzmite aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> da biste aktivirali novu SIM karticu"</string>
@@ -1858,6 +1866,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS zahtev je promenjen u USSD zahtev"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Promenjeno je u novi SS zahtev"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil za Work"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Proširi"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Skupi"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"uključite/isključite proširenje"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index db75d1d..3462a84 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-тэлефанія | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWi-Fi ад <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Выкл."</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Прыярытэт Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Прыярытэт мабільнай сеткі"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Дазваляе праграме атрымліваць доступ да дадатковых каманд службаў вызначэння месцазнаходжання. Гэта можа дазволіць праграме ўмешвацца ў функцыянаванне GPS або іншых крыніц даных аб месцазнаходжаннi."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"доступ да дакладнага месцазнаходжання толькі ў асноўным рэжыме"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Гэта праграма можа атрымліваць звесткі пра ваша дакладнае месцазнаходжанне толькі ў асноўным рэжыме. Службы геалакацыі павінны быць уключаны і даступныя на вашым тэлефоне, каб праграма магла імі карыстацца. Гэта можа павялічыць спажыванне зараду акумулятара."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"атрымліваць доступ да прыблізнага месцазнаходжання (на аснове даных сеткі)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Гэтыя сэрвісы вызначэння месцазнаходжання павінны быць уключаны i даступныя на вашым планшэце, каб праграма магла іх выкарыстоўваць."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Гэтыя сэрвісы вызначэння месцазнаходжання павінны быць уключаны i даступныя на вашым тэлевізары, каб праграма магла іх выкарыстоўваць."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Гэтыя сэрвісы вызначэння месцазнаходжання павінны быць уключаны i даступныя на вашым тэлефоне, каб праграма магла іх выкарыстоўваць."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"доступ да прыблізнага месцазнаходжання (на падставе сеткі) толькі ў актыўным рэжыме"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Каб праграма магла карыстацца гэтымі службамі геалакацыі, неабходна ўключыць і зрабіць іх даступнымі на планшэце."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Каб праграма магла карыстацца гэтымі службамі геалакацыі, неабходна ўключыць і зрабіць іх даступнымі на тэлевізары."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Гэта праграма можа атрымліваць звесткі пра ваша месцазнаходжанне толькі ў актыўным рэжыме на падставе даных сеткавых крыніц, такіх як вышкі сотавай сувязі і сеткі Wi-Fi. Каб праграма магла карыстацца гэтымі службамі геалакацыі, неабходна ўключыць і зрабіць іх даступнымі на тэлефоне."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"доступ да вызначэння месцазнаходжання ў фонавым рэжыме"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Акрамя доступу да прыкладнага ці дакладнага месцазнаходжання праграма можа мець доступ да вызначэння геалакацыі ў фонавым рэжыме працы. На гэта патрабуецца дазвол."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змяняць налады аудыё"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-запыт заменены на USSD-запыт"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Зроблена замена на новы SS-запыт"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Працоўны профіль"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Разгарнуць"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Згарнуць"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"разгарнуць/згарнуць"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index e2e5bd4..6693dfd 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Обаждания през Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWi-Fi от <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Изключено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предпочита се Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Предпочитат се мобилни данни"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Разрешава на приложението достъп до допълнителни команди на доставчика на местоположение. Това може да позволи на приложението да смущава работата на GPS или на другите източници на местоположение."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"достъп до точното местоположение само на преден план"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Приложението може да получава данни за точното ви местоположение само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на телефона ви, за да могат да се използват от приложението. Това може да увеличи потреблението на батерията."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"достъп до приблизителното местоположение (въз основа на мрежата)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни кули и Wi-Fi. Тези услуги за местоположение трябва да са включени и налице на таблета ви, за да могат да се използват от приложението."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни кули и Wi-Fi. Тези услуги за местоположение трябва да са включени и налице на телевизора ви, за да могат да се използват от приложението."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни кули и Wi-Fi. Тези услуги за местоположение трябва да са включени и налице на телефона ви, за да могат да се използват от приложението."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"достъп до приблизителното местоположение (основано на мрежи) само на преден план"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на таблета ви, за да могат да се използват от приложението."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на телевизора ви, за да могат да се използват от приложението."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Приложението може да получава данни за местоположението ви въз основа на мрежови източници, като клетъчни базови станции и Wi-Fi мрежи, само когато работи на преден план. Тези услуги за местоположение трябва да са включени и налице на телефона ви, за да могат да се използват от приложението."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"достъп до местоположението на заден план"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ако разрешението бъде предоставено в допълнение към достъпа до приблизителното или точното местоположение, приложението може да осъществява достъп до местоположението, докато се изпълнява на заден план."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"промяна на настройките ви за звука"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS заявката е променена на USSD заявка"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Променено на нова SS заявка"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Служебен потребителски профил"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Разгъване"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Свиване"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"превключване на разгъването"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 0122c6c..120abf0 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ওয়াই-ফাই"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ওয়াই-ফাই কলিং | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"বন্ধ আছে"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"পছন্দের ওয়াই-ফাই"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"পছন্দের মোবাইল"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"লোকেশনের সাথে সম্পর্কিত তথ্য প্রদানকারীর অতিরিক্ত কম্যান্ডগুলিকে অ্যাপ্লিকেশানটিকে মঞ্জুর করে৷ এটি অ্যাপ্লিকেশানটিকে GPS অথবা অন্যান্য লোকেশন নির্ণয়ের সাথে সম্পর্কিত উৎসগুলির ক্রিয়াপ্রণালীর নিয়ন্ত্রণকে মঞ্জুর করতে পারে৷"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"শুধুমাত্র অ্যাপটি খোলা থাকলে আপনার যথাযথ লোকেশন অ্যাক্সেস করা"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"এই অ্যাপটি ফোরগ্রাউন্ডে চলতে থাকলে যেকোনও সময়ে আপনার যথাযথ লোকেশন জানতে পারবে। এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং আপনার ফোনে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে। এর জন্য অতিরিক্ত ব্যাটারি খরচ হতে পারে।"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"আনুমানিক লোকেশন (নেটওয়ার্ক-ভিত্তিক) অ্যাক্সেস করুন"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন শনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেইজন্য সেগুলিকে আপনার ট্যাবলেটে উপলব্ধ করে রাখতে হবে৷"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্কের উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন শনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার টিভিতে উপলব্ধ করে রাখতে হবে৷"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"মোবাইল টাওয়ার এবং ওয়াই-ফাই নেটওয়ার্কগুলির মত নেটওয়ার্ক উৎসগুলির উপর ভিত্তি করে এই অ্যাপটি আপনার লোকেশন শনাক্ত করতে পারে৷ এই লোকেশন পরিষেবাগুলি অবশ্যই চালু রাখতে হবে এবং অ্যাপটি যাতে সেগুলি ব্যবহার করতে পারে সেজন্য সেগুলিকে আপনার ফোনে উপলব্ধ করে রাখতে হবে৷"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"শুধুমাত্র খোলা অবস্থায় আনুমানিক লোকেশন (নেটওয়ার্ক ভিত্তিক) অ্যাক্সেস করবে"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"অ্যাপটি শুধুমাত্র খোলা অবস্থায় সেল টাওয়ার এবং ওয়াই-ফাইয়ের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারবে। লোকেশন সংক্রান্ত এই পরিষেবাগুলি অবশ্যই চালু থাকতে হবে এবং আপনার ট্যাবলেটে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে।"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"অ্যাপটি শুধুমাত্র খোলা অবস্থায় সেল টাওয়ার এবং ওয়াই-ফাইয়ের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারবে। লোকেশন সংক্রান্ত এই পরিষেবাগুলি অবশ্যই চালু থাকতে হবে এবং আপনার টিভিতে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে।"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"অ্যাপটি শুধুমাত্র খোলা অবস্থায় সেল টাওয়ার এবং ওয়াই-ফাইয়ের মতো নেটওয়ার্ক সোর্স ব্যবহার করে আপনার লোকেশন জানতে পারবে। লোকেশন সংক্রান্ত এই পরিষেবাগুলি অবশ্যই চালু থাকতে হবে এবং আপনার ফোনে সেগুলি উপলভ্য থাকতে হবে যাতে অ্যাপটি সেগুলি ব্যবহার করতে পারে।"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ব্যাকগ্রাউন্ডে লোকেশন অ্যাক্সেস করা"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"আনুমানিক বা একদম যথাযথ লোকেশন অ্যাক্সেস করার অনুমতি দেওয়া হলে এই অ্যাপটি ব্যাকগ্রাউন্ডে চালু থাকাকালীন আপনার লোকেশন অ্যাক্সেস করতে পারবে।"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"আপনার অডিও সেটিংস পরিবর্তন করে"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS অনুরোধ USSD অনুরোধে পরিবর্তন করা হয়েছে"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"নতুন SS অনুরোধে পরিবর্তন করা হয়েছে"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"কর্মস্থলের প্রোফাইল"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"বড় করুন"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"সঙ্কুচিত করুন"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"টগল সম্প্রসারণ"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 453bedf..e0abbe1 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pozivanje putem WiFi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferira se WiFi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferira se mobilna mreža"</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Dozvoljava aplikaciji pristup dodatnim naredbama pružatelja lokacija. Ovim se aplikaciji može dozvoliti da ometa rad GPS-a ili drugih izvora lokacija."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"pristup tačnoj lokaciji samo u prvom planu"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ova aplikacija može odrediti vašu tačnu lokaciju samo kada je u prvom planu. Ove usluge lokacije moraju biti uključene i dostupne na vašem telefonu da ih aplikacija može koristiti. To može dovesti do povećane potrošnje baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"pristup približnoj lokaciji (utvrđena preko mreže)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem tabletu kako bi ih aplikacija mogla koristiti."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem TV-u kako bi ih aplikacija mogla koristiti."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem telefonu kako bi ih aplikacija mogla koristiti."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"pristup približnoj lokaciji (utvrđena preko mreže) samo u prvom planu"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže ali samo kada je aplikacija u prvom planu. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem tabletu kako bi ih aplikacija mogla koristiti."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže ali samo kada je aplikacija u prvom planu. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem TV uređaju kako bi ih aplikacija mogla koristiti."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ova aplikacija može odrediti vašu lokaciju na osnovu izvora mreže kao što su predajnici za mobilnu mrežu i WiFi mreže ali samo kada je aplikacija u prvom planu. Ove usluge za određivanje lokacije moraju biti uključene i omogućene na vašem telefonu kako bi ih aplikacija mogla koristiti."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"pristup lokaciji u pozadini"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ako je ovo odobreno, pored pristupa približnoj ili tačnoj lokaciji, aplikacija može pristupiti lokaciji dok radi u pozadini."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"izmjene postavki zvuka"</string>
@@ -1860,6 +1868,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS zahtjev je promijenjen u USSD zahtjev"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Promijenjeno u novi SS zahtjev"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil za posao"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Proširi"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Suzi"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"aktiviraj/deaktiviraj proširenje"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index a212014..cb2c183 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi (<xliff:g id="SPN">%s</xliff:g>)"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Trucades per Wi‑Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi (<xliff:g id="SPN">%s</xliff:g>)"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivat"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferència per la Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferència per dades mòbils"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet que l\'aplicació accedeixi a ordres addicionals del proveïdor d\'ubicacions; per tant, és possible que l\'aplicació pugui interferir en el funcionament del GPS o d\'altres fonts d\'ubicacions."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"accedeix a la ubicació exacta només en primer pla"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Aquesta aplicació pot obtenir la teva ubicació exacta només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar, i això pot fer que el consum de bateria augmenti."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"accedir a la ubicació aproximada (basada en la xarxa)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi-Fi. Aquests serveis d\'ubicació han d\'estar activats i disponibles a la tauleta perquè l\'aplicació els pugui utilitzar."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi-Fi. Aquests serveis d\'ubicació han d\'estar activats i disponibles al televisor perquè l\'aplicació els pugui utilitzar."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi-Fi. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"accedeix a la ubicació aproximada (basada en xarxa) només en primer pla"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles a la tauleta perquè l\'aplicació els pugui utilitzar."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al televisor perquè l\'aplicació els pugui utilitzar."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aquesta aplicació pot obtenir la teva ubicació a partir de fonts de xarxa, com ara torres de telefonia mòbil i xarxes Wi‑Fi, però només quan està en primer pla. Aquests serveis d\'ubicació han d\'estar activats i disponibles al telèfon perquè l\'aplicació els pugui utilitzar."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"accedir a la ubicació en segon pla"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Si es concedeix aquest permís, a més de l\'accés a la ubicació aproximada o exacta, l\'aplicació pot accedir a la ubicació mentre s\'executa en segon pla."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"canviar la configuració d\'àudio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"La sol·licitud SS s\'ha canviat per una sol·licitud USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"S\'ha canviat a una nova sol·licitud SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil professional"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Desplega"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Replega"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"desplega o replega"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index d71f72c..019e7e0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Volání přes Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>: VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuto"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferována síť W-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferována mobilní data"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Umožňuje aplikaci přístup k dalším příkazům poskytovatele polohy. To aplikaci umožní zasahovat do fungování systému GPS a dalších zdrojů polohy."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"přístup k přesné poloze jen na popředí"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Tato aplikace může zjistit vaši přesnou polohu, jen když běží na popředí. Aby tyto služby určování polohy mohla aplikace používat, musí být v telefonu dostupné a musí být zapnuté. Tyto služby mohou způsobit rychlejší vybíjení baterie."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"přístup k přibližné poloze (pomocí sítě)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi. Aby tyto služby určování polohy mohla aplikace používat, musí být v tabletu dostupné a musí být zapnuté."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi. Aby tyto služby určování polohy mohla aplikace používat, musí být v televizi dostupné a musí být zapnuté."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi. Aby tyto služby určování polohy mohla aplikace používat, musí být v telefonu dostupné a musí být zapnuté."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"přístup k přibližené poloze (na základě sítě) jen na popředí"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v tabletu dostupné a musí být zapnuté."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v televizi dostupné a musí být zapnuté."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Tato aplikace může zjistit vaši polohu podle zdrojů sítě, jako jsou vysílací věže nebo sítě Wi-Fi (ale pouze pokud je aplikace na popředí). Aby tyto služby určování polohy mohla aplikace používat, musí být v telefonu dostupné a musí být zapnuté."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"přístup k poloze na pozadí"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Bude-li oprávnění uděleno dodatečně k přístupu k přibližné nebo přesné poloze, aplikace bude moci používat polohu při spuštění na pozadí."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"změna nastavení zvuku"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Požadavek SS byl změněn na požadavek USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Změněno na nový požadavek SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Pracovní profil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Rozbalit"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Sbalit"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"přepnout rozbalení"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 6e9ae6b..f7013ec 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-opkald | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi via <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Fra"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi-netværk er foretrukket"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobildata foretrækkes"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tillader, at appen kan få adgang til yderligere kommandoer for placeringsudbydere. Dette kan gøre det muligt for appen at forstyrre GPS-funktionen eller andre placeringskilder."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"få kun adgang til nøjagtig placering i forgrunden"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Denne app kan kun få din nøjagtige placering, når den er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på din telefon, før appen kan bruge dem. Dette kan øge batteriforbruget."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"få adgang til omtrentlig placering (netværksbaseret)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Denne app kan bestemme din placering ved hjælp af netværkskilder, som f.eks. mobilmaster og Wi-Fi-netværk. Disse placeringstjenester skal være aktiverede og tilgængelige på din tablet, før appen kan bruge dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Denne app kan bestemme din placering ved hjælp af netværkskilder, som f.eks. mobilmaster og Wi-Fi-netværk. Disse placeringstjenester skal være aktiverede og tilgængelige på dit fjernsyn, før appen kan bruge dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Denne app kan bestemme din placering ved hjælp af netværkskilder, som f.eks. mobilmaster og Wi-Fi-netværk. Disse placeringstjenester skal være aktiverede og tilgængelige på din telefon, før appen kan bruge dem."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"få kun adgang til omtrentlig placering (netværksbaseret) i forgrunden"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på din tablet, før appen kan bruge dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiverede og tilgængelige på dit fjernsyn, før appen kan bruge dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Denne app kan fastslå din placering ved hjælp af netværkskilder som f.eks. mobilmaster og Wi-Fi-netværk, men kun når appen er i forgrunden. Disse placeringstjenester skal være aktiveret og tilgængelige på din telefon, før appen kan bruge dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"adgang til placering i baggrunden"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Hvis appen godkendes, og der gives adgang til den omtrentlige eller nøjagtige placering, kan appen registrere placeringen, mens den kører i baggrunden."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"skifte dine lydindstillinger"</string>
@@ -646,11 +654,11 @@
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Tjek længden samt tilladte tegn i adgangskoder og pinkoder til skærmlåsen."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Overvåg forsøg på oplåsning af skærm"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Overvåg antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås din tablet, eller slet alle data i den, hvis der er indtastet for mange forkerte adgangskoder."</string>
- <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Overvåg antallet af forkert indtastede adgangskoder ved oplåsning af skærmen, og lås tv\'et eller slet alle dets data, hvis der indtastes for mange forkerte adgangskoder."</string>
+ <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Overvåg antallet af forkert indtastede adgangskoder ved oplåsning af skærmen, og lås tv\'et eller slet alle dets data, hvis der angives for mange forkerte adgangskoder."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Overvåg antallet af forkerte adgangskoder ved oplåsning af skærmen, og lås telefonen eller slet alle data på telefonen, hvis der er indtastet for mange forkerte adgangskoder."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Registrer antallet af forkerte adgangskoder, der indtastes ved oplåsning af skærmen, og lås din tablet, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Registrer antallet af forkerte adgangskoder, der indtastes ved oplåsning af skærmen, og lås tv-adgangen, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Registrer antallet af forkerte adgangskoder, der indtastes ved oplåsning af skærmen, og lås telefonen, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Registrer antallet af forkerte adgangskoder, der angives ved oplåsning af skærmen, og lås din tablet, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Registrer antallet af forkerte adgangskoder, der angives ved oplåsning af skærmen, og lås tv-adgangen, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Registrer antallet af forkerte adgangskoder, der angives ved oplåsning af skærmen, og lås telefonen, eller slet alle brugerens data, hvis adgangskoden tastes forkert for mange gange."</string>
<string name="policylab_resetPassword" msgid="4934707632423915395">"Skifte skærmlås"</string>
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Skifter skærmlås"</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Låse skærmen"</string>
@@ -802,7 +810,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Tryk på Menu for at låse op eller foretage et nødopkald."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Tryk på Menu for at låse op."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Tegn oplåsningsmønster"</string>
- <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødopkald"</string>
+ <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Nødsituation"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Tilbage til opkald"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Rigtigt!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Prøv igen"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-anmodningen blev ændret til en USSD-anmodning"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Ændret til en SS-anmodning"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbejdsprofil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Udvid"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Skjul"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Slå udvidelse til eller fra"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index e0f8201..2bad90e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -70,7 +70,7 @@
<string name="ThreeWCMmi" msgid="9051047170321190368">"Dreierkonferenz"</string>
<string name="RuacMmi" msgid="7827887459138308886">"Ablehnung unerwünschter Anrufe"</string>
<string name="CndMmi" msgid="3116446237081575808">"Rufnummernübermittlung"</string>
- <string name="DndMmi" msgid="1265478932418334331">"Nicht stören"</string>
+ <string name="DndMmi" msgid="1265478932418334331">"Bitte nicht stören"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Anrufer-ID ist standardmäßig beschränkt. Nächster Anruf: Beschränkt"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Anrufer-ID ist standardmäßig beschränkt. Nächster Anruf: Nicht beschränkt"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Anrufer-ID ist standardmäßig nicht beschränkt. Nächster Anruf: Beschränkt"</string>
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WLAN-Telefonie | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWLAN"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Aus"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WLAN bevorzugt"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobilverbindung bevorzugt"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ermöglicht der App, auf zusätzliche Standortanbieterbefehle zuzugreifen. Damit könnte die App die Funktionsweise von GPS oder anderen Standortquellen beeinträchtigen."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"Nur bei Ausführung im Vordergrund auf den genauen Standort zugreifen"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Diese App kann deinen genauen Standort nur dann ermitteln, wenn sie im Vordergrund ausgeführt wird. Die App kann diese Standortdienste nur verwenden, wenn sie auf deinem Smartphone aktiviert und verfügbar sind. Hierdurch kann sich der Akkuverbrauch erhöhen."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"Auf den ungefähren Standort zugreifen (netzwerkbasiert)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Diese App kann deinen Standort mithilfe von Netzwerkquellen wie Mobilfunkmasten und WLAN ermitteln. Die App kann diese Standortdienste nur verwenden, wenn sie auf deinem Tablet aktiviert und verfügbar sind."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Diese App kann deinen Standort mithilfe von Netzwerkquellen wie Mobilfunkmasten und WLAN ermitteln. Die App kann diese Standortdienste nur verwenden, wenn sie auf deinem Fernseher aktiviert und verfügbar sind."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Diese App kann deinen Standort mithilfe von Netzwerkquellen wie Mobilfunkmasten und WLAN ermitteln. Die App kann diese Standortdienste nur verwenden, wenn sie auf deinem Smartphone aktiviert und verfügbar sind."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Nur bei Ausführung im Vordergrund auf den ungefähren Standort (netzwerkbasiert) zugreifen"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Diese Standortdienste müssen auf deinem Tablet aktiviert und verfügbar sein, damit die App sie nutzen kann."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Diese Standortdienste müssen auf deinem Fernseher aktiviert und verfügbar sein, damit die App sie nutzen kann."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Diese App kann deinen Standort anhand von Netzwerkquellen wie Mobilfunkmasten und WLANs ermitteln, allerdings nur, wenn sie im Vordergrund ausgeführt wird. Diese Standortdienste müssen auf deinem Smartphone aktiviert und verfügbar sein, damit die App sie nutzen kann."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"Im Hintergrund auf den Standort zugreifen"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Wenn zusätzlich zum Zugriff auf den ungefähren oder genauen Standort diese Erlaubnis erteilt wird, kann die App bei Ausführung im Hintergrund auf den Standort zugreifen."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Audio-Einstellungen ändern"</string>
@@ -640,8 +648,8 @@
<string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Ermöglicht dem Eigentümer die Bindung an die Oberfläche eines Mobilfunkanbieter-Messaging-Dienstes auf oberster Ebene. Für normale Apps sollte dies nie erforderlich sein."</string>
<string name="permlab_bindCarrierServices" msgid="3233108656245526783">"An Mobilfunkanbieter-Dienste binden"</string>
<string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Ermöglicht dem Eigentümer die Bindung an Mobilfunkanbieter-Dienste. Für normale Apps sollte dies nicht erforderlich sein."</string>
- <string name="permlab_access_notification_policy" msgid="4247510821662059671">"Auf \"Nicht stören\" zugreifen"</string>
- <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ermöglicht der App Lese- und Schreibzugriff auf die \"Nicht stören\"-Konfiguration"</string>
+ <string name="permlab_access_notification_policy" msgid="4247510821662059671">"Auf \"Bitte nicht stören\" zugreifen"</string>
+ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Ermöglicht der App Lese- und Schreibzugriff auf die \"Bitte nicht stören\"-Konfiguration"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Zulässige Länge und Zeichen für Passwörter für die Displaysperre festlegen"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Versuche zum Entsperren des Displays überwachen"</string>
@@ -1804,10 +1812,10 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="9128205721301330797">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (nächste Weckzeit)"</string>
<string name="zen_mode_forever" msgid="931849471004038757">"Bis zur Deaktivierung"</string>
- <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Bis zur Deaktivierung von \"Nicht stören\""</string>
+ <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Bis zur Deaktivierung von \"Bitte nicht stören\""</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string>
- <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nicht stören"</string>
+ <string name="zen_mode_feature_name" msgid="5254089399895895004">"Bitte nicht stören"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Ruhezeit"</string>
<string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Abends unter der Woche"</string>
<string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Wochenende"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-Anfrage wurde in USSD-Anfrage geändert"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"In neue SS-Anfrage geändert"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbeitsprofil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Maximieren"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Minimieren"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Maximierung ein-/auschalten"</string>
@@ -1832,7 +1842,7 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-Port für Peripheriegeräte"</string>
<string name="floating_toolbar_open_overflow_description" msgid="4797287862999444631">"Weitere Optionen"</string>
- <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Überlauf schließen"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="559796923090723804">"Dreipunkt-Menü schließen"</string>
<string name="maximize_button_text" msgid="7543285286182446254">"Maximieren"</string>
<string name="close_button_text" msgid="3937902162644062866">"Schließen"</string>
<string name="notification_messaging_title_template" msgid="3452480118762691020">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 6090465..15e4b1c 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Κλήση Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ανενεργό"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Προτίμηση Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Προτίμηση δικτύου κινητής τηλεφωνίας"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Επιτρέπει στην εφαρμογή την πρόσβαση σε επιπλέον εντολές παρόχου τοποθεσίας. Αυτό μπορεί να δώσει τη δυνατότητα στην εφαρμογή να παρέμβει στη λειτουργία του GPS ή άλλων πηγών τοποθεσίας."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"πρόσβαση στην ακριβή τοποθεσία μόνο στο προσκήνιο"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την ακριβή τοποθεσία σας όταν βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο τηλέφωνό σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή. Με την ενεργοποίηση αυτής της ρύθμισης, μπορεί να αυξηθεί η κατανάλωση μπαταρίας."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"έχει πρόσβαση στην τοποθεσία κατά προσέγγιση (με βάση το δίκτυο)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο tablet που χρησιμοποιείτε, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στην τηλεόρασή σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο τηλέφωνό σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"πρόσβαση στην κατά προσέγγιση τοποθεσία (βάσει δικτύου) μόνο στο προσκήνιο"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο tablet που χρησιμοποιείτε, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στην τηλεόρασή σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Αυτή η εφαρμογή μπορεί να ανιχνεύσει την τοποθεσία σας βάσει πηγών δικτύου, όπως κεραίες κινητής τηλεφωνίας και δίκτυα Wi-Fi, αλλά μόνο όταν η εφαρμογή βρίσκεται στο προσκήνιο. Αυτές οι υπηρεσίες τοποθεσίας θα πρέπει να είναι ενεργοποιημένες και διαθέσιμες στο τηλέφωνό σας, προκειμένου να μπορεί να τις χρησιμοποιήσει η εφαρμογή."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"πρόσβαση στην τοποθεσία στο παρασκήνιο"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Εάν εκχωρηθεί επιπρόσθετα σε μια καταπροσέγγιση ή ακριβή πρόσβαση τοποθεσίας, η εφαρμογή μπορεί να έχει πρόσβαση στην τοποθεσία κατά την εκτέλεση στο παρασκήνιο."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"αλλάζει τις ρυθμίσεις ήχου"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Το αίτημα SS τροποποιήθηκε σε αίτημα USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Τροποποιήθηκε σε νέο αίτημα SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Προφίλ εργασίας"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Ανάπτυξη"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Σύμπτυξη"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"εναλλαγή επέκτασης"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index e102e5b..8b6b404 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"access precise location only in the foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can pick up your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can pick up your location based on network sources such as mobile towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"access approximate location (network-based) only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"access location in the background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS request changed to USSD request"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Changed to new SS request"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 518efc9..4929e87 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"access precise location only in the foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can pick up your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can pick up your location based on network sources such as mobile towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"access approximate location (network-based) only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"access location in the background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS request changed to USSD request"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Changed to new SS request"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index e102e5b..8b6b404 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"access precise location only in the foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can pick up your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can pick up your location based on network sources such as mobile towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"access approximate location (network-based) only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"access location in the background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS request changed to USSD request"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Changed to new SS request"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index e102e5b..8b6b404 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"access precise location only in the foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can pick up your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can pick up your location based on network sources such as mobile towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as phone masts and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"access approximate location (network-based) only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"This app can get your location based on network sources such as phone masts and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"access location in the background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"If this is granted additionally to the approximate or precise location access, the app can access the location while running in the background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS request changed to USSD request"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Changed to new SS request"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index 29a797b..b646d86b 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -136,6 +136,10 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_calling" msgid="4990486735013125329">"Wi-Fi Calling"</string>
+ <string name="wfcSpnFormat_wifi" msgid="1892673884655959773">"Wi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="1336669776254502831">"WiFi Calling"</string>
+ <string name="wfcSpnFormat_vowifi" msgid="1765176406171272629">"VoWifi"</string>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferred"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobile preferred"</string>
@@ -417,10 +421,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Allows the app to access extra location provider commands. This may allow the app to interfere with the operation of the GPS or other location sources."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"access precise location only in the foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"access approximate location (network-based)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"access approximate location (network-based) only in the foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"access location in the background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"If this is granted additionally to the approximate or precise location access the app can access the location while running in the background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"change your audio settings"</string>
@@ -1825,6 +1829,7 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS request changed to USSD request"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Changed to new SS request"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <string name="notification_alerted_content_description" msgid="1296617716556420585">"Alerted"</string>
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expand"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"toggle expansion"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 254d6bb..c51e1aa 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Llamada por Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivada"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Red Wi-Fi preferida"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Red móvil preferida"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que la aplicación acceda a comandos adicionales del proveedor de ubicación. Esto puede permitirle a la aplicación interferir con el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"acceder a la ubicación exacta solo en primer plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Esta app puede obtener tu ubicación exacta solo cuando está en primer plano. Los servicios de ubicación deben estar activados y disponibles en el teléfono para que la app pueda usarlos. Es posible que aumente el consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"acceder a la ubicación aproximada (según la red)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Esta app puede obtener tu ubicación a través de fuentes de red, como torres de telefonía móvil y redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu tablet para que la app pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Esta app puede obtener tu ubicación a través de fuentes de red, telefonía móvil y redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu TV para que la app pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Esta app puede obtener tu ubicación a través de fuentes de red, como torres de celulares y redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu teléfono para que la app pueda usarlos."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"acceso a la ubicación aproximada (mediante red) solo en primer plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu tablet para que la app pueda usarlos."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu TV para que la app pueda usarlos."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esta app puede obtener tu ubicación desde fuentes de red, como torres de telefonía celular y redes Wi-Fi, pero solo en primer plano. Los servicios de ubicación deben estar activados y disponibles en tu teléfono para que la app pueda usarlos."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"acceder a la ubicación en segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Si este permiso se otorga de manera adicional para aproximar o precisar el acceso a la ubicación, la app podrá acceder a la ubicación mientras se ejecuta en segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"cambiar tu configuración de audio"</string>
@@ -643,11 +651,11 @@
<string name="permlab_access_notification_policy" msgid="4247510821662059671">"Acceso a la función No interrumpir"</string>
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Permite que la aplicación lea y modifique la configuración de la función No interrumpir."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
- <string name="policydesc_limitPassword" msgid="2502021457917874968">"Permite controlar la longitud y los caracteres permitidos en las contraseñas y los PIN para el bloqueo de pantalla."</string>
+ <string name="policydesc_limitPassword" msgid="2502021457917874968">"Controlar la longitud y los caracteres permitidos en las contraseñas y los PIN para el bloqueo de pantalla."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Supervisa los intentos para desbloquear la pantalla"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Controla la cantidad de contraseñas incorrectas ingresadas al desbloquear la pantalla y bloquea la tablet o borra todos los datos de la tablet si se ingresaron demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Permite controlar la cantidad de contraseñas incorrectas que se escriben al desbloquear la pantalla y permite bloquear la TV o borrar todos los datos de la TV si se escriben demasiadas contraseñas incorrectas."</string>
- <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Controla la cantidad de contraseñas ingresadas incorrectamente al desbloquear la pantalla y bloquea el dispositivo o borra todos sus datos si se ingresan demasiadas contraseñas incorrectas."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Supervisar la cantidad de contraseñas ingresadas incorrectamente al desbloquear la pantalla, y bloquear el dispositivo o borrar todos sus datos si se ingresan demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Permite controlar la cantidad de contraseñas incorrectas que se escriben al desbloquear la pantalla y bloquear la tablet, o borrar todos los datos del usuario, si se ingresan demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Permite controlar la cantidad de contraseñas incorrectas que se escriben al desbloquear la pantalla y bloquear la televisión, o borrar todos los datos del usuario, si se ingresan demasiadas contraseñas incorrectas."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Permite controlar la cantidad de contraseñas incorrectas que se escriben al desbloquear la pantalla y bloquear el teléfono, o borrar todos los datos del usuario, si se ingresan demasiadas contraseñas incorrectas."</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Se cambió la solicitud SS por una solicitud USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Se cambió a una nueva solicitud SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabajo"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expandir"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Contraer"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"activar o desactivar la expansión"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 2472e2b..a7ec220 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi‑Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Llamada por Wi‑Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWiFi de <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Dar preferencia a Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferir datos móviles"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que la aplicación acceda a otros comandos del proveedor de ubicación. De esta forma, la aplicación podrá interferir en el funcionamiento del GPS o de otras fuentes de ubicación."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"acceder a la ubicación exacta solo en primer plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Esta aplicación solo puede obtener tu ubicación exacta cuando está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en tu teléfono para que la aplicación pueda utilizarlos. Es posible que aumente el consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"acceder a tu ubicación aproximada (basada en red)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu tablet para que la aplicación pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu TV para que la aplicación pueda usarlos."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi-Fi. Estos servicios de ubicación deben estar activados y disponibles en tu teléfono para que la aplicación pueda usarlos."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"acceder a la ubicación aproximada (a partir de la red) solo en primer plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en el tablet para que la aplicación pueda usarlos."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en la TV para que la aplicación pueda usarlos."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esta aplicación puede obtener tu ubicación a partir de fuentes de red como las antenas de telefonía móvil y las redes Wi‑Fi, pero únicamente si la aplicación está en primer plano. Estos servicios de ubicación deben estar activados y disponibles en el teléfono para que la aplicación pueda usarlos."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"acceder a la ubicación en segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Si se concede este permiso además del acceso a la ubicación exacta o aproximada, la aplicación podrá acceder a la ubicación mientras se ejecuta en segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"cambiar la configuración de audio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Se ha cambiado la solicitud de SS a una solicitud de USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Se ha cambiado a una nueva solicitud de SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabajo"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Mostrar"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Ocultar"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"alternar mostrar y ocultar"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index b77b772..05486c2 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>: WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi-kõne | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>: VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Väljas"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"WiFi eelistusega"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Eelistatud on mobiilne andmeside"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Võimaldab rakendusel juurde pääseda asukohapakkuja erikäskudele. See võib lubada rakendusel mõjutada GPS-i või muude asukohaallikate tööd."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"juurdepääs täpsele asukohale ainult esiplaanil"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"See rakendus hangib teie täpse asukoha ainult siis, kui see töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie telefonis saadaval, et rakendus saaks neid kasutada. See võib suurendada akutoite tarbimist."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"juurdepääs ligikaudsele asukohale (võrgupõhine)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta. Need asukohateenused peavad olema sisse lülitatud ja teie tahvelarvutis saadaval, et rakendus neid kasutada saaks."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta. Need asukohateenused peavad olema sisse lülitatud ja teie teleris saadaval, et rakendus neid kasutada saaks."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta. Need asukohateenused peavad olema sisse lülitatud ja teie telefonis saadaval, et rakendus neid kasutada saaks."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"pääseda juurde ligikaudsele asukohale (võrgupõhiselt) ainult esiplaanil"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie tahvelarvutis saadaval, et rakendus saaks neid kasutada."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie teleris saadaval, et rakendus saaks neid kasutada."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"See rakendus näeb võrguallikate (nt mobiilimastid ja WiFi-võrgud) abil teie asukohta, kuid ainult siis, kui rakendus töötab esiplaanil. Need asukohateenused peavad olema sisse lülitatud ja teie telefonis saadaval, et rakendus saaks neid kasutada."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"juurdepääs asukohale taustal"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Kui see on antud ka umbkaudsele või täpsele asukohale juurdepääsu puhul, saab rakendus taustal käitamisel juurdepääsu asukohale."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuda heliseadeid"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-taotlus muudeti USSD-taotluseks"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Muudeti uueks SS-taotluseks"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Tööprofiil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Laienda"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Ahenda"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"vaheta laiendamist"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 26d8b31..b301568b 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi bidezko deiak | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desaktibatuta"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi sarea hobesten da"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datu-konexioa hobesten da"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Kokapen-hornitzailearen agindu gehigarriak atzitzea baimentzen die aplikazioei. Horrela, agian aplikazioek GPSaren edo bestelako kokapenaren iturburuen funtzionamenduan eragina izan dezakete."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"lortu kokapen zehatza aurreko planoan bakarrik"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Aplikazioak zure kokapen zehatza lor dezake aurreko planoan funtzionatzen duenean bakarrik. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan. Baliteke bateria gehiago erabiltzea."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"atzitu gutxi gorabeherako kokapena (sarean oinarrituta)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Aplikazioak zure kokapenaren berri izan dezake sareen iturburuak (adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak) erabilita. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu tabletan, aplikazioak erabil ditzan."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Aplikazioak zure kokapenaren berri izan dezake sareen iturburuak (adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak) erabilita. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telebistan, aplikazioak erabil ditzan."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Aplikazioak zure kokapenaren berri izan dezake sareen iturburuak (adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak) erabilita. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Atzitu sarean oinarritutako gutxi gorabeherako kokapena aurreko planoan bakarrik"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu tabletan, aplikazioak erabil ditzan."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telebistan, aplikazioak erabil ditzan."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aplikazioa aurreko planoan dagoenean, zure kokapenaren berri izan dezake sareen iturburuak erabilita; adibidez, telefonia mugikorreko dorreak eta Wi-Fi sareak. Kokapen-zerbitzu horiek aktibatuta eta erabilgarri izan behar dituzu telefonoan, aplikazioak erabil ditzan."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"Atzitu kokapena atzeko planoan"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Baimen hau ematen bada kokapen zehatz edo gutxi gorabeherakorako sarbideaz gain, atzeko planoan exekutatu bitartean atzitu ahalko du aplikazioak kokapena."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"aldatu audio-ezarpenak"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS eskaera USSD eskaerara aldatu da"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"SS eskaera berrira aldatu da"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profila"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Zabaldu"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Tolestu"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"zabaldu edo tolestu"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 2d6c2ef..00a86ce 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"درحال تماس ازطریق WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"خاموش"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ترجیحی"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"داده شبکه تلفن همراه ارجح است"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"به برنامه اجازه میدهد به دستورات ارائهدهنده مکان تکمیلی دسترسی داشته باشد. این کار ممکن است به برنامه امکان دهد با کارکرد GPS یا منابع دیگر مکان تداخل داشته باشد."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"دسترسی به مکان دقیق فقط در پیشزمینه"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"این برنامه فقط زمانی میتواند موقعیت مکانی دقیق شما را دریافت کند که در پیشزمینه باشد. برای اینکه برنامه بتواند از خدمات مکان استفاده کند، این خدمات باید در تلفنتان روشن و دردسترس باشد. ممکن است با این کار مصرف باتری افزایش یابد."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"دسترسی به مکان تقریبی (مبتنی بر شبکه)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکان شما را تشخیص دهد. این خدمات مکان باید روشن و در رایانه لوحی شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکان شما را تشخیص دهد. این خدمات مکان باید روشن و در تلویزیون شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکان شما را تشخیص دهد. این خدمات مکان باید روشن و در تلفن شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"دسترسی به مکان تقریبی (مبتنی بر شبکه) فقط در پیشزمینه"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه باشد. این خدمات مکان باید روشن و در رایانه لوحی شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه باشد. این خدمات مکان باید روشن و در تلویزیون شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"این برنامه میتواند براساس منابع شبکه مانند دکلهای مخابراتی و شبکههای Wi-Fi، مکانتان را تشخیص دهد، اما فقط درصورتیکه برنامه در پیشزمینه است. این خدمات مکان باید روشن و در تلفن شما دردسترس باشند تا برنامه بتواند از آنها استفاده کند."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"دسترسی به مکان در پسزمینه"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"اگر این مجوز نیز برای دسترسی دقیق یا تقریبی به مکان داده شود، برنامه میتواند درحین اجرا در پسزمینه به مکان دسترسی پیدا کند."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"تغییر تنظیمات صوتی"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"درخواست SS به درخواست USSD تغییر کرد"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"به درخواست SS جدید تغییر کرد"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"نمایه کاری"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"بزرگ کردن"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"کوچک کردن"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"روشن/خاموش کردن بزرگنمایی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 39c4912..7fc02df 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-puhelut | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ei käytössä"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ensisijainen"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobiiliverkko ensisijainen"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Antaa sovelluksen käyttää ylimääräisiä sijaintipalvelukomentoja. Sovellus saattaa tällöin häiritä GPS:n tai muiden sijaintilähteiden toimintaa."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"käyttää tarkkaa sijaintia vain etualalla"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Tämä sovellus saa tarkat sijaintitietosi käyttöönsä vain etualalla. Näiden sijaintipalveluiden tulee olla käytössä ja käytettävissä puhelimellasi, jotta sovellus voi käyttää niitä. Tämä voi lisätä akun kulutusta."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"käyttää likimääräistä sijaintia (verkkopohjainen)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella. Näiden sijaintipalveluiden tulee olla käytössä ja käytettävissä tabletillasi, jotta sovellus voi käyttää niitä."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella. Näiden sijaintipalveluiden tulee olla käytössä ja käytettävissä TV:lläsi, jotta sovellus voi käyttää niitä."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella. Näiden sijaintipalveluiden tulee olla käytössä ja käytettävissä puhelimellasi, jotta sovellus voi käyttää niitä."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"käyttää karkeaa verkkoon perustuvaa sijaintia vain etualalla"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä tabletilla, jotta sovellus voi käyttää niitä."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä televisiossa, jotta sovellus voi käyttää niitä."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Tämä sovellus voi määrittää sijaintisi matkapuhelinverkon tukiasemien, Wi-Fi-verkkojen ja muiden verkkolähteiden perusteella vain jos sovellus on etualalla. Näiden sijaintipalveluiden tulee olla päällä ja käytettävissä puhelimessa, jotta sovellus voi käyttää niitä."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"käytä sijaintia taustalla"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Jos tämä myönnetään karkean tai tarkan sijainnin käyttöoikeuden lisäksi, sovellus voi käyttää sijaintia toimiessaan taustalla."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"muuta ääniasetuksia"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-pyyntö vaihdettu USSD-pyynnöksi"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Vaihdettu uudeksi SS-pyynnöksi"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Työprofiili"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Laajenna"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Tiivistä"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Laajenna/tiivistä painikkeella"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index a03f25f..b58a051 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Appels Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Voix par Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Réseau Wi-Fi de préférence"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Connexion cellulaire de préférence"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"accéder à votre position précise seulement en avant-plan"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Cette application peut obtenir votre position exacte seulement lorsqu\'elle fonctionne en avant-plan. Ces services de localisation doivent être activés et accessibles sur votre téléviseur pour que l\'application puisse les utiliser. Cela peut entraîner une utilisation accrue de la pile."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"accéder à votre position approximative (réseau)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi. Ces services de localisation doivent être activés et accessibles sur votre tablette pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi. Ces services de localisation doivent être activés et accessibles sur votre téléviseur pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi. Ces services de localisation doivent être activés et accessibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"accéder à la position approximative (selon les données réseau), mais uniquement lorsque l\'application s\'exécute au premier plan"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre tablette pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre téléviseur pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Cette application peut déterminer votre position à l\'aide de différentes sources de localisation sur le réseau, comme les tours de téléphonie cellulaire et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et accessibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"accès à la localisation en arrière-plan"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Si cette autorisation est accordée en plus de l\'accès approximatif ou précis à la localisation, alors l\'application peut accéder à la localisation lorsqu\'elle fonctionne en arrière-plan."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifier vos paramètres audio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"La demande SS a été remplacée par une demande USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"La demande a été remplacée par une nouvelle demande SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil professionnel"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Développer"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Réduire"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"activer/désactiver le développement"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 5e9d5c1..6f9e0bc 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Appels Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWiFi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Désactivé"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi de préférence"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Données mobiles de préférence"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permet à l\'application d\'accéder à des commandes de localisation supplémentaires offertes par le fournisseur. Elle est ainsi susceptible d\'interférer avec le bon fonctionnement du GPS ou de toute autre source de localisation."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"accéder à la position exacte au premier plan uniquement"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Cette application peut obtenir votre position exacte uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre téléphone pour que l\'application puisse les utiliser. Ceci peut réduire l\'autonomie de la batterie."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"accéder à votre position approximative (selon le réseau)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Cette application peut obtenir votre position via des sources de réseau telles que les antennes-relais et les réseaux Wi-Fi. Ces services de localisation doivent être activés et disponibles sur votre tablette pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Cette application peut obtenir votre position via des sources de réseau telles que les antennes-relais et les réseaux Wi-Fi. Ces services de localisation doivent être activés et disponibles sur votre téléviseur pour que l\'application puisse les utiliser."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Cette application peut obtenir votre position via des sources de réseau telles que les antennes-relais et les réseaux Wi-Fi. Ces services de localisation doivent être activés et disponibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"accéder à la position approximative (à l\'aide des réseaux) au premier plan uniquement"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre tablette pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre téléviseur pour que l\'application puisse les utiliser."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Cette application peut obtenir votre position à l\'aide de sources de réseau telles que les antennes-relais et les réseaux Wi-Fi, mais uniquement lorsqu\'elle s\'exécute au premier plan. Ces services de localisation doivent être activés et disponibles sur votre téléphone pour que l\'application puisse les utiliser."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"accéder à la position en arrière-plan"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Si vous lui accordez cette autorisation en plus de l\'accès à la position approximative ou précise, l\'application peut accéder à votre position lorsqu\'elle est s\'exécute en arrière-plan."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifier vos paramètres audio"</string>
@@ -665,13 +673,13 @@
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Effacer les informations sur cet utilisateur de ce téléphone sans avertissement"</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Définir le proxy global du mobile"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Indiquer le proxy global à utiliser pour l\'appareil lorsque la règle est activée. Seul le propriétaire de l\'appareil peut définir le proxy global."</string>
- <string name="policylab_expirePassword" msgid="5610055012328825874">"Config. expir. mot passe verr. écran"</string>
+ <string name="policylab_expirePassword" msgid="5610055012328825874">"Définir l\'expiration du mot de passe de verrouillage d\'écran"</string>
<string name="policydesc_expirePassword" msgid="5367525762204416046">"Modifier la fréquence de modification du mot de passe, du code d\'accès ou du schéma de verrouillage de l\'écran"</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Définir chiffrement du stockage"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Exiger le chiffrement des données d\'application stockées"</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Désactiver les appareils photo"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"Empêcher l\'utilisation de tous les appareils photos"</string>
- <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Désact. options du verr. écran"</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Désactiver les options de verrouillage de l\'écran"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Empêcher l\'utilisation de certaines fonctionnalités du verrouillage de l\'écran."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Domicile"</item>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Requête SS transformée en requête USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Remplacement par une nouvelle requête SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil professionnel"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Développer"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Réduire"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"activer/désactiver le développement"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index d522b53..7f5a244 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi de <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamadas por wifi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desactivado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wifi preferida"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Datos móbiles preferidos"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite á aplicación acceder a comandos adicionais de fornecedor de localizacións. É posible que isto provoque que a aplicación interfira co funcionamento do GPS ou doutras fontes da localización."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"acceder á localización exacta só en primeiro plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Esta aplicación pode obter a túa localización exacta só cando se atope en primeiro plano. É necesario activar estes servizos de localización e deben estar dispoñibles no teléfono para que a aplicación poida utilizalos. Ademais, poden supoñer un aumento do consumo de batería."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"acceder á localización aproximada (baseada na rede)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Esta aplicación pode obter a túa localización a partir de fontes de rede como torres de telecomunicacións e redes wifi. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles na túa tableta."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Esta aplicación pode obter a túa localización a partir de fontes de rede como torres de telecomunicacións e redes wifi. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles na túa televisión."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Esta aplicación pode obter a túa localización a partir de fontes de rede como torres de telecomunicacións e redes wifi. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles no teu teléfono."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"acceder á localización aproximada a partir de fontes de rede só en primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como torres de telecomunicacións e redes wifi, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles na túa tableta."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como torres de telecomunicacións e redes wifi, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles na túa televisión."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esta aplicación pode obter a túa localización a partir de fontes de rede, como torres de telecomunicacións e redes wifi, pero só mentres está en primeiro plano. Para que a aplicación poida utilizar os servizos de localización, deben estar activados e dispoñibles no teu teléfono."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"acceder á localización en segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se a aplicación ten acceso á localización aproximada ou exacta e lle concedes este permiso, poderá consultar onde te atopas cando estea en segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"cambiar a configuración de son"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"A solicitude SS transformouse nunha solicitude USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Transformouse nunha nova solicitude SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de traballo"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Despregar"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Contraer"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"alterna a expansión"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 9e9c21e..5f98ff2 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> વાઇ-ફાઇ"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"વાઇ-ફાઇ કૉલિંગ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"બંધ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"વાઇ-ફાઇ પસંદ કર્યું"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"મોબાઇલને પસંદગી"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"એપ્લિકેશનને વધારાના સ્થાન પ્રદાતા આદેશોને ઍક્સેસ કરવાની મંજૂરી આપે છે. આ એપ્લિકેશનને GPS અથવા અન્ય સ્થાન સ્રોતોના ઓપરેશનમાં દખલ કરવાની મંજૂરી આપી શકે છે."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ફૉરગ્રાઉન્ડમાં ફક્ત ચોક્કસ સ્થાન ઍક્સેસ કરો"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"આ ઍપ ફક્ત બૅકગ્રાઉન્ડમાં હોય ત્યારે જ તમારું ચોક્કસ સ્થાન મેળવી શકે છે. ઍપ આ સ્થાન સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ફોન પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે. આ બૅટરી વપરાશ વધારી શકે છે."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"અંદાજિત સ્થાન ઍક્સેસ કરો (નેટવર્ક-આધારિત)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટેબ્લેટ પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ટીવી પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"આ ઍપ્લિકેશન, સેલ ટાવર્સ અને વાઇ-ફાઇ નેટવર્ક્સ જેવા નેટવર્ક સ્રોતોના આધારે તમારું સ્થાન મેળવી શકે છે. ઍપ્લિકેશન દ્વારા આ સ્થાન સેવાઓનો ઉપયોગ કરવામાં સમર્થ થવા માટે તમારા ફોન પર આ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"અંદાજિત જગ્યાને (નેટવર્ક આધારિત) માત્ર ફૉરગ્રાઉન્ડમાંથી ઍક્સેસ કરો"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ અૅપ તમારી જગ્યા જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ અૅપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ જગ્યાની સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ટૅબ્લેટ પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ અૅપ તમારી જગ્યા જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ અૅપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ જગ્યાની સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ટીવી પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"સેલ ટાવર અને વાઇ-ફાઇ નેટવર્ક જેવા નેટવર્ક સૉર્સનો ઉપયોગ કરીને આ અૅપ તમારી જગ્યા જાણી શકે છે, પરંતુ આ માત્ર ત્યારે શક્ય છે જ્યારે આ અૅપ ફૉરગ્રાઉન્ડમાં ચાલુ હોય. ઍપ આ જગ્યાની સેવાઓનો ઉપયોગ કરી શકે તે માટે તમારા ફોન પર આ સેવાઓ ઉપલબ્ધ અને ચાલુ હોવી આવશ્યક છે."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"બૅકગ્રાઉન્ડમાં સ્થાન ઍક્સેસ કરો"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"જો અંદાજિત અથવા ચોક્કસ સ્થાનના ઍક્સેસ ઉપરાંત આને પરવાનગી આપવામાં આવી હશે, તો ઍપ બૅકગ્રાઉન્ડમાં ચાલતી હોય ત્યારે સ્થાનને ઍક્સેસ કરી શકશે."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"તમારી ઑડિઓ સેટિંગ્સ બદલો"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS વિનંતીને USSD વિનંતીમાં બદલવામાં આવી છે"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"નવી SS વિનંતીમાં બદલવામાં આવી છે"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"કાર્યાલયની પ્રોફાઇલ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"વિસ્તૃત કરો"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"સંકુચિત કરો"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"વિસ્તરણ ટૉગલ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 87b35c9..92e3ae5 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाई-फ़ाई"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"वाई-फ़ाई कॉलिंग | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाई-फ़ाई को प्राथमिकता"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"मोबाइल को प्राथमिकता"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ऐप को कुछ और जगह की जानकारी देने वाले आदेशों की पहुंच पाने देता है. इससे ऐप जीपीएस या जगह की जानकारी देने वाले दूसरे स्रोतों के काम में रोक-टोक कर सकता है."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ऐप्लिकेशन \'जगह की सटीक जानकारी\' सिर्फ़ सामने खुली होने पर एक्सेस करे"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"यह ऐप्लिकेशन सिर्फ़ तब आपकी \'जगह की सटीक जानकारी\' का इस्तेमाल कर सकता है जब यह स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके फ़ोन में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए. ऐसा करने से ज़्यादा बैटरी खर्च हो सकती है."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अनुमानित जगह की पहुंच दें (नेटवर्क-आधारित)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके टैबलेट पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके टीवी पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"यह ऐप सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क के स्रोतों के आधार पर आपकी जगह का पता कर सकता है. ये जगह की जानकारी आपके फ़ोन पर चालू और मौजूद होनी चाहिए ताकि ऐप उनका इस्तेमाल कर सके."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"स्क्रीन पर दिखाई देते समय \'जगह की अनुमानित जानकारी\' (नेटवर्क-आधारित) एक्सेस करें"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"यह ऐप्लिकेशन सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपकी जगह का पता लगा सकता है, लेकिन सिर्फ़ तब जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके टैबलेट में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"यह ऐप्लिकेशन सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपकी जगह का पता लगा सकता है, लेकिन सिर्फ़ तब जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके टीवी पर मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"यह ऐप्लिकेशन सेल टावर और वाई-फ़ाई नेटवर्क जैसे नेटवर्क स्रोतों के आधार पर आपकी जगह का पता लगा सकता है, लेकिन सिर्फ़ तब, जब ऐप्लिकेशन स्क्रीन पर दिखाई दे रहा हो. यह ज़रूरी है कि \'जगह की जानकारी\' वाली ये सेवाएं आपके फ़ोन में मौजूद हों और चालू की गई हों ताकि ऐप्लिकेशन उनका इस्तेमाल कर पाए."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"बैकग्राउंड में जगह की जानकारी एक्सेस करना"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"अनुमानित या बिल्कुल सही जगह की जानकारी का एक्सेस करने की अनुमति अलग से दिए जाने पर, बैकग्राउंड में चलने के दौरान ऐप्लिकेशन आपकी जगह की जानकारी एक्सेस कर सकता है."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"अपनी ऑडियो सेटिंग बदलें"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"एसएस कोड चलाने के अनुरोध को यूएसएसडी कोड चलाने के अनुरोध में बदला गया"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"एसएस कोड चलाने के नए अनुरोध में बदला गया"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफ़ाइल"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"विस्तार करें"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"छोटा करें"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"टॉगल विस्तार"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 7b24bba..7e581a20 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi pozivi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednost ima Wi-Fi mreža"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Za mobilne uređaje"</string>
@@ -222,7 +230,7 @@
<string name="global_actions" product="default" msgid="2406416831541615258">"Opcije telefona"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Zaključavanje zaslona"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"Isključi"</string>
- <string name="global_action_emergency" msgid="7112311161137421166">"Hitno"</string>
+ <string name="global_action_emergency" msgid="7112311161137421166">"Hitne službe"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"Izvješće o bugovima"</string>
<string name="global_action_logout" msgid="935179188218826050">"Završi sesiju"</string>
<string name="global_action_screenshot" msgid="8329831278085426283">"Snimka zaslona"</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Omogućuje aplikaciji pristup dodatnim naredbama davatelja usluga lokacije. To može omogućiti aplikaciji ometanje rada GPS-a ili drugih izvora lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"pristupiti preciznoj lokaciji samo u prednjem planu"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Aplikacija može dobiti vašu točnu lokaciju samo kada je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na telefonu da bi ih aplikacija mogla upotrebljavati. To može pojačati potrošnju baterije."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"pristupati približnoj lokaciji (na temelju mreža)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Aplikacija može dohvatiti vašu lokaciju putem mrežnih izvora poput baznih stanica i Wi-Fi mreža. Te usluge lokacije moraju biti uključene i dostupne na tabletu da bi ih aplikacija mogla upotrebljavati."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Aplikacija može dohvatiti vašu lokaciju putem mrežnih izvora poput baznih stanica i Wi-Fi mreža. Te usluge lokacije moraju biti uključene i dostupne na televizoru da bi ih aplikacija mogla upotrebljavati."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Aplikacija može dohvatiti vašu lokaciju putem mrežnih izvora poput baznih stanica i Wi-Fi mreža. Te usluge lokacije moraju biti uključene i dostupne na telefonu da bi ih aplikacija mogla upotrebljavati."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"pristupiti približnoj lokaciji (na temelju mreže) samo u prednjem planu"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem tabletu da bi ih aplikacija mogla upotrebljavati."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem televizoru da bi ih aplikacija mogla upotrebljavati."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ova aplikacija može dobiti vašu lokaciju na temelju mrežnih izvora kao što su bazne stanice i Wi-Fi mreže, no samo kad je u prednjem planu. Te usluge lokacije moraju biti uključene i dostupne na vašem telefonu da bi ih aplikacija mogla upotrebljavati."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"pristup lokaciji u pozadini"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ako se ovo odobrava dodatno za pristup približnoj ili preciznoj lokaciji, aplikacija može pristupiti lokaciji tijekom rada u pozadini."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"promjena postavki zvuka"</string>
@@ -805,7 +813,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Pritisnite Izbornik za otključavanje ili pozivanje hitnih službi."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Pritisnite Izbornik za otključavanje."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Iscrtajte uzorak za otključavanje"</string>
- <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitno"</string>
+ <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Hitne službe"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Uzvrati poziv"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Ispravno!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Pokušajte ponovo"</string>
@@ -1858,6 +1866,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS zahtjev promijenjen je u USSD zahtjev"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Promijenjeno u novi SS zahtjev"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Radni profil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Proširivanje"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Sažimanje"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"promjena proširenja"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index b02b68b..41bf09b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-hívás | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Ki"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi előnyben részesítve"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferált: mobil"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Lehetővé teszi az alkalmazás számára további helyszolgáltatói parancsok elérését. Ezáltal az alkalmazás beavatkozhat a GPS vagy más helyforrások működésébe."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"pontos helyadatokhoz való hozzáférés csak előtérben"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ez az alkalmazás csak akkor férhet hozzá az eszköz pontos helyadataihoz, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a telefonon ahhoz, hogy az alkalmazás használhassa őket. Ez növelheti az akkumulátorhasználatot."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"hozzáférés a hozzávetőleges (hálózatalapú) helyadatokhoz"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Az alkalmazás hozzáférhet hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz. A helyszolgáltatásoknak bekapcsolt és elérhető állapotban kell lenniük a táblagépen ahhoz, hogy az alkalmazás használhassa őket."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Az alkalmazás hozzáférhet hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz. A helyszolgáltatásoknak bekapcsolt és elérhető állapotban kell lenniük a TV-n ahhoz, hogy az alkalmazás használhassa őket."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Az alkalmazás hozzáférhet hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz. A helyszolgáltatásoknak bekapcsolt és elérhető állapotban kell lenniük a telefonon ahhoz, hogy az alkalmazás használhassa őket."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"hozzávetőleges (hálózaton alapuló) helyadatokhoz való hozzáférés csak előtérben"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a táblagépen ahhoz, hogy az alkalmazás használhassa őket."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a tévén ahhoz, hogy az alkalmazás használhassa őket."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ez az alkalmazás hozzáférhet a hálózati forrásokon (például az adótornyokon és a Wi-Fi-hálózatokon) alapuló helyadataihoz, de csak akkor, amikor az előtérben fut. A helyszolgáltatásoknak bekapcsolt és hozzáférhető állapotban kell lenniük a telefonon ahhoz, hogy az alkalmazás használhassa őket."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"Hozzáférés a helyadatokhoz a háttérben"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ha engedélyezi ezt a hozzávetőleges vagy pontos helyadatokhoz való hozzáférés mellett, akkor az alkalmazás hozzáférhet a helyadatokhoz, miközben a háttérben fut."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"hangbeállítások módosítása"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Az SS-kérés módosítva USSD-kérésre"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Új SS-kérésre módosítva"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Munkaprofil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Kibontás"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Összecsukás"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"kibontás be- és kikapcsolása"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 90ab955..30721cf 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Զանգեր Wi-Fi-ի միջոցով | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Անջատված է"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi, նախընտրելի"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Նախընտրելի է բջջային ցանցը"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ծրագրին թույլ է տալիս օգտագործել տեղադրության մասին տվյալների աղբյուրների կառավարման լրացուցիչ հրահանգներ: Սա կարող է ծրագրին թույլ տալ միջամտել GPS-ի կամ տեղադրության մասին տվյալների այլ աղբյուրների գործառույթներին:"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"Տեղադրության ճշգրիտ տվյալների հասանելիություն միայն ֆոնային ռեժիմում"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ֆոնային ռեժիմում։ Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք: Սա կարող է արագացնել մարտկոցի լիցքի սպառումը:"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"օգտագործել մոտավոր տեղադրությունը (ցանցային)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր պլանշետում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռուստացույցում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Մոտավոր տեղադրությունը (ցանցային) հասանելի է միայն ֆոնային ռեժիմում"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր պլանշետում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռուստացույցում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Այս հավելվածը կարող է ստանալ ձեր տեղադրության տվյալները ցանցային տարբեր աղբյուրներից, օրինակ՝ բջջային աշտարակներից և Wi-Fi ցանցերից, սակայն միայն երբ հավելվածն աշխատում է ֆոնային ռեժիմում: Այս տեղորոշման ծառայությունները պետք է միացված և հասանելի լինեն ձեր հեռախոսում, որպեսզի հավելվածը կարողանա օգտագործել դրանք:"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"տեղադրության մասին տվյալների հասանելիություն ֆոնային ռեժիմում"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Եթե բացի մոտավոր կամ ճշգրիտ տեղորոշման տվյալների հասանելիությունից հավելվածին տրամադրեք այս թույլտվությունը, հավելվածին տեղադրության մասին տվյալները հասանելի կլինեն ֆոնային ռեժիմում։"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"փոխել ձեր աուդիո կարգավորումները"</string>
@@ -1139,8 +1147,8 @@
<string name="noApplications" msgid="2991814273936504689">"Ոչ մի հավելված չի կարող կատարել այս գործողությունը:"</string>
<string name="aerr_application" msgid="250320989337856518">"<xliff:g id="APPLICATION">%1$s</xliff:g> – աշխատանքն ընդհատվեց"</string>
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացն ընդհատվել է"</string>
- <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածի աշխատանքը շարունակաբար ընդհատվում է"</string>
- <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը շարունակաբար ընդհատվում է"</string>
+ <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g>-ն էլի ընդհատվեց"</string>
+ <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g>՝ նորից ընդհատվեց"</string>
<string name="aerr_restart" msgid="7581308074153624475">"Կրկին բացել հավելվածը"</string>
<string name="aerr_report" msgid="5371800241488400617">"Հաղորդել"</string>
<string name="aerr_close" msgid="2991640326563991340">"Փակել"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS հարցումը փոխվել է USSD հարցման"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Փոխվել է նոր SS հարցման"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Աշխատանքային պրոֆիլ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Ընդարձակել"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Կոծկել"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Կոծկել/Ընդարձակել"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 924b264..49c80d7 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Panggilan WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Nonaktif"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi dipilih"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Seluler dipilih"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Memungkinkan aplikasi mengakses perintah penyedia lokasi ekstra. Tindakan ini memungkinkan aplikasi mengganggu pengoperasian GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"akses lokasi pasti hanya saat di latar depan"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Aplikasi ini bisa mendapatkan lokasi pasti Anda ketika aplikasi berada di latar depan. Fitur layanan lokasi ini harus diaktifkan dan tersedia di ponsel agar dapat digunakan oleh aplikasi. Fitur ini dapat meningkatkan konsumsi baterai."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"akses perkiraan lokasi (berbasis jaringan)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Aplikasi ini dapat memperoleh lokasi Anda berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi. Layanan lokasi ini harus diaktifkan dan tersedia di tablet agar aplikasi dapat menggunakannya."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Aplikasi ini dapat memperoleh lokasi Anda berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi. Layanan lokasi ini harus diaktifkan dan tersedia di TV agar aplikasi dapat menggunakannya."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Aplikasi ini dapat memperoleh lokasi Anda berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi. Layanan lokasi ini harus diaktifkan dan tersedia di ponsel agar aplikasi dapat menggunakannya."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"akses perkiraan lokasi (berbasis jaringan) hanya di latar depan"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Aplikasi ini dapat mengetahui lokasi berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, namun hanya jika aplikasi berada di latar depan. Layanan lokasi tersebut harus diaktifkan dan tersedia di tablet agar aplikasi dapat menggunakannya."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aplikasi ini dapat mengetahui lokasi berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, namun hanya jika aplikasi berada di latar depan. Layanan lokasi tersebut harus diaktifkan dan tersedia di TV agar aplikasi dapat menggunakannya."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aplikasi ini dapat mengetahui lokasi berdasarkan sumber jaringan seperti menara seluler dan jaringan Wi-Fi, namun hanya jika aplikasi berada di latar depan. Layanan lokasi tersebut harus diaktifkan dan tersedia di ponsel agar aplikasi dapat menggunakannya."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"akses lokasi di latar belakang"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Jika aplikasi diberi izin tambahan ke akses lokasi perkiraan atau akurat, aplikasi dapat mengakses lokasi saat bekerja di latar belakang."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ubah setelan audio Anda"</string>
@@ -644,19 +652,19 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Mengizinkan aplikasi membaca dan menulis konfigurasi status Jangan Ganggu."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Mengontrol panjang dan karakter yang diizinkan dalam sandi dan PIN kunci layar."</string>
- <string name="policylab_watchLogin" msgid="5091404125971980158">"Memantau upaya pembukaan kunci layar"</string>
- <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Memantau jumlah sandi yang salah ketik saat membuka kunci layar, dan mengunci tablet atau menghapus semua data tablet jika sandi yang salah ketik terlalu banyak."</string>
- <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Memantau banyaknya sandi salah yang diketikkan saat membuka kunci layar, dan mengunci TV atau menghapus semua data TV jika terlalu banyak sandi salah diketikkan."</string>
- <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Memantau jumlah sandi salah ketik saat membuka kunci layar, dan mengunci ponsel atau menghapus semua data ponsel jika sandi yang salah ketik terlalu banyak."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Memantau banyaknya sandi salah yang diketikkan saat membuka kunci layar, dan mengunci tablet atau menghapus semua data pengguna ini jika terlalu banyak sandi salah diketikkan."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Memantau banyaknya sandi salah yang diketikkan saat membuka kunci layar, dan mengunci TV atau menghapus semua data pengguna ini jika terlalu banyak sandi salah diketikkan."</string>
- <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Memantau banyaknya sandi salah yang diketikkan saat membuka kunci layar, dan mengunci ponsel atau menghapus semua data pengguna ini jika terlalu banyak sandi salah diketikkan."</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Pantau upaya pembukaan kunci layar"</string>
+ <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci tablet atau menghapus semua data tablet jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
+ <string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci TV atau menghapus semua data TV jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
+ <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci ponsel atau menghapus semua data ponsel jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci tablet atau menghapus semua data pengguna ini jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci TV atau menghapus semua data pengguna ini jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
+ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Memantau berapa kali sandi yang dimasukkan salah saat ingin membuka kunci layar, dan mengunci ponsel atau menghapus semua data pengguna ini jika terjadi terlalu banyak kesalahan memasukkan sandi."</string>
<string name="policylab_resetPassword" msgid="4934707632423915395">"Mengubah kunci layar"</string>
<string name="policydesc_resetPassword" msgid="1278323891710619128">"Mengubah kunci layar."</string>
<string name="policylab_forceLock" msgid="2274085384704248431">"Mengunci layar"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"Mengontrol cara dan kapan layar mengunci."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"Menghapus semua data"</string>
- <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Hapus data tablet tanpa peringatan dengan menyetel ulang data pabrik."</string>
+ <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Menghapus data tablet tanpa peringatan dengan mereset ke setelan pabrik."</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Menghapus data TV tanpa peringatan dengan mengembalikan ke setelan pabrik."</string>
<string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Menghapus data ponsel tanpa peringatan dengan melakukan reset ke setelan pabrik."</string>
<string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Menghapus data pengguna"</string>
@@ -665,13 +673,13 @@
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Menghapus data pengguna ini di ponsel ini tanpa peringatan."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Setel proxy global perangkat"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Menyetel proxy global perangkat yang akan digunakan jika kebijakan diaktifkan. Hanya pemilik perangkat yang dapat menyetel proxy global."</string>
- <string name="policylab_expirePassword" msgid="5610055012328825874">"Menyetel berakhirnya sandi kunci layar"</string>
+ <string name="policylab_expirePassword" msgid="5610055012328825874">"Setel akhir masa berlaku sandi kunci layar"</string>
<string name="policydesc_expirePassword" msgid="5367525762204416046">"Mengubah seberapa sering sandi, PIN, atau pola kunci layar harus diubah."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"Setel enkripsi penyimpanan"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Mengharuskan data apl yang disimpan untuk dienkripsi."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"Nonaktifkan kamera"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"Mencegah penggunaan semua kamera perangkat."</string>
- <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Menonaktifkan beberapa fitur kunci layar"</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Nonaktifkan beberapa fitur kunci layar"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Mencegah penggunaan beberapa fitur kunci layar."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"Rumah"</item>
@@ -824,7 +832,7 @@
<string name="lockscreen_transport_stop_description" msgid="5907083260651210034">"Berhenti"</string>
<string name="lockscreen_transport_rew_description" msgid="6944412838651990410">"Putar Ulang"</string>
<string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Maju cepat"</string>
- <string name="emergency_calls_only" msgid="6733978304386365407">"Telepon urgen saja"</string>
+ <string name="emergency_calls_only" msgid="6733978304386365407">"Panggilan darurat saja"</string>
<string name="lockscreen_network_locked_message" msgid="143389224986028501">"Jaringan terkunci"</string>
<string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Kartu SIM terkunci PUK."</string>
<string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Lihatlah Panduan Pengguna atau hubungi Layanan Pelanggan."</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Permintaan SS diubah ke permintaan USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Diubah ke permintaan SS baru"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil kerja"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Luaskan"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Ciutkan"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"beralih ke perluasan"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 1be394a..a33c80c 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi símtal | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Slökkt"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi í forgangi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Farsímakerfi í forgangi"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Leyfir forriti að fá aðgang að fleiri skipunum staðsetningarveitu. Þetta getur gert forritinu kleift að hafa áhrif á virkni GPS og annars staðsetningarbúnaðar."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"aðgangur að nákvæmri staðsetningu aðeins í forgrunni"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Þetta forrit getur aðeins séð staðsetningu þína þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg í símanum til að forritið geti notað hana. Þetta getur aukið rafhlöðunotkun."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"fá aðgang að áætlaðri staðsetningu (frá símkerfi)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net. Það verður að vera kveikt á slíkri staðsetningarþjónustu og hún þarf að vera aðgengileg spjaldtölvunni til að forritið geti notað hana."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net. Það verður að vera kveikt á slíkri staðsetningarþjónustu og hún þarf að vera aðgengileg sjónvarpinu til að forritið geti notað hana."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net. Það verður að vera kveikt á slíkri staðsetningarþjónustu og hún þarf að vera aðgengileg símanum til að forritið geti notað hana."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"aðgangur að áætlaðri staðsetningu (út frá netkerfi), aðeins í forgrunni"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg spjaldtölvunni til að forritið geti notað hana."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg sjónvarpinu til að forritið geti notað hana."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Þetta forrit getur séð staðsetningu þína út frá netkerfum á borð við farsímasenda og Wi-Fi net, en þó aðeins þegar það er í forgrunni. Það verður að vera kveikt á þessari staðsetningarþjónustu og hún þarf að vera aðgengileg símanum til að forritið geti notað hana."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"aðgangur að staðsetningu í bakgrunni"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ef þetta er veitt til viðbótar við aðgang að áætlaðri eða nákvæmri staðsetningu getur forritið fengið aðgang að staðsetningu á meðan það keyrir í bakgrunni."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"breyta hljóðstillingum"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-beiðni breytt í USSD-beiðni"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Breytt í nýja SS-beiðni"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Vinnusnið"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Stækka"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Minnka"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"stækka eða minnka"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index a3b9835..7c78677 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chiamate Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Non attiva"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rete preferita: Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Rete preferita: dati mobili"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Consente all\'app di accedere a ulteriori comandi del fornitore di posizione. Ciò potrebbe consentire all\'app di interferire con il funzionamento del GPS o di altre fonti di geolocalizzazione."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"Accesso alla posizione esatta solo in primo piano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Questa app può recuperare la tua posizione esatta solo quando è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli. Potrebbe aumentare il consumo della batteria."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"accesso alla posizione approssimativa (basata sulla rete)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Questa app può accedere alla tua posizione tramite fonti di rete come antenne di telefonia mobile e reti Wi-Fi. Tali servizi di geolocalizzazione devono essere attivati e disponibili sul tablet per consentire all\'app di utilizzarli."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Questa app può accedere alla tua posizione tramite fonti di rete come antenne di telefonia mobile e reti Wi-Fi. Tali servizi di geolocalizzazione devono essere attivati e disponibili sulla TV per consentire all\'app di utilizzarli."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Questa app può accedere alla tua posizione tramite fonti di rete come antenne di telefonia mobile e reti Wi-Fi. Tali servizi di geolocalizzazione devono essere attivati e disponibili sul telefono per consentire all\'app di utilizzarli."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Accesso alla posizione approssimativa (in base alla rete) solo in primo piano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul tablet affinché l\'app possa usarli."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sulla TV affinché l\'app possa usarli."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Questa app può recuperare la tua posizione tramite fonti di rete quali ripetitori di telefonia mobile e reti Wi-Fi, ma soltanto quando l\'app è in primo piano. Questi servizi di geolocalizzazione devono essere attivi e disponibili sul telefono affinché l\'app possa usarli."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"accesso alla posizione in background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se concedi l\'autorizzazione insieme all\'accesso alla posizione precisa o approssimativa, l\'app potrà accedere alla posizione mentre viene eseguita in background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modifica impostazioni audio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Richiesta SS modificata in richiesta USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Modificata in nuova richiesta SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profilo di lavoro"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Espandi"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Comprimi"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"attiva/disattiva l\'espansione"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5bf5704..6034ee0 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"שיחות WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"כבוי"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi מועדף"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"מצב מועדף: רשת סלולרית"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"מאפשרת לאפליקציה לגשת לפקודות נוספות של ספק המיקום. הרשאה זו עשויה לאפשר לאפליקציה לשבש את פעולת ה-GPS או מקורות מיקום אחרים."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"קבלת גישה למיקום מדויק בחזית בלבד"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"אפליקציה זו יכולה לזהות את המיקום המדויק שלך רק כאשר היא פועלת בחזית. כדי שהאפליקציה תוכל להשתמש בשירותי המיקום, עליהם להיות מופעלים וזמינים בטלפון. ייתכן שפעולה זו תגביר את צריכת הסוללה."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"גישה אל מיקום משוער (מבוסס רשת)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטאבלט שלך כדי שהאפליקציה תוכל להשתמש בהם."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטלוויזיה שלך כדי שהאפליקציה תוכל להשתמש בהם."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטלפון שלך כדי שהאפליקציה תוכל להשתמש בהם."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"קבלת גישה למיקום המשוער (מבוסס-רשת) רק במצב פעיל"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטאבלט כדי שהאפליקציה תוכל להשתמש בהם."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטלוויזיה כדי שהאפליקציה תוכל להשתמש בהם."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"אפליקציה זו יכולה לזהות את המיקום שלך על סמך מקורות מיקום ברשת, כגון אנטנות סלולריות ורשתות Wi-Fi, אבל רק כשהאפליקציה במצב פעיל. שירותי מיקום אלה חייבים להיות מופעלים וזמינים בטלפון כדי שהאפליקציה תוכל להשתמש בהם."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"גישה למיקום ברקע"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"אם מתקבל אישור, בנוסף לגישה למיקום משוער או מדויק, תהיה לאפליקציה גישה למיקום גם כשהיא פועלת ברקע."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"שנה את הגדרות האודיו שלך"</string>
@@ -622,8 +630,8 @@
<string name="permdesc_manageNetworkPolicy" msgid="7537586771559370668">"מאפשר לאפליקציה לנהל מדיניות הרשת להגדיר כללים ספציפיים-לאפליקציה."</string>
<string name="permlab_modifyNetworkAccounting" msgid="5088217309088729650">"שנה ניהול חשבונות של שימוש ברשת"</string>
<string name="permdesc_modifyNetworkAccounting" msgid="5443412866746198123">"הרשאה זו מאפשרת לאפליקציה לשנות את אופן החישוב של נתוני שימוש ברשת מול כל אפליקציה. לא מיועד לשימוש באפליקציות רגילות."</string>
- <string name="permlab_accessNotifications" msgid="7673416487873432268">"גישה להודעות"</string>
- <string name="permdesc_accessNotifications" msgid="458457742683431387">"מאפשר לאפליקציה לאחזר, לבדוק ולמחוק הודעות, כולל כאלה שפורסמו על ידי אפליקציות אחרות."</string>
+ <string name="permlab_accessNotifications" msgid="7673416487873432268">"גישה להתראות"</string>
+ <string name="permdesc_accessNotifications" msgid="458457742683431387">"מאפשר לאפליקציה לאחזר, לבדוק ולמחוק התראות, כולל כאלה שפורסמו על ידי אפליקציות אחרות."</string>
<string name="permlab_bindNotificationListenerService" msgid="7057764742211656654">"איגוד לשירות של מאזין להתראות"</string>
<string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של שירות מאזין להתראות. הרשאה זו אף פעם אינה נחוצה לאפליקציות רגילים."</string>
<string name="permlab_bindConditionProviderService" msgid="1180107672332704641">"איגוד לשירות ספק תנאי"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"בקשת SS שונתה לבקשת USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"היה שינוי לבקשת SS חדשה"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"פרופיל עבודה"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"הרחב"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"כווץ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"החלפת מצב הרחבה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index a9f94c9..4bebf20 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"OFF"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi優先"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"モバイル優先"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"位置情報提供元の追加のコマンドにアクセスすることをアプリに許可します。許可すると、アプリがGPSなどの位置情報源の動作を妨害する恐れがあります。"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"フォアグラウンドでのみ正確な位置情報にアクセス"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"このアプリは、フォアグラウンド状態でのみユーザーの正確な位置情報を取得できます。この位置情報サービスは ON の状態にして、スマートフォンでアプリがサービスを利用できるようにする必要があります。これにより、電池の消費量が増える可能性があります。"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"おおよその位置情報(ネットワーク基地局)へのアクセス"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"このアプリは、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得します。これらの位置情報サービスは ON の状態にして、タブレットでアプリがサービスを利用できるようにする必要があります。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"このアプリは、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得します。これらの位置情報サービスは ON の状態にして、テレビでアプリがサービスを利用できるようにする必要があります。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"このアプリは、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得します。これらの位置情報サービスは ON の状態にして、スマートフォンでアプリがサービスを利用できるようにする必要があります。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"フォアグラウンドでのみ(ネットワークに基づく)おおよその位置情報にアクセス"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、タブレットでアプリがサービスを利用できるようにする必要があります。"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、テレビでアプリがサービスを利用できるようにする必要があります。"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"このアプリは、フォアグラウンドでのみ、ネットワーク位置情報源(携帯基地局や Wi-Fi ネットワークなど)に基づいて、ユーザーの位置情報を取得できます。これらの位置情報サービスは ON の状態にして、スマートフォンでアプリがサービスを利用できるようにする必要があります。"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"バックグラウンドでの位置情報へのアクセス"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"これが、おおよその位置情報または正確な位置情報へのアクセスの追加権限の場合、アプリはバックグラウンドでの実行中も位置情報にアクセスできます。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"音声設定の変更"</string>
@@ -640,8 +648,8 @@
<string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"携帯通信会社のSMSサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_bindCarrierServices" msgid="3233108656245526783">"携帯通信会社のサービスへのバインド"</string>
<string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"携帯通信会社のサービスにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
- <string name="permlab_access_notification_policy" msgid="4247510821662059671">"マナーモードへのアクセス"</string>
- <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"マナーモード設定の読み取りと書き込みをアプリに許可します。"</string>
+ <string name="permlab_access_notification_policy" msgid="4247510821662059671">"サイレント モードへのアクセス"</string>
+ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"サイレント モード設定の読み取りと書き込みをアプリに許可します。"</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"画面ロックのパスワードとPINの長さと使用できる文字を制御します。"</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"画面ロック解除試行の監視"</string>
@@ -1804,10 +1812,10 @@
<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="931849471004038757">"自分が OFF にするまで"</string>
- <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"マナーモードを OFF にするまで"</string>
+ <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"サイレント モードを OFF にするまで"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string>
- <string name="zen_mode_feature_name" msgid="5254089399895895004">"マナーモード"</string>
+ <string name="zen_mode_feature_name" msgid="5254089399895895004">"サイレント モード"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"ダウンタイム"</string>
<string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"平日の夜"</string>
<string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"週末"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS リクエストは USSD リクエストに変更されました"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"新しい SS リクエストに変更されました"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"仕事用プロファイル"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"展開"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"折りたたむ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"展開の切り替え"</string>
@@ -1948,10 +1958,10 @@
<string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"着信や通知をバイブレーションで知らせます"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"着信音と通知音をミュートします"</string>
<string name="notification_channel_system_changes" msgid="5072715579030948646">"システムの変更"</string>
- <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"マナーモード"</string>
- <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"新機能: マナーモードでは通知が非表示になります"</string>
+ <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"サイレント モード"</string>
+ <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"新機能: サイレント モードでは通知が非表示になります"</string>
<string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"タップすると、詳細を確認して設定を変更できます。"</string>
- <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"マナーモードが変わりました"</string>
+ <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"サイレント モードが変わりました"</string>
<string name="zen_upgrade_notification_content" msgid="1794994264692424562">"タップしてブロック対象をご確認ください。"</string>
<string name="notification_app_name_system" msgid="4205032194610042794">"システム"</string>
<string name="notification_app_name_settings" msgid="7751445616365753381">"設定"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index e776289..fdcfc0c 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi დარეკვა | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"გამორთული"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"სასურველია Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"უპირატესობა მიენიჭოს მობილურს"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"აპს შეეძლება წვდომა ჰქონდეს მდებარეობის სერვისის დამატებით ბრძანებებზე. შესაძლოა აპმა ეს გამოიყენოს GPS-ისა და მდებარეობის სხვა წყაროების მუშაობის პროცესში ჩარევისთვის."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ზუსტ მდებარეობაზე წვდომა მხოლოდ წინა პლანზე"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ამ აპს შეუძლია თქვენი ზუსტი მდებარეობის შესახებ ინფორმაციის მიღება მხოლოდ მაშინ, როცა გაშვებულია წინა პლანზე. თქვენს ტელეფონზე ჩართული და ხელმისაწვდომი უნდა იყოს მდებარეობის სერვისები, აპმა მათი გამოყენება რომ შეძლოს. ამან შეიძლება გაზარდოს ბატარეის მოხმარება."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"მიახლოებით მდებარეობაზე წვდომა (ქსელის მეშვეობით)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ამ აპს თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროების მეშვეობით შეუძლია, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები. მდებარეობის აღნიშნული სერვისები თქვენს ტაბლეტზე ჩართული და ხელმისაწვდომი უნდა იყოს, რათა აპმა მათი გამოყენება შეძლოს."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ამ აპს თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროების მეშვეობით შეუძლია, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები. მდებარეობის აღნიშნული სერვისები თქვენს ტელევიზორზე ჩართული და ხელმისაწვდომი უნდა იყოს, რათა აპმა მათი გამოყენება შეძლოს."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ამ აპს თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროების მეშვეობით შეუძლია, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები. მდებარეობის აღნიშნული სერვისები თქვენს ტელეფონზე ჩართული და ხელმისაწვდომი უნდა იყოს, რათა აპმა მათი გამოყენება შეძლოს."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"მიახლოებით მდებარეობაზე (ქსელის კოორდინატების მიხედვით) წვდომა მხოლოდ წინა პლანზე"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს ტაბლეტზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს ტელევიზორზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ამ აპს შეუძლია თქვენი მდებარეობის შესახებ ინფორმაციის მიღება ისეთი წყაროებიდან, როგორიცაა მობილური კავშირგაბმულობის ანძები და Wi-Fi ქსელები (თუმცა მხოლოდ მაშინ, როცა აპი გაშვებულია წინა პლანზე). მდებარეობის აღნიშნული სერვისები თქვენს ტელეფონზე ჩართული და ხელმისაწვდომი უნდა იყოს, აპმა მათი გამოყენება რომ შეძლოს."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"მდებარეობაზე წვდომა ფონურ რეჟიმში"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ამ ნებართვის მიახლოებით ან ზუსტ მდებარეობაზე წვდომის ნებართვასთან ერთად მინიჭების შემთხვევაში, აპს შეეძლება მდებარეობაზე წვდომა ფონურ რეჟიმში."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"თქვენი აუდიო პარამეტრების შეცვლა"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS მოთხოვნა შეიცვალა USSD მოთხოვნით"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"შეიცვალა ახალი SS მოთხოვნით"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"სამსახურის პროფილი"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"გაშლა"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ჩაკეცვა"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"გაშლის გადართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 375aa82..7f3e611 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi қоңыраулары | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өшірулі"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Қалаулы Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Таңдаулы мобильдік байланыс"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Қолданбаға орын жеткізушісінің қосымша пәрмендеріне қатынасуға рұқсат береді. Бұл қолданбаға GPS немесе басқа орын көздерінің жұмысына кедергі келтіруге рұқсат беруі мүмкін."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"нақты орналасқан жер туралы ақпаратқа тек ашық экранда кіру"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Бұл қолданба нақты орналасқан жеріңіз туралы ақпаратты экранда ашық тұрғанда ғана анықтай алады. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі телефонда қолжетімді болуы керек. Батарея көбірек тұтынылуы мүмкін."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"шамамен алған орынға қатынасу (желі негізінде)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін олар қосулы әрі планшетте қолжетімді болуы керек."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін олар қосулы әрі теледидарда қолжетімді болуы керек."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін олар қосулы әрі телефонда қолжетімді болуы керек."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"болжалды геодерекке (желі негізінде) тек экрандық режимде кіру"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба экрандық режимде жұмыс істеп тұруы керек. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі планшетте қолжетімді болуы керек."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба экранда ашық тұруы керек. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі теледидарда қолжетімді болуы керек."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Бұл қолданба орналасқан жеріңізді ұялы байланыс мұнаралары мен Wi-Fi желілері сияқты желі көздерінің негізінде анықтайды. Бірақ бұл үшін қолданба экранда ашық тұруы керек. Қолданба бұл орынды анықтау қызметтерін пайдалана алуы үшін, олар қосулы әрі телефонда қолжетімді болуы керек."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"геодеректерді фондық режимде пайдалану"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Егер ол шамамен есептегендегі немесе нақты орынды пайдалануға рұқсат алса, қолданба фондық режимде жұмыс істеп тұрып-ақ геодеректерді пайдалана алады."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"аудио параметрлерін өзгерту"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS сұрауы USSD сұрауына өзгертілді"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Жаңа SS сұрауына өзгертілді"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Жұмыс профилі"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Жаю"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Жию"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"жаю/жию"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index b9cf1eb..06e6540 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ការហៅតាម WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"បិទ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ជាអាទិភាព"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ទិន្នន័យទូរសព្ទចល័តជាអាទិភាព"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ឲ្យកម្មវិធីចូលដំណើរការពាក្យបញ្ជាកម្មវិធីផ្ដល់ទីតាំងបន្ថែម។ វាអាចអនុញ្ញាតឲ្យកម្មវិធីទាក់ទងជាមួយប្រតិបត្តិការជីភីអេស ឬប្រភពទីតាំងផ្សេង។"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ចូលប្រើទីតាំងជាក់លាក់តែនៅផ្ទៃខាងមុខប៉ុណ្ណោះ"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"កម្មវិធីនេះអាចទទួលបានទីតាំងពិតប្រាកដរបស់អ្នកតែនៅពេលវាស្ថិតនៅផ្ទៃខាងមុខប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើទូរសព្ទរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើពួកវាបាន។ វាអាចប្រើថាមពលច្រើនជាងមុន។"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ចូលដំណើរការទីតាំងប្រហាក់ប្រហែល (ផ្អែកលើបណ្តាញ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញ ដូចជា៖ អង់តែន និងបណ្តាញ Wi-Fi ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងត្រូវតែមាននៅលើថេប្លេតរបស់អ្នក ដើម្បីឲ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញ ដូចជា៖ អង់តែន និងបណ្តាញ Wi-Fi ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងត្រូវតែមាននៅលើទូរទស្សន៍របស់អ្នក ដើម្បីឲ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញ ដូចជា៖ អង់តែន និងបណ្តាញ Wi-Fi ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងត្រូវតែមាននៅលើទូរសព្ទរបស់អ្នក ដើម្បីឲ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ចូលប្រើទីតាំងប្រហាក់ប្រហែល (ផ្អែកលើបណ្តាញ) នៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើថេប្លេតរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើទូរទស្សន៍របស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"កម្មវិធីនេះអាចទទួលបានទីតាំងរបស់អ្នក ដោយផ្អែកលើប្រភពបណ្តាញដូចជា អង់តែនបណ្តាញទូរសព្ទ និងបណ្តាញ Wi-Fi ជាដើម ប៉ុន្តែនៅពេលកម្មវិធីស្ថិតនៅផ្ទៃខាងមុខតែប៉ុណ្ណោះ។ សេវាកម្មទីតាំងទាំងនេះត្រូវតែបើក និងមាននៅលើទូរសព្ទរបស់អ្នក ដើម្បីឱ្យកម្មវិធីនេះអាចប្រើវាបាន។"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ចូលប្រើទីតាំងនៅផ្ទៃខាងក្រោយ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ប្រសិនបើផ្ដល់ការអនុញ្ញាតនេះបន្ថែមពីលើការចូលប្រើទីតាំងជាក់លាក់ ឬប្រហាក់ប្រហែល កម្មវិធីនឹងអាចចូលប្រើទីតាំងនោះ ខណៈពេលដំណើរការនៅផ្ទៃខាងក្រោយ។"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ប្ដូរការកំណត់អូឌីយូរបស់អ្នក"</string>
@@ -1827,6 +1835,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"សំណើ SS ត្រូវបានប្ដូរទៅសំណើ USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"បានប្ដូរទៅសំណើ SS ថ្មី"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ប្រវត្តិរូបការងារ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ពង្រីក"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"លាក់"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"បិទ/បើកការពង្រីក"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 2a480cd..88e7ce1 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ವೈ-ಫೈ"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ವೈಫೈ ಕರೆಮಾಡುವಿಕೆ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ಆಫ್"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ವೈ-ಫೈಗೆ ಆದ್ಯತೆ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ಮೊಬೈಲ್ಗೆ ಆದ್ಯತೆ"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ಹೆಚ್ಚಿನ ಸ್ಥಳ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಳ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ನಿಖರವಾದ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಮುಂಭಾಗದಲ್ಲಿರುವಾಗ ಮಾತ್ರ ನಿಮ್ಮ ನಿಖರ ಸ್ಥಳವನ್ನು ಪಡೆಯಬಹುದು. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ (ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ಮುನ್ನೆಲೆಯಲ್ಲಿ ಮಾತ್ರ ಅಂದಾಜು ಸ್ಥಳವನ್ನು (ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ) ಪ್ರವೇಶಿಸಿ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ಈ ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ಈ ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ಈ ಆ್ಯಪ್ ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಂತಹ ನೆಟ್ವರ್ಕ್ ಮೂಲಗಳ ಆಧಾರದ ಮೇಲೆ ಪಡೆಯಬಹುದು, ಆದರೆ ಆ್ಯಪ್ ಮುನ್ನೆಲೆಯಲ್ಲಿದ್ದಾಗ ಮಾತ್ರ. ಈ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ಅವುಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ಗೆ ಸಾಧ್ಯವಾಗುವಂತೆ ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಅವುಗಳು ಲಭ್ಯವಿರಬೇಕು."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ಹಿನ್ನೆಲೆಯಲ್ಲಿ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ಇದನ್ನು ಅಂದಾಜು ಅಥವಾ ನಿಖರವಾದ ಸ್ಥಳ ಪ್ರವೇಶಕ್ಕೆ ಹೆಚ್ಚುವರಿಯಾಗಿ ಅನುಮತಿಸಿದರೆ, ಆ್ಯಪ್ ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿರುವಾಗ ಅದು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಬಹುದು."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ನಿಮ್ಮ ಆಡಿಯೊ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS ವಿನಂತಿಯನ್ನು USSD ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"ಹೊಸ SS ವಿನಂತಿಗೆ ಬದಲಾಯಿಸಲಾಗಿದೆ"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ವಿಸ್ತೃತಗೊಳಿಸಿ"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ಕುಗ್ಗಿಸಿ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ವಿಸ್ತರಣೆ ಟಾಗಲ್ ಮಾಡಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index b66cbf4..97d799e 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 통화 | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"꺼짐"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi를 기본으로 설정"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"모바일에 최적화됨"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"앱이 추가 위치 정보 제공 기능의 명령에 접근하도록 허용합니다. 이 경우 앱이 GPS 또는 기타 위치 소스의 작동을 방해할 수 있습니다."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"포그라운드에서만 정확한 위치에 액세스"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"이 앱은 포그라운드에 있을 때만 나의 정확한 위치를 알 수 있습니다. 앱에서 위치 서비스를 사용하려면 휴대전화에서 위치 서비스가 사용 설정되어 있으며 사용할 수 있어야 합니다. 배터리 사용량이 늘어날 수 있습니다."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"대략적인 위치(네트워크 기반)에 액세스"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"이 앱은 기지국 및 Wi-Fi 네트워크와 같은 네트워크 소스를 통해 내 위치를 알 수 있습니다. 앱에서 위치 서비스를 사용하려면 태블릿에서 위치 서비스가 사용 설정되어 있으며 사용 가능해야 합니다."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"이 앱은 기지국 및 Wi-Fi 네트워크와 같은 네트워크 소스를 통해 내 위치를 알 수 있습니다. 앱에서 위치 서비스를 사용하려면 TV에서 위치 서비스가 사용 설정되어 있으며 사용 가능해야 합니다."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"이 앱은 기지국 및 Wi-Fi 네트워크와 같은 네트워크 소스를 통해 내 위치를 알 수 있습니다. 앱에서 위치 서비스를 사용하려면 휴대전화에서 위치 서비스가 사용 설정되어 있으며 사용 가능해야 합니다."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"포그라운드에서만 대략적인 위치(네트워크 기반)에 액세스"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 태블릿에서 위치 서비스가 켜져 있으며 사용 가능해야 합니다."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 TV에서 위치 서비스가 켜져 있으며 사용 가능해야 합니다."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"앱이 포그라운드에 있을 때만 휴대전화 기지국과 Wi-Fi 네트워크 등의 네트워크 소스를 바탕으로 사용자의 위치를 파악할 수 있습니다. 앱에서 위치 서비스를 사용하려면 휴대전화에서 위치 서비스가 켜져 있으며 사용 가능해야 합니다."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"백그라운드에서 위치 정보 액세스"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"이 권한이 대략적인 위치 정보 또는 정확한 위치 정보 액세스 권한에 추가적으로 부여되면 앱이 백그라운드에서 실행되는 동안 위치에 액세스할 수 있습니다."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"오디오 설정 변경"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS 요청이 USSD 요청으로 변경됨"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"새 SS 요청으로 변경됨"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"직장 프로필"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"펼치기"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"접기"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"확장 전환"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index de3bcd2..6608029 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi аркылуу чалуу | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Өчүк"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi тандалган"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Тандалган мобилдик түзмөк"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Колдонмого жайгашкан жерди табуучу кошумча жабдуучулардын буйруктарын колдонуу мүмкүнчүлүгүн берет. Ушуну менен колдонмо GPS\'тин ишине жана башка жайгашкан жерлерди аныктоо кызматтарына кийлигише алат."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"так аныкталган жайгашкан жерге активдүү режимде гана кирүүгө уруксат берүү"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Бул колдонмонун активдүү режимде гана жайгашкан жериңиздин дайындарын алууга мүмкүнчүлүгү бар. Колдонмо бул кызматтарды пайдаланышы үчүн аларды күйгүзүп, телефонуңузга туташтырып коюшуңуз керек. Ушуну менен батареянын кубаты көбүрөөк сарпталышы мүмкүн."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"болжолдуу жайгашкан жерге (тармактын негизинде) уруксат"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, планшетиңизге туташтырып коюшуңуз керек."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, сыналгыңызга туташтырып коюшуңуз керек."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, телефонуңузга туташтырып коюшуңуз керек."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"болжолдуу аныкталган жайгашкан жерге (тармактын негизинде) автивдүү режимде гана кирүүгө уруксат берүү"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, планшетиңизге туташтырып коюшуңуз керек."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, сыналгыңызга туташтырып коюшуңуз керек."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Бул колдонмо байланыш мунаралары жана Wi-Fi сыяктуу тармактык булактар аркылуу жайгашкан жериңизди аныктай алат, бирок ал үчүн колдонмо ачылып турушу керек. Колдонмо бул кызматтарды пайдаланышы үчүн, аларды күйгүзүп, телефонуңузга туташтырып коюшуңуз керек."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"жайгашкан жерди фондо аныктоо"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Эгер колдонмого жайгашкан жерди болжолдуу же так аныктоого уруксат берилсе, ал фондо иштеп жатып эле жайгашкан жерди аныктап турат."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"аудио жөндөөлөрүңүздү өзгөртүңүз"</string>
@@ -1827,6 +1835,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS сурамы USSD сурамына өзгөртүлдү"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Жаңы SS сурамына өзгөртүлдү"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Жумуш профили"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Жайып көрсөтүү"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Жыйыштыруу"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"жайып көрсөтүү же жыйыштыруу"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9fb0adb..e12ec28 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi Calling | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ປິດ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ເລືອກໃຊ້ Wi-Fi ກ່ອນ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ຕ້ອງການໃຊ້ມືຖື"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຄຳສັ່ງເພີ່ມເຕີມຂອງຜູ່ໃຫ້ບໍລິການສະຖານທີ່. ນີ້ອາດຈະເປັນການເຮັດໃຫ້ແອັບຯ ລົບກວນການເຮັດວຽກຂອງ GPS ຫຼືແຫລ່ງຂໍ້ມູນສະຖານທີ່ອື່ນໆໄດ້."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ເຂົ້າເຖິງສະຖານທີ່ແນ່ນອນໃນພື້ນໜ້າເທົ່ານັ້ນ"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ແອັບນີ້ສາມາດຮັບເອົາສະຖານທີ່ແນ່ນອນຂອງທ່ານໄດ້ທຸກເວລາທີ່ມັນຢູ່ໃນພື້ນໜ້າ. ການບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຕ້ອງເປີດຢູ່ ແລະ ສາມາດໃຊ້ໄດ້ໃນໂທລະສັບຂອງທ່ານເພື່ອໃຫ້ແອັບສາມາດໃຊ້ພວກມັນໄດ້. ນີ້ອາດຈະເຮັດໃຫ້ການໃຊ້ແບັດເຕີຣີເພີ່ມຂຶ້ນ."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ເຂົ້າຫາທີ່ຕັ້ງໂດຍປະມານ (ອີງໃສ່ເຄືອຂ່າຍ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານ (ອ້າງອີງຈາກເຄືອຂ່າຍ) ສະເພາະໃນພື້ນໜ້າ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ແອັບນີ້ສາມາດເບິ່ງສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງຈາກແຫລ່ງທີ່ມເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບ ແລະ ເຄືອຂ່າຍ Wi-Fi ໄດ້, ແຕ່ສະເພາະເມື່ອແອັບເຮັດວຽກໂດຍປາກົດຢູ່ໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ແທັບເລັດຂອງທ່ານ, ແອັບຈຶ່ງຈະສາມາດໃຊ້ພວກມັນໄດ້."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ແອັບນີ້ສາມາດເບິ່ງສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງຈາກແຫລ່ງທີ່ມເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບ ແລະ ເຄືອຂ່າຍ Wi-Fi ໄດ້, ແຕ່ສະເພາະເມື່ອແອັບເຮັດວຽກໂດຍປາກົດຢູ່ໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ໂທລະທັດຂອງທ່ານ, ແອັບຈຶ່ງຈະສາມາດໃຊ້ພວກມັນໄດ້."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ແອັບນີ້ສາມາດເບິ່ງສະຖານທີ່ຂອງທ່ານໂດຍອ້າງອີງຈາກແຫລ່ງທີ່ມເຄືອຂ່າຍ ເຊັ່ນ: ເສົາສັນຍານໂທລະສັບ ແລະ ເຄືອຂ່າຍ Wi-Fi ໄດ້, ແຕ່ສະເພາະເມື່ອແອັບເຮັດວຽກໂດຍປາກົດຢູ່ໜ້າເທົ່ານັ້ນ. ບໍລິການສະຖານທີ່ເຫຼົ່ານີ້ຈະຕ້ອງຖືກເປີດໃຊ້ ແລະ ສາມາດໃຊ້ໄດ້ຢູ່ໂທລະສັບຂອງທ່ານ, ແອັບຈຶ່ງຈະສາມາດໃຊ້ພວກມັນໄດ້."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ເຂົ້າເຖິງສະຖານທີ່ໃນພື້ນຫຼັງ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ຖ້າອະນຸຍາດສິ່ງນີ້ນອກຈາກການເຂົ້າເຖິງສະຖານທີ່ໂດຍປະມານ ຫຼື ທີ່ແນ່ນອນ ແອັບສາມາດເຂົ້າເຖິງສະຖານທີ່ໄດ້ໃນຂະນະທີ່ເປີດໃຊ້ໃນພື້ນຫຼັງ."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ປ່ຽນການຕັ້ງຄ່າສຽງຂອງທ່ານ"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"ປ່ຽນຄຳຂໍ SS ເປັນຄຳຂໍ USSD ແລ້ວ"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"ປ່ຽນຄຳຂໍ SS ໃໝ່ແລ້ວ"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ຂະຫຍາຍ"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ຫຍໍ້ເຂົ້າ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ປິດ/ເປີດ ການຂະຫຍາຍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index f5225c5..86cee5e 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> „Wi-Fi“"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"„Wi-Fi“ skambinimas | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> „VoWifi“"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Išjungta"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Pageidautinas „Wi-Fi“ ryšys"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Pirmenybė mobiliojo ryšio tinklui"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Programai leidžiama pasiekti papildomas vietovės nustatymo paslaugų teikėjų komandas. Dėl to programa gali trukdyti veikti GPS ar kitiems vietovės nustatymo šaltiniams."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"pasiekti tikslią vietovę, tik kai programa veikia priekiniame plane"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ši programa gali gauti tikslius jūsų vietovės duomenis bet kuriuo metu, kai veikia priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos telefone, kad programa galėtų jas naudoti. Tai gali padidinti akumuliatoriaus energijos suvartojimą."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"pasiekti apytikslę vietą (nustatytą atsižvelgiant į tinklą)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos planšetiniame kompiuteryje, kad programa galėtų jas naudoti."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos TV, kad programa galėtų jas naudoti."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos telefone, kad programa galėtų jas naudoti."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"pasiekti apytikslę vietovę (pagal tinklo duomenis), tik kai programa veikia priekiniame plane"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos planšetiniame kompiuteryje, kad programa galėtų jas naudoti."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos TV, kad programa galėtų jas naudoti."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ši programa gali gauti jūsų vietos informaciją naudodamasi tinklo šaltinių, pvz., mobiliojo ryšio bokštų ir „Wi-Fi“ tinklų, duomenimis, bet tik kai ji yra naudojama priekiniame plane. Šios vietovės paslaugos turi būti įjungtos ir pasiekiamos telefone, kad programa galėtų jas naudoti."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"prieiga prie vietovės fone"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Jei papildomai suteikiama prieiga prie apytikslės arba tikslios vietovės, programa gali pasiekti vietovės duomenis veikdama fone."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"keisti garso nustatymus"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS užklausa pakeista į USSD užklausą"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Pakeista į naują SS užklausą"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Darbo profilis"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Išskleisti"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Sutraukti"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"perjungti išskleidimą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index d0c16d8..6f63f0c 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi zvani | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izslēgts"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Vēlams Wi-Fi tīkls"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Vēlams mobilo datu savienojums"</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ļauj lietotnei piekļūt papildu atrašanās vietas noteikšanas nodrošinātāju komandām. Tas var ļaut lietotnei traucēt GPS vai citu atrašanās vietas noteikšanas avotu darbību."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"piekļuve precīzai atrašanās vietai, tikai darbojoties priekšplānā"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Šī lietotne var iegūt precīzu jūsu atrašanās vietu, tikai darbojoties priekšplānā. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu tālrunī, lai lietotne varētu tos izmantot. Tādējādi var palielināties akumulatora jaudas patēriņš."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"Piekļūt aptuvenai atrašanās vietai (izmantojot tīklu)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Šī lietotne var iegūt jūsu atrašanās vietu, pamatojoties uz tīkla avotiem, piemēram, mobilo sakaru torņiem un Wi-Fi tīkliem. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu planšetdatorā, lai lietotne tos varētu izmantot."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Šī lietotne var iegūt jūsu atrašanās vietu, pamatojoties uz tīkla avotiem, piemēram, mobilo sakaru torņiem un Wi-Fi tīkliem. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu televizorā, lai lietotne tos varētu izmantot."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Šī lietotne var iegūt jūsu atrašanās vietu, pamatojoties uz tīkla avotiem, piemēram, mobilo sakaru torņiem un Wi-Fi tīkliem. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu tālrunī, lai lietotne tos varētu izmantot."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"piekļuve aptuvenai atrašanās vietai (pēc tīkla datiem), tikai darbojoties priekšplānā"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu planšetdatorā, lai lietotne varētu tos izmantot."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu televizorā, lai lietotne varētu tos izmantot."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Kad šī lietotne darbojas priekšplānā, tā var noteikt jūsu atrašanās vietu, izmantojot tīkla resursus, piemēram, mobilo sakaru torņus un Wi-Fi tīklus. Šiem atrašanās vietu pakalpojumiem ir jābūt ieslēgtiem un pieejamiem jūsu tālrunī, lai lietotne varētu tos izmantot."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"piekļūt atrašanās vietai fonā"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ja šī atļauja tiek piešķirta līdz ar piekļuvi aptuvenai vai precīzai atrašanās vietai, lietotne var piekļūt atrašanās vietai, darbojoties fonā."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"mainīt audio iestatījumus"</string>
@@ -1858,6 +1866,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS pieprasījums mainīts uz USSD pieprasījumu"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Mainīts uz jaunu SS pieprasījumu"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Darba profils"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Izvērst"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Sakļaut"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"izvērst/sakļaut"</string>
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 36efd0a..c26bebe 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -33,7 +33,7 @@
<item>LPP_PROFILE=3</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml
index a11dd95..96338b58 100644
--- a/core/res/res/values-mcc302-mnc221/config.xml
+++ b/core/res/res/values-mcc302-mnc221/config.xml
@@ -30,7 +30,7 @@
<item>LPP_PROFILE=3</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index 8d29ec1..79f4bb6 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -34,7 +34,7 @@
<item>LPP_PROFILE=2</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml
index 650aa62..10b007e 100644
--- a/core/res/res/values-mcc302-mnc610/config.xml
+++ b/core/res/res/values-mcc302-mnc610/config.xml
@@ -32,7 +32,7 @@
<item>LPP_PROFILE=2</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml
index 4bb68dc..657d1e7 100644
--- a/core/res/res/values-mcc302-mnc640/config.xml
+++ b/core/res/res/values-mcc302-mnc640/config.xml
@@ -28,7 +28,7 @@
<item>LPP_PROFILE=2</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index 735a8c8..ba8c75a 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -34,7 +34,7 @@
<item>LPP_PROFILE=2</item>
<item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
<item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
- <item>GPS_LOCK=0</item>
+ <item>GPS_LOCK=3</item>
</string-array>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 4b3a53e..d8bb4a7 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Повици преку Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Глас преку Wi-Fi на <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Исклучено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Се претпочита Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Претпочитам мобилен интернет"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Овозможува апликацијата да пристапи кон дополнителни наредби на давател на локација. Ова може да овозможи апликацијата да го попечи функционирањето на GPS или други извори на локација."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"пристап до прецизната локација само во преден план"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Апликацијава може да ја добие вашата точна локација само кога е во преден план. Услугиве според локација мора да се вклучени и достапни на телефонот за да може да ги користи апликацијата. Ова може да го зголеми трошењето на батеријата."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"пристап до приближната локација (врз база на мрежа)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите. Овие услуги за локација мора да се вклучени и достапни на таблетот за да може да ги користи апликацијата."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите. Овие услуги за локација мора да се вклучени и достапни на телевизорот за да може да ги користи апликацијата."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите. Овие услуги за локација мора да се вклучени и достапни на телефонот за да може да ги користи апликацијата."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"пристап до приближна локација (според мрежа) само во преден план"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преде план. Овие услуги за локација мора да се вклучени и достапни на таблетот за да може да ги користи апликацијата."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преде план. Овие услуги за локација мора да се вклучени и достапни на телевизорот за да може да ги користи апликацијата."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Апликацијава може да ја добие вашата локација од мрежните извори како што се репетиторите за мобилни мрежи и Wi-Fi мрежите, но само кога апликацијата е во преде план. Овие услуги за локација мора да се вклучени и достапни на телефонот за да може да ги користи апликацијата."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"пристап до локацијата во заднина"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ако покрај дозволата за пристап до приближната или прецизната локација е доделена и оваа дозвола, тогаш апликацијата ќе може да пристапува до локацијата додека се извршува во заднина."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"менува аудио поставки"</string>
@@ -1828,6 +1836,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Барањето SS е изменето во барање USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Променето на ново барање SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Работен профил"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Прошири"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Собери"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"вклучи/исклучи проширување"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 2184af0..4a5f1cd 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> വൈഫൈ"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"വൈഫൈ കോളിംഗ് | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> Voവൈഫൈ"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ഓഫ്"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"വൈഫൈ തിരഞ്ഞെടുത്തിരിക്കുന്നു"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"മൊബൈൽ ഡാറ്റ ഉപയോഗിക്കാൻ താൽപ്പര്യപ്പെടുന്നു"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ലൊക്കേഷൻ ദാതാവിന്റെ അധിക കമാൻഡുകൾ ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ഇത് GPS-ന്റെയോ മറ്റ് ലൊക്കേഷൻ ഉറവിടങ്ങളുടെയോ പ്രവർത്തനത്തിൽ ഇടപെടാൻ അപ്ലിക്കേഷനെ അനുവദിക്കാനിടയുണ്ട്."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ഫോർഗ്രൗണ്ടിൽ മാത്രം കൃത്യമായ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ഈ ആപ്പിന് നിങ്ങളുടെ കൃത്യമായ ലൊക്കേഷൻ നേടാനാവൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ഫോണിൽ ലഭ്യമാവുകയും വേണം. ഇതിലൂടെ ബാറ്ററി ഉപഭോഗം വർദ്ധിച്ചേക്കാം."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ഏകദേശ ലൊക്കേഷൻ (നെറ്റ്വർക്ക് അധിഷ്ഠിതം) ആക്സസ് ചെയ്യുക"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങളെ അടിസ്ഥാനമാക്കിക്കൊണ്ട് ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ അനുമാനിക്കാൻ കഴിയും. നിങ്ങളുടെ ടാബ്ലെറ്റിൽ ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓൺ ചെയ്തിട്ടുണ്ടെങ്കിൽ മാത്രമാണ് ആപ്പിന് അവ ഉപയോഗിക്കാൻ കഴിയുക."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങളെ അടിസ്ഥാനമാക്കിക്കൊണ്ട് ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ അനുമാനിക്കാൻ കഴിയും. നിങ്ങളുടെ ടിവിയിൽ ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓൺ ചെയ്തിട്ടുണ്ടെങ്കിൽ മാത്രമാണ് ആപ്പിന് അവ ഉപയോഗിക്കാൻ കഴിയുക."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങളെ അടിസ്ഥാനമാക്കിക്കൊണ്ട് ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ അനുമാനിക്കാൻ കഴിയും. നിങ്ങളുടെ ഫോണിൽ ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓൺ ചെയ്തിട്ടുണ്ടെങ്കിൽ മാത്രമാണ് ആപ്പിന് അവ ഉപയോഗിക്കാൻ കഴിയുക."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ഫോർഗ്രൗണ്ടിൽ മാത്രം, ഏകദേശ ലൊക്കേഷൻ (നെറ്റ്വർക്ക്-അടിസ്ഥാനമാക്കി) ആക്സസ് ചെയ്യുക"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങൾ അടിസ്ഥാനമാക്കി, ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാൻ കഴിയും. എന്നാൽ, ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ആപ്പിന് ഇതിന് കഴിയൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ടാബ്ലെറ്റിൽ ലഭ്യമാവുകയും വേണം."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങൾ അടിസ്ഥാനമാക്കി, ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാൻ കഴിയും. എന്നാൽ, ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ആപ്പിന് ഇതിന് കഴിയൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ടിവിയിൽ ലഭ്യമാവുകയും വേണം."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"സെൽ ടവറുകളും വൈഫൈ നെറ്റ്വർക്കുകളും പോലുള്ള നെറ്റ്വർക്ക് ഉറവിടങ്ങൾ അടിസ്ഥാനമാക്കി, ഈ ആപ്പിന് നിങ്ങളുടെ ലൊക്കേഷൻ നേടാൻ കഴിയും. എന്നാൽ, ഫോർഗ്രൗണ്ടിൽ ഉള്ളപ്പോൾ മാത്രമേ ആപ്പിന് ഇതിന് കഴിയൂ. ആപ്പിന് ഉപയോഗിക്കാനായി, ഈ ലൊക്കേഷൻ സേവനങ്ങൾ ഓണായിരിക്കുകയും നിങ്ങളുടെ ഫോണിൽ ലഭ്യമാവുകയും വേണം."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"പശ്ചാത്തലത്തിൽ ലൊക്കേഷൻ ആക്സസ് ചെയ്യുക"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ഏകദേശം അല്ലെങ്കിൽ കൃത്യമായ ലൊക്കേഷൻ ആക്സസിന് ഇത് അധികമായി അനുവദിച്ചതാണെങ്കിൽ, പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുമ്പോഴും ആപ്പിന് ലൊക്കേഷൻ ആക്സസ് ചെയ്യാനാവും."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"നിങ്ങളുടെ ഓഡിയോ ക്രമീകരണങ്ങൾ മാറ്റുക"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS അഭ്യർത്ഥന, USSD അഭ്യർത്ഥനയിലേക്ക് മാറ്റി"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"പുതിയ SS അഭ്യർത്ഥനയിലേക്ക് മാറ്റി"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"വികസിപ്പിക്കുക"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ചുരുക്കുക"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"വികസിപ്പിക്കൽ ടോഗിൾ ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 45e118f..994b4d9 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi дуудлага | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Идэвхгүй"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi давуу эрхтэй"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобайл давуу эрхтэй"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Апп нь байршил нийлүүлэгчийн нэмэлт тушаалд хандах боломжтой. Энэ нь апп-д GPS эсвэл бусад байршлын үйлчилгээний ажиллагаанд нөлөөлөх боломжийг олгоно."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"нарийвчилсан байршилд зөвхөн нүүр хэсэгт хандах"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Энэ апп нь зөвхөн нүүр хэсэгт байх үедээ л таны байршлыг нарийн тогтоох боломжтой. Апп эдгээр байршлын үйлчилгээг ашиглахын тулд эдгээрийг таны утсан дээр асааж идэвхтэй байлгах шаардлагатай. Энэ нь батарейны хэрэглээг ихэсгэж болзошгүй."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ойролцоох байршилд хандах (сүлжээнд суурилсан)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Энэ апп үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний байршлын эх сурвалжийг ашиглан таны байршлыг мэдэх боломжтой. Эдгээр байршлын үйлчилгээ нь таны таблетад асаалттай байх ёстой ба апп ашиглах боломжтой байх ёстой."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Энэ апп үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний байршлын эх сурвалжийг ашиглан таны байршлыг мэдэх боломжтой. Эдгээр байршлын үйлчилгээ нь таны ТВ-д асаалттай байх ёстой ба апп ашиглах боломжтой байх ёстой."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Энэ апп үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний байршлын эх сурвалжийг ашиглан таны байршлыг мэдэх боломжтой. Эдгээр байршлын үйлчилгээ нь таны утсанд асаалттай байх ёстой ба апп ашиглах боломжтой байх ёстой."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ойролцоох байршилд (сүлжээнд суурилсан) зөвхөн дэлгэц дээр хандах"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг таблет дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг TB дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Энэ апп зөвхөн дэлгэц дээр байх үед үүрэн цамхаг, Wi-Fi сүлжээ зэрэг сүлжээний эх сурвалжид тулгуурлан таны байршлыг мэдэх боломжтой. Та энэ аппад эдгээр байршлын үйлчилгээг ашиглуулахын тулд эдгээрийг утсан дээрээ асааж, боломжтой байлгах шаардлагатай."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"байршилд ард хандах"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Хэрэв үүнийг ойролцоо эсвэл нарийвчилсан байршлын хандалтад нэмэлтээр зөвшөөрсөн бол энэ апп ард ажиллах явцдаа байршилд хандаж болно."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Аудио тохиргоо солих"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS хүсэлтийг USSD хүсэлт болгон өөрчилсөн"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Шинэ SS хүсэлт болгон өөрчилсөн"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Ажлын профайл"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Дэлгэх"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Буулгах"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"унтраах/асаах өргөтгөл"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index fb4c408..ca7f6df 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> वाय-फाय"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"वाय-फाय कॉलिंग | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"बंद"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"वाय-फाय अग्रमानांकित"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"प्राधान्य दिलेला मोबाइल"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अॅपला अतिरिक्त स्थान प्रदाता आदेशावर प्रवेश करण्याची अनुमती देते. हे कदाचित अॅपला GPS किंवा इतर स्थान स्त्रोत च्या ऑपरेशनमध्ये हस्तक्षेप करण्याची अनुमती देऊ शकते."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"फक्त फोरग्राउंडमध्ये अचूकपणे अॅक्सेस करा"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच तुमचे अचूक स्थान मिळवू शकते. या स्थान सेवा सुरू करणे आणि त्या वापरण्यासाठी अॅपसाठी तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे, यामुळे बॅटरी वापर वाढू शकतो."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अंदाजे स्थानामध्ये (नेटवर्क-आधारित) अॅक्सेस करा"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या टॅब्लेटवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या टीव्हीवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"हा अॅप सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतांच्या आधारावर तुमचे स्थान मिळवू शकतो. अॅपला या स्थान सेवा वापरण्यास सक्षम असण्यासाठी तुमच्या फोनवर त्या चालू केलेल्या आणि उपलब्ध असणे आवश्यक आहे."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"फक्त फोरग्राउंडमध्ये अंदाजे स्थान (नेटवर्क आधारित) अॅक्सेस करा"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टॅबलेटवर उपलब्ध करणे आवश्यक आहे."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. त्या वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या टीव्हीवर उपलब्ध करणे आवश्यक आहे."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"हे अॅप फक्त फोरग्राउंडमध्ये असतानाच, सेल टॉवर आणि वाय-फाय नेटवर्क सारख्या नेटवर्क स्रोतवर आधारित तुमचे स्थान मिळवू शकते. ते वापरण्याकरता अॅपसाठी, या स्थान सेवा सुरू करणे आणि त्या तुमच्या फोनवर उपलब्ध करणे आवश्यक आहे."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"बॅकग्राउंडमध्ये स्थान अॅक्सेस करू शकतो"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"याला अंदाजे किंवा अचूक स्थान अॅक्सेस करण्यास अतिरिक्त मंजूरी दिल्यास, बॅकग्राउंडमध्ये चालतांना अॅप स्थान अॅक्सेस करू शकतो."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"आपल्या ऑडिओ सेटिंग्ज बदला"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS विनंती USSD विनंतीवर बदलली"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"नवीन SS विनंतीवर बदलली"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफाईल"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"विस्तृत करा"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"संकुचित करा"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"टॉगल विस्तार"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 2896923..a1af8f2 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Panggilan Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Mati"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi diutamakan"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mudah alih diutamakan"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Membenarkan apl mengakses arahan pembekal lokasi tambahan. Ini boleh membenarkan apl untuk campur tangan dengan operasi GPS atau sumber lokasi lain."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"akses lokasi tepat hanya di latar depan"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Apl ini boleh mendapatkan lokasi tepat anda hanya apabila apl tersebut berada di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada telefon anda untuk membolehkan apl menggunakan perkhidmatan tersebut. Tindakan ini mungkin meningkatkan penggunaan bateri."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"akses lokasi anggaran (berasaskan rangkaian)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada tablet anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada TV anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada telefon anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"akses lokasi anggaran (berdasarkan rangkaian) hanya di latar depan"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada tablet anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada TV anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Apl ini boleh mendapatkan lokasi anda berdasarkan sumber rangkaian seperti menara selular dan rangkaian Wi-Fi, tetapi hanya apabila apl itu di latar depan. Perkhidmatan lokasi ini mesti dihidupkan dan tersedia pada telefon anda untuk membolehkan apl menggunakan perkhidmatan tersebut."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"akses lokasi di latar belakang"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Jika tindakan ini dibenarkan bagi akses lokasi anggaran atau lokasi tepat, apl tersebut boleh mengakses lokasi itu semasa berjalan di latar belakang."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"tukar tetapan audio anda"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Permintaan SS ditukar kepada permintaan USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Bertukar kepada permintaan SS baharu"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil kerja"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Kembangkan"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Runtuhkan"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"togol pengembangan"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index e509577..372be10 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi ခေါ်ဆိုမှု | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ပိတ်ထားရသည်"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ဝိုင်ဖိုင်အား ပိုနှစ်သက်သော"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"မိုဘိုင်းကို အသုံးပြုလိုပါသည်"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"အက်ပ်အား တည်နေရာ စီမံပေးရေး ညွှန်ကြားချက် အပိုများကို ရယူခွင့်ပြုသည်။ သို့ဖြစ်၍ အက်ပ်သည် GPS သို့မဟုတ် အခြား တည်နေရာ ရင်းမြစ်ကို သုံးကြသူတို့၏ လုပ်ငန်းများကို ဝင်စွက်ခွင့် ပြုနိုင်သည်။"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"မျက်နှာစာတွင်သာ တည်နေရာအတိအကျ အသုံးပြုခြင်း"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"မျက်နှာစာတွင် ဖွင့်ထားမှသာ ဤအက်ပ်က သင်၏တည်နေရာအတိအကျကို ရယူနိုင်ပါသည်။ သင်၏ဖုန်းတွင် အက်ပ်ကအသုံးပြုရန်အတွက် ဤတည်နေရာဝန်ဆောင်မှုများကို ဖွင့်ထားပြီး အသုံးပြု၍ ရပါမည်။ ၎င်းက ဘက်ထရီ ပိုကုန်နိုင်ပါသည်။"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"အနီးစပ်ဆုံး တည်နေရာ (ကွန်ရက် အခြေခံ)ကို ရယူသုံးရန်"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ဤအက်ပ်သည် ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်အရင်းအမြစ်ပေါ် အခြေခံပြီး သင့်တည်နေရာအချက်အလက်ကို ရယူနိုင်ပါသည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်တက်ဘလက်ပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ဤအက်ပ်သည် ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်အရင်းအမြစ်ပေါ် အခြေခံပြီး သင့်တည်နေရာအချက်အလက်ကို ရယူနိုင်ပါသည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်တီဗီပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ဤအက်ပ်သည် ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်အရင်းအမြစ်ပေါ် အခြေခံပြီး သင့်တည်နေရာအချက်အလက်ကို ရယူနိုင်ပါသည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်ဖုန်းပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"မျက်နှာစာတွင်သာ (ကွန်ရက် အခြေပြု) တည်နေရာခန့်မှန်း အသုံးပြုခြင်း"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ဤအက်ပ်က ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များအပေါ် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သော်လည်း အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားမှ ရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်တက်ဘလက်ပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ဤအက်ပ်က ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များအပေါ် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သော်လည်း အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားမှ ရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်တီဗီပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ဤအက်ပ်က ဆဲလ်တာဝါများနှင့် Wi-Fi ကွန်ရက်များကဲ့သို့ ကွန်ရက်ရင်းမြစ်များအပေါ် အခြေခံပြီး သင်၏တည်နေရာကို ရယူနိုင်သော်လည်း အက်ပ်ကို မျက်နှာစာတွင်ဖွင့်ထားမှ ရပါမည်။ အက်ပ်က အသုံးပြုနိုင်ရန်အတွက် ဤတည်နေရာ ဝန်ဆောင်မှုများကို ဖွင့်ထားရမည် ဖြစ်ပြီး သင့်ဖုန်းပေါ်တွင် ရရှိနိုင်ရပါမည်။"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"နောက်ခံတွင် တည်နေရာကို အသုံးပြုရန်"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ခန့်မှန်းခြေ သို့မဟုတ် တိကျသော တည်နေရာ ဝင်သုံးခွင့်အတွက် ၎င်းကို နောက်ဆက်တွဲ ခွင့်ပြုထားပါက နောက်ခံတွင် လုပ်ဆောင်နေစဉ် အက်ပ်က တည်နေရာကို ရယူအသုံးပြုနိုင်ပါသည်။"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"သင့်အသံအပြင်အဆင်အားပြောင်းခြင်း"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS တောင်းဆိုမှုကို USSD တောင်းဆိုမှုအဖြစ် ပြောင်းထားသည်"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"SS တောင်းဆိုမှုအသစ်သို့ ပြောင်းထားသည်"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"အလုပ်ကိုယ်ရေးအချက်အလက်"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ချဲ့ရန်"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ခေါက်သိမ်းရန်"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ချဲ့ခြင်းခလုတ်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b47c965..5fc75ad 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-anrop | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi er foretrukket"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Først-på-mobil"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Appen gis tillatelse til å bruke ekstra kommandoer fra posisjonsleverandører. Dette kan gi appen tillatelse til å påvirke bruken av GPS eller andre posisjonskilder."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"bare tilgang til nøyaktig posisjon i forgrunnen"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Denne appen kan bare få den nøyaktige posisjonen din når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på telefonen din for at appen skal kunne bruke dem. Dette kan øke batteriforbruket."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"få tilgang til omtrentlig posisjon (nettverksbasert)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Denne appen kan få posisjonen din fra nettverkskilder som mobilmaster og Wi-Fi-nettverk. Disse posisjonstjenestene må være slått på og tilgjengelige på nettbrettet ditt for at appen skal kunne bruke dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Denne appen kan få posisjonen din fra nettverkskilder som mobilmaster og Wi-Fi-nettverk. Disse posisjonstjenestene må være slått på og tilgjengelige på TV-en din for at appen skal kunne bruke dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Denne appen kan få posisjonen din fra nettverkskilder som mobilmaster og Wi-Fi-nettverk. Disse posisjonstjenestene må være slått på og tilgjengelige på telefonen din for at appen skal kunne bruke dem."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"bare tilgang til omtrentlig posisjon (nettverksbasert) i forgrunnen"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på nettbrettet ditt for at appen skal kunne bruke dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på TV-en din for at appen skal kunne bruke dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Denne appen kan bare få posisjonen din basert på nettverkskilder, for eksempel mobilmaster og Wi-Fi-nettverk, når den er på i forgrunnen. Disse posisjonstjenestene må være slått på og tilgjengelige på telefonen din for at appen skal kunne bruke dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"tilgang til posisjon i bakgrunnen"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Hvis du gir denne tillatelsen, får appen tilgang til posisjonen mens den kjører i bakgrunnen, i tillegg til tilgang til omtrentlig eller presis posisjon."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"endre lydinnstillinger"</string>
@@ -528,7 +536,7 @@
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Deler av fingeravtrykket er registrert. Prøv på nytt."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Kunne ikke registrere fingeravtrykket. Prøv på nytt."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Fingeravtrykksensoren er skitten. Rengjør den og prøv på nytt."</string>
- <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Du flyttet fingeren for kjapt. Prøv på nytt."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Du flyttet fingeren for raskt. Prøv på nytt."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Du flyttet fingeren for sakte. Prøv på nytt."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
@@ -541,7 +549,7 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Tidsavbrudd for fingeravtrykk er nådd. Prøv på nytt."</string>
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Fingeravtrykk-operasjonen ble avbrutt."</string>
<string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Fingeravtrykk-operasjonen ble avbrutt av brukeren."</string>
- <string name="fingerprint_error_lockout" msgid="5536934748136933450">"For mange forsøk. Prøve på nytt senere."</string>
+ <string name="fingerprint_error_lockout" msgid="5536934748136933450">"For mange forsøk. Prøv på nytt senere."</string>
<string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"For mange forsøk. Fingeravtrykkssensoren er slått av."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Prøv igjen."</string>
<string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Ingen fingeravtrykk er registrert."</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-forespørsel endret til USSD-forespørsel"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Endret til ny SS-forespørsel"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbeidsprofil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Vis"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Skjul"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"slå utvidelse av/på"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 47d4d6a..cddd308 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wifi कलिङ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"निष्क्रिय"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi मनपराइयो"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"रूचाइएको मोबाइल"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"अनुप्रयोगलाई अतिरिक्त स्थान प्रदायक आदेशहरू पहुँच गर्न अनुमति दिन्छ। यो अनुप्रयोगलाई GPS वा अन्य स्थान स्रोतहरूको संचालन साथै हस्तक्षेप गर्न अनुमति दिन सक्छ।"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"अग्रभूमिमा मात्र सटीक स्थानमाथि पहुँच राख्नुहोस्"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"यो अनुप्रयोगले अग्रभागमा चलिरहेको अवस्थामा मात्र तपाईंलाई स्थानको सटिक जानकारी दिन सक्छ। यी स्थानसम्बन्धी सेवाहरू अनिवार्य रूपमा सक्रिय गरिएका हुनु पर्छ र अनुप्रयोगले यिनीहरूको प्रयोग गर्न सकोस् भन्नाका खातिर तपाईंको फोनमै उपलब्ध हुन्छन्। यस कार्यले गर्दा ब्याट्री बढी खर्च हुन सक्छ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"अनुमानित स्थान पहुँच गराउनुहोस् (नेटवर्कमा आधारित)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको ट्याब्लेटमा उपलब्ध हुनु पर्छ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको TV मा उपलब्ध हुनु पर्छ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको फोनमा उपलब्ध हुनु पर्छ।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"अग्रभूमिमा मात्र अनुमानित स्थान (नेटवर्कमा आधारित) माथि पहुँच राख्नुहोस्"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको ट्याब्लेटमा उपलब्ध हुनु पर्छ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको TV मा उपलब्ध हुनु पर्छ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"यस अनुप्रयोगले सेलका टावर र Wi-Fi नेटवर्कहरू जस्ता नेटवर्कका स्रोतहरूको आधारमा तपाईंको स्थान बारे जानकारी प्राप्त गर्न सक्छ। यो अनुप्रयोग ती स्रोतहरूको प्रयोग गर्न सक्षम होस् भन्नका खातिर यी स्थान सम्बन्धी सेवाहरूलाई अनिवार्य रूपमा सक्रिय पार्नुपर्छ र यी तपाईंको फोनमा उपलब्ध हुनु पर्छ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"पृष्ठभूमिमा स्थानसम्बन्धी पहुँच"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"यसका अतिरिक्त यसलाई अनुमानित वा सटिक स्थानमाथि पहुँच राख्ने अनुमति दिइएको छ भने उक्त अनुप्रयोगले पृष्ठभूमिमा चलिरहेको बेला स्थानमाथि पहुँच राख्न सक्छ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"तपाईँका अडियो सेटिङहरू परिवर्तन गर्नुहोस्"</string>
@@ -1831,6 +1839,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS अनुरोधलाई USSD अनुरोधमा परिवर्तन गरियो"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"नयाँ SS अनुरोधमा परिवर्तन गरियो"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफाइल"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"विस्तृत गर्नुहोस्"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"संक्षिप्त गर्नुहोस्"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"विस्तारलाई टगल गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ed79f7b..c1883fa 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wifi van <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Bellen via wifi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi van <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Uit"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Voorkeur voor wifi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Voorkeur voor mobiel"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Hiermee kan de app toegang krijgen tot extra opdrachten voor de locatieprovider. De app kan hiermee de werking van gps of andere locatiebronnen te verstoren."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"alleen toegang tot precieze locatie op de voorgrond"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Deze app kan je exacte locatie ophalen wanneer de app op de voorgrond wordt uitgevoerd. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je telefoon. Hierdoor kan het batterijverbruik toenemen."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"toegang tot geschatte locatie (netwerkgebaseerd)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je tablet."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je tv."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je telefoon."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"alleen toegang tot geschatte locatie (op basis van netwerk) op de voorgrond"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen wanneer de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je tablet."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen wanneer de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je tv."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Deze app kan je locatie ophalen op basis van netwerkbronnen zoals zendmasten en wifi-netwerken, maar alleen wanneer de app zich op de voorgrond bevindt. De app kan alleen gebruikmaken van deze locatieservices als ze zijn ingeschakeld en beschikbaar zijn op je telefoon."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"toegang tot locatie op de achtergrond"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Als dit wordt verleend als aanvulling op toegang tot de geschatte of precieze locatie, kan de app toegang tot de locatie krijgen terwijl de app actief is op de achtergrond."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"je audio-instellingen wijzigen"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-verzoek gewijzigd in USSD-verzoek"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Gewijzigd in nieuw SS-verzoek"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Werkprofiel"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Uitvouwen"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Samenvouwen"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"uitvouwen in-/uitschakelen"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 031cacb..59c689b 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ୱାଇ-ଫାଇ"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ୱାଇଫାଇ କଲିଂ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ଅଫ୍"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ପସନ୍ଦ କରାଯାଇଥିବା ୱାଇ-ଫାଇ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ପସନ୍ଦର ମୋବାଇଲ୍"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ଅତିରିକ୍ତ ଲୋକେଶନ୍ ପ୍ରଦାନକାରୀ କମାଣ୍ଡ ଆକ୍ସେସ୍ କରିବା ପାଇଁ ଆପ୍କୁ ଅନୁମତି ଦିଏ। GPS କିମ୍ବା ଅନ୍ୟ ଲୋକେଶନ୍ ସୋର୍ସଗୁଡିକରେ ଆପ୍ଟି ପ୍ରଭାବ ପକାଇପାରେ।"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"କେବଳ ସମ୍ମୁଖଭାଗରେ ସଠିକ୍ ଲୋକେଶନ୍ର ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ଏହି ଆପ୍ ଯେତେବେଳେ ସମ୍ମୁଖଭାଗରେ ଥିବାବେଳେ ଆପଣଙ୍କର ସଠିକ୍ ଲୋକେଶନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେଶନ୍ ସେବାଗୁଡ଼ିକ ନିଶ୍ଚିତରୂପେ ଅନ୍ ରହିବା ଦରକାର ଏବଂ ଆପ୍ର ବ୍ୟବହାର ପାଇଁ ଫୋନ୍ରେ ଉପଲବ୍ଧ ଥିବା ଦରକାର। ଏହା ବ୍ୟାଟେରୀ ଅଧିକା ଖର୍ଚ୍ଚ କରିପାରେ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ପାଖାପାଖି ଲୋକେଶନ୍ ଆକ୍ସେସ୍ କରେ (ନେଟ୍ୱର୍କ-ଆଧାରିତ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ଏହି ଆପ୍, ନେଟ୍ୱର୍କ ସୋର୍ସ ଉପରେ ଆଧାର କରି ଆପଣଙ୍କ ଲୋକେଶନ୍ ପ୍ରାପ୍ତ କରିପାରେ, ଯେପରିକି ସେଲ୍ ଟାୱାର୍ ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ। ଏହି ଲୋକେଶନ୍ ସେବା, ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଅନ୍ ରହିଥିବା ଓ ଉପଲବ୍ଧ ଥିବା ଦରକାର, ଯେଉଁଥିରୁ ଆପ୍ ସେଗୁଡ଼ିକର ବ୍ୟବହାର କରିପାରିବ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ଏହି ଆପ୍, ନେଟ୍ୱର୍କ ସୋର୍ସ ଉପରେ ଆଧାର କରି ଆପଣଙ୍କ ଲୋକେଶନ୍ ପ୍ରାପ୍ତ କରିପାରେ, ଯେପରିକି ସେଲ୍ ଟାୱାର୍ ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ। ଏହି ଲୋକେଶନ୍ ସେବା, ଆପଣଙ୍କ ଟିଭିରେ ଅନ୍ ରହିଥିବା ଓ ଉପଲବ୍ଧ ଥିବା ଦରକାର, ଯେଉଁଥିରୁ ଆପ୍ ସେଗୁଡ଼ିକର ବ୍ୟବହାର କରିପାରିବ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ସୋର୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେଶନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେଶନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଅନ୍ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଫୋନ୍ରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"କେବଳ ସମ୍ମୁଖଭାଗରେ ହାରାହାରି ଲୋକେସନ୍ (ନେଟ୍ୱର୍କ-ଆଧାରିତ)ର ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଚାଲୁ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଟାବ୍ଲେଟ୍ରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ ଅଟେ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଚାଲୁ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଟିଭିରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ ଅଟେ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ସେଲ୍ ଟାୱାର ଓ ୱାଇ-ଫାଇ ନେଟ୍ୱର୍କ ପରି ଉତ୍ସକୁ ଆଧାର କରି ଏହି ଆପ୍ ଆପଣଙ୍କ ଲୋକେସନ୍ ପ୍ରାପ୍ତ କରିପାରିବ। ଏହି ଲୋକେସନ୍ ସେବାଗୁଡ଼ିକର ବ୍ୟବହାର କରିବାକୁ ସେଗୁଡ଼ିକ ଚାଲୁ କରାଯିବା ଏବଂ ଆପଣଙ୍କ ଫୋନ୍ରେ ଉପଲବ୍ଧ ଥିବା ଜରୁରୀ ଅଟେ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ୍ରେ ଲୋକେସନ୍ ଆକ୍ସେସ୍ କରନ୍ତୁ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ଅନୁମାନିତ କିମ୍ବା ବିଲ୍କୁଲ୍ ସଠିକ୍ ସ୍ଥାନ ଆକ୍ସେସ୍ କରିବାର ଅନୁମତି ଅତିରିକ୍ତ ଭାବରେ ଦିଆଗଲେ, ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡରେ ଚାଲୁଥିବା ସମୟରେ ଆପ୍ ଆପଣଙ୍କର ସ୍ଥାନର ଆକ୍ସେସ୍ କରିପାରିବ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ଆପଣଙ୍କ ଅଡିଓ ସେଟିଙ୍ଗକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS ଅନୁରୋଧ, USSD ଅନୁରୋଧକୁ ପରିବର୍ତ୍ତନ ହେଲା"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"ନୂତନ SS ଅନୁରୋଧରେ ପରିବର୍ତ୍ତନ ହେଲା"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ୱର୍କ ପ୍ରୋଫାଇଲ୍"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ବଢ଼ାନ୍ତୁ"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ଛୋଟ କରନ୍ତୁ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ଟୋଗଲ୍ ସମ୍ପ୍ରସାରଣ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2b30459..0bbe94d 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> ਵਾਈ-ਫਾਈ"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ਬੰਦ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ਤਰਜੀਹੀ ਵਾਈ-ਫਾਈ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ਮੋਬਾਈਲ ਨੂੰ ਤਰਜੀਹ ਹੈ"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ਐਪ ਨੂੰ ਵਾਧੂ ਟਿਕਾਣਾ ਪ੍ਰਦਾਤਾ ਕਮਾਂਡਾਂ ਤੱਕ ਪਹੁੰਚ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ। ਇਹ ਐਪ ਨੂੰ GPS ਜਾਂ ਹੋਰ ਟਿਕਾਣਾ ਸਰੋਤਾਂ ਦੇ ਓਪਰੇਸ਼ਨ ਵਿੱਚ ਵਿਘਨ ਪਾਉਣ ਦੀ ਆਗਿਆ ਦੇ ਸਕਦਾ ਹੈ।"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"ਸਿਰਫ਼ ਫੋਰਗ੍ਰਾਊਂਡ ਵਿੱਚ ਸਟੀਕ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ਇਹ ਐਪ ਫੋਰਗ੍ਰਾਉਂਡ ਵਿੱਚ ਹੋਣ \'ਤੇ ਹੀ ਤੁਹਾਡਾ ਸਟੀਕ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕਰਨ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ। ਇਸ ਨਾਲ ਬੈਟਰੀ ਦੀ ਖਪਤ ਵਧ ਸਕਦੀ ਹੈ।"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ਅੰਦਾਜ਼ਨ ਟਿਕਾਣੇ \'ਤੇ ਪਹੁੰਚ ਕਰੋ (ਨੈੱਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਦੁਆਰਾ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ਸਿਰਫ਼ ਫੋਰਗ੍ਰਾਊਂਡ ਵਿੱਚ ਅਨੁਮਾਨਿਤ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰੋ (ਨੈੱਟਵਰਕ-ਆਧਾਰਿਤ)"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਟੀਵੀ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ਇਹ ਐਪ ਨੈੱਟਵਰਕ ਸਰੋਤਾਂ ਜਿਵੇਂ ਕਿ ਸੈੱਲ ਟਾਵਰਾਂ ਅਤੇ ਵਾਈ-ਫਾਈ ਨੈੱਟਵਰਕਾਂ \'ਤੇ ਆਧਾਰਿਤ ਤੁਹਾਡਾ ਟਿਕਾਣਾ ਪਤਾ ਕਰ ਸਕਦੀ ਹੈ, ਪਰ ਸਿਰਫ਼ ਐਪ ਦੇ ਫੋਰਗ੍ਰਾਊਂਡ ਹੋਣ \'ਤੇ ਹੀ। ਐਪ ਵੱਲੋਂ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦੀ ਵਰਤੋਂ ਕੀਤੇ ਜਾਣ ਦੇ ਯੋਗ ਹੋਣ ਲਈ ਇਹ ਸੇਵਾਵਾਂ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਉਪਲਬਧ ਹੋਣੀਆਂ ਅਤੇ ਚਾਲੂ ਕੀਤੀਆਂ ਹੋਣੀਆਂ ਲਾਜ਼ਮੀ ਹਨ।"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"ਐਪ ਨੂੰ ਵਧੀਕ ਤੌਰ \'ਤੇ ਅਨੁਮਾਨਿਤ ਜਾਂ ਸਟੀਕ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਦੇਣ \'ਤੇ ਇਹ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵੇਲੇ ਟਿਕਾਣੇ ਤੱਕ ਪਹੁੰਚ ਕਰ ਸਕਦੀ ਹੈ।"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ਆਪਣੀਆਂ ਆਡੀਓ ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS ਬੇਨਤੀ ਨੂੰ USSD ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"ਨਵੀਂ SS ਬੇਨਤੀ ਵਿੱਚ ਬਦਲਿਆ ਗਿਆ"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ਵਿਸਤਾਰ ਕਰੋ"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ਸੁੰਗੇੜੋ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ਟੌਗਲ ਵਿਸਤਾਰ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7ef4907..f36edf4 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g>, Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Połączenia przez Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g>, VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Wył."</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferuj Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferowane komórkowe"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Pozwala aplikacji na dostęp do dodatkowych poleceń dostawcy informacji o lokalizacji. Aplikacje z tym uprawnieniem mogą wpływać na działanie GPS-a lub innych źródeł lokalizacji."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"dostęp do dokładnej lokalizacji tylko na pierwszym planie"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ta aplikacja może określić Twoją dokładną lokalizację tylko wtedy, gdy działa na pierwszym planie. Te usługi lokalizacyjne muszą być włączone i dostępne na telefonie, by aplikacja mogła z nich korzystać. Może to zwiększyć zużycie baterii."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"dostęp do przybliżonej lokalizacji (na podstawie sieci)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych, takich jak stacje bazowe i sieci Wi-Fi. Te usługi lokalizacyjne muszą być włączone i dostępne na tablecie, by aplikacja mogła z nich korzystać."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych, takich jak stacje bazowe i sieci Wi-Fi. Te usługi lokalizacyjne muszą być włączone i dostępne na telewizorze, by aplikacja mogła z nich korzystać."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych, takich jak stacje bazowe i sieci Wi-Fi. Te usługi lokalizacyjne muszą być włączone i dostępne na telefonie, by aplikacja mogła z nich korzystać."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"dostęp do przybliżonej lokalizacji (na podstawie sieci) tylko na pierwszym planie"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Wymienione usługi lokalizacyjne muszą być włączone i dostępne na tablecie, by aplikacja mogła z nich korzystać."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Wymienione usługi lokalizacyjne muszą być włączone i dostępne na telewizorze, by aplikacja mogła z nich korzystać."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ta aplikacja może określać Twoją lokalizację na podstawie źródeł sieciowych takich jak stacje bazowe i sieci Wi-Fi, ale tylko wtedy, gdy działa na pierwszym planie. Wymienione usługi lokalizacyjne muszą być włączone i dostępne na telefonie, by aplikacja mogła z nich korzystać."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"dostęp do lokalizacji w tle"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Jeśli te uprawnienia zostaną przyznane wraz z dostępem do dokładnej lub przybliżonej lokalizacji, aplikacja będzie mogła uzyskiwać dostęp do lokalizacji podczas działania w tle."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"zmienianie ustawień audio"</string>
@@ -650,7 +658,7 @@
<string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Pozwala aplikacji na odczyt i zmianę konfiguracji trybu Nie przeszkadzać."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Kontrolowanie długości haseł blokady ekranu i kodów PIN oraz dozwolonych w nich znaków."</string>
- <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitoruj próby odblokowania ekranu"</string>
+ <string name="policylab_watchLogin" msgid="5091404125971980158">"Monitorowanie prób odblokowania ekranu"</string>
<string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Przy odblokowywaniu ekranu monitoruj, ile razy wpisano nieprawidłowe hasło i blokuj tablet lub usuń z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy."</string>
<string name="policydesc_watchLogin" product="TV" msgid="2707817988309890256">"Monitorowanie, ile razy wpisano niepoprawne hasło podczas odblokowywania ekranu, oraz blokowanie telewizora albo kasowanie na nim wszystkich danych, gdy zbyt wiele razy wpisano niepoprawne hasło."</string>
<string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Przy odblokowywaniu ekranu monitoruje, ile razy wpisano nieprawidłowe hasło, i blokuje telefon lub usuwa z niego wszystkie dane, jeśli nieprawidłowe hasło podano zbyt wiele razy"</string>
@@ -671,11 +679,11 @@
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"Kasowanie danych tego użytkownika na tym telefonie bez ostrzeżenia."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Ustaw globalny serwer proxy urządzenia"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"Ustawianie globalnego serwera proxy urządzenia do użycia przy włączonych zasadach. Tylko właściciel urządzenia może ustawić globalny serwer proxy."</string>
- <string name="policylab_expirePassword" msgid="5610055012328825874">"Ustaw czas ważności hasła blokady ekranu"</string>
+ <string name="policylab_expirePassword" msgid="5610055012328825874">"Ustawianie czasu ważności hasła blokady ekranu"</string>
<string name="policydesc_expirePassword" msgid="5367525762204416046">"Zmiana częstotliwości, z jaką należy zmieniać hasło blokady ekranu, kod PIN lub wzór."</string>
- <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ustaw szyfrowanie pamięci"</string>
+ <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Ustawianie szyfrowania pamięci"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Wymaganie szyfrowania przechowywanych danych aplikacji"</string>
- <string name="policylab_disableCamera" msgid="6395301023152297826">"Wyłącz aparaty"</string>
+ <string name="policylab_disableCamera" msgid="6395301023152297826">"Wyłączanie aparatów"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"Zapobieganie używaniu wszystkich aparatów w urządzeniu"</string>
<string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"Wył. funkcji blokady ekranu"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"Zapobieganie użyciu niektórych funkcji blokady ekranu."</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Żądanie SS zmienione na żądanie USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Zmieniono na nowe żądanie SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil służbowy"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Rozwiń"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Zwiń"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"przełącz rozwijanie"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 5ab4fce..05bb1ed 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamada no Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"acessar localização precisa apenas em primeiro plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Este app pode ver sua localização exata a qualquer momento apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"acessar localização aproximada (com base na rede)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis na sua TV para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"acessar localização aproximada (baseada em rede) apenas em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis na sua TV para que o app possa usá-los."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"acessar a localização em segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se essa permissão for concedida, além do acesso à localização precisa ou aproximada, o app poderá acessar a localização durante a execução em segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas configurações de áudio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Solicitação SS alterada para solicitação USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Alterada para uma nova solicitação SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expandir"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Recolher"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"alternar expansão"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index ec853bb..abb0023 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamadas Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Rede Wi-Fi preferida"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que a aplicação aceda a comandos adicionais do fornecedor de localização. Esta opção pode permitir que a aplicação interfira com o funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"apenas aceder à localização exata em primeiro plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Esta aplicação apenas pode obter a sua localização exata quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu telemóvel para que a aplicação os possa utilizar. Esta ação pode aumentar o consumo da bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"aceder à localização aproximada (baseada na rede)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi. É necessário que estes serviços de localização estejam ativados e disponíveis no seu tablet para que a aplicação os possa utilizar."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi. É necessário que estes serviços de localização estejam ativados e disponíveis na sua TV para que a aplicação os possa utilizar."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi. É necessário que estes serviços de localização estejam ativados e disponíveis no seu telemóvel para que a aplicação os possa utilizar."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"aceder à localização aproximada (baseada na rede) apenas em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu tablet para que a aplicação os possa utilizar."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis na sua TV para que a aplicação os possa utilizar."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esta aplicação pode obter a sua localização com base em fontes de rede, tais como torres de redes móveis e redes Wi-Fi, mas apenas quando estiver em primeiro plano. É necessário que estes Serviços de localização estejam ativados e disponíveis no seu telemóvel para que a aplicação os possa utilizar."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"aceder à localização em segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se tal for concedido em conjunto com o acesso à localização aproximada ou exata, a aplicação pode aceder à localização mesmo estando em segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas definições de áudio"</string>
@@ -1341,7 +1349,7 @@
<string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="alert_windows_notification_channel_group_name" msgid="1463953341148606396">"Sobrepor a outras aplicações"</string>
<string name="alert_windows_notification_channel_name" msgid="3116610965549449803">"A aplicação <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplicações"</string>
- <string name="alert_windows_notification_title" msgid="3697657294867638947">"O <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras aplic."</string>
+ <string name="alert_windows_notification_title" msgid="3697657294867638947">"O <xliff:g id="NAME">%s</xliff:g> sobrepõe-se a outras app"</string>
<string name="alert_windows_notification_message" msgid="8917232109522912560">"Se não pretende que a aplicação <xliff:g id="NAME">%s</xliff:g> utilize esta funcionalidade, toque para abrir as definições e desative-a."</string>
<string name="alert_windows_notification_turn_off_action" msgid="2902891971380544651">"Desligar"</string>
<string name="ext_media_checking_notification_title" msgid="4411133692439308924">"A verificar o <xliff:g id="NAME">%s</xliff:g>…"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"O pedido SS foi alterado para um novo pedido USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Foi alterado para um novo pedido SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expandir"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Reduzir"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ativar/desativar expansão"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 5ab4fce..05bb1ed 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi de <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Chamada no Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi de <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi preferido"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferência pela rede móvel"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite que o app acesse comandos do provedor não relacionados à localização. Isso pode permitir que o app interfira no funcionamento do GPS ou de outras fontes de localização."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"acessar localização precisa apenas em primeiro plano"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Este app pode ver sua localização exata a qualquer momento apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los. Isso pode aumentar o consumo de bateria."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"acessar localização aproximada (com base na rede)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis na sua TV para que o app possa usá-los."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Este app pode ver seu local com base nas fontes de rede, como torres de celular e redes Wi-Fi. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"acessar localização aproximada (baseada em rede) apenas em primeiro plano"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu tablet para que o app possa usá-los."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis na sua TV para que o app possa usá-los."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Esse app pode acessar sua localização com base em fontes de rede, como torres de celular e redes Wi-Fi, mas apenas quando está em primeiro plano. Esses serviços de localização precisam estar ativados e disponíveis no seu smartphone para que o app possa usá-los."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"acessar a localização em segundo plano"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Se essa permissão for concedida, além do acesso à localização precisa ou aproximada, o app poderá acessar a localização durante a execução em segundo plano."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"alterar as suas configurações de áudio"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Solicitação SS alterada para solicitação USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Alterada para uma nova solicitação SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Expandir"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Recolher"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"alternar expansão"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7c4a571..40812fd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Apelare prin Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Dezactivată"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Se preferă conexiunea Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Se preferă datele mobile"</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Permite aplicației să acceseze comenzi suplimentare pentru furnizorul locației. Aplicația ar putea să utilizeze această permisiune pentru a influența operațiile GPS sau ale altor surse de locații."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"să acceseze locația exactă în prim-plan"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Aplicația vă poate obține locația exactă numai când rulează în prim-plan. Serviciile de localizare trebuie să fie activate și disponibile pe telefon pentru ca aplicația să le poată folosi. Acest lucru poate accelera descărcarea bateriei."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"să acceseze locația aproximativă (bazată pe rețea)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Această aplicație vă poate obține locația cu ajutorul surselor rețelei, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi. Aceste servicii de localizare trebuie să fie activate și disponibile pe tabletă pentru ca aplicația să le poată folosi."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Această aplicație vă poate obține locația cu ajutorul surselor rețelei, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi. Aceste servicii de localizare trebuie să fie activate și disponibile pe televizor pentru ca aplicația să le poată folosi."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Această aplicație vă poate obține locația cu ajutorul surselor rețelei, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi. Aceste servicii de localizare trebuie să fie activate și disponibile pe telefon pentru ca aplicația să le poată folosi."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"să acceseze locația aproximativă (bazată pe rețea) doar în prim-plan"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe tabletă pentru ca aplicația să le poată folosi."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe televizor pentru ca aplicația să le poată folosi."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Aplicația vă poate determina locația folosind sursele din rețea, cum ar fi turnurile de telefonie mobilă și rețelele Wi-Fi, însă numai când rulează în prim-plan. Aceste servicii de localizare trebuie să fie activate și disponibile pe telefon pentru ca aplicația să le poată folosi."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"accesați locația în fundal"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Dacă se acordă în plus față de accesul la locație aproximativă sau exactă, aplicația poate accesa locația în timp ce rulează în fundal."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"modificare setări audio"</string>
@@ -1858,6 +1866,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Solicitarea SS a fost schimbată cu o solicitare USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Schimbat cu o solicitare SS nouă"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil de serviciu"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Extindeți"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Restrângeți"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"extindeți/restrângeți"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index ece22b1..766a68b 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Звонки по Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Отключено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Приоритет Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Приоритет мобильного Интернета"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Доступ к дополнительным командам управления источниками геоданных и вмешательство в работу системы GPS или других источников геоданных."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"Доступ к точному местоположению только в фоновом режиме"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Приложение может получать сведения о вашем точном местоположении только в фоновом режиме. Для этого необходимо включить соответствующие параметры на телефоне и разрешить использовать геоданные. Может увеличиться расход заряда батареи."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"Доступ к примерному местоположению (по координатам сети)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Приложение может получать сведения о вашем местоположении от сетевых источников, таких как вышки сотовой связи и точки доступа Wi-Fi. Необходимо включить соответствующие параметры на планшете и разрешить приложению использовать геоданные."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Приложение может получать сведения о вашем местоположении от сетевых источников, таких как вышки сотовой связи и точки доступа Wi-Fi. Необходимо включить соответствующие параметры на телевизоре и разрешить приложению использовать геоданные."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Приложение может получать сведения о вашем местоположении от сетевых источников, таких как вышки сотовой связи и точки доступа Wi-Fi. Необходимо включить соответствующие параметры на телефоне и разрешить приложению использовать геоданные."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"Доступ к примерному местоположению (по координатам сети) только в фоновом режиме"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Приложение может получать сведения о вашем местоположении от источников сетей, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в фоновом режиме. Для этого необходимо включить соответствующие параметры на планшете и разрешить использовать геоданные."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Приложение может получать сведения о вашем местоположении от источников сетей, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в фоновом режиме. Для этого необходимо включить соответствующие параметры на телевизоре и разрешить использовать геоданные."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Приложение может получать сведения о вашем местоположении от источников сетей, таких как вышки сотовой связи и точки доступа Wi-Fi, но только в фоновом режиме. Для этого необходимо включить соответствующие параметры на телефоне и разрешить использовать геоданные."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"доступ к геоданным в фоновом режиме"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Если помимо доступа к данным о точном или приблизительном местоположении вы предоставите это разрешение, приложение сможет получать доступ к геоданным в фоновом режиме."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"Изменение настроек аудио"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-запрос преобразован в USSD-запрос"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Преобразовано в SS-запрос"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Рабочий профиль"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Развернуть"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Скрыть"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Свернуть или развернуть"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index ed3d0f5..bd5b82a 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi ඇමතුම් | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ක්රියාවිරහිතයි"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi වඩා කැමතියි"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ජංගම කැමතියි"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ස්ථානය සපයන අමතර අණ වලට ප්රවේශය කිරීමට යෙදුමට අවසර දෙන්න. GPS ක්රියාවන් හෝ වෙනත් ස්ථාන මූලාශ්ර සමඟ මැදිහත් වීමට මෙයින් යෙදුමට ඉඩ ලැබේ."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"පෙරබිම තුළ පමණක් නිශ්චිත ස්ථානය වෙත පිවිසෙන්න"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"මෙම යෙදුම පෙරබිම තුළ ඇති විට පමණක් එයට ඔබේ නිශ්චිත ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර සහ ඔබේ දුරකථනය මත ලබා ගත හැකිව තිබිය යුතුය. මෙය බැටරි පරිභෝජනය වැඩි කළ හැකිය."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ආසන්නතම ස්ථානයට (ජාලය-පාදක වූ) පිවිසීම"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර සහ ඔබේ ටැබ්ලට් පරිගණකය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර සහ ඔබේ TV මත ලබා ගත හැකිව තිබිය යුතුය."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකිය. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර සහ ඔබේ දුරකථනය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"ඉදිරියේ ඇති ආසන්න ස්ථානය (ජාලය පදනම්වූ) පමණක් ප්ර වේශ වන්න"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ ටැබ්ලටය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ TV එක මත ලබා ගත හැකිව තිබිය යුතුය."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"මෙම යෙදුමට ජංගම දුරකථන කුළුණු සහ Wi-Fi ජාල වැනි ජාල මූලාශ්ර පදනම්ව ඔබගේ ස්ථානය ලබා ගත හැකි නමුත් යෙදුම ඉදිරියේ ඇති විට පමණී. යෙදුමට ඒවා භාවිත කිරීමට හැකි වීමට මෙම ස්ථාන සේවා ක්රියාත්මක කර ඔබේ දුරකථනය මත ලබා ගත හැකිව තිබිය යුතුය."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"පසුබිමේ ස්ථානය ප්රවේශ කිරීම"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"මෙය ආසන්න වශයෙන් හෝ නිශ්චිත ස්ථානයක ප්රවේශය ලබා දෙන්නේ නම් පසුබිම් ධාවන අතරතුරදී යෙදුමට ස්ථානය වෙත ප්රවේශය විය හැක."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ඔබගේ ශ්රව්ය සැකසීම් වෙනස් කරන්න"</string>
@@ -1827,6 +1835,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS ඉල්ලීම USSD ඉල්ලීමට වෙනස් කරන ලදී"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"නව SS ඉල්ලීමට වෙනස් කරන ලදී"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"කාර්යාල පැතිකඩ"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"දිග හරින්න"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"හකුළන්න"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"පුළුල් කිරීම ටොගල කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 525fcde..ea45c9d 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -72,7 +72,7 @@
<string name="ThreeWCMmi" msgid="9051047170321190368">"Konferencia troch účastníkov"</string>
<string name="RuacMmi" msgid="7827887459138308886">"Odmietnutie nevyžiadaných obťažujúcich hovorov"</string>
<string name="CndMmi" msgid="3116446237081575808">"Doručenie volaného čísla"</string>
- <string name="DndMmi" msgid="1265478932418334331">"Nerušiť"</string>
+ <string name="DndMmi" msgid="1265478932418334331">"Režim bez vyrušení"</string>
<string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"V predvolenom nastavení je identifikácia volajúceho obmedzená. Ďalší hovor: Obmedzené"</string>
<string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"V predvolenom nastavení je identifikácia volajúceho obmedzená. Ďalší hovor: Bez obmedzenia"</string>
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"V predvolenom nastavení nie je identifikácia volajúceho obmedzená. Ďalší hovor: Obmedzené"</string>
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Volanie cez WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Vypnuté"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferovať Wi‑Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferovať mobilné spojenie"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Umožňuje aplikácii pristupovať k ďalším príkazom poskytovateľa informácií o polohe. Aplikácii to môže umožniť zasahovať do činnosti systému GPS alebo iných zdrojov informácií o polohe."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"prístup k presnej polohe iba v popredí"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Táto aplikácia dokáže získať vašu presnú polohu iba vtedy, keď je spustená v popredí. Na to, aby mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v telefóne. Môže to zvýšiť spotebu batérie."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"prístup k približnej polohe (pomocou siete)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na tablete."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na televízore."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii na telefóne."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"prístup k približnej polohe (pomocou siete) iba v popredí"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi, keď je spustená v popredí. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v tablete."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi, keď je spustená v popredí. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v televízore."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Táto aplikácia môže získať údaje o vašej polohe na základe sieťových zdrojov, ako sú mobilné veže a siete Wi‑Fi, ale iba keď je spustená v popredí. Na to, aby aplikácia mohla používať služby určovania polohy, musia byť tieto služby zapnuté a k dispozícii v telefóne."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"prístup k polohe na pozadí"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ak okrem prístupu k približnej alebo presnej polohe udelíte aj toto povolenie, aplikácia bude môcť používať polohu, keď bude spustená na pozadí."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"meniť nastavenia zvuku"</string>
@@ -646,8 +654,8 @@
<string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby na odosielanie správ SMS a MMS operátora. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_bindCarrierServices" msgid="3233108656245526783">"naviazať sa na služby operátora"</string>
<string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Umožňuje držiteľovi povolenia naviazať sa na služby operátora. Bežné aplikácie by toto povolenie nemali nikdy nepotrebovať."</string>
- <string name="permlab_access_notification_policy" msgid="4247510821662059671">"prístup k nastaveniu Nerušiť"</string>
- <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikácii čítať a zapisovať konfiguráciu nastavenia Nerušiť."</string>
+ <string name="permlab_access_notification_policy" msgid="4247510821662059671">"prístup k režimu bez vyrušení"</string>
+ <string name="permdesc_access_notification_policy" msgid="3296832375218749580">"Umožňuje aplikácii čítať a zapisovať konfiguráciu režimu bez vyrušení."</string>
<string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
<string name="policydesc_limitPassword" msgid="2502021457917874968">"Nastavte dĺžku hesiel na odomknutie obrazovky aj kódov PIN a v nich používané znaky."</string>
<string name="policylab_watchLogin" msgid="5091404125971980158">"Sledovanie pokusov o odomknutie obrazovky"</string>
@@ -1870,10 +1878,10 @@
<string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string>
<string name="zen_mode_alarm" msgid="9128205721301330797">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> (ďalší budík)"</string>
<string name="zen_mode_forever" msgid="931849471004038757">"Dokiaľ túto funkciu nevypnete"</string>
- <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dokiaľ nevypnete režim Nerušiť"</string>
+ <string name="zen_mode_forever_dnd" msgid="3792132696572189081">"Dokiaľ nevypnete režim bez vyrušení"</string>
<string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string>
<string name="toolbar_collapse_description" msgid="2821479483960330739">"Zbaliť"</string>
- <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nerušiť"</string>
+ <string name="zen_mode_feature_name" msgid="5254089399895895004">"Režim bez vyrušení"</string>
<string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Doba pokoja"</string>
<string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noc pracovného dňa"</string>
<string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Víkend"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Žiadosť SS bola zmenená na žiadosť USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Zmenené na novú žiadosť SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Pracovný profil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Rozbaliť"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Zbaliť"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"prepnúť rozbalenie"</string>
@@ -2018,10 +2028,10 @@
<string name="volume_dialog_ringer_guidance_vibrate" msgid="8902050240801159042">"Hovory a upozornenia budú vibrovať"</string>
<string name="volume_dialog_ringer_guidance_silent" msgid="2128975224280276122">"Hovory a upozornenia budú stlmené"</string>
<string name="notification_channel_system_changes" msgid="5072715579030948646">"Zmeny systému"</string>
- <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Nerušiť"</string>
- <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"Novinka: režim Nerušiť skrýva upozornenia"</string>
+ <string name="notification_channel_do_not_disturb" msgid="6766940333105743037">"Režim bez vyrušení"</string>
+ <string name="zen_upgrade_notification_visd_title" msgid="3288313883409759733">"Novinka: režim bez vyrušení skrýva upozornenia"</string>
<string name="zen_upgrade_notification_visd_content" msgid="5533674060311631165">"Klepnutím získate ďalšie informácie a budete môcť vykonať zmeny."</string>
- <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Nastavenie Nerušiť sa zmenilo"</string>
+ <string name="zen_upgrade_notification_title" msgid="3799603322910377294">"Režim bez vyrušení sa zmenil"</string>
<string name="zen_upgrade_notification_content" msgid="1794994264692424562">"Klepnutím skontrolujete, čo je blokované."</string>
<string name="notification_app_name_system" msgid="4205032194610042794">"Systém"</string>
<string name="notification_app_name_settings" msgid="7751445616365753381">"Nastavenia"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 252246a..4a41228 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Klicanje prek WiFi-ja | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"Govor prek Wi-Fi-ja operaterja <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Izklopljeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Prednostno Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Prednostno mobilno"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Aplikaciji omogoča dostop do dodatnih ukazov ponudnika lokacij. S tem lahko aplikacija moti delovanje sistema GPS ali drugih virov lokacije."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"dostop do točne lokacije samo, ko deluje v ospredju"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ta aplikacija lahko pridobi vašo točno lokacijo samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v telefonu. Poraba energije akumulatorja bo morda večja."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"dostop do približne lokacije (na podlagi podatkov omrežja)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v tabličnem računalniku."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v televizorju."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v telefonu."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"dostop do približne lokacije (na podlagi omrežja) samo med delovanjem v ospredju"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v tabličnem računalniku."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v televizorju."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ta aplikacija lahko pridobi vašo lokacijo na podlagi omrežnih virov, kot so bazne postaje in omrežja Wi-Fi, vendar samo, ko deluje v ospredju. Če želite aplikaciji omogočiti uporabo teh lokacijskih storitev, morajo biti te vklopljene in na voljo v telefonu."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"dostop do lokacije med izvajanjem v ozadju"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Če to dovolite poleg dostopa do približne ali natančne lokacije, lahko aplikacija dostopa do lokacije, medtem ko se izvaja v ozadju."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"spreminjanje nastavitev zvoka"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Zahteva SS je spremenjena v zahtevo USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Spremenjeno v novo zahtevo SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Delovni profil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Razširi"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Strni"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"preklop razširitve"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 9062f29..fc88556 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi në <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Telefonatë me Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi në <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Çaktivizuar"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Preferohet Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Preferohet rrjeti celular"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Lejon aplikacionin të ketë qasje në komandat shtesë të ofruesit për vendndodhjen. Kjo mund ta lejojë aplikacionin të ndërhyjë në operacionin e GPS-së apo të burimeve të tjera për vendndodhjen."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"qasu në vendndodhjen e saktë vetëm në plan të parë"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ky aplikacion mund të marrë vendndodhjen tënde të saktë në çdo kohë kur është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në telefonin tënd që aplikacioni të mund t\'i përdorë. Kjo gjë mund të rritë konsumin e baterisë."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"qasu te vendndodhja e përafërt (bazuar në rrjet)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në tabletin tënd që aplikacioni të mund t\'i përdorë."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në televizorin tënd që aplikacioni të mund t\'i përdorë."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe në dispozicion në telefonin tënd që aplikacioni të mund t\'i përdorë."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"qasu te vendndodhja e përafërt (bazuar te rrjeti) vetëm në plan të parë"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në tabletin tënd që aplikacioni të mund t\'i përdorë."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në televizorin tënd që aplikacioni të mund t\'i përdorë."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ky aplikacion mund të marrë vendndodhjen tënde bazuar në burimet e rrjetit si antenat e operatorëve celulare dhe rrjetet Wi-Fi, por vetëm kur aplikacioni është në plan të parë. Këto shërbime të vendndodhjes duhet të jenë të aktivizuara dhe të ofrohen në telefonin tënd që aplikacioni të mund t\'i përdorë."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"qasje te vendndodhja në sfond"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Nëse kjo jepet përveç qasjes te vendndodhja e përafërt ose të saktë, aplikacioni mund të qaset te vendndodhja ndërkohë që ekzekutohet në sfond."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ndrysho cilësimet e audios"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Kërkesa SS u ndryshua në kërkesë USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"U ndryshua në kërkesë të re SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profili i punës"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Zgjero"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Palos"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"aktivizo zgjerimin"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 642e12e..b2e3059 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -137,6 +137,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Позивање преко Wi-Fi-ја | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Искључено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Предност има Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Желим мобилне податке"</string>
@@ -213,7 +221,7 @@
<string name="shutdown_confirm" product="watch" msgid="3490275567476369184">"Сат ће се угасити."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Телефон ће се искључити."</string>
<string name="shutdown_confirm_question" msgid="2906544768881136183">"Да ли желите да искључите телефон?"</string>
- <string name="reboot_safemode_title" msgid="7054509914500140361">"Поново покрени систем у безбедном режиму"</string>
+ <string name="reboot_safemode_title" msgid="7054509914500140361">"Рестартуј систем у безбедном режиму"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"Да ли желите да поново покренете систем у безбедном режиму? Ово ће онемогућити све инсталиране апликације независних произвођача. Оне ће бити враћене када поново покренете систем."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"Недавно"</string>
<string name="no_recent_tasks" msgid="8794906658732193473">"Нема недавних апликација."</string>
@@ -420,10 +428,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Омогућава апликацији да приступа додатним командама даваоца услуга локације. То може да омогући апликацији да утиче на рад GPS-а или других извора локације."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"приступ прецизној локацији само у првом плану"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Ова апликација може да одреди вашу тачну локацију само када ради у првом плану. Ове услуге локације морају да буду укључене и доступне на телефону да би апликација могла да их користи. То може да повећа потрошњу батерије."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"приступ приближној локацији (утврђена преко мреже)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже. Ове услуге локације морају да буду укључене и доступне на таблету да би апликација могла да их користи."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже. Ове услуге локације морају да буду укључене и доступне на ТВ-у да би апликација могла да их користи."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже. Ове услуге локације морају да буду укључене и доступне на телефону да би апликација могла да их користи."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"приступ приближној локацији (утврђеној преко мреже) само у првом плану"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на таблету да би апликација могла да их користи"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на телевизору да би апликација могла да их користи."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Ова апликација може да приступи вашој локацији помоћу извора мреже, као што су мобилни предајници и Wi-Fi мреже, али само када апликација ради у првом плану. Ове услуге локације морају да буду укључене и доступне на телефону да би апликација могла да их користи."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"приступ локацији у позадини"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Ако се поред приближног или прецизног приступа локација одобри и овај, апликација може да приступа локацији док је покренута у позадини."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"промена аудио подешавања"</string>
@@ -507,11 +515,11 @@
<string name="permlab_disableKeyguard" msgid="3598496301486439258">"онемогућавање закључавања екрана"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дозвољава апликацији да онемогући закључавање тастатуре и све повезане безбедносне мере са лозинкама. На пример, телефон онемогућава закључавање тастатуре при пријему долазног телефонског позива, а затим га поново омогућава по завршетку позива."</string>
<string name="permlab_useBiometric" msgid="8837753668509919318">"користи биометријски хардвер"</string>
- <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозвољава апликацији да користи биометријски хардвер за потврду аутентичности"</string>
+ <string name="permdesc_useBiometric" msgid="8389855232721612926">"Дозвољава апликацији да користи биометријски хардвер за потврду идентитета"</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"управљај хардвером за отиске прстију"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"Дозвољава апликацији да активира методе за додавање и брисање шаблона отисака прстију који ће се користити."</string>
<string name="permlab_useFingerprint" msgid="3150478619915124905">"користи хардвер за отиске прстију"</string>
- <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Дозвољава апликацији да користи хардвер за отиске прстију ради потврде аутентичности"</string>
+ <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Дозвољава апликацији да користи хардвер за отиске прстију ради потврде идентитета"</string>
<string name="permlab_audioRead" msgid="6617225220728465565">"читање музичке колекције"</string>
<string name="permdesc_audioRead" msgid="5034032570243484805">"Дозвољава апликацији да чита музичку колекцију."</string>
<string name="permlab_audioWrite" msgid="2661772059799779292">"измена музичке колекције"</string>
@@ -898,7 +906,7 @@
<string name="factorytest_failed" msgid="5410270329114212041">"Фабричко тестирање није успело"</string>
<string name="factorytest_not_system" msgid="4435201656767276723">"Радња FACTORY_TEST је подржана само за пакете инсталиране у директоријуму /system/app."</string>
<string name="factorytest_no_action" msgid="872991874799998561">"Није пронађен ниједан пакет који обезбеђује радњу FACTORY_TEST."</string>
- <string name="factorytest_reboot" msgid="6320168203050791643">"Поново покрени"</string>
+ <string name="factorytest_reboot" msgid="6320168203050791643">"Рестартуј"</string>
<string name="js_dialog_title" msgid="1987483977834603872">"На страници на адреси „<xliff:g id="TITLE">%s</xliff:g>“ пише:"</string>
<string name="js_dialog_title_default" msgid="6961903213729667573">"JavaScript"</string>
<string name="js_dialog_before_unload_title" msgid="2619376555525116593">"Потврда навигације"</string>
@@ -1318,7 +1326,7 @@
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM картица је додата"</string>
<string name="sim_added_message" msgid="6599945301141050216">"Рестартујте уређај да бисте могли да приступите мобилној мрежи."</string>
- <string name="sim_restart_button" msgid="4722407842815232347">"Поново покрени"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Рестартуј"</string>
<string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активирајте мобилну услугу"</string>
<string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Преузмите апликацију мобилног оператера да бисте активирали нови SIM"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Преузмите апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> да бисте активирали нову SIM картицу"</string>
@@ -1858,6 +1866,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS захтев је промењен у USSD захтев"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Промењено је у нови SS захтев"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Профил за Work"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Прошири"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Скупи"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"укључите/искључите проширење"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2ace15c..dbe9b69 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi via <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi-samtal | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi via <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Av"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi i första hand"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Använd mobildata"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Tillåter att appen får åtkomst till extra kommandon för platsleverantör. Detta kan innebära att appen tillåts störa funktionen för GPS eller andra platskällor."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"endast åtkomst till exakt plats i förgrunden"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Den här appen kan endast få information om din exakta plats när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på mobilen om appen ska kunna använda dem. Detta kan leda till ökad batteriförbrukning."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"få åtkomst till din ungefärliga position (nätverksbaserad)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Appen kan få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk. De platstjänsterna måste ha aktiverats och finnas på surfplattan om appen ska kunna använda dem."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Appen kan få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk. De platstjänsterna måste ha aktiverats och fungera på TV:n om appen ska kunna använda dem."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Appen kan få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk. De platstjänsterna måste ha aktiverats och finnas på mobilen om appen ska kunna använda dem."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"endast åtkomst till beräknad plats (nätverksbaserad) i förgrunden"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Appen kan endast få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk, när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på surfplattan om appen ska kunna använda dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Appen kan endast få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk, när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på tv:n om appen ska kunna använda dem."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Appen kan endast få information om din plats från källor i nätverket, som mobilmaster och Wi-Fi-nätverk, när den körs i förgrunden. Platstjänsterna måste ha aktiverats och finnas på mobilen om appen ska kunna använda dem."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"få åtkomst till platsinformation i bakgrunden"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Om denna behörighet ges utöver ungefärlig eller exakt platsåtkomst får appen åtkomst till platsinformation när den körs i bakgrunden."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ändra dina ljudinställningar"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS-begäran har ändrats till en USSD-begäran"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Har ändrats till ny SS-begäran"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Jobbprofil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Utöka"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Komprimera"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"Utöka/komprimera"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index dcfa08d..46434cb 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ya <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Kupiga Simu kupitia WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi ya <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Imezimwa"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi inapedelewa"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mtandao wa simu unapendelewa"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ruhusu programu kufikia amri za ziada za mtoa huduma za mahali. Hii huenda ikaruhusu programu ikatize matumizi ya GPS au vyanzo vingine vya eneo."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"kufikia mahali mahususi ikiwa tu programu imefunguliwa kwenye skrini"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Programu hii inaweza kupata mahali halisi ikiwa tu umeifungua kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu yako ili programu iweze kuzitumia. Hatua hii inaweza kuongeza utumiaji wa betri."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"fikia mahali karibu na hapo (inategemea mtandao)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi. Huduma hizi za mahali lazima ziwashwe na zipatikane kwenye kompyuta yako kibao ili programu iweze kuzitumia."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi. Huduma hizi za mahali lazima ziwashwe na zipatikane kwenye runinga yako ili programu iweze kuzitumia."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi. Huduma hizi za mahali lazima ziwashwe na zipatikane kwenye simu yako ili programu iweze kuzitumia."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"fikia eneo linalokadiriwa (kulingana na mtandao) wakati tu programu inatumika kwenye skrini"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu kibao yako ili programu iweze kuzitumia."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye TV yako ili programu iweze kuzitumia."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Programu hii inaweza kupata eneo lako kulingana na vyanzo vya mtandao kama vile minara ya simu na mitandao ya Wi-Fi, lakini hili hufanyika tu wakati programu inatumika kwenye skrini. Ni lazima uwashe huduma hizi za mahali na zipatikane kwenye simu yako ili programu iweze kuzitumia."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"ifikie mahali inapotumika chinichini"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Kama ruhusa hii itatolewa, mbali na idhini ya kufikia mahali panapokadiriwa au mahali mahususi, programu inaweza kufikia mahali wakati inatumika chinichini."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"badilisha mipangilio yako ya sauti"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Imebadilisha ombi la SS kuwa ombi la USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Imebadilisha kuwa ombi jipya la SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Wasifu wa kazini"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Panua"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Kunja"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"geuza upanuzi"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 8ed9b7d..d5b8cf8 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> வைஃபை"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"வைஃபை அழைப்பு | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ஆஃப்"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"வைஃபைக்கு முன்னுரிமை"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"மொபைல் தரவிற்கு முன்னுரிமை"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"கூடுதல் இட வழங்குநர் கட்டளைகளை அணுகப் பயன்பாட்டை அனுமதிக்கிறது. இது, GPS அல்லது பிற இருப்பிட மூலங்களின் செயல்பாட்டை இடைமறிக்க பயன்பாட்டை அனுமதிக்கலாம்."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"முன்புலத்தில் இயங்கும்போது மட்டும் துல்லியமான இருப்பிடத்தைக் கண்டறிதல்"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"இந்த ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே நீங்கள் இருக்கும் இடத்தைத் துல்லியமாகக் கண்டறியும். உங்கள் மொபைலில், இருப்பிடச் சேவைகளை ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக, அவை ஆன் செய்யப்பட்டிருக்க வேண்டும். இதனால் பேட்டரி அதிகம் பயன்படுத்தப்படலாம்."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"தோராயமான இருப்பிடத்தை அணுகுதல் (நெட்வொர்க் அடிப்படையில்)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"இந்தப் பயன்பாடு நெட்வொர்க் மூலங்களின் (செல் கோபுரங்கள், வைஃபை நெட்வொர்க்குகள் போன்றவை) அடிப்படையில் உங்கள் இருப்பிடத்தைப் பெறலாம். பயன்பாடு பயன்படுத்தும் வகையில், உங்கள் டேப்லெட்டில் இந்த இருப்பிடச் சேவைகள் இயக்கப்பட்டு, கிடைக்கும்படி இருக்க வேண்டும்."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"இந்தப் பயன்பாடு நெட்வொர்க் மூலங்களின் (செல் கோபுரங்கள், வைஃபை நெட்வொர்க்குகள் போன்றவை) அடிப்படையில் உங்கள் இருப்பிடத்தைப் பெறலாம். பயன்பாடு பயன்படுத்தும் வகையில், உங்கள் டிவியில் இந்த இருப்பிடச் சேவைகள் இயக்கப்பட்டு, கிடைக்கும்படி இருக்க வேண்டும்."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"இந்தப் பயன்பாடு நெட்வொர்க் மூலங்களின் (செல் கோபுரங்கள், வைஃபை நெட்வொர்க்குகள் போன்றவை) அடிப்படையில் உங்கள் இருப்பிடத்தைப் பெறலாம். பயன்பாடு பயன்படுத்தும் வகையில், உங்கள் மொபைலில் இந்த இருப்பிடச் சேவைகள் இயக்கப்பட்டு, கிடைக்கும்படி இருக்க வேண்டும்."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"முன்புலத்தில் இயங்கும்போது மட்டும் தோராயமான இருப்பிடத்தைக் கண்டறிதல் (நெட்வொர்க் அடிப்படையில்)"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் மூலங்கள் மூலம் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். உங்கள் டேப்லெட்டில் \'இருப்பிடச் சேவைகளை\' ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக அவை ஆன் செய்யப்பட்டிருக்க வேண்டும்."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் மூலங்கள் மூலம் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். உங்கள் டிவியில் \'இருப்பிடச் சேவைகளை\' ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக அவை ஆன் செய்யப்பட்டிருக்க வேண்டும்."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ஆப்ஸ் முன்புலத்தில் இயங்கும்போது மட்டுமே மொபைல் டவர்கள், வைஃபை நெட்வொர்க்குகள் போன்ற நெட்வொர்க் மூலங்கள் மூலம் ஆப்ஸால் உங்கள் இருப்பிடத்தைப் பெற முடியும். உங்கள் மொபைலில் \'இருப்பிடச் சேவைகளை\' ஆப்ஸ் பயன்படுத்துவதற்கு வசதியாக அவை ஆன் செய்யப்பட்டிருக்க வேண்டும்."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"பின்புலத்தில் இருப்பிடத்தை அணுகுதல்"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"தோராயமான அல்லது துல்லியமான \'இருப்பிட அணுகலுடன்\' சேர்ந்து இதற்கும் அனுமதி வழங்கப்பட்டால், ஆப்ஸ் பின்புலத்தில் இயங்கினாலும் இருப்பிடத்தை அணுக இயலும்."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"எனது ஆடியோ அமைப்புகளை மாற்றுதல்"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS கோரிக்கை, USSD கோரிக்கைக்கு மாற்றப்பட்டது"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"புதிய SS கோரிக்கைக்கு மாற்றப்பட்டது"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"பணி சுயவிவரம்"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"விரிவாக்கும்"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"சுருக்கும்"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"விரிவாக்கத்தை நிலைமாற்றும்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index cce816d..37d4a7b 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi కాలింగ్ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ఆఫ్లో ఉంది"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fiకి ప్రాధాన్యత"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"మొబైల్కి ప్రాధాన్యత ఇవ్వబడింది"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"అదనపు స్థాన ప్రదాత ఆదేశాలను యాక్సెస్ చేయడానికి యాప్ను అనుమతిస్తుంది. ఇది GPS లేదా ఇతర స్థాన మూలాల నిర్వహణలో యాప్ ప్రమేయం ఉండేలా అనుమతించవచ్చు."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"స్క్రీన్పై ఉన్నప్పుడు మాత్రమే ఖచ్చితమైన స్థానాన్ని యాక్సెస్ చేయండి"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"ఈ యాప్ స్క్రీన్పై ఉన్నప్పుడు మాత్రమే అది మీ ఖచ్చితమైన స్థానాన్ని తెలుసుకోగలదు. యాప్ ఉపయోగించడానికి మీ ఫోన్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి. ఇది బ్యాటరీ వినియోగాన్ని పెంచవచ్చు."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ఇంచుమించు స్థానాన్ని (నెట్వర్క్-ఆధారితం) యాక్సెస్ చేయడం"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్ ఉపయోగించడానికి మీ టాబ్లెట్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్ ఉపయోగించడానికి మీ టీవీలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు. యాప్ ఉపయోగించడానికి మీ ఫోన్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"స్క్రీన్పై ఉన్నప్పుడు మాత్రమే సమీప స్థానాన్ని (నెట్వర్క్-ఆధారిత) యాక్సెస్ చేయండి"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ టాబ్లెట్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ టీవీలో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"ఈ యాప్ సెల్ టవర్లు మరియు Wi-Fi నెట్వర్క్ల వంటి నెట్వర్క్ మూలాధారాల ఆధారంగా మీ స్థానాన్ని తెలుసుకోగలదు, కానీ యాప్ తెరపై ఉన్నప్పుడు మాత్రమే. యాప్ ఉపయోగించడానికి మీ ఫోన్లో ఈ స్థాన సేవలను తప్పనిసరిగా ఆన్ చేయాలి మరియు అందుబాటులో ఉండాలి."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"నేపథ్యంలో స్థానాన్ని యాక్సెస్ చేయి"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"సుమారుగా లేదా ఖచ్చితమైన స్థాన యాక్సెస్తో పాటు అదనందా ఇది మంజూరు చేయబడితే, యాప్ నేపథ్యంలో నడుస్తున్నప్పుడు స్థానాన్ని యాక్సెస్ చేయగలదు."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"మీ ఆడియో సెట్టింగ్లను మార్చడం"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS అభ్యర్థన USSD అభ్యర్థనకు మార్చబడింది"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"కొత్త SS అభ్యర్థనకు మార్చబడింది"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"కార్యాలయ ప్రొఫైల్"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"విస్తరింపజేయి"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"కుదించు"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"విస్తరణను టోగుల్ చేయండి"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index ebbf155..1b473f0 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"การโทรผ่าน Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ปิด"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ต้องการใช้ Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"ต้องการใช้อินเทอร์เน็ตมือถือ"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"อนุญาตให้แอปเข้าถึงคำสั่งของผู้ให้บริการตำแหน่งเพิ่มเติม ซึ่งอาจทำให้แอปสามารถแทรกแซงการทำงานของ GPS หรือต้นทางของตำแหน่งอื่นๆ ได้"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"เข้าถึงตำแหน่งที่แม่นยำเมื่ออยู่เบื้องหน้าเท่านั้น"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"แอปนี้รับตำแหน่งที่แม่นยำของคุณได้เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในโทรศัพท์ของคุณ ซึ่งอาจทำให้มีการใช้แบตเตอรี่มากขึ้น"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"เข้าถึงตำแหน่งโดยประมาณ (อิงจากเครือข่าย)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"แอปนี้สามารถรับตำแหน่งของคุณโดยอิงจากแหล่งข้อมูลเครือข่าย เช่น เสาสัญญาณมือถือและเครือข่าย Wi-Fi แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในแท็บเล็ตของคุณ"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"แอปนี้สามารถรับตำแหน่งของคุณโดยอิงจากแหล่งข้อมูลเครือข่าย เช่น เสาสัญญาณมือถือและเครือข่าย Wi-Fi แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในทีวีของคุณ"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"แอปนี้สามารถรับตำแหน่งของคุณโดยอิงจากแหล่งข้อมูลเครือข่าย เช่น เสาสัญญาณมือถือและเครือข่าย Wi-Fi แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในโทรศัพท์ของคุณ"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"เข้าถึงตำแหน่งโดยประมาณ (อิงตามเครือข่าย) เมื่อทำงานอยู่เบื้องหน้าเท่านั้น"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"แอปนี้รับตำแหน่งของคุณโดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในแท็บเล็ตของคุณ"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"แอปนี้รับตำแหน่งของคุณโดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในทีวีของคุณ"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"แอปนี้รับตำแหน่งของคุณโดยอิงตามแหล่งที่มาของเครือข่าย เช่น เสาส่งสัญญาณมือถือและเครือข่าย Wi-Fi เมื่อทำงานอยู่เบื้องหน้าเท่านั้น แอปจะใช้บริการตำแหน่งเหล่านี้ได้ต่อเมื่อคุณเปิดบริการและบริการพร้อมใช้งานในโทรศัพท์ของคุณ"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"เข้าถึงตำแหน่งในเบื้องหลัง"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"หากได้รับสิทธิ์นี้เพิ่มจากการเข้าถึงตำแหน่งโดยประมาณหรือตำแหน่งที่แม่นยำ แอปจะมีสิทธิ์เข้าถึงตำแหน่งระหว่างที่ทำงานในเบื้องหลังได้"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"เปลี่ยนการตั้งค่าเสียงของคุณ"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"คำขอ SS เปลี่ยนเป็นคำขอ USSD แล้ว"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"เปลี่ยนเป็นคำขอ SS ใหม่แล้ว"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"โปรไฟล์งาน"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"ขยาย"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"ยุบ"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"สลับการขยาย"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index e5bde1d..3e3b4f9 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi ng <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Pagtawag Gamit ang Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi ng <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Naka-off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Mas gusto ang Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mas gusto ang mobile"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Nagbibigay-daan sa app na mag-access ng mga karagdagang command ng provider ng lokasyon. Maaari nitong bigyang-daan ang app na gambalain ang pagpapatakbo ng GPS o ng iba pang mga pinagmulan ng lokasyon."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"i-access lang ang tumpak na lokasyon sa foreground"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Makukuha lang ng app na ito ang iyong eksaktong lokasyon kapag nasa foreground ito. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong telepono para magamit ng app ang mga ito. Maaaring lumakas ang pagkonsumo ng baterya dahil dito."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"i-access ang tinatantyang lokasyon (batay sa network)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Makukuha ng app na ito ang iyong lokasyon batay sa mga pinagmulan ng network gaya ng mga cell tower at Wi-Fi network. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong tablet para sa app upang magamit ang mga ito."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Makukuha ng app na ito ang iyong lokasyon batay sa mga pinagmulan ng network gaya ng mga cell tower at Wi-Fi network. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong TV para sa app upang magamit ang mga ito."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Makukuha ng app na ito ang iyong lokasyon batay sa mga pinagmulan ng network gaya ng mga cell tower at Wi-Fi network. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong telepono para sa app upang magamit ang mga ito."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"i-access lang ang tinatantiyang lokasyon (batay sa network) sa foreground"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell tower at Wi-Fi network ngunit magagawa lang ito kapag nasa foreground ang app. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong tablet para magamit ng app ang mga ito."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell tower at Wi-Fi network, ngunit magagawa lang ito kapag nasa foreground ang app. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong TV para magamit ng app ang mga ito."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Makukuha ng app na ito ang iyong lokasyon batay sa mga source ng network gaya ng mga cell tower at Wi-Fi network, ngunit magagawa lang ito kapag nasa foreground ang app. Ang mga serbisyo ng lokasyon na ito ay dapat naka-on at available sa iyong telepono para magamit ng app ang mga ito."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"i-access ang lokasyon sa background"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Kung papahintulutan ito bukod pa sa pag-access sa tinataya o tumpak na lokasyon, maaaring i-access ng app ang lokasyon habang tumatakbo sa background."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"baguhin ang mga setting ng iyong audio"</string>
@@ -528,7 +536,7 @@
<string name="fingerprint_acquired_partial" msgid="735082772341716043">"Hindi buo ang natukoy na fingerprint. Pakisubukang muli."</string>
<string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Hindi maproseso ang fingerprint. Pakisubukang muli."</string>
<string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Marumi ang sensor ng fingerprint. Pakilinis at subukang muli."</string>
- <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Masyadong mabilis ang paggalaw ng daliri. Pakisubukang muli."</string>
+ <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Napakabilis ng paggalaw ng daliri. Pakisubukan ulit."</string>
<string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Masyadong mabagal ang paggalaw ng daliri. Pakisubukang muli."</string>
<string-array name="fingerprint_acquired_vendor">
</string-array>
@@ -541,7 +549,7 @@
<string name="fingerprint_error_timeout" msgid="3927186043737732875">"Nag-time out ang fingerprint. Subukang muli."</string>
<string name="fingerprint_error_canceled" msgid="4402024612660774395">"Nakansela ang operasyong ginagamitan ng fingerprint."</string>
<string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Kinansela ng user ang operasyon sa fingerprint."</string>
- <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Masyadong maraming beses sumubok. Subukang muli sa ibang pagkakataon."</string>
+ <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Napakaraming pagtatangka. Subukan ulit sa ibang pagkakataon."</string>
<string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Masyadong maraming beses sumubok. Na-disable ang sensor para sa fingerprint."</string>
<string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Subukang muli."</string>
<string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Walang naka-enroll na fingerprint."</string>
@@ -1416,7 +1424,7 @@
<string name="forward_intent_to_work" msgid="621480743856004612">"Ginagamit mo ang app na ito sa iyong profile sa trabaho"</string>
<string name="input_method_binding_label" msgid="1283557179944992649">"Pamamaraan ng pag-input"</string>
<string name="sync_binding_label" msgid="3687969138375092423">"I-sync"</string>
- <string name="accessibility_binding_label" msgid="4148120742096474641">"Kakayahang Ma-access"</string>
+ <string name="accessibility_binding_label" msgid="4148120742096474641">"Pagiging Accessible"</string>
<string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string>
<string name="chooser_wallpaper" msgid="7873476199295190279">"Baguhin ang wallpaper"</string>
<string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Ginawang USSD na kahilingan ang SS na kahilingan"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Ginawang bagong SS na kahilingan"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profile sa trabaho"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Palawakin"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"I-collapse"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"i-toggle ang pagpapalawak"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 18e1911..e326b2c 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Kablosuz"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Kablosuz Çağrı | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Kapalı"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kablosuz bağlantı tercihli"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil tercihli"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Uygulamanın, ekstra konum sağlayıcı komutlarına erişmesine izin verir. Bu izin, uygulamanın GPS veya diğer konum kaynaklarının çalışmasını kesmesine olanak sağlayabilir."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"yalnızca ön planda kesin konuma erişme"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Bu uygulama yalnızca ön plandayken kesin konumunuzu alabilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır. Bu, pil tüketimini artırabilir."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"konum bilgilerine yaklaşık olarak erişme (ağ tabanlı)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Bu uygulama baz istasyonu ve kablosuz ağ gibi ağ kaynaklarını kullanarak konumunuzu belirleyebilir. Uygulamanın bu hizmetleri kullanabilmesi için tabletinizde bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Bu uygulama baz istasyonu ve kablosuz ağ gibi ağ kaynaklarını kullanarak konumunuzu belirleyebilir. Uygulamanın bu hizmetleri kullanabilmesi için TV\'nizde bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Bu uygulama baz istasyonu ve kablosuz ağ gibi ağ kaynaklarını kullanarak konumunuzu belirleyebilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"yalnızca ön planda yaklaşık konuma (ağa dayalı) erişme"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için tabletinizde bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için TV\'nizde bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Bu uygulama baz istasyonları ve kablosuz ağlar gibi ağ kaynaklarını dikkate alarak konumunuzu bulabilir, ancak bunu yalnızca ön plandayken yapabilir. Uygulamanın bu hizmetleri kullanabilmesi için telefonunuzda bu konum hizmetleri açık ve kullanılabilir olmalıdır."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"konum bilgisine arka planda eriş"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Bu izin, yaklaşık veya tam konum erişimine ek olarak verilirse uygulama, konum bilgisine arka planda çalışırken erişebilir."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ses ayarlarınızı değiştirin"</string>
@@ -1194,7 +1202,7 @@
<string name="dump_heap_title" msgid="5864292264307651673">"Yığın dökümü paylaşılsın mı?"</string>
<string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g>, <xliff:g id="SIZE">%2$s</xliff:g> olan işlem bellek sınırını aştı. İşlemin geliştiricisiyle paylaşabileceğiniz bir bellek yığını dökümü hazır. Dikkat: Bu bellek yığını dökümü, uygulamanın erişebildiği tüm kişisel bilgilerinizi içerebilir."</string>
<string name="sendText" msgid="5209874571959469142">"Kısa mesaj için bir işlem seçin"</string>
- <string name="volume_ringtone" msgid="6885421406845734650">"Zil sesi düzeyi"</string>
+ <string name="volume_ringtone" msgid="6885421406845734650">"Zil ses düzeyi"</string>
<string name="volume_music" msgid="5421651157138628171">"Medya ses düzeyi"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth üzerinden çalıyor"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Sessiz zil sesi ayarlandı"</string>
@@ -1204,7 +1212,7 @@
<string name="volume_notification" msgid="2422265656744276715">"Bildirim ses düzeyi"</string>
<string name="volume_unknown" msgid="1400219669770445902">"Ses"</string>
<string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth ses düzeyi"</string>
- <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zil sesi düzeyi"</string>
+ <string name="volume_icon_description_ringer" msgid="3326003847006162496">"Zil ses düzeyi"</string>
<string name="volume_icon_description_incall" msgid="8890073218154543397">"Çağrı ses düzeyi"</string>
<string name="volume_icon_description_media" msgid="4217311719665194215">"Medya ses düzeyi"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Bildirim ses düzeyi"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS isteği USSD isteği olarak değişti"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Yeni SS isteği olarak değişti"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"İş profili"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Genişlet"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Daralt"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"genişletmeyi aç/kapat"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index e9f44bf..f9cbfd6 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -138,6 +138,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> через Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Виклики через Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> через VoWi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Вимкнено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi за умовчанням"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Мобільна мережа за умовчанням"</string>
@@ -423,10 +431,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Додаток отримуватиме доступ до додаткових команд постачальника геоданих. Можливе втручання додатка в роботу GPS чи інших джерел геоданих."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"отримувати доступ до даних про точне місцезнаходження лише в активному режимі"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Цей додаток може отримувати дані про ваше точне місцезнаходження лише в активному режимі. Щоб додаток користувався службами локації, вони мають бути наявні й увімкнені на вашому телефоні. Через це може швидше розряджатись акумулятор."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"отримувати дані про приблизне місцезнаходження (на основі мережі)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому планшеті."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому телевізорі."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому телефоні."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"отримувати доступ до даних про приблизне місцезнаходження (на основі мережі) лише в активному режимі"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому планшеті."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому телевізорі."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Цей додаток може отримувати дані про ваше місцезнаходження на основі джерел мережі, як-от антен мобільного зв’язку та мереж Wi-Fi, лише в активному режимі. Щоб додаток міг користуватися цими службами локації, вони мають бути доступними й увімкненими на вашому телефоні."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"доступ до геоданих у фоновому режимі"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Якщо ви надасте цей дозвіл і доступ до приблизного або точного місцезнаходження, додаток зможе отримувати геодані у фоновому режимі."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"змінювати налаштув-ня звуку"</string>
@@ -1340,7 +1348,7 @@
<string name="sim_done_button" msgid="827949989369963775">"Готово"</string>
<string name="sim_added_title" msgid="3719670512889674693">"SIM-карту додано"</string>
<string name="sim_added_message" msgid="6599945301141050216">"Перезапустіть пристрій, щоб отримати доступ до мобільної мережі."</string>
- <string name="sim_restart_button" msgid="4722407842815232347">"Перезапуск"</string>
+ <string name="sim_restart_button" msgid="4722407842815232347">"Перезапустити"</string>
<string name="install_carrier_app_notification_title" msgid="9056007111024059888">"Активувати мобільну службу"</string>
<string name="install_carrier_app_notification_text" msgid="3346681446158696001">"Завантажити додаток оператора, щоб активувати нову SIM-карту"</string>
<string name="install_carrier_app_notification_text_app_name" msgid="1196505084835248137">"Щоб активувати нову SIM-карту, завантажте додаток <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
@@ -1891,6 +1899,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Запит SS змінено на запит USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Змінено на новий запит SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Робочий профіль"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Розгорнути"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Згорнути"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"розгорнути або згорнути"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 96bd9a3..60b650d 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi کالنگ | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"آف"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi ترجیحی"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"موبائل ترجیحی"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ایپ کو اضافی مقام فراہم کنندہ کی کمانڈز تک رسائی حاصل کرنے کی اجازت دیتی ہے۔ یہ ایپ کو GPS یا دوسرے مقام کے مآخذ کے عمل کے ساتھ مداخلت کرنے کی اجازت دے سکتی ہے۔"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"صرف پیش منظر میں درست مقام تک رسائی حاصل کریں"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"یہ ایپ جب پس منظر میں ہوتی ہے تبھی یہ آپ کا صحیح مقام حاصل کر سکتی ہے۔ ایپ کو ان مقام کی سروسز کو استعمال کر سکنے کیلئے ان کا آن ہونا اور آپ کے فون پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"تخمینی مقام تک رسائی حاصل کریں (نیٹ ورک پر مبنی)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"نیٹ ورک مآخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کیلئے ان کا آن ہونا اور آپ کے ٹیبلیٹ پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"نیٹ ورک مآخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کیلئے ان کا آن ہونا اور آپ کے TV پر دستیاب ہونا ضروری ہے۔"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"نیٹ ورک مآخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کیلئے ان کا آن ہونا اور آپ کے فون پر دستیاب ہونا ضروری ہے۔"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"صرف پیش منظر میں (نیٹ ورک پر مبنی) تخمینی مقام تک رسائی حاصل کریں"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کے ٹیبلیٹ پر دستیاب ہونا ضروری ہے۔"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کی ٹی وی پر دستیاب ہونا ضروری ہے۔"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"نیٹ ورک ماخذات جیسے کہ سیل ٹاورز اور Wi-Fi نیٹ ورکس کی بنیاد پر یہ ایپ آپ کا مقام حاصل کر سکتی ہے لیکن صرف اس وقت جب ایپ پیش منظر میں ہو۔ ایپ کو ان مقام کی سروسز کو استعمال کرنے کے لیے ان کا آن ہونا اور آپ کے فون پر دستیاب ہونا ضروری ہے۔"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"پس منظر میں مقام کی رسائی حاصل کریں"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"اگر اضافی طور پر اسے تخمینی یا درست مقام تک رسائی کی منظوری دی جاتی ہے تو پس منظر میں چلنے کے دوران ایپ اس مقام تک رسائی حاصل کر سکتی ہے۔"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"اپنے آڈیو کی ترتیبات کو تبدیل کریں"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS درخواست کو USSD درخواست میں تبدیل کر دیا گیا"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"نئی SS درخواست میں تبدیل کر دیا گیا"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"دفتری پروفائل"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"پھیلائیں"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"سکیڑیں"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"پھیلاؤ کو ٹوگل کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index ccb9e15..2192ad4 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi chaqiruv | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"O‘chiq"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi afzalligi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Mobil internet afzalligi"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ilovaga qo‘shimcha joylashuv xizmati buyruqlaridan foydalanishga ruxsat beradi. Uning yordamida ilova GPS yoki boshqa joylashuv ma’lumoti manbalarining ishlashiga xalaqit qilishi mumkin."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"aniq joylashuv axborotini olishga faqat old fonda ruxsat"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Bu ilova faqat fon rejimida aniq joylashuv axborotingizdan foydalanishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular telefoningizda yoniq turishi va ishlashi kerak. Bunda batareya sarfi oshishi mumkin."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"taxminiy joylashuv (tarmoq asosida) ma’lumotlaridan foydalanishga ruxsat"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Bu ilova Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular planshetda yoniq bo‘lishi va ishlashi kerak."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Bu ilova Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular televizorda yoniq bo‘lishi va ishlashi kerak."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Bu ilova Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular telefoningizda yoniq bo‘lishi va ishlashi kerak."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"faqat faol rejimda taxminiy joylashuv axborotiga (tarmoq asosida) ruxsat"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular planshetingizda yoniq bo‘lishi va ishlashi kerak."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular televizoringizda yoniq bo‘lishi va ishlashi kerak."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Bu ilova faqat faol rejimda ekanida Wi-Fi va uyali tarmoq antennalari kabi tarmoq manbalari asosida joylashuvingiz axborotini olishi mumkin. Ilova ushbu joylashuv xizmatlaridan foydalana olishi uchun ular telefoningizda yoniq bo‘lishi va ishlashi kerak."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"fonda joylashuv axborotidan foydalanish"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Agar taxminiy yoki aniq joylashuv axborotiga qo‘shimcha tarzda ruxsat berilgan bo‘lsa, ilova ishlayotganda joylashuv axborotidan fonda foydala oladi."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"audio sozlamalaringizni o‘zgartirish"</string>
@@ -1826,6 +1834,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS talabi USSD talabiga almashtirildi"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Yangi SS talabiga almashtirildi"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Ishchi profil"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Yoyish"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Yig‘ish"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"ochish yoki yopish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 02b9ed9..00e9891 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"Wi-Fi <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Gọi qua Wi-Fi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"VoWifi <xliff:g id="SPN">%s</xliff:g>"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Tắt"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Ưu tiên Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Ưu tiên dữ liệu di động"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Cho phép ứng dụng truy cập vào các lệnh của nhà cung cấp vị trí bổ sung. Điều này có thể cho phép ứng dụng can thiệp vào hoạt động của Hệ thống định vị toàn cầu (GPS) hoặc các nguồn vị trí khác."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"chỉ truy cập vị trí chính xác trong nền trước"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí chính xác của bạn. Để ứng dụng có thể sử các dụng dịch vụ vị trí, điện thoại của bạn phải có các dịch vụ này và dịch vụ ở trạng thái bật. Hoạt động này có thể tăng mức tiêu thụ pin."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"truy cập vị trí gần đúng (dựa vào mạng)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Ứng dụng này có thể nhận thông tin vị trí của bạn dựa trên các nguồn mạng như tháp phát sóng di động và mạng Wi-Fi. Các dịch vụ vị trí này phải được bật và khả dụng trên máy tính bảng của bạn để ứng dụng có thể sử dụng chúng."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Ứng dụng này có thể nhận thông tin vị trí của bạn dựa trên các nguồn mạng như tháp phát sóng di động và mạng Wi-Fi. Các dịch vụ vị trí này phải được bật và khả dụng trên TV của bạn để ứng dụng có thể sử dụng chúng."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Ứng dụng này có thể nhận thông tin vị trí của bạn dựa trên các nguồn mạng như tháp phát sóng di động và mạng Wi-Fi. Các dịch vụ vị trí này phải được bật và khả dụng trên điện thoại của bạn để ứng dụng có thể sử dụng chúng."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"chỉ truy cập vị trí gần đúng (dựa trên mạng) trong nền trước"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí dựa trên nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Để ứng dụng có thể dùng các dịch vụ vị trí, máy tính bảng của bạn phải có các dịch vụ này ở trạng thái bật."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí dựa trên nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Để ứng dụng có thể dùng các dịch vụ vị trí, TV của bạn phải có các dịch vụ này ở trạng thái bật."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Bất cứ khi nào chạy trong nền trước, ứng dụng này có thể nhận thông tin vị trí dựa trên nguồn mạng, chẳng hạn như trạm phát sóng di động và mạng Wi-Fi. Để ứng dụng có thể dùng các dịch vụ vị trí, điện thoại của bạn phải có các dịch vụ này ở trạng thái bật."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"truy cập vào vị trí trong nền"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Nếu bạn cấp cho ứng dụng quyền truy cập bổ sung vào vị trị gần đúng hoặc chính xác, thì ứng dụng có thể truy cập vào vị trí đó khi chạy trong nền."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"thay đổi cài đặt âm thanh của bạn"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Yêu cầu SS đã thay đổi thành yêu cầu USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Đã thay đổi thành yêu cầu SS mới"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Hồ sơ công việc"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Mở rộng"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Thu gọn"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"chuyển đổi mở rộng"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 076d6f9..d655d32 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> WLAN"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WLAN 通话 | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"关闭"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首选 WLAN"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"首选移动数据网络"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允许该应用使用其他的位置信息提供程序命令。此权限使该应用可以干扰GPS或其他位置信息源的运作。"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"只能在前台获取精确的位置信息"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"此应用只有在前台运行时才能获取您的精确位置信息。您的手机必须支持并开启这些位置信息服务,此应用才能使用这些服务。这可能会增加耗电量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"访问大致位置信息(以网络为依据)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"此应用可根据网络来源(例如基站和 WLAN 网络)获取您的位置信息。您的平板电脑必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"此应用可根据网络来源(例如基站和 WLAN 网络)获取您的位置信息。您的电视必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"此应用可根据网络来源(例如基站和 WLAN 网络)获取您的位置信息。您的手机必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"只能在前台获取大概位置(基于网络)"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"此应用只能在前台根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的平板电脑必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"此应用只能在前台根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的电视必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"此应用只能在前台根据网络来源(例如手机信号塔和 WLAN 网络)获取您的位置信息。您的手机必须支持并开启这些位置信息服务,此应用才能使用这些服务。"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"在后台使用位置信息"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"如果另外授予大致位置信息或精确位置信息访问权限,该应用便可在后台运行时使用位置信息。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"更改您的音频设置"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS 请求已更改为 USSD 请求"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"已更改为新的 SS 请求"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"工作资料"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"展开"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"收起"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"切换展开模式"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 1484006..086a068 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"WiFi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"首選 Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"流動數據優先"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允許應用程式存取額外的位置提供者指令。這項設定可能會使應用程式干擾 GPS 或其他位置來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"只在前景存取精確位置"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"此應用程式只可在前台運行時獲取您的確實位置資訊。您的手機必須支援並啟用這些位置資訊服務,應用程式方可使用這項功能,但這樣做可能會增加耗電量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"存取約略位置 (根據網絡)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"此應用程式可以根據您的網絡來源 (例如手機訊號塔和 Wi-Fi 網絡) 取得您的位置。您的平板電腦必須支援並啟用這些位置資訊服務,應用程式方可使用這項功能。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"此應用程式可以根據您的網絡來源 (例如手機訊號塔和 Wi-Fi 網絡) 取得您的位置。您的電視必須支援並啟用這些位置資訊服務,應用程式方可使用這項功能。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"此應用程式可以根據您的網絡來源 (例如手機訊號塔和 Wi-Fi 網絡) 取得您的位置。您的手機必須支援並啟用這些位置資訊服務,應用程式方可使用這項功能。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"只可在前景存取大概位置 (根據網絡定位)"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在平板電腦上開啟這些位置資訊服務,才能讓此應用程式使用位置資訊。"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在電視上開啟這些位置資訊服務,才能讓此應用程式使用位置資訊。"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"此應用程式只能在前景中根據網絡來源 (例如手機訊號發射塔和 Wi-Fi 網絡) 獲取您的位置資訊。您必須在手機上開啟這些位置資訊服務,才能讓此應用程式使用位置資訊。"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"在背景存取位置資訊"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"如果您另外授予概略位置或精確位置的存取權,這個應用程式在背景運行時將可存取位置資訊。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"更改音效設定"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS 要求已變更為 USSD 要求"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"已變更為新的 SS 要求"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"工作設定檔"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"展開"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"收合"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"切換展開"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 608a758b..e789e9a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Wi-Fi 通話 | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"關閉"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Wi-Fi 優先"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"行動網路優先"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"允許應用程式存取額外位置資訊提供者指令。這項設定可能會造成應用程式干擾 GPS 或其他位置資訊來源的運作。"</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"僅可在前景中取得精確位置"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"這個應用程式只能在前景中取得你的確切位置。你必須在手機上開啟這些定位服務,才能讓這個應用程式取得確切位置。請注意,這麼做可能會增加耗電量。"</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"存取概略位置 (以網路為依據)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"這個應用程式可根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。你必須在平板電腦上開啟這類定位服務,才能讓這個應用程式取得位置資訊。"</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"這個應用程式可根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。你必須在電視上開啟這類定位服務,才能讓這個應用程式取得位置資訊。"</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"這個應用程式可根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。你必須在手機上開啟這類定位服務,才能讓這個應用程式取得位置資訊。"</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"只有在前景執行時才能根據網路取得概略位置"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在平板電腦上開啟這些服務。"</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在電視上開啟這些服務。"</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"只要這個應用程式在前景執行,就可以根據網路來源 (例如基地台和 Wi-Fi 網路) 取得你的位置資訊。如要讓這個應用程式使用定位服務,你必須在手機上開啟這些服務。"</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"在背景存取位置資訊"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"除了概略位置或精確位置的存取權外,若您另外授予這項存取權,這個應用程式就能在背景執行時存取位置資訊。"</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"變更音訊設定"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"SS 要求已變更為 USSD 要求"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"已變更為新的 SS 要求"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"工作資料夾"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"展開"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"收合"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"切換展開模式"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 42a1ad0..2e1540f 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -136,6 +136,14 @@
<string name="wfcSpnFormat_spn_wifi" msgid="6546481665561961938">"<xliff:g id="SPN">%s</xliff:g> Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_bar_spn" msgid="1726178784338466265">"Ukushaya kwe-WiFi | <xliff:g id="SPN">%s</xliff:g>"</string>
<string name="wfcSpnFormat_spn_vowifi" msgid="4444638298656953681">"<xliff:g id="SPN">%s</xliff:g> VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_calling (4990486735013125329) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi (1892673884655959773) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_wifi_calling_wo_hyphen (1336669776254502831) -->
+ <skip />
+ <!-- no translation found for wfcSpnFormat_vowifi (1765176406171272629) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"Valiwe"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"Kuncanyelwa i-Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="1988279625335345908">"Kuncanyelwa iselula"</string>
@@ -417,10 +425,10 @@
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"Ivumela uhlelo lokusebenza ukufinyelela imiyalo eyengeziwe yabahlinzeki bendawo. Lokhu kungase kuvumele uhlelo lokusebenza ukuthi liphazamisane nomsebenzi we-GPS noma eminye imithombo yendawo."</string>
<string name="permlab_accessFineLocation" msgid="6265109654698562427">"finyelela indawo eqondile kuphela phambili"</string>
<string name="permdesc_accessFineLocation" msgid="3520508381065331098">"Lolu hlelo lokusebenza lungakutholela indawo eqondile kuphela uma liphambili. Lawa masevisi endawo kufanele avulwe futhi atholakale efonini yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa. Lokhu kungakhulisa ukusebenza kwebhethri."</string>
- <string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"finyelela kundawo elinganiselwe (esuselwa kunethiwekhi)"</string>
- <string name="permdesc_accessCoarseLocation" product="tablet" msgid="3373266766487862426">"Lolu hlelo lokusebenza lungathola indawo yakho ngokususelwe kumithombo yenethiwekhi njengamathawa eseli namanethiwekhi e-Wi-Fi. Lawa masevisi endawo kufanele avulwe futhi atholakale kuthebhulethi yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
- <string name="permdesc_accessCoarseLocation" product="tv" msgid="1884022719818788511">"Lolu hlelo lokusebenza lingathola indawo yakho ngokususelwe kumithombo yenethiwekhi njengamathawa eseli namanethiwekhi e-Wi-Fi. Lawa masevisi endawo kufanele avulwe futhi atholakale ku-TV yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
- <string name="permdesc_accessCoarseLocation" product="default" msgid="7788009094906196995">"Lolu hlelo lokusebenza lungathola indawo yakho ngokususelwe kumithombo yenethiwekhi njengamathawa eseli kanye namanethiwekhi e-Wi-Fi. Lawa masevisi endawo kufanele avulwe futhi atholakale efonini yakho ukuze uhlelo lokusebenza likwazi ukuwasebenzisa."</string>
+ <string name="permlab_accessCoarseLocation" msgid="3707180371693213469">"finyelela indawo eseduze (esuselwa kunethiwekhi) kuphela ngaphambili"</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet" msgid="8594719010575779120">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale kuthebulethi yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
+ <string name="permdesc_accessCoarseLocation" product="tv" msgid="3027871910200890806">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale ku-TV yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
+ <string name="permdesc_accessCoarseLocation" product="default" msgid="854896049371048754">"Lolu hlelo lokusebenza lungathola indawo yakho kusukela kumithombo yenethiwekhi efana nezinqaba zeselula kanye namanethiwekhi e-Wi-Fi, kodwa kuphela uma uhlelo lokusebenza lungaphambili. Lawa masevisi endawo kumele avulwe futhi atholakale kufoni yakho ukuze uhlelo lokusebenza lukwazi ukuwasebenzisa."</string>
<string name="permlab_accessBackgroundLocation" msgid="3965397804300661062">"finyelela kundawo ngemuva"</string>
<string name="permdesc_accessBackgroundLocation" msgid="1096394429579210251">"Uma lokhu kunikezwa ngokungeziwe ekufinyeleleni okulinganiselwe noma okunembile kwendawo uhlelo lokusebenza lungafinyelela kundawo ngenkathi lusebenza ngemuva."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"shintsha izilungiselelo zakho zomsindo"</string>
@@ -1825,6 +1833,8 @@
<string name="stk_cc_ss_to_ussd" msgid="5614626512855868785">"Isicelo se-SS sishintshele kusicelo se-USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="7716729801537709054">"Ishintshele kusicelo esisha se-SS"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Iphrofayela yomsebenzi"</string>
+ <!-- no translation found for notification_alerted_content_description (1296617716556420585) -->
+ <skip />
<string name="expand_button_content_description_collapsed" msgid="3609784019345534652">"Nweba"</string>
<string name="expand_button_content_description_expanded" msgid="8520652707158554895">"Goqa"</string>
<string name="expand_action_accessibility" msgid="5307730695723718254">"guqula ukunwebisa"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bca72f4..6ae183b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -906,7 +906,7 @@
<!-- Control whether to lock day/night mode change from normal application. When it is
true, day / night mode change is only allowed to apps with MODIFY_DAY_NIGHT_MODE
permission. -->
- <bool name="config_lockDayNightMode">false</bool>
+ <bool name="config_lockDayNightMode">true</bool>
<!-- Control the default night mode to use when there is no other mode override set.
One of the following values (see UiModeManager.java):
@@ -2428,7 +2428,10 @@
Can be customized for other product types -->
<string name="config_chooseTypeAndAccountActivity" translatable="false"
>android/android.accounts.ChooseTypeAndAccountActivity</string>
-
+ <!-- Name of the activity that will handle requests to the system to choose an activity for
+ the purposes of resolving an intent. -->
+ <string name="config_chooserActivity" translatable="false"
+ >com.android.systemui/com.android.systemui.chooser.ChooserActivity</string>
<!-- Component name of a custom ResolverActivity (Intent resolver) to be used instead of
the default framework version. If left empty, then the framework version will be used.
Example: com.google.android.myapp/.resolver.MyResolverActivity -->
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 3183169..64e5bc0 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -121,6 +121,18 @@
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SCROLL_RIGHT}. -->
<item type="id" name="accessibilityActionScrollRight" />
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_UP}. -->
+ <item type="id" name="accessibilityActionPageUp" />
+
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_DOWN}. -->
+ <item type="id" name="accessibilityActionPageDown" />
+
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_LEFT}. -->
+ <item type="id" name="accessibilityActionPageLeft" />
+
+ <!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_PAGE_RIGHT}. -->
+ <item type="id" name="accessibilityActionPageRight" />
+
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_SET_PROGRESS}. -->
<item type="id" name="accessibilityActionSetProgress" />
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index 35eee6a..d6c0a10 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -23,80 +23,81 @@
<item>ak-GH</item> <!-- Akan (Ghana) -->
<item>am-ET</item> <!-- Amharic (Ethiopia) -->
<item>ar-AE</item> <!-- Arabic (United Arab Emirates) -->
- <item>ar-AE-u-nu-latn</item> <!-- Arabic (United Arab Emirates,Western Digits) -->
+ <item>ar-AE-u-nu-latn</item> <!-- Arabic (United Arab Emirates, Western Digits) -->
<item>ar-BH</item> <!-- Arabic (Bahrain) -->
- <item>ar-BH-u-nu-latn</item> <!-- Arabic (Bahrain,Western Digits) -->
+ <item>ar-BH-u-nu-latn</item> <!-- Arabic (Bahrain, Western Digits) -->
<item>ar-DJ</item> <!-- Arabic (Djibouti) -->
- <item>ar-DJ-u-nu-latn</item> <!-- Arabic (Djibouti,Western Digits) -->
+ <item>ar-DJ-u-nu-latn</item> <!-- Arabic (Djibouti, Western Digits) -->
<item>ar-DZ</item> <!-- Arabic (Algeria) -->
- <item>ar-DZ-u-nu-arab</item> <!-- Arabic (Algeria,Arabic-Indic Digits) -->
+ <item>ar-DZ-u-nu-arab</item> <!-- Arabic (Algeria, Arabic-Indic Digits) -->
<item>ar-EG</item> <!-- Arabic (Egypt) -->
- <item>ar-EG-u-nu-latn</item> <!-- Arabic (Egypt,Western Digits) -->
+ <item>ar-EG-u-nu-latn</item> <!-- Arabic (Egypt, Western Digits) -->
<item>ar-EH</item> <!-- Arabic (Western Sahara) -->
- <item>ar-EH-u-nu-arab</item> <!-- Arabic (Western Sahara,Arabic-Indic Digits) -->
+ <item>ar-EH-u-nu-arab</item> <!-- Arabic (Western Sahara, Arabic-Indic Digits) -->
<item>ar-ER</item> <!-- Arabic (Eritrea) -->
- <item>ar-ER-u-nu-latn</item> <!-- Arabic (Eritrea,Western Digits) -->
+ <item>ar-ER-u-nu-latn</item> <!-- Arabic (Eritrea, Western Digits) -->
<item>ar-IL</item> <!-- Arabic (Israel) -->
- <item>ar-IL-u-nu-latn</item> <!-- Arabic (Israel,Western Digits) -->
+ <item>ar-IL-u-nu-latn</item> <!-- Arabic (Israel, Western Digits) -->
<item>ar-IQ</item> <!-- Arabic (Iraq) -->
- <item>ar-IQ-u-nu-latn</item> <!-- Arabic (Iraq,Western Digits) -->
+ <item>ar-IQ-u-nu-latn</item> <!-- Arabic (Iraq, Western Digits) -->
<item>ar-JO</item> <!-- Arabic (Jordan) -->
- <item>ar-JO-u-nu-latn</item> <!-- Arabic (Jordan,Western Digits) -->
+ <item>ar-JO-u-nu-latn</item> <!-- Arabic (Jordan, Western Digits) -->
<item>ar-KM</item> <!-- Arabic (Comoros) -->
- <item>ar-KM-u-nu-latn</item> <!-- Arabic (Comoros,Western Digits) -->
+ <item>ar-KM-u-nu-latn</item> <!-- Arabic (Comoros, Western Digits) -->
<item>ar-KW</item> <!-- Arabic (Kuwait) -->
- <item>ar-KW-u-nu-latn</item> <!-- Arabic (Kuwait,Western Digits) -->
+ <item>ar-KW-u-nu-latn</item> <!-- Arabic (Kuwait, Western Digits) -->
<item>ar-LB</item> <!-- Arabic (Lebanon) -->
- <item>ar-LB-u-nu-latn</item> <!-- Arabic (Lebanon,Western Digits) -->
+ <item>ar-LB-u-nu-latn</item> <!-- Arabic (Lebanon, Western Digits) -->
<item>ar-LY</item> <!-- Arabic (Libya) -->
- <item>ar-LY-u-nu-arab</item> <!-- Arabic (Libya,Arabic-Indic Digits) -->
+ <item>ar-LY-u-nu-arab</item> <!-- Arabic (Libya, Arabic-Indic Digits) -->
<item>ar-MA</item> <!-- Arabic (Morocco) -->
- <item>ar-MA-u-nu-arab</item> <!-- Arabic (Morocco,Arabic-Indic Digits) -->
+ <item>ar-MA-u-nu-arab</item> <!-- Arabic (Morocco, Arabic-Indic Digits) -->
<item>ar-MR</item> <!-- Arabic (Mauritania) -->
- <item>ar-MR-u-nu-latn</item> <!-- Arabic (Mauritania,Western Digits) -->
+ <item>ar-MR-u-nu-latn</item> <!-- Arabic (Mauritania, Western Digits) -->
<item>ar-OM</item> <!-- Arabic (Oman) -->
- <item>ar-OM-u-nu-latn</item> <!-- Arabic (Oman,Western Digits) -->
+ <item>ar-OM-u-nu-latn</item> <!-- Arabic (Oman, Western Digits) -->
<item>ar-PS</item> <!-- Arabic (Palestine) -->
- <item>ar-PS-u-nu-latn</item> <!-- Arabic (Palestine,Western Digits) -->
+ <item>ar-PS-u-nu-latn</item> <!-- Arabic (Palestine, Western Digits) -->
<item>ar-QA</item> <!-- Arabic (Qatar) -->
- <item>ar-QA-u-nu-latn</item> <!-- Arabic (Qatar,Western Digits) -->
+ <item>ar-QA-u-nu-latn</item> <!-- Arabic (Qatar, Western Digits) -->
<item>ar-SA</item> <!-- Arabic (Saudi Arabia) -->
- <item>ar-SA-u-nu-latn</item> <!-- Arabic (Saudi Arabia,Western Digits) -->
+ <item>ar-SA-u-nu-latn</item> <!-- Arabic (Saudi Arabia, Western Digits) -->
<item>ar-SD</item> <!-- Arabic (Sudan) -->
- <item>ar-SD-u-nu-latn</item> <!-- Arabic (Sudan,Western Digits) -->
+ <item>ar-SD-u-nu-latn</item> <!-- Arabic (Sudan, Western Digits) -->
<item>ar-SO</item> <!-- Arabic (Somalia) -->
- <item>ar-SO-u-nu-latn</item> <!-- Arabic (Somalia,Western Digits) -->
+ <item>ar-SO-u-nu-latn</item> <!-- Arabic (Somalia, Western Digits) -->
<item>ar-SS</item> <!-- Arabic (South Sudan) -->
- <item>ar-SS-u-nu-latn</item> <!-- Arabic (South Sudan,Western Digits) -->
+ <item>ar-SS-u-nu-latn</item> <!-- Arabic (South Sudan, Western Digits) -->
<item>ar-SY</item> <!-- Arabic (Syria) -->
- <item>ar-SY-u-nu-latn</item> <!-- Arabic (Syria,Western Digits) -->
+ <item>ar-SY-u-nu-latn</item> <!-- Arabic (Syria, Western Digits) -->
<item>ar-TD</item> <!-- Arabic (Chad) -->
- <item>ar-TD-u-nu-latn</item> <!-- Arabic (Chad,Western Digits) -->
+ <item>ar-TD-u-nu-latn</item> <!-- Arabic (Chad, Western Digits) -->
<item>ar-TN</item> <!-- Arabic (Tunisia) -->
- <item>ar-TN-u-nu-arab</item> <!-- Arabic (Tunisia,Arabic-Indic Digits) -->
+ <item>ar-TN-u-nu-arab</item> <!-- Arabic (Tunisia, Arabic-Indic Digits) -->
<item>ar-XB</item> <!-- Right-to-left pseudolocale -->
<item>ar-YE</item> <!-- Arabic (Yemen) -->
- <item>ar-YE-u-nu-latn</item> <!-- Arabic (Yemen,Western Digits) -->
+ <item>ar-YE-u-nu-latn</item> <!-- Arabic (Yemen, Western Digits) -->
<item>as-IN</item> <!-- Assamese (India) -->
<item>asa-TZ</item> <!-- Asu (Tanzania) -->
- <item>az-Cyrl-AZ</item> <!-- Azerbaijani (Cyrillic,Azerbaijan) -->
- <item>az-Latn-AZ</item> <!-- Azerbaijani (Latin,Azerbaijan) -->
+ <item>ast-ES</item> <!-- Asturian (Spain) -->
+ <item>az-Cyrl-AZ</item> <!-- Azerbaijani (Cyrillic, Azerbaijan) -->
+ <item>az-Latn-AZ</item> <!-- Azerbaijani (Latin, Azerbaijan) -->
<item>bas-CM</item> <!-- Basaa (Cameroon) -->
<item>be-BY</item> <!-- Belarusian (Belarus) -->
<item>bem-ZM</item> <!-- Bemba (Zambia) -->
<item>bez-TZ</item> <!-- Bena (Tanzania) -->
<item>bg-BG</item> <!-- Bulgarian (Bulgaria) -->
<item>bm-ML</item> <!-- Bambara (Mali) -->
- <item>bn-BD</item> <!-- Bengali (Bangladesh) -->
- <item>bn-BD-u-nu-latn</item> <!-- Bengali (Bangladesh,Western Digits) -->
- <item>bn-IN</item> <!-- Bengali (India) -->
- <item>bn-IN-u-nu-latn</item> <!-- Bengali (India,Western Digits) -->
+ <item>bn-BD</item> <!-- Bangla (Bangladesh) -->
+ <item>bn-BD-u-nu-latn</item> <!-- Bangla (Bangladesh, Western Digits) -->
+ <item>bn-IN</item> <!-- Bangla (India) -->
+ <item>bn-IN-u-nu-latn</item> <!-- Bangla (India, Western Digits) -->
<item>bo-CN</item> <!-- Tibetan (China) -->
<item>bo-IN</item> <!-- Tibetan (India) -->
<item>br-FR</item> <!-- Breton (France) -->
<item>brx-IN</item> <!-- Bodo (India) -->
- <item>bs-Cyrl-BA</item> <!-- Bosnian (Cyrillic,Bosnia & Herzegovina) -->
- <item>bs-Latn-BA</item> <!-- Bosnian (Latin,Bosnia & Herzegovina) -->
+ <item>bs-Cyrl-BA</item> <!-- Bosnian (Cyrillic, Bosnia & Herzegovina) -->
+ <item>bs-Latn-BA</item> <!-- Bosnian (Latin, Bosnia & Herzegovina) -->
<item>ca-AD</item> <!-- Catalan (Andorra) -->
<item>ca-ES</item> <!-- Catalan (Spain) -->
<item>ca-FR</item> <!-- Catalan (France) -->
@@ -113,6 +114,7 @@
<item>de-BE</item> <!-- German (Belgium) -->
<item>de-CH</item> <!-- German (Switzerland) -->
<item>de-DE</item> <!-- German (Germany) -->
+ <item>de-IT</item> <!-- German (Italy) -->
<item>de-LI</item> <!-- German (Liechtenstein) -->
<item>de-LU</item> <!-- German (Luxembourg) -->
<item>dje-NE</item> <!-- Zarma (Niger) -->
@@ -230,6 +232,8 @@
<item>en-ZW</item> <!-- English (Zimbabwe) -->
<item>es-AR</item> <!-- Spanish (Argentina) -->
<item>es-BO</item> <!-- Spanish (Bolivia) -->
+ <item>es-BR</item> <!-- Spanish (Brazil) -->
+ <item>es-BZ</item> <!-- Spanish (Belize) -->
<item>es-CL</item> <!-- Spanish (Chile) -->
<item>es-CO</item> <!-- Spanish (Colombia) -->
<item>es-CR</item> <!-- Spanish (Costa Rica) -->
@@ -257,9 +261,9 @@
<item>eu-ES</item> <!-- Basque (Spain) -->
<item>ewo-CM</item> <!-- Ewondo (Cameroon) -->
<item>fa-AF</item> <!-- Persian (Afghanistan) -->
- <item>fa-AF-u-nu-latn</item> <!-- Persian (Afghanistan,Western Digits) -->
+ <item>fa-AF-u-nu-latn</item> <!-- Persian (Afghanistan, Western Digits) -->
<item>fa-IR</item> <!-- Persian (Iran) -->
- <item>fa-IR-u-nu-latn</item> <!-- Persian (Iran,Western Digits) -->
+ <item>fa-IR-u-nu-latn</item> <!-- Persian (Iran, Western Digits) -->
<item>ff-CM</item> <!-- Fulah (Cameroon) -->
<item>ff-GN</item> <!-- Fulah (Guinea) -->
<item>ff-MR</item> <!-- Fulah (Mauritania) -->
@@ -274,9 +278,9 @@
<item>fr-BJ</item> <!-- French (Benin) -->
<item>fr-BL</item> <!-- French (St. Barthélemy) -->
<item>fr-CA</item> <!-- French (Canada) -->
- <item>fr-CD</item> <!-- French (Congo (DRC)) -->
+ <item>fr-CD</item> <!-- French (Congo - Kinshasa) -->
<item>fr-CF</item> <!-- French (Central African Republic) -->
- <item>fr-CG</item> <!-- French (Congo (Republic)) -->
+ <item>fr-CG</item> <!-- French (Congo - Brazzaville) -->
<item>fr-CH</item> <!-- French (Switzerland) -->
<item>fr-CI</item> <!-- French (Côte d’Ivoire) -->
<item>fr-CM</item> <!-- French (Cameroon) -->
@@ -329,20 +333,20 @@
<item>ha-NE</item> <!-- Hausa (Niger) -->
<item>ha-NG</item> <!-- Hausa (Nigeria) -->
<item>haw-US</item> <!-- Hawaiian (United States) -->
- <item>iw-IL</item> <!-- Hebrew (Israel) -->
<item>hi-IN</item> <!-- Hindi (India) -->
<item>hr-BA</item> <!-- Croatian (Bosnia & Herzegovina) -->
<item>hr-HR</item> <!-- Croatian (Croatia) -->
<item>hsb-DE</item> <!-- Upper Sorbian (Germany) -->
<item>hu-HU</item> <!-- Hungarian (Hungary) -->
<item>hy-AM</item> <!-- Armenian (Armenia) -->
- <item>in-ID</item> <!-- Indonesian (Indonesia) -->
<item>ig-NG</item> <!-- Igbo (Nigeria) -->
<item>ii-CN</item> <!-- Sichuan Yi (China) -->
+ <item>in-ID</item> <!-- Indonesian (Indonesia) -->
<item>is-IS</item> <!-- Icelandic (Iceland) -->
<item>it-CH</item> <!-- Italian (Switzerland) -->
<item>it-IT</item> <!-- Italian (Italy) -->
<item>it-SM</item> <!-- Italian (San Marino) -->
+ <item>iw-IL</item> <!-- Hebrew (Israel) -->
<item>ja-JP</item> <!-- Japanese (Japan) -->
<item>jgo-CM</item> <!-- Ngomba (Cameroon) -->
<item>jmc-TZ</item> <!-- Machame (Tanzania) -->
@@ -372,12 +376,12 @@
<item>lg-UG</item> <!-- Ganda (Uganda) -->
<item>lkt-US</item> <!-- Lakota (United States) -->
<item>ln-AO</item> <!-- Lingala (Angola) -->
- <item>ln-CD</item> <!-- Lingala (Congo (DRC)) -->
+ <item>ln-CD</item> <!-- Lingala (Congo - Kinshasa) -->
<item>ln-CF</item> <!-- Lingala (Central African Republic) -->
- <item>ln-CG</item> <!-- Lingala (Congo (Republic)) -->
+ <item>ln-CG</item> <!-- Lingala (Congo - Brazzaville) -->
<item>lo-LA</item> <!-- Lao (Laos) -->
<item>lt-LT</item> <!-- Lithuanian (Lithuania) -->
- <item>lu-CD</item> <!-- Luba-Katanga (Congo (DRC)) -->
+ <item>lu-CD</item> <!-- Luba-Katanga (Congo - Kinshasa) -->
<item>luo-KE</item> <!-- Luo (Kenya) -->
<item>luy-KE</item> <!-- Luyia (Kenya) -->
<item>lv-LV</item> <!-- Latvian (Latvia) -->
@@ -418,11 +422,11 @@
<item>nyn-UG</item> <!-- Nyankole (Uganda) -->
<item>om-ET</item> <!-- Oromo (Ethiopia) -->
<item>om-KE</item> <!-- Oromo (Kenya) -->
- <item>or-IN</item> <!-- Oriya (India) -->
+ <item>or-IN</item> <!-- Odia (India) -->
<item>os-GE</item> <!-- Ossetic (Georgia) -->
<item>os-RU</item> <!-- Ossetic (Russia) -->
- <item>pa-Arab-PK</item> <!-- Punjabi (Arabic,Pakistan) -->
- <item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi,India) -->
+ <item>pa-Arab-PK</item> <!-- Punjabi (Arabic, Pakistan) -->
+ <item>pa-Guru-IN</item> <!-- Punjabi (Gurmukhi, India) -->
<item>pl-PL</item> <!-- Polish (Poland) -->
<item>ps-AF</item> <!-- Pashto (Afghanistan) -->
<item>pt-AO</item> <!-- Portuguese (Angola) -->
@@ -471,18 +475,18 @@
<item>sq-AL</item> <!-- Albanian (Albania) -->
<item>sq-MK</item> <!-- Albanian (Macedonia (FYROM)) -->
<item>sq-XK</item> <!-- Albanian (Kosovo) -->
- <item>sr-Cyrl-BA</item> <!-- Serbian (Cyrillic,Bosnia & Herzegovina) -->
- <item>sr-Cyrl-ME</item> <!-- Serbian (Cyrillic,Montenegro) -->
- <item>sr-Cyrl-RS</item> <!-- Serbian (Cyrillic,Serbia) -->
- <item>sr-Cyrl-XK</item> <!-- Serbian (Cyrillic,Kosovo) -->
- <item>sr-Latn-BA</item> <!-- Serbian (Latin,Bosnia & Herzegovina) -->
- <item>sr-Latn-ME</item> <!-- Serbian (Latin,Montenegro) -->
- <item>sr-Latn-RS</item> <!-- Serbian (Latin,Serbia) -->
- <item>sr-Latn-XK</item> <!-- Serbian (Latin,Kosovo) -->
+ <item>sr-Cyrl-BA</item> <!-- Serbian (Cyrillic, Bosnia & Herzegovina) -->
+ <item>sr-Cyrl-ME</item> <!-- Serbian (Cyrillic, Montenegro) -->
+ <item>sr-Cyrl-RS</item> <!-- Serbian (Cyrillic, Serbia) -->
+ <item>sr-Cyrl-XK</item> <!-- Serbian (Cyrillic, Kosovo) -->
+ <item>sr-Latn-BA</item> <!-- Serbian (Latin, Bosnia & Herzegovina) -->
+ <item>sr-Latn-ME</item> <!-- Serbian (Latin, Montenegro) -->
+ <item>sr-Latn-RS</item> <!-- Serbian (Latin, Serbia) -->
+ <item>sr-Latn-XK</item> <!-- Serbian (Latin, Kosovo) -->
<item>sv-AX</item> <!-- Swedish (Åland Islands) -->
<item>sv-FI</item> <!-- Swedish (Finland) -->
<item>sv-SE</item> <!-- Swedish (Sweden) -->
- <item>sw-CD</item> <!-- Swahili (Congo (DRC)) -->
+ <item>sw-CD</item> <!-- Swahili (Congo - Kinshasa) -->
<item>sw-KE</item> <!-- Swahili (Kenya) -->
<item>sw-TZ</item> <!-- Swahili (Tanzania) -->
<item>sw-UG</item> <!-- Swahili (Uganda) -->
@@ -502,12 +506,12 @@
<item>ug-CN</item> <!-- Uyghur (China) -->
<item>uk-UA</item> <!-- Ukrainian (Ukraine) -->
<item>ur-IN</item> <!-- Urdu (India) -->
- <item>ur-IN-u-nu-latn</item> <!-- Urdu (India,Western Digits) -->
+ <item>ur-IN-u-nu-latn</item> <!-- Urdu (India, Western Digits) -->
<item>ur-PK</item> <!-- Urdu (Pakistan) -->
- <item>ur-PK-u-nu-arabext</item> <!-- Urdu (Pakistan,Extended Arabic-Indic Digits) -->
- <item>uz-Arab-AF</item> <!-- Uzbek (Arabic,Afghanistan) -->
- <item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic,Uzbekistan) -->
- <item>uz-Latn-UZ</item> <!-- Uzbek (Latin,Uzbekistan) -->
+ <item>ur-PK-u-nu-arabext</item> <!-- Urdu (Pakistan, Extended Arabic-Indic Digits) -->
+ <item>uz-Arab-AF</item> <!-- Uzbek (Arabic, Afghanistan) -->
+ <item>uz-Cyrl-UZ</item> <!-- Uzbek (Cyrillic, Uzbekistan) -->
+ <item>uz-Latn-UZ</item> <!-- Uzbek (Latin, Uzbekistan) -->
<item>vi-VN</item> <!-- Vietnamese (Vietnam) -->
<item>vun-TZ</item> <!-- Vunjo (Tanzania) -->
<item>wae-CH</item> <!-- Walser (Switzerland) -->
@@ -515,15 +519,16 @@
<item>yav-CM</item> <!-- Yangben (Cameroon) -->
<item>yo-BJ</item> <!-- Yoruba (Benin) -->
<item>yo-NG</item> <!-- Yoruba (Nigeria) -->
- <item>yue-HK</item> <!-- Cantonese (Hong Kong) -->
+ <item>yue-Hans-CN</item> <!-- Cantonese (Simplified, China) -->
+ <item>yue-Hant-HK</item> <!-- Cantonese (Traditional, Hong Kong) -->
<item>zgh-MA</item> <!-- Standard Moroccan Tamazight (Morocco) -->
- <item>zh-Hans-CN</item> <!-- Chinese (Simplified Han,China) -->
- <item>zh-Hans-HK</item> <!-- Chinese (Simplified Han,Hong Kong) -->
- <item>zh-Hans-MO</item> <!-- Chinese (Simplified Han,Macau) -->
- <item>zh-Hans-SG</item> <!-- Chinese (Simplified Han,Singapore) -->
- <item>zh-Hant-HK</item> <!-- Chinese (Traditional Han,Hong Kong) -->
- <item>zh-Hant-MO</item> <!-- Chinese (Traditional Han,Macau) -->
- <item>zh-Hant-TW</item> <!-- Chinese (Traditional Han,Taiwan) -->
+ <item>zh-Hans-CN</item> <!-- Chinese (Simplified, China) -->
+ <item>zh-Hans-HK</item> <!-- Chinese (Simplified, Hong Kong) -->
+ <item>zh-Hans-MO</item> <!-- Chinese (Simplified, Macau) -->
+ <item>zh-Hans-SG</item> <!-- Chinese (Simplified, Singapore) -->
+ <item>zh-Hant-HK</item> <!-- Chinese (Traditional, Hong Kong) -->
+ <item>zh-Hant-MO</item> <!-- Chinese (Traditional, Macau) -->
+ <item>zh-Hant-TW</item> <!-- Chinese (Traditional, Taiwan) -->
<item>zu-ZA</item> <!-- Zulu (South Africa) -->
</string-array>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 15f29ce..86879c3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2930,6 +2930,10 @@
</public-group>
<public-group type="id" first-id="0x01020046">
+ <public name="accessibilityActionPageUp" />
+ <public name="accessibilityActionPageDown" />
+ <public name="accessibilityActionPageLeft" />
+ <public name="accessibilityActionPageRight" />
</public-group>
<public-group type="string" first-id="0x0104001b">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8d3992d..200c35d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -248,6 +248,10 @@
<item>@string/wfcSpnFormat_spn_wifi</item>
<item>@string/wfcSpnFormat_wifi_calling_bar_spn</item>
<item>@string/wfcSpnFormat_spn_vowifi</item>
+ <item>@string/wfcSpnFormat_wifi_calling</item>
+ <item>@string/wfcSpnFormat_wifi</item>
+ <item>@string/wfcSpnFormat_wifi_calling_wo_hyphen</item>
+ <item>@string/wfcSpnFormat_vowifi</item>
</string-array>
<!-- Spn during Wi-Fi Calling: "<operator>" -->
@@ -264,6 +268,14 @@
<string name="wfcSpnFormat_wifi_calling_bar_spn">WiFi Calling | <xliff:g id="spn" example="Operator">%s</xliff:g></string>
<!-- Spn during Wi-Fi Calling: "<operator> VoWifi" -->
<string name="wfcSpnFormat_spn_vowifi"><xliff:g id="spn" example="Operator">%s</xliff:g> VoWifi</string>
+ <!-- Spn during Wi-Fi Calling: "Wi-Fi Calling" -->
+ <string name="wfcSpnFormat_wifi_calling">Wi-Fi Calling</string>
+ <!-- Spn during Wi-Fi Calling: "Wi-Fi" -->
+ <string name="wfcSpnFormat_wifi">Wi-Fi</string>
+ <!-- Spn during Wi-Fi Calling: "WiFi Calling" (without hyphen) -->
+ <string name="wfcSpnFormat_wifi_calling_wo_hyphen">WiFi Calling</string>
+ <!-- Spn during Wi-Fi Calling: "VoWifi" -->
+ <string name="wfcSpnFormat_vowifi">VoWifi</string>
<!-- WFC, summary for Disabled -->
<string name="wifi_calling_off_summary">Off</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5418e03..6276884 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1113,6 +1113,7 @@
<java-symbol type="string" name="owner_name" />
<java-symbol type="string" name="config_chooseAccountActivity" />
<java-symbol type="string" name="config_chooseTypeAndAccountActivity" />
+ <java-symbol type="string" name="config_chooserActivity" />
<java-symbol type="string" name="config_customResolverActivity" />
<java-symbol type="string" name="config_appsAuthorizedForSharedAccounts" />
<java-symbol type="string" name="error_message_title" />
diff --git a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
index fe51a39..689e683 100644
--- a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
+++ b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
@@ -133,8 +133,6 @@
private void assertStructureWithManySmallViews(AssistStructure structure, int expectedSize) {
int i = 0;
try {
- assertPackageName(structure);
-
assertThat(structure.getWindowNodeCount()).isEqualTo(1);
ViewNode rootView = structure.getWindowNodeAt(0).getRootViewNode();
@@ -188,8 +186,6 @@
private void assertStructureWithOneBigView(AssistStructure structure) {
try {
- assertPackageName(structure);
-
assertThat(structure.getWindowNodeCount()).isEqualTo(1);
ViewNode rootView = structure.getWindowNodeAt(0).getRootViewNode();
@@ -275,12 +271,6 @@
assertThat(hint.charAt(BIG_VIEW_SIZE - 1)).isEqualTo(BIG_VIEW_CHAR);
}
- private void assertPackageName(AssistStructure structure) {
- assertThat(structure.getActivityComponent()).isEqualTo(
- new ComponentName("com.android.frameworks.coretests",
- "android.app.assist.EmptyLayoutActivity"));
- }
-
private AssistStructure cloneThroughParcel(AssistStructure structure) {
Parcel parcel = Parcel.obtain();
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 3342266..727f399 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -197,6 +197,7 @@
Settings.Global.DESK_DOCK_SOUND,
Settings.Global.DESK_UNDOCK_SOUND,
Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT,
+ Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,
Settings.Global.DEVELOPMENT_FORCE_RTL,
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED,
@@ -260,8 +261,7 @@
Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
Settings.Global.HIDDEN_API_ACCESS_LOG_SAMPLING_RATE,
- Settings.Global.HIDDEN_API_POLICY_P_APPS,
- Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS,
+ Settings.Global.HIDDEN_API_POLICY,
Settings.Global.HIDE_ERROR_DIALOGS,
Settings.Global.HTTP_PROXY,
HYBRID_SYSUI_BATTERY_WARNING_FLAGS,
@@ -456,6 +456,7 @@
Settings.Global.GPU_DEBUG_LAYERS,
Settings.Global.GPU_DEBUG_LAYERS_GLES,
Settings.Global.ANGLE_ENABLED_APP,
+ Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP,
Settings.Global.GPU_DEBUG_LAYER_APP,
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
diff --git a/core/tests/coretests/src/android/view/textclassifier/ModelFileManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/ModelFileManagerTest.java
index 51e5aec..f2efabf 100644
--- a/core/tests/coretests/src/android/view/textclassifier/ModelFileManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/ModelFileManagerTest.java
@@ -43,7 +43,7 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ModelFileManagerTest {
-
+ private static final Locale DEFAULT_LOCALE = Locale.forLanguageTag("en-US");
@Mock
private Supplier<List<ModelFileManager.ModelFile>> mModelFileSupplier;
private ModelFileManager.ModelFileSupplierImpl mModelFileSupplierImpl;
@@ -71,6 +71,8 @@
mRootTestDir.mkdirs();
mFactoryModelDir.mkdirs();
+
+ Locale.setDefault(DEFAULT_LOCALE);
}
@After
@@ -134,7 +136,7 @@
}
@Test
- public void findBestModel_useIndependentWhenNoLanguageModelMatch() {
+ public void findBestModel_noMatchedLanguageModel() {
Locale locale = Locale.forLanguageTag("ja");
ModelFileManager.ModelFile languageIndependentModelFile =
new ModelFileManager.ModelFile(
@@ -157,6 +159,28 @@
}
@Test
+ public void findBestModel_noMatchedLanguageModel_defaultLocaleModelExists() {
+ ModelFileManager.ModelFile languageIndependentModelFile =
+ new ModelFileManager.ModelFile(
+ new File("/path/a"), 1,
+ Collections.emptyList(), true);
+
+ ModelFileManager.ModelFile languageDependentModelFile =
+ new ModelFileManager.ModelFile(
+ new File("/path/b"), 1,
+ Collections.singletonList(DEFAULT_LOCALE), false);
+
+ when(mModelFileSupplier.get())
+ .thenReturn(
+ Arrays.asList(languageIndependentModelFile, languageDependentModelFile));
+
+ ModelFileManager.ModelFile bestModelFile =
+ mModelFileManager.findBestModelFile(
+ LocaleList.forLanguageTags("zh-hk"));
+ assertThat(bestModelFile).isEqualTo(languageIndependentModelFile);
+ }
+
+ @Test
public void findBestModel_languageIsMoreImportantThanVersion() {
ModelFileManager.ModelFile matchButOlderModel =
new ModelFileManager.ModelFile(
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index 8646c68..3a33d57 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -19,6 +19,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
@@ -325,6 +326,33 @@
}
@Test
+ public void testSuggestConversationActions_textReplyOnly_maxThree() {
+ if (isTextClassifierDisabled()) return;
+ ConversationActions.Message message =
+ new ConversationActions.Message.Builder().setText("Hello").build();
+ ConversationActions.TypeConfig typeConfig =
+ new ConversationActions.TypeConfig.Builder().includeTypesFromTextClassifier(false)
+ .setIncludedTypes(
+ Collections.singletonList(ConversationActions.TYPE_TEXT_REPLY))
+ .build();
+ ConversationActions.Request request =
+ new ConversationActions.Request.Builder(Collections.singletonList(message))
+ .setMaxSuggestions(1)
+ .setTypeConfig(typeConfig)
+ .build();
+
+ ConversationActions conversationActions = mClassifier.suggestConversationActions(request);
+ assertTrue(conversationActions.getConversationActions().size() <= 1);
+ for (ConversationActions.ConversationAction conversationAction :
+ conversationActions.getConversationActions()) {
+ assertEquals(conversationAction.getType(), ConversationActions.TYPE_TEXT_REPLY);
+ assertNotNull(conversationAction.getTextReply());
+ assertTrue(conversationAction.getConfidenceScore() > 0);
+ assertTrue(conversationAction.getConfidenceScore() <= 1);
+ }
+ }
+
+ @Test
public void testSetTextClassifier() {
TextClassifier classifier = mock(TextClassifier.class);
mTcm.setTextClassifier(classifier);
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextLinksTest.java b/core/tests/coretests/src/android/view/textclassifier/TextLinksTest.java
index fff723f..f6ec0e6 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextLinksTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextLinksTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
+import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
@@ -38,6 +39,12 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextLinksTest {
+ private static final String BUNDLE_KEY = "key";
+ private static final String BUNDLE_VALUE = "value";
+ private static final Bundle BUNDLE = new Bundle();
+ static {
+ BUNDLE.putString(BUNDLE_KEY, BUNDLE_VALUE);
+ }
private Map<String, Float> getEntityScores(float address, float phone, float other) {
final Map<String, Float> result = new ArrayMap<>();
@@ -59,6 +66,7 @@
final TextLinks reference = new TextLinks.Builder(fullText)
.addLink(0, 4, getEntityScores(0.f, 0.f, 1.f))
.addLink(5, 12, getEntityScores(.8f, .1f, .5f))
+ .setExtras(BUNDLE)
.build();
// Parcel and unparcel.
@@ -83,6 +91,7 @@
assertEquals(.8f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_ADDRESS), 1e-7f);
assertEquals(.5f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_OTHER), 1e-7f);
assertEquals(.1f, resultList.get(1).getConfidenceScore(TextClassifier.TYPE_PHONE), 1e-7f);
+ assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
}
@Test
@@ -94,6 +103,7 @@
final TextLinks.Request reference = new TextLinks.Request.Builder("text")
.setDefaultLocales(new LocaleList(Locale.US, Locale.GERMANY))
.setEntityConfig(entityConfig)
+ .setExtras(BUNDLE)
.build();
// Parcel and unparcel.
@@ -108,5 +118,6 @@
result.getEntityConfig().getHints().toArray());
assertEquals(new HashSet<String>(Arrays.asList("a", "c")),
result.getEntityConfig().resolveEntityListModifications(Collections.emptyList()));
+ assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
}
}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextSelectionTest.java b/core/tests/coretests/src/android/view/textclassifier/TextSelectionTest.java
index 4855dad..7ea5108b 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextSelectionTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextSelectionTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
+import android.os.Bundle;
import android.os.LocaleList;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
@@ -31,6 +32,12 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class TextSelectionTest {
+ private static final String BUNDLE_KEY = "key";
+ private static final String BUNDLE_VALUE = "value";
+ private static final Bundle BUNDLE = new Bundle();
+ static {
+ BUNDLE.putString(BUNDLE_KEY, BUNDLE_VALUE);
+ }
@Test
public void testParcel() {
@@ -42,6 +49,7 @@
.setEntityType(TextClassifier.TYPE_PHONE, 0.7f)
.setEntityType(TextClassifier.TYPE_URL, 0.1f)
.setId(id)
+ .setExtras(BUNDLE)
.build();
// Parcel and unparcel
@@ -61,6 +69,7 @@
assertEquals(0.7f, result.getConfidenceScore(TextClassifier.TYPE_PHONE), 1e-7f);
assertEquals(0.3f, result.getConfidenceScore(TextClassifier.TYPE_ADDRESS), 1e-7f);
assertEquals(0.1f, result.getConfidenceScore(TextClassifier.TYPE_URL), 1e-7f);
+ assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
}
@Test
@@ -69,6 +78,7 @@
final TextSelection.Request reference =
new TextSelection.Request.Builder(text, 0, text.length())
.setDefaultLocales(new LocaleList(Locale.US, Locale.GERMANY))
+ .setExtras(BUNDLE)
.build();
// Parcel and unparcel.
@@ -81,5 +91,6 @@
assertEquals(0, result.getStartIndex());
assertEquals(text.length(), result.getEndIndex());
assertEquals("en-US,de-DE", result.getDefaultLocales().toLanguageTags());
+ assertEquals(BUNDLE_VALUE, result.getExtras().getString(BUNDLE_KEY));
}
}
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
index a2a40e6..cfb6bdd 100644
--- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -19,6 +19,7 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
@@ -41,14 +42,14 @@
import android.content.pm.UserInfo;
import android.net.Uri;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
-import java.util.ArrayList;
-import java.util.List;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -57,6 +58,9 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+import java.util.List;
+
@RunWith(AndroidJUnit4.class)
public class IntentForwarderActivityTest {
@@ -549,8 +553,8 @@
}
@Override
- public void startActivityAsCaller(Intent intent, @Nullable Bundle options, boolean
- ignoreTargetSecurity, int userId) {
+ public void startActivityAsCaller(Intent intent, @Nullable Bundle options,
+ IBinder permissionToken, boolean ignoreTargetSecurity, int userId) {
mStartActivityIntent = intent;
mUserIdActivityLaunchedIn = userId;
}
@@ -589,4 +593,4 @@
@Override
public void showToast(int messageId, int duration) {}
}
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
index b798042..3cfc644 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsTests.java
@@ -38,6 +38,7 @@
BatteryStatsUidTest.class,
BatteryStatsUserLifecycleTests.class,
KernelCpuProcReaderTest.class,
+ KernelCpuProcStringReaderTest.class,
KernelMemoryBandwidthStatsTest.class,
KernelSingleUidTimeReaderTest.class,
KernelUidCpuFreqTimeReaderTest.class,
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
new file mode 100644
index 0000000..dae9eb5
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2018 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 static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.os.FileUtils;
+import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+/**
+ * Test class for {@link KernelCpuProcStringReader}.
+ *
+ * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcStringReaderTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class KernelCpuProcStringReaderTest {
+ private File mRoot;
+ private File mTestDir;
+ private File mTestFile;
+ private Random mRand = new Random(12345);
+ private KernelCpuProcStringReader mReader;
+
+ private Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
+ @Before
+ public void setUp() {
+ mTestDir = getContext().getDir("test", Context.MODE_PRIVATE);
+ mRoot = getContext().getFilesDir();
+ mTestFile = new File(mTestDir, "test.file");
+ mReader = new KernelCpuProcStringReader(mTestFile.getAbsolutePath());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ FileUtils.deleteContents(mTestDir);
+ FileUtils.deleteContents(mRoot);
+ }
+
+
+ /**
+ * Tests that reading will return null if the file does not exist.
+ */
+ @Test
+ public void testReadInvalidFile() throws Exception {
+ assertEquals(null, mReader.open());
+ }
+
+ /**
+ * Tests that reading will always return null after 5 failures.
+ */
+ @Test
+ public void testReadErrorsLimit() throws Exception {
+ for (int i = 0; i < 3; i++) {
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ assertNull(iter);
+ }
+ SystemClock.sleep(50);
+ }
+ final String data = "018n9x134yrm9sry01298yMF1X980Ym908u98weruwe983^(*)0N)&tu09281my\n";
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ assertEquals(data.length(), iter.size());
+ assertEquals(data, iter.nextLine().toString() + '\n');
+ }
+ assertTrue(mTestFile.delete());
+ for (int i = 0; i < 3; i++) {
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open(true)) {
+ assertNull(iter);
+ }
+ SystemClock.sleep(50);
+ }
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open(true)) {
+ assertNull(iter);
+ }
+ }
+
+ /** Tests nextLine functionality. */
+ @Test
+ public void testReadLine() throws Exception {
+ final String data = "10103: 0 0 0 1 5 3 1 2 0 0 3 0 0 0 0 2 2 330 0 0 0 0 1 0 0 0 0 0 0 0"
+ + " 0 0 0 0 0 0 0 0 0 0 0 13\n"
+ + "50083: 0 0 0 29 0 13 0 4 5 0 0 0 0 0 1 0 0 15 0 0 0 0 0 0 1 0 0 0 0 1 0 1 7 0 "
+ + "0 1 1 1 0 2 0 221\n"
+ + "50227: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 196 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
+ + " 0 2 0 0 0 2 721\n"
+ + "10158: 0 0 0 0 19 3 9 1 0 7 4 3 3 3 1 3 10 893 2 0 3 0 0 0 0 0 0 0 0 1 0 2 0 0"
+ + " 1 2 10 0 0 0 1 58\n"
+ + "50138: 0 0 0 8 7 0 0 0 0 0 0 0 0 0 0 0 0 322 0 0 0 3 0 5 0 0 3 0 0 0 0 1 0 0 0"
+ + " 0 0 2 0 0 7 707\n";
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ assertEquals(
+ "10103: 0 0 0 1 5 3 1 2 0 0 3 0 0 0 0 2 2 330 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0"
+ + " 0 0 0 0 0 0 0 13",
+ iter.nextLine().toString());
+ assertEquals(
+ "50083: 0 0 0 29 0 13 0 4 5 0 0 0 0 0 1 0 0 15 0 0 0 0 0 0 1 0 0 0 0 1 0 1 7 "
+ + "0 0 1 1 1 0 2 0 221",
+ iter.nextLine().toString());
+ long[] actual = new long[43];
+ iter.nextLineAsArray(actual);
+ assertArrayEquals(
+ new long[]{50227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 721},
+ actual);
+ assertEquals(
+ "10158: 0 0 0 0 19 3 9 1 0 7 4 3 3 3 1 3 10 893 2 0 3 0 0 0 0 0 0 0 0 1 0 2 0"
+ + " 0 1 2 10 0 0 0 1 58",
+ iter.nextLine().toString());
+ assertEquals(
+ "50138: 0 0 0 8 7 0 0 0 0 0 0 0 0 0 0 0 0 322 0 0 0 3 0 5 0 0 3 0 0 0 0 1 0 0"
+ + " 0 0 0 2 0 0 7 707",
+ iter.nextLine().toString());
+ }
+ }
+
+ /** Stress tests read functionality. */
+ @Test
+ public void testMultipleRead() throws Exception {
+ for (int i = 0; i < 100; i++) {
+ final String data = getTestString(600, 150);
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ String[] lines = data.split("\n");
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open(true)) {
+ for (String line : lines) {
+ assertEquals(line, iter.nextLine().toString());
+ }
+ }
+ assertTrue(mTestFile.delete());
+ }
+ }
+
+ /** Tests nextLineToArray functionality. */
+ @Test
+ public void testReadLineToArray() throws Exception {
+ final long[][] data = getTestArray(800, 50);
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(arrayToString(data));
+ }
+ long[] actual = new long[50];
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ for (long[] expected : data) {
+ assertEquals(50, iter.nextLineAsArray(actual));
+ assertArrayEquals(expected, actual);
+ }
+ }
+ }
+
+ /**
+ * Tests that reading a file over the limit (1MB) will return null.
+ */
+ @Test
+ public void testReadOverLimit() throws Exception {
+ final String data = getTestString(1, 1024 * 1024 + 1);
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ assertNull(iter);
+ }
+ }
+
+ /**
+ * Tests concurrent reading with 5 threads.
+ */
+ @Test
+ public void testConcurrent() throws Exception {
+ final String data = getTestString(200, 150);
+ final String data1 = getTestString(180, 120);
+ final String[] lines = data.split("\n");
+ final String[] lines1 = data1.split("\n");
+ final List<Throwable> errs = Collections.synchronizedList(new ArrayList<>());
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data);
+ }
+ // An additional thread for modifying the file content.
+ ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(11);
+ final CountDownLatch ready = new CountDownLatch(10);
+ final CountDownLatch start = new CountDownLatch(1);
+ final CountDownLatch modify = new CountDownLatch(1);
+ final CountDownLatch done = new CountDownLatch(10);
+
+ // Schedules 5 threads to be executed together now, and 5 to be executed after file is
+ // modified.
+ for (int i = 0; i < 5; i++) {
+ threadPool.submit(() -> {
+ ready.countDown();
+ try {
+ start.await();
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ for (String line : lines) {
+ assertEquals(line, iter.nextLine().toString());
+ }
+ }
+ } catch (Throwable e) {
+ errs.add(e);
+ } finally {
+ done.countDown();
+ }
+ });
+ threadPool.submit(() -> {
+ ready.countDown();
+ try {
+ start.await();
+ // Wait for file modification.
+ modify.await();
+ try (KernelCpuProcStringReader.ProcFileIterator iter = mReader.open()) {
+ for (String line : lines1) {
+ assertEquals(line, iter.nextLine().toString());
+ }
+ }
+ } catch (Throwable e) {
+ errs.add(e);
+ } finally {
+ done.countDown();
+ }
+ });
+ }
+
+ assertTrue("Prep timed out", ready.await(100, TimeUnit.MILLISECONDS));
+ start.countDown();
+
+ threadPool.schedule(() -> {
+ assertTrue(mTestFile.delete());
+ try (BufferedWriter w = Files.newBufferedWriter(mTestFile.toPath())) {
+ w.write(data1);
+ modify.countDown();
+ } catch (Throwable e) {
+ errs.add(e);
+ }
+ }, 600, TimeUnit.MILLISECONDS);
+
+ assertTrue("Execution timed out", done.await(3, TimeUnit.SECONDS));
+ threadPool.shutdownNow();
+
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ errs.forEach(e -> e.printStackTrace(pw));
+
+ assertTrue("All Exceptions:\n" + sw.toString(), errs.isEmpty());
+ }
+
+ private String getTestString(int lines, int charsPerLine) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < lines; i++) {
+ for (int j = 0; j < charsPerLine; j++) {
+ sb.append((char) (mRand.nextInt(93) + 32));
+ }
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ private long[][] getTestArray(int lines, int numPerLine) {
+ return IntStream.range(0, lines).mapToObj(
+ (i) -> mRand.longs(numPerLine, 0, Long.MAX_VALUE).toArray()).toArray(long[][]::new);
+ }
+
+ private String arrayToString(long[][] array) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < array.length; i++) {
+ sb.append(array[i][0]).append(':');
+ for (int j = 1; j < array[0].length; j++) {
+ sb.append(' ').append(array[i][j]);
+ }
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 2604365..a1fbe0a 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -391,6 +391,7 @@
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.REAL_GET_TASKS"/>
<permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
+ <permission name="android.permission.START_ACTIVITY_AS_CALLER"/>
<permission name="android.permission.START_TASKS_FROM_RECENTS"/>
<permission name="android.permission.STATUS_BAR"/>
<permission name="android.permission.STOP_APP_SWITCHES"/>
diff --git a/core/java/android/view/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
similarity index 70%
rename from core/java/android/view/FrameInfo.java
rename to graphics/java/android/graphics/FrameInfo.java
index 6c5e048..42a5cc4 100644
--- a/core/java/android/view/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.view;
+package android.graphics;
import android.annotation.LongDef;
@@ -33,14 +33,14 @@
* long layout & measure took it's displayListRecordStart - performTraversalsStart.
*
* These constants must be kept in sync with FrameInfo.h in libhwui and are
- * used for indexing into AttachInfo's mFrameInfo long[], which is intended
+ * used for indexing into AttachInfo's frameInfo long[], which is intended
* to be quick to pass down to native via JNI, hence a pre-packed format
*
* @hide
*/
-final class FrameInfo {
+public final class FrameInfo {
- long[] mFrameInfo = new long[9];
+ public long[] frameInfo = new long[9];
// Various flags set to provide extra metadata about the current frame
private static final int FLAGS = 0;
@@ -48,8 +48,11 @@
// Is this the first-draw following a window layout?
public static final long FLAG_WINDOW_LAYOUT_CHANGED = 1;
+ // A renderer associated with just a Surface, not with a ViewRootImpl instance.
+ public static final long FLAG_SURFACE_CANVAS = 1 << 2;
+
@LongDef(flag = true, value = {
- FLAG_WINDOW_LAYOUT_CHANGED })
+ FLAG_WINDOW_LAYOUT_CHANGED, FLAG_SURFACE_CANVAS })
@Retention(RetentionPolicy.SOURCE)
public @interface FrameInfoFlags {}
@@ -78,41 +81,48 @@
// When View:draw() started
private static final int DRAW_START = 8;
+ /** checkstyle */
public void setVsync(long intendedVsync, long usedVsync) {
- mFrameInfo[INTENDED_VSYNC] = intendedVsync;
- mFrameInfo[VSYNC] = usedVsync;
- mFrameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
- mFrameInfo[NEWEST_INPUT_EVENT] = 0;
- mFrameInfo[FLAGS] = 0;
+ frameInfo[INTENDED_VSYNC] = intendedVsync;
+ frameInfo[VSYNC] = usedVsync;
+ frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
+ frameInfo[NEWEST_INPUT_EVENT] = 0;
+ frameInfo[FLAGS] = 0;
}
+ /** checkstyle */
public void updateInputEventTime(long inputEventTime, long inputEventOldestTime) {
- if (inputEventOldestTime < mFrameInfo[OLDEST_INPUT_EVENT]) {
- mFrameInfo[OLDEST_INPUT_EVENT] = inputEventOldestTime;
+ if (inputEventOldestTime < frameInfo[OLDEST_INPUT_EVENT]) {
+ frameInfo[OLDEST_INPUT_EVENT] = inputEventOldestTime;
}
- if (inputEventTime > mFrameInfo[NEWEST_INPUT_EVENT]) {
- mFrameInfo[NEWEST_INPUT_EVENT] = inputEventTime;
+ if (inputEventTime > frameInfo[NEWEST_INPUT_EVENT]) {
+ frameInfo[NEWEST_INPUT_EVENT] = inputEventTime;
}
}
+ /** checkstyle */
public void markInputHandlingStart() {
- mFrameInfo[HANDLE_INPUT_START] = System.nanoTime();
+ frameInfo[HANDLE_INPUT_START] = System.nanoTime();
}
+ /** checkstyle */
public void markAnimationsStart() {
- mFrameInfo[ANIMATION_START] = System.nanoTime();
+ frameInfo[ANIMATION_START] = System.nanoTime();
}
+ /** checkstyle */
public void markPerformTraversalsStart() {
- mFrameInfo[PERFORM_TRAVERSALS_START] = System.nanoTime();
+ frameInfo[PERFORM_TRAVERSALS_START] = System.nanoTime();
}
+ /** checkstyle */
public void markDrawStart() {
- mFrameInfo[DRAW_START] = System.nanoTime();
+ frameInfo[DRAW_START] = System.nanoTime();
}
+ /** checkstyle */
public void addFlags(@FrameInfoFlags long flags) {
- mFrameInfo[FLAGS] |= flags;
+ frameInfo[FLAGS] |= flags;
}
}
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
new file mode 100644
index 0000000..e402055
--- /dev/null
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (C) 2018 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.graphics;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.FrameMetricsObserver;
+import android.view.IGraphicsStats;
+import android.view.IGraphicsStatsCallback;
+import android.view.NativeVectorDrawableAnimator;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.TextureLayer;
+
+import com.android.internal.util.VirtualRefBasePtr;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import sun.misc.Cleaner;
+
+/**
+ * <p>Creates an instance of a hardware-accelerated renderer. This is used to render a scene built
+ * from {@link RenderNode}'s to an output {@link android.view.Surface}. There can be as many
+ * HardwareRenderer instances as desired.</p>
+ *
+ * <h3>Threading</h3>
+ * <p>HardwareRenderer is not thread safe. An instance of a HardwareRenderer must only be
+ * created & used from a single thread. It does not matter what thread is used, however
+ * it must have a {@link android.os.Looper}. Multiple instances do not have to share the same
+ * thread, although they can.</p>
+ *
+ * <h3>Resources & lifecycle</h3>
+ * <p>All HardwareRenderer instances share a common render thread. The render thread contains
+ * the GPU context & resources necessary to do GPU-accelerated rendering. As such, the first
+ * HardwareRenderer created comes with the cost of also creating the associated GPU contexts,
+ * however each incremental HardwareRenderer thereafter is fairly cheap. The expected usage
+ * is to have a HardwareRenderer instance for every active {@link Surface}. For example
+ * when an Activity shows a Dialog the system internally will use 2 hardware renderers, both
+ * of which may be drawing at the same time.</p>
+ * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
+ * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
+ * consumers such as {@link android.view.SurfaceView},
+ * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
+ * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
+ * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
+ * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
+ * Failure to do so will cause the render thread to stall on that surface, blocking all
+ * HardwareRenderer instances.</p>
+ *
+ * @hide
+ */
+public class HardwareRenderer {
+ private static final String LOG_TAG = "HardwareRenderer";
+
+ // Keep in sync with DrawFrameTask.h SYNC_* flags
+ /**
+ * Nothing interesting to report. Sync & draw kicked off
+ */
+ public static final int SYNC_OK = 0;
+
+ /**
+ * The renderer is requesting a redraw. This can occur if there's an animation that's running
+ * in the RenderNode tree and the hardware renderer is unable to self-animate.
+ *
+ * If this is returned from syncAndDrawFrame the expectation is that syncAndDrawFrame
+ * will be called again on the next vsync signal.
+ */
+ public static final int SYNC_REDRAW_REQUESTED = 1 << 0;
+
+ /**
+ * The hardware renderer no longer has a valid {@link android.view.Surface} to render to.
+ * This can happen if {@link Surface#destroy()} was called. The user should no longer
+ * attempt to call syncAndDrawFrame until a new surface has been provided by calling
+ * setSurface.
+ *
+ * Spoiler: the reward is GPU-accelerated drawing, better find that Surface!
+ */
+ public static final int SYNC_LOST_SURFACE_REWARD_IF_FOUND = 1 << 1;
+
+ /**
+ * The hardware renderer has been set to a "stopped" state. If this is returned then the
+ * rendering content has been synced, however a frame was not produced.
+ */
+ public static final int SYNC_CONTEXT_IS_STOPPED = 1 << 2;
+
+ /**
+ * The content was synced but the renderer has declined to produce a frame in this vsync
+ * interval. This can happen if a frame was already drawn in this vsync or if the renderer
+ * is outrunning the frame consumer. The renderer will internally re-schedule itself
+ * to render a frame in the next vsync signal, so the caller does not need to do anything
+ * in response to this signal.
+ */
+ public static final int SYNC_FRAME_DROPPED = 1 << 3;
+
+ @IntDef(value = {
+ SYNC_OK, SYNC_REDRAW_REQUESTED, SYNC_LOST_SURFACE_REWARD_IF_FOUND,
+ SYNC_CONTEXT_IS_STOPPED, SYNC_FRAME_DROPPED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SyncAndDrawResult {
+ }
+
+ /** @hide */
+ public static final int FLAG_DUMP_FRAMESTATS = 1 << 0;
+ /** @hide */
+ public static final int FLAG_DUMP_RESET = 1 << 1;
+ /** @hide */
+ public static final int FLAG_DUMP_ALL = FLAG_DUMP_FRAMESTATS;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = {"FLAG_DUMP_"}, value = {
+ FLAG_DUMP_FRAMESTATS,
+ FLAG_DUMP_RESET
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DumpFlags {
+ }
+
+ /**
+ * Name of the file that holds the shaders cache.
+ */
+ private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
+ private static final String CACHE_PATH_SKIASHADERS = "com.android.skia.shaders_cache";
+
+ private final long mNativeProxy;
+ /** @hide */
+ protected RenderNode mRootNode;
+ private boolean mOpaque = true;
+ private boolean mForceDark = false;
+ private FrameInfo mScratchInfo;
+
+ /**
+ * Creates a new instance of a HardwareRenderer. The HardwareRenderer will default
+ * to opaque with no light source configured.
+ */
+ public HardwareRenderer() {
+ mRootNode = RenderNode.adopt(nCreateRootRenderNode());
+ mRootNode.setClipToBounds(false);
+ mNativeProxy = nCreateProxy(!mOpaque, mRootNode.mNativeRenderNode);
+ if (mNativeProxy == 0) {
+ throw new OutOfMemoryError("Unable to create hardware renderer");
+ }
+ Cleaner.create(this, new DestroyContextRunnable(mNativeProxy));
+ ProcessInitializer.sInstance.init(mNativeProxy);
+ }
+
+ /**
+ * Destroys the rendering context of this HardwareRenderer. This destroys the resources
+ * associated with this renderer and releases the currently set {@link Surface}.
+ *
+ * The renderer may be restored from this state by setting a new {@link Surface}, setting
+ * new rendering content with {@link #setContentRoot(RenderNode)}, and resuming
+ * rendering with {@link #syncAndDrawFrame(long)}.
+ *
+ * It is suggested to call this in response to callbacks such as
+ * {@link android.view.SurfaceHolder.Callback#surfaceDestroyed(SurfaceHolder)}.
+ *
+ * Note that if there are any outstanding frame commit callbacks they may end up never being
+ * invoked if the frame was deferred to a later vsync.
+ */
+ public void destroy() {
+ nDestroy(mNativeProxy, mRootNode.mNativeRenderNode);
+ }
+
+ /**
+ * Sets a name for this renderer. This is used to identify this renderer instance
+ * when reporting debug information such as the per-window frame time metrics
+ * reported by 'adb shell dumpsys gfxinfo [package] framestats'
+ *
+ * @param name The debug name to use for this HardwareRenderer instance
+ */
+ public void setName(String name) {
+ nSetName(mNativeProxy, name);
+ }
+
+ /**
+ * Sets the center of the light source. The light source point controls the directionality
+ * and shape of shadows rendered by RenderNode Z & elevation.
+ *
+ * The platform's recommendation is to set lightX to 'displayWidth / 2f - windowLeft', set
+ * lightY to 0 - windowTop, lightZ set to 600dp, and lightRadius to 800dp.
+ *
+ * The light source should be setup both as part of initial configuration, and whenever
+ * the window moves to ensure the light source stays anchored in display space instead
+ * of in window space.
+ *
+ * This must be set at least once along with {@link #setLightSourceAlpha(float, float)}
+ * before shadows will work.
+ *
+ * @param lightX The X position of the light source
+ * @param lightY The Y position of the light source
+ * @param lightZ The Z position of the light source. Must be >= 0.
+ * @param lightRadius The radius of the light source. Smaller radius will have sharper edges,
+ * larger radius will have softer shadows.
+ */
+ public void setLightSourceGeometry(float lightX, float lightY, float lightZ,
+ float lightRadius) {
+ validateFinite(lightX, "lightX");
+ validateFinite(lightY, "lightY");
+ validatePositive(lightZ, "lightZ");
+ validatePositive(lightRadius, "lightRadius");
+ nSetLightGeometry(mNativeProxy, lightX, lightY, lightZ, lightRadius);
+ }
+
+ /**
+ * Configures the ambient & spot shadow alphas. This is the alpha used when the shadow
+ * has max alpha, and ramps down from the values provided to zero.
+ *
+ * These values are typically provided by the current theme, see
+ * {@link android.R.attr#spotShadowAlpha} and {@link android.R.attr#ambientShadowAlpha}.
+ *
+ * This must be set at least once along with
+ * {@link #setLightSourceGeometry(float, float, float, float)} before shadows will work.
+ *
+ * @param ambientShadowAlpha The alpha for the ambient shadow. If unsure, a reasonable default
+ * is 0.039f.
+ * @param spotShadowAlpha The alpha for the spot shadow. If unsure, a reasonable default is
+ * 0.19f.
+ */
+ public void setLightSourceAlpha(@FloatRange(from = 0.0f, to = 1.0f) float ambientShadowAlpha,
+ @FloatRange(from = 0.0f, to = 1.0f) float spotShadowAlpha) {
+ validateAlpha(ambientShadowAlpha, "ambientShadowAlpha");
+ validateAlpha(spotShadowAlpha, "spotShadowAlpha");
+ nSetLightAlpha(mNativeProxy, ambientShadowAlpha, spotShadowAlpha);
+ }
+
+ /**
+ * Sets the content root to render. It is not necessary to call this whenever the content
+ * recording changes. Any mutations to the RenderNode content, or any of the RenderNode's
+ * contained within the content node, will be applied whenever {@link #syncAndDrawFrame(long)}
+ * is called.
+ *
+ * @param content The content to set as the root RenderNode. If null the content root is removed
+ * and the renderer will draw nothing.
+ */
+ public void setContentRoot(@Nullable RenderNode content) {
+ RecordingCanvas canvas = mRootNode.startRecording();
+ if (content != null) {
+ canvas.drawRenderNode(content);
+ }
+ mRootNode.endRecording();
+ }
+
+ /**
+ * <p>The surface to render into. The surface is assumed to be associated with the display and
+ * as such is still driven by vsync signals such as those from
+ * {@link android.view.Choreographer} and that it has a native refresh rate matching that of
+ * the display's (typically 60hz).</p>
+ *
+ * <p>NOTE: Due to the shared, cooperative nature of the render thread it is critical that
+ * any {@link Surface} used must have a prompt, reliable consuming side. System-provided
+ * consumers such as {@link android.view.SurfaceView},
+ * {@link android.view.Window#takeSurface(SurfaceHolder.Callback2)},
+ * or {@link android.view.TextureView} all fit this requirement. However if custom consumers
+ * are used such as when using {@link SurfaceTexture} or {@link android.media.ImageReader}
+ * it is the app's responsibility to ensure that they consume updates promptly and rapidly.
+ * Failure to do so will cause the render thread to stall on that surface, blocking all
+ * HardwareRenderer instances.</p>
+ *
+ * @param surface The surface to render into. If null then rendering will be stopped. If
+ * non-null then {@link Surface#isValid()} must be true.
+ */
+ public void setSurface(@Nullable Surface surface) {
+ if (surface != null && !surface.isValid()) {
+ throw new IllegalArgumentException("Surface is invalid. surface.isValid() == false.");
+ }
+ nSetSurface(mNativeProxy, surface);
+ }
+
+ /**
+ * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
+ *
+ * @hide
+ */
+ @SyncAndDrawResult
+ public int syncAndDrawFrame(@NonNull FrameInfo frameInfo) {
+ return nSyncAndDrawFrame(mNativeProxy, frameInfo.frameInfo, frameInfo.frameInfo.length);
+ }
+
+ /**
+ * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
+ *
+ * @param vsyncTime The vsync timestamp for this frame. Typically this comes from
+ * {@link android.view.Choreographer.FrameCallback}. Must be set and be valid
+ * as the renderer uses this time internally to drive animations.
+ * @return The result of the sync operation. See {@link SyncAndDrawResult}.
+ */
+ @SyncAndDrawResult
+ public int syncAndDrawFrame(long vsyncTime) {
+ if (mScratchInfo == null) {
+ mScratchInfo = new FrameInfo();
+ }
+ mScratchInfo.setVsync(vsyncTime, vsyncTime);
+ mScratchInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
+ return syncAndDrawFrame(mScratchInfo);
+ }
+
+ /**
+ * Syncs the RenderNode tree to the render thread and requests a frame to be drawn.
+ * frameCommitCallback callback will be invoked when the current rendering content has been
+ * rendered into a frame and submitted to the swap chain.
+ *
+ * @param vsyncTime The vsync timestamp for this frame. Typically this comes from
+ * {@link android.view.Choreographer.FrameCallback}. Must be set and
+ * be valid as the renderer uses this time internally to drive
+ * animations.
+ * @param frameCommitCallback The callback to invoke when the frame content has been drawn.
+ * Will be invoked on the current {@link android.os.Looper} thread.
+ * @return The result of the sync operation. See {@link SyncAndDrawResult}.
+ */
+ @SyncAndDrawResult
+ public int syncAndDrawFrame(long vsyncTime,
+ @Nullable Runnable frameCommitCallback) {
+ if (frameCommitCallback != null) {
+ setFrameCompleteCallback(frameNr -> frameCommitCallback.run());
+ }
+ return syncAndDrawFrame(vsyncTime);
+ }
+
+ /**
+ * Suspends any current rendering into the surface but do not do any destruction. This
+ * is useful to temporarily suspend using the active Surface in order to do any Surface
+ * mutations necessary.
+ *
+ * Any subsequent draws will override the pause, resuming normal operation.
+ *
+ * @return true if there was an outstanding render request, false otherwise. If this is true
+ * the caller should ensure that {@link #syncAndDrawFrame(long)} is called at the soonest
+ * possible time to resume normal operation.
+ *
+ * TODO Should this be exposed? ViewRootImpl needs it because it destroys the old
+ * Surface before getting a new one. However things like SurfaceView will ensure that
+ * the old surface remains un-destroyed until after a new frame has been produced with
+ * the new surface.
+ * @hide
+ */
+ public boolean pause() {
+ return nPause(mNativeProxy);
+ }
+
+ /**
+ * Hard stops rendering into the surface. If the renderer is stopped it will
+ * block any attempt to render. Calls to {@link #syncAndDrawFrame(long)} will still
+ * sync over the latest rendering content, however they will not render and instead
+ * {@link #SYNC_CONTEXT_IS_STOPPED} will be returned.
+ *
+ * If false is passed then rendering will resume as normal. Any pending rendering requests
+ * will produce a new frame at the next vsync signal.
+ *
+ * This is useful in combination with lifecycle events such as {@link Activity#onStop()}
+ * and {@link Activity#onStart()}.
+ *
+ * @param stopped true to stop all rendering, false to resume
+ */
+ public void setStopped(boolean stopped) {
+ nSetStopped(mNativeProxy, stopped);
+ }
+
+ /**
+ * Destroys all hardware rendering resources associated with the current rendering content.
+ * This includes releasing a reference to the current content root RenderNode. It will
+ * therefore be necessary to call {@link #setContentRoot(RenderNode)} in order to resume
+ * rendering after calling this.
+ *
+ * It is recommended, but not necessary, to use this in combination with lifecycle events
+ * such as {@link Activity#onStop()} and {@link Activity#onStart()} or in response to
+ * {@link android.content.ComponentCallbacks2#onTrimMemory(int)} signals such as
+ * {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN}
+ *
+ * See also {@link #setStopped(boolean)}
+ */
+ public void destroyHardwareResources() {
+ nDestroyHardwareResources(mNativeProxy);
+ }
+
+ /**
+ * Whether or not the force-dark feature should be used for this renderer.
+ */
+ public boolean setForceDark(boolean enable) {
+ if (mForceDark != enable) {
+ mForceDark = enable;
+ nSetForceDark(mNativeProxy, enable);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Allocate buffers ahead of time to avoid allocation delays during rendering.
+ *
+ * Typically a Surface will allocate buffers lazily. This is usually fine and reduces the
+ * memory usage of Surfaces that render rarely or never hit triple buffering. However
+ * for UI it can result in a slight bit of jank on first launch. This hint will
+ * tell the HardwareRenderer that now is a good time to allocate the 3 buffers
+ * necessary for typical rendering.
+ *
+ * Must be called after a {@link Surface} has been set.
+ */
+ public void allocateBuffers() {
+ nAllocateBuffers(mNativeProxy);
+ }
+
+ /**
+ * Notifies the hardware renderer that a call to {@link #syncAndDrawFrame(long)} will
+ * be coming soon. This is used to help schedule when RenderThread-driven animations will
+ * happen as the renderer wants to avoid producing more than one frame per vsync signal.
+ */
+ public void notifyFramePending() {
+ nNotifyFramePending(mNativeProxy);
+ }
+
+ /**
+ * Change the HardwareRenderer's opacity. Will take effect on the next frame produced.
+ *
+ * If the renderer is set to opaque it is the app's responsibility to ensure that the
+ * content renders to every pixel of the Surface, otherwise corruption may result. Note that
+ * this includes ensuring that the first draw of any given pixel does not attempt to blend
+ * against the destination. If this is false then the hardware renderer will clear to
+ * transparent at the start of every frame.
+ *
+ * @param opaque true if the content rendered is opaque, false if the renderer should clear
+ * to transparent before rendering
+ */
+ public void setOpaque(boolean opaque) {
+ if (mOpaque != opaque) {
+ mOpaque = opaque;
+ nSetOpaque(mNativeProxy, mOpaque);
+ }
+ }
+
+ /**
+ * Whether or not the renderer is set to be opaque. See {@link #setOpaque(boolean)}
+ *
+ * @return true if the renderer is opaque, false otherwise
+ */
+ public boolean isOpaque() {
+ return mOpaque;
+ }
+
+ /** @hide */
+ public void setFrameCompleteCallback(FrameCompleteCallback callback) {
+ nSetFrameCompleteCallback(mNativeProxy, callback);
+ }
+
+ /**
+ * TODO: Public API this?
+ *
+ * @hide
+ */
+ public void addFrameMetricsObserver(FrameMetricsObserver observer) {
+ long nativeObserver = nAddFrameMetricsObserver(mNativeProxy, observer);
+ observer.mNative = new VirtualRefBasePtr(nativeObserver);
+ }
+
+ /**
+ * TODO: Public API this?
+ *
+ * @hide
+ */
+ public void removeFrameMetricsObserver(FrameMetricsObserver observer) {
+ nRemoveFrameMetricsObserver(mNativeProxy, observer.mNative.get());
+ observer.mNative = null;
+ }
+
+ /**
+ * Enable/disable wide gamut rendering on this renderer. Whether or not the actual rendering
+ * will be wide gamut depends on the hardware support for such rendering.
+ *
+ * @param wideGamut true if this renderer should render in wide gamut, false if it should
+ * render in sRGB
+ * TODO: Figure out color...
+ * @hide
+ */
+ public void setWideGamut(boolean wideGamut) {
+ nSetWideGamut(mNativeProxy, wideGamut);
+ }
+
+ /**
+ * Blocks until all previously queued work has completed.
+ *
+ * TODO: Only used for draw finished listeners, but the FrameCompleteCallback does that
+ * better
+ *
+ * @hide
+ */
+ public void fence() {
+ nFence(mNativeProxy);
+ }
+
+ /** @hide */
+ public void registerAnimatingRenderNode(RenderNode animator) {
+ nRegisterAnimatingRenderNode(mRootNode.mNativeRenderNode, animator.mNativeRenderNode);
+ }
+
+ /** @hide */
+ public void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator) {
+ nRegisterVectorDrawableAnimator(mRootNode.mNativeRenderNode,
+ animator.getAnimatorNativePtr());
+ }
+
+ /**
+ * Prevents any further drawing until {@link #syncAndDrawFrame(long)} is called.
+ * This is a signal that the contents of the RenderNode tree are no longer safe to play back.
+ * In practice this usually means that there are Functor pointers in the
+ * display list that are no longer valid.
+ *
+ * TODO: Can we get webview off of this?
+ *
+ * @hide
+ */
+ public void stopDrawing() {
+ nStopDrawing(mNativeProxy);
+ }
+
+ /**
+ * Creates a new hardware layer. A hardware layer built by calling this
+ * method will be treated as a texture layer, instead of as a render target.
+ *
+ * @return A hardware layer
+ * @hide
+ */
+ public TextureLayer createTextureLayer() {
+ long layer = nCreateTextureLayer(mNativeProxy);
+ return TextureLayer.adoptTextureLayer(this, layer);
+ }
+
+ /**
+ * Detaches the layer's surface texture from the GL context and releases
+ * the texture id
+ *
+ * @hide
+ */
+ public void detachSurfaceTexture(long hardwareLayer) {
+ nDetachSurfaceTexture(mNativeProxy, hardwareLayer);
+ }
+
+
+ /** @hide */
+ public void buildLayer(RenderNode node) {
+ if (node.hasDisplayList()) {
+ nBuildLayer(mNativeProxy, node.mNativeRenderNode);
+ }
+ }
+
+ /** @hide */
+ public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
+ return nCopyLayerInto(mNativeProxy,
+ layer.getDeferredLayerUpdater(), bitmap);
+ }
+
+ /**
+ * Indicates that the specified hardware layer needs to be updated
+ * as soon as possible.
+ *
+ * @param layer The hardware layer that needs an update
+ * @hide
+ */
+ public void pushLayerUpdate(TextureLayer layer) {
+ nPushLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
+ }
+
+ /**
+ * Tells the HardwareRenderer that the layer is destroyed. The renderer
+ * should remove the layer from any update queues.
+ *
+ * @hide
+ */
+ public void onLayerDestroyed(TextureLayer layer) {
+ nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
+ }
+
+ /** @hide */
+ public void setFrameCallback(FrameDrawingCallback callback) {
+ nSetFrameCallback(mNativeProxy, callback);
+ }
+
+ /**
+ * Adds a rendernode to the renderer which can be drawn and changed asynchronously to the
+ * rendernode of the UI thread.
+ *
+ * @param node The node to add.
+ * @param placeFront If true, the render node will be placed in front of the content node,
+ * otherwise behind the content node.
+ * @hide
+ */
+ public void addRenderNode(RenderNode node, boolean placeFront) {
+ nAddRenderNode(mNativeProxy, node.mNativeRenderNode, placeFront);
+ }
+
+ /**
+ * Only especially added render nodes can be removed.
+ *
+ * @param node The node which was added via addRenderNode which should get removed again.
+ * @hide
+ */
+ public void removeRenderNode(RenderNode node) {
+ nRemoveRenderNode(mNativeProxy, node.mNativeRenderNode);
+ }
+
+ /**
+ * Draws a particular render node. If the node is not the content node, only the additional
+ * nodes will get drawn and the content remains untouched.
+ *
+ * @param node The node to be drawn.
+ * @hide
+ */
+ public void drawRenderNode(RenderNode node) {
+ nDrawRenderNode(mNativeProxy, node.mNativeRenderNode);
+ }
+
+ /**
+ * Loads system properties used by the renderer. This method is invoked
+ * whenever system properties are modified. Implementations can use this
+ * to trigger live updates of the renderer based on properties.
+ *
+ * @return True if a property has changed.
+ * @hide
+ */
+ public boolean loadSystemProperties() {
+ return nLoadSystemProperties(mNativeProxy);
+ }
+
+ /**
+ * @hide
+ */
+ public void dumpProfileInfo(FileDescriptor fd, @DumpFlags int dumpFlags) {
+ nDumpProfileInfo(mNativeProxy, fd, dumpFlags);
+ }
+
+ /**
+ * To avoid unnecessary overdrawing of the main content all additionally passed render nodes
+ * will be prevented to overdraw this area. It will be synchronized with the draw call.
+ * This should be updated in the content view's draw call.
+ *
+ * @param left The left side of the protected bounds.
+ * @param top The top side of the protected bounds.
+ * @param right The right side of the protected bounds.
+ * @param bottom The bottom side of the protected bounds.
+ * @hide
+ */
+ public void setContentDrawBounds(int left, int top, int right, int bottom) {
+ nSetContentDrawBounds(mNativeProxy, left, top, right, bottom);
+ }
+
+ /**
+ * Interface used to receive callbacks when a frame is being drawn.
+ *
+ * @hide
+ */
+ public interface FrameDrawingCallback {
+ /**
+ * Invoked during a frame drawing.
+ *
+ * @param frame The id of the frame being drawn.
+ */
+ void onFrameDraw(long frame);
+ }
+
+ /**
+ * Interface used to be notified when a frame has finished rendering
+ *
+ * @hide
+ */
+ public interface FrameCompleteCallback {
+ /**
+ * Invoked after a frame draw
+ *
+ * @param frameNr The id of the frame that was drawn.
+ */
+ void onFrameComplete(long frameNr);
+ }
+
+ private static void validateAlpha(float alpha, String argumentName) {
+ if (!(alpha >= 0.0f && alpha <= 1.0f)) {
+ throw new IllegalArgumentException(argumentName + " must be a valid alpha, "
+ + alpha + " is not in the range of 0.0f to 1.0f");
+ }
+ }
+
+ private static void validatePositive(float f, String argumentName) {
+ if (!(Float.isFinite(f) && f >= 0.0f)) {
+ throw new IllegalArgumentException(argumentName
+ + " must be a finite positive, given=" + f);
+ }
+ }
+
+ private static void validateFinite(float f, String argumentName) {
+ if (!Float.isFinite(f)) {
+ throw new IllegalArgumentException(argumentName + " must be finite, given=" + f);
+ }
+ }
+
+ /** @hide */
+ public static void invokeFunctor(long functor, boolean waitForCompletion) {
+ nInvokeFunctor(functor, waitForCompletion);
+ }
+
+ /**
+ * b/68769804: For low FPS experiments.
+ *
+ * @hide
+ */
+ public static void setFPSDivisor(int divisor) {
+ nHackySetRTAnimationsEnabled(divisor <= 1);
+ }
+
+ /**
+ * Changes the OpenGL context priority if IMG_context_priority extension is available. Must be
+ * called before any OpenGL context is created.
+ *
+ * @param priority The priority to use. Must be one of EGL_CONTEXT_PRIORITY_* values.
+ * @hide
+ */
+ public static void setContextPriority(int priority) {
+ nSetContextPriority(priority);
+ }
+
+ /**
+ * Sets whether or not high contrast text rendering is enabled. The setting is global
+ * but only affects content rendered after the change is made.
+ *
+ * @hide
+ */
+ public static void setHighContrastText(boolean highContrastText) {
+ nSetHighContrastText(highContrastText);
+ }
+
+ /**
+ * If set RenderThread will avoid doing any IPC using instead a fake vsync & DisplayInfo source
+ *
+ * @hide
+ */
+ public static void setIsolatedProcess(boolean isIsolated) {
+ nSetIsolatedProcess(isIsolated);
+ }
+
+ /**
+ * If set extra graphics debugging abilities will be enabled such as dumping skp
+ *
+ * @hide
+ */
+ public static void setDebuggingEnabled(boolean enable) {
+ nSetDebuggingEnabled(enable);
+ }
+
+ /** @hide */
+ public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
+ if (srcRect == null) {
+ // Empty rect means entire surface
+ return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
+ } else {
+ return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
+ srcRect.right, srcRect.bottom, bitmap);
+ }
+ }
+
+ /**
+ * Creates a {@link android.graphics.Bitmap.Config#HARDWARE} bitmap from the given
+ * RenderNode. Note that the RenderNode should be created as a root node (so x/y of 0,0), and
+ * not the RenderNode from a View.
+ *
+ * @hide
+ **/
+ public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
+ return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
+ }
+
+ /**
+ * Invoke this method when the system is running out of memory. This
+ * method will attempt to recover as much memory as possible, based on
+ * the specified hint.
+ *
+ * @param level Hint about the amount of memory that should be trimmed,
+ * see {@link android.content.ComponentCallbacks}
+ * @hide
+ */
+ public static void trimMemory(int level) {
+ nTrimMemory(level);
+ }
+
+ /** @hide */
+ public static void overrideProperty(@NonNull String name, @NonNull String value) {
+ if (name == null || value == null) {
+ throw new IllegalArgumentException("name and value must be non-null");
+ }
+ nOverrideProperty(name, value);
+ }
+
+ /**
+ * Sets the directory to use as a persistent storage for threaded rendering
+ * resources.
+ *
+ * @param cacheDir A directory the current process can write to
+ * @hide
+ */
+ public static void setupDiskCache(File cacheDir) {
+ setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath(),
+ new File(cacheDir, CACHE_PATH_SKIASHADERS).getAbsolutePath());
+ }
+
+ /** @hide */
+ public static void setPackageName(String packageName) {
+ ProcessInitializer.sInstance.setPackageName(packageName);
+ }
+
+ private static final class DestroyContextRunnable implements Runnable {
+ private final long mNativeInstance;
+
+ DestroyContextRunnable(long nativeInstance) {
+ mNativeInstance = nativeInstance;
+ }
+
+ @Override
+ public void run() {
+ nDeleteProxy(mNativeInstance);
+ }
+ }
+
+ private static class ProcessInitializer {
+ static ProcessInitializer sInstance = new ProcessInitializer();
+
+ private boolean mInitialized = false;
+
+ private String mPackageName;
+ private IGraphicsStats mGraphicsStatsService;
+ private IGraphicsStatsCallback mGraphicsStatsCallback = new IGraphicsStatsCallback.Stub() {
+ @Override
+ public void onRotateGraphicsStatsBuffer() throws RemoteException {
+ rotateBuffer();
+ }
+ };
+
+ private ProcessInitializer() {
+ }
+
+ synchronized void setPackageName(String name) {
+ if (mInitialized) return;
+ mPackageName = name;
+ }
+
+ synchronized void init(long renderProxy) {
+ if (mInitialized) return;
+ mInitialized = true;
+
+ initSched(renderProxy);
+ initGraphicsStats();
+ }
+
+ private void initSched(long renderProxy) {
+ try {
+ int tid = nGetRenderThreadTid(renderProxy);
+ ActivityManager.getService().setRenderThread(tid);
+ } catch (Throwable t) {
+ Log.w(LOG_TAG, "Failed to set scheduler for RenderThread", t);
+ }
+ }
+
+ private void initGraphicsStats() {
+ if (mPackageName == null) return;
+
+ try {
+ IBinder binder = ServiceManager.getService("graphicsstats");
+ if (binder == null) return;
+ mGraphicsStatsService = IGraphicsStats.Stub.asInterface(binder);
+ requestBuffer();
+ } catch (Throwable t) {
+ Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
+ }
+ }
+
+ private void rotateBuffer() {
+ nRotateProcessStatsBuffer();
+ requestBuffer();
+ }
+
+ private void requestBuffer() {
+ try {
+ ParcelFileDescriptor pfd = mGraphicsStatsService
+ .requestBufferForProcess(mPackageName, mGraphicsStatsCallback);
+ nSetProcessStatsBuffer(pfd.getFd());
+ pfd.close();
+ } catch (Throwable t) {
+ Log.w(LOG_TAG, "Could not acquire gfx stats buffer", t);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static native void disableVsync();
+
+ /** @hide */
+ protected static native void setupShadersDiskCache(String cacheFile, String skiaCacheFile);
+
+ private static native void nRotateProcessStatsBuffer();
+
+ private static native void nSetProcessStatsBuffer(int fd);
+
+ private static native int nGetRenderThreadTid(long nativeProxy);
+
+ private static native long nCreateRootRenderNode();
+
+ private static native long nCreateProxy(boolean translucent, long rootRenderNode);
+
+ private static native void nDeleteProxy(long nativeProxy);
+
+ private static native boolean nLoadSystemProperties(long nativeProxy);
+
+ private static native void nSetName(long nativeProxy, String name);
+
+ private static native void nSetSurface(long nativeProxy, Surface window);
+
+ private static native boolean nPause(long nativeProxy);
+
+ private static native void nSetStopped(long nativeProxy, boolean stopped);
+
+ private static native void nSetLightGeometry(long nativeProxy,
+ float lightX, float lightY, float lightZ, float lightRadius);
+
+ private static native void nSetLightAlpha(long nativeProxy, float ambientShadowAlpha,
+ float spotShadowAlpha);
+
+ private static native void nSetOpaque(long nativeProxy, boolean opaque);
+
+ private static native void nSetWideGamut(long nativeProxy, boolean wideGamut);
+
+ private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
+
+ private static native void nDestroy(long nativeProxy, long rootRenderNode);
+
+ private static native void nRegisterAnimatingRenderNode(long rootRenderNode,
+ long animatingNode);
+
+ private static native void nRegisterVectorDrawableAnimator(long rootRenderNode, long animator);
+
+ private static native void nInvokeFunctor(long functor, boolean waitForCompletion);
+
+ private static native long nCreateTextureLayer(long nativeProxy);
+
+ private static native void nBuildLayer(long nativeProxy, long node);
+
+ private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
+
+ private static native void nPushLayerUpdate(long nativeProxy, long layer);
+
+ private static native void nCancelLayerUpdate(long nativeProxy, long layer);
+
+ private static native void nDetachSurfaceTexture(long nativeProxy, long layer);
+
+ private static native void nDestroyHardwareResources(long nativeProxy);
+
+ private static native void nTrimMemory(int level);
+
+ private static native void nOverrideProperty(String name, String value);
+
+ private static native void nFence(long nativeProxy);
+
+ private static native void nStopDrawing(long nativeProxy);
+
+ private static native void nNotifyFramePending(long nativeProxy);
+
+ private static native void nDumpProfileInfo(long nativeProxy, FileDescriptor fd,
+ @DumpFlags int dumpFlags);
+
+ private static native void nAddRenderNode(long nativeProxy, long rootRenderNode,
+ boolean placeFront);
+
+ private static native void nRemoveRenderNode(long nativeProxy, long rootRenderNode);
+
+ private static native void nDrawRenderNode(long nativeProxy, long rootRenderNode);
+
+ private static native void nSetContentDrawBounds(long nativeProxy, int left,
+ int top, int right, int bottom);
+
+ private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);
+
+ private static native void nSetFrameCompleteCallback(long nativeProxy,
+ FrameCompleteCallback callback);
+
+ private static native long nAddFrameMetricsObserver(long nativeProxy,
+ FrameMetricsObserver observer);
+
+ private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
+
+ private static native int nCopySurfaceInto(Surface surface,
+ int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
+
+ private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
+
+ private static native void nSetHighContrastText(boolean enabled);
+
+ // For temporary experimentation b/66945974
+ private static native void nHackySetRTAnimationsEnabled(boolean enabled);
+
+ private static native void nSetDebuggingEnabled(boolean enabled);
+
+ private static native void nSetIsolatedProcess(boolean enabled);
+
+ private static native void nSetContextPriority(int priority);
+
+ private static native void nAllocateBuffers(long nativeProxy);
+
+ private static native void nSetForceDark(long nativeProxy, boolean enabled);
+}
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 12128b3..45d7a21 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -161,7 +161,7 @@
* top-level content is desired, and finally calling {@link Surface#unlockCanvasAndPost(Canvas)}.
* </p>
*/
-public class RenderNode {
+public final class RenderNode {
// Use a Holder to allow static initialization in the boot image.
private static class NoImagePreloadHolder {
@@ -178,6 +178,16 @@
private final AnimationHost mAnimationHost;
private RecordingCanvas mCurrentRecordingCanvas;
+ /**
+ * Creates a new RenderNode that can be used to record batches of
+ * drawing operations, and store / apply render properties when drawn.
+ *
+ * @param name The name of the RenderNode, used for debugging purpose. May be null.
+ */
+ public RenderNode(String name) {
+ this(name, null);
+ }
+
private RenderNode(String name, AnimationHost animationHost) {
mNativeRenderNode = nCreate(name);
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mNativeRenderNode);
@@ -193,17 +203,6 @@
mAnimationHost = null;
}
- /**
- * Creates a new RenderNode that can be used to record batches of
- * drawing operations, and store / apply render properties when drawn.
- *
- * @param name The name of the RenderNode, used for debugging purpose. May be null.
- * @return A new RenderNode.
- */
- public static @NonNull RenderNode create(@Nullable String name) {
- return new RenderNode(name, null);
- }
-
/** @hide */
public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
return new RenderNode(name, animationHost);
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 7e8bfb3..bf969ef 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -664,6 +664,11 @@
/**
* Sets a system fallback by name.
*
+ * You can specify generic font familiy names or OEM specific family names. If the system
+ * don't have a specified fallback, the default fallback is used instead.
+ * For more information about generic font families, see <a
+ * href="https://www.w3.org/TR/css-fonts-4/#generic-font-families">CSS specification</a>
+ *
* For more information about fallback, see class description.
*
* @param familyName a family name to be used for fallback if the provided fonts can not be
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 0a4ac8c..c10e482 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -30,6 +30,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.security.KeyStoreException;
import android.security.keymaster.ExportResult;
import android.security.keymaster.KeyCharacteristics;
import android.security.keymaster.KeymasterArguments;
@@ -40,14 +41,21 @@
import android.security.keystore.KeyExpiredException;
import android.security.keystore.KeyNotYetValidException;
import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
import android.security.keystore.StrongBoxUnavailableException;
import android.security.keystore.UserNotAuthenticatedException;
import android.util.Log;
-
+import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import java.math.BigInteger;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
import java.security.InvalidKeyException;
import java.util.List;
import java.util.Locale;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
/**
* @hide This should not be made public in its present form because it
@@ -69,6 +77,7 @@
public static final int VALUE_CORRUPTED = 8;
public static final int UNDEFINED_ACTION = 9;
public static final int WRONG_PASSWORD = 10;
+ public static final int KEY_ALREADY_EXISTS = 16;
public static final int CANNOT_ATTEST_IDS = -66;
public static final int HARDWARE_TYPE_UNAVAILABLE = -68;
@@ -239,7 +248,12 @@
if (value == null) {
value = new byte[0];
}
- return mBinder.insert(key, value, uid, flags);
+ int error = mBinder.insert(key, value, uid, flags);
+ if (error == KEY_ALREADY_EXISTS) {
+ mBinder.del(key, uid);
+ error = mBinder.insert(key, value, uid, flags);
+ }
+ return error;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
@@ -366,53 +380,6 @@
return isEmpty(UserHandle.myUserId());
}
- public boolean generate(String key, int uid, int keyType, int keySize, int flags,
- byte[][] args) {
- try {
- return mBinder.generate(key, uid, keyType, keySize, flags,
- new KeystoreArguments(args)) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public boolean importKey(String keyName, byte[] key, int uid, int flags) {
- try {
- return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- public byte[] sign(String key, byte[] data) {
- try {
- return mBinder.sign(key, data);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return null;
- } catch (android.os.ServiceSpecificException e) {
- Log.w(TAG, "KeyStore exception", e);
- return null;
- }
-
- }
-
- public boolean verify(String key, byte[] data, byte[] signature) {
- try {
- signature = signature != null ? signature : new byte[0];
- return mBinder.verify(key, data, signature) == NO_ERROR;
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- } catch (android.os.ServiceSpecificException e) {
- Log.w(TAG, "KeyStore exception", e);
- return false;
- }
-
- }
-
public String grant(String key, int uid) {
try {
String grantAlias = mBinder.grant(key, uid);
@@ -496,7 +463,12 @@
try {
entropy = entropy != null ? entropy : new byte[0];
args = args != null ? args : new KeymasterArguments();
- return mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics);
+ int error = mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics);
+ if (error == KEY_ALREADY_EXISTS) {
+ mBinder.del(alias, uid);
+ error = mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics);
+ }
+ return error;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
@@ -528,8 +500,14 @@
public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData,
int uid, int flags, KeyCharacteristics outCharacteristics) {
try {
- return mBinder.importKey(alias, args, format, keyData, uid, flags,
+ int error = mBinder.importKey(alias, args, format, keyData, uid, flags,
outCharacteristics);
+ if (error == KEY_ALREADY_EXISTS) {
+ mBinder.del(alias, uid);
+ error = mBinder.importKey(alias, args, format, keyData, uid, flags,
+ outCharacteristics);
+ }
+ return error;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
@@ -541,13 +519,78 @@
return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics);
}
+ private String getAlgorithmFromPKCS8(byte[] keyData) {
+ try {
+ final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData));
+ final PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject());
+ final String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId();
+ return new AlgorithmId(new ObjectIdentifier(algOid)).getName();
+ } catch (IOException e) {
+ Log.e(TAG, "getAlgorithmFromPKCS8 Failed to parse key data");
+ Log.e(TAG, Log.getStackTraceString(e));
+ return null;
+ }
+ }
+
+ private KeymasterArguments makeLegacyArguments(String algorithm) {
+ KeymasterArguments args = new KeymasterArguments();
+ args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM,
+ KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(algorithm));
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_SIGN);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_VERIFY);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE);
+ if (algorithm.equalsIgnoreCase(KeyProperties.KEY_ALGORITHM_RSA)) {
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_OAEP);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN);
+ args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PSS);
+ }
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_MD5);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA1);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_224);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_256);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_384);
+ args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_512);
+ args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
+ KeymasterArguments.UINT64_MAX_VALUE);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME,
+ KeymasterArguments.UINT64_MAX_VALUE);
+ args.addUnsignedLong(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, BigInteger.ZERO);
+ return args;
+ }
+
+ public boolean importKey(String alias, byte[] keyData, int uid, int flags) {
+ String algorithm = getAlgorithmFromPKCS8(keyData);
+ if (algorithm == null) return false;
+ KeymasterArguments args = makeLegacyArguments(algorithm);
+ KeyCharacteristics out = new KeyCharacteristics();
+ int result = importKey(alias, args, KeymasterDefs.KM_KEY_FORMAT_PKCS8, keyData, uid,
+ flags, out);
+ if (result != NO_ERROR) {
+ Log.e(TAG, Log.getStackTraceString(
+ new KeyStoreException(result, "legacy key import failed")));
+ return false;
+ }
+ return true;
+ }
+
public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey,
String wrappingKeyAlias,
byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid, int uid,
KeyCharacteristics outCharacteristics) {
try {
- return mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
+ int error = mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
maskingKey, args, rootSid, fingerprintSid, outCharacteristics);
+ if (error == KEY_ALREADY_EXISTS) {
+ mBinder.del(wrappedKeyAlias, -1);
+ error = mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias,
+ maskingKey, args, rootSid, fingerprintSid, outCharacteristics);
+ }
+ return error;
} catch (RemoteException e) {
Log.w(TAG, "Cannot connect to keystore", e);
return SYSTEM_ERROR;
@@ -627,21 +670,6 @@
}
/**
- * Check if the operation referenced by {@code token} is currently authorized.
- *
- * @param token An operation token returned by a call to
- * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}.
- */
- public boolean isOperationAuthorized(IBinder token) {
- try {
- return mBinder.isOperationAuthorized(token);
- } catch (RemoteException e) {
- Log.w(TAG, "Cannot connect to keystore", e);
- return false;
- }
- }
-
- /**
* Add an authentication record to the keystore authorization table.
*
* @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster.
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index 92efb6b..98af3eb 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -59,8 +59,6 @@
"ZipFileRO.cpp",
"ZipUtils.cpp",
],
- // Allow implicit fallthroughs in Locale.cpp and ResourceTypes.cpp until they are fixed.
- cflags: ["-Wno-implicit-fallthrough"],
export_include_dirs: ["include"],
export_shared_lib_headers: ["libz"],
target: {
diff --git a/libs/androidfw/Locale.cpp b/libs/androidfw/Locale.cpp
index 2870066..3eedda8 100644
--- a/libs/androidfw/Locale.cpp
+++ b/libs/androidfw/Locale.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include "android-base/macros.h"
#include "androidfw/Locale.h"
#include "androidfw/Util.h"
@@ -162,6 +163,7 @@
set_script(subtags[1].c_str());
break;
}
+ FALLTHROUGH_INTENDED;
case 5:
case 6:
case 7:
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 388548b..76db18d 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -29,6 +29,7 @@
#include <memory>
#include <type_traits>
+#include <android-base/macros.h>
#include <androidfw/ByteBucketArray.h>
#include <androidfw/ResourceTypes.h>
#include <androidfw/TypeWrappers.h>
@@ -3073,6 +3074,7 @@
}
break;
}
+ FALLTHROUGH_INTENDED;
case 5:
case 6:
case 7:
@@ -7002,7 +7004,7 @@
switch (value->dataType) {
case Res_value::TYPE_ATTRIBUTE:
resolvedType = Res_value::TYPE_ATTRIBUTE;
- // fallthrough
+ FALLTHROUGH_INTENDED;
case Res_value::TYPE_REFERENCE:
// Only resolve non-dynamic references and attributes if the package is loaded as a
// library or if a shared library is attempting to retrieve its own resource
@@ -7015,7 +7017,7 @@
break;
case Res_value::TYPE_DYNAMIC_ATTRIBUTE:
resolvedType = Res_value::TYPE_ATTRIBUTE;
- // fallthrough
+ FALLTHROUGH_INTENDED;
case Res_value::TYPE_DYNAMIC_REFERENCE:
break;
default:
diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp
index 236a6b6..b04c774 100644
--- a/libs/hwui/FrameInfoVisualizer.cpp
+++ b/libs/hwui/FrameInfoVisualizer.cpp
@@ -66,6 +66,7 @@
FrameInfoVisualizer::FrameInfoVisualizer(FrameInfoSource& source) : mFrameSource(source) {
setDensity(1);
+ consumeProperties();
}
FrameInfoVisualizer::~FrameInfoVisualizer() {
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index c58bcb3..769fce49 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -84,7 +84,7 @@
const minikin::FontFakery& fakery) const {
SkPaint skPaint;
MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint, fakery);
- SkPaint::FontMetrics metrics;
+ SkFontMetrics metrics;
skPaint.getFontMetrics(&metrics);
extent->ascent = metrics.fAscent;
extent->descent = metrics.fDescent;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 92a749f..f1a522e 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -180,14 +180,20 @@
}
}
-void CanvasContext::setup(float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
- mLightGeometry.radius = lightRadius;
+void CanvasContext::allocateBuffers() {
+ if (mNativeSurface) {
+ mNativeSurface->allocateBuffers();
+ }
+}
+
+void CanvasContext::setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
mLightInfo.ambientShadowAlpha = ambientShadowAlpha;
mLightInfo.spotShadowAlpha = spotShadowAlpha;
}
-void CanvasContext::setLightCenter(const Vector3& lightCenter) {
+void CanvasContext::setLightGeometry(const Vector3& lightCenter, float lightRadius) {
mLightGeometry.center = lightCenter;
+ mLightGeometry.radius = lightRadius;
}
void CanvasContext::setOpaque(bool opaque) {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2307ee4..70be4a6 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -113,9 +113,10 @@
bool pauseSurface();
void setStopped(bool stopped);
bool hasSurface() { return mNativeSurface.get(); }
+ void allocateBuffers();
- void setup(float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
- void setLightCenter(const Vector3& lightCenter);
+ void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
+ void setLightGeometry(const Vector3& lightCenter, float lightRadius);
void setOpaque(bool opaque);
void setWideGamut(bool wideGamut);
bool makeCurrent();
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 54219b5..085812a0 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -80,22 +80,16 @@
mRenderThread.queue().runSync([this, name]() { mContext->setName(std::string(name)); });
}
-void RenderProxy::initialize(const sp<Surface>& surface) {
+void RenderProxy::setSurface(const sp<Surface>& surface) {
mRenderThread.queue().post(
[ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); });
}
-void RenderProxy::allocateBuffers(const sp<Surface>& surface) {
- mRenderThread.queue().post(
- [ surf = surface ]() mutable { surf->allocateBuffers(); });
+void RenderProxy::allocateBuffers() {
+ mRenderThread.queue().post([=]() { mContext->allocateBuffers(); });
}
-void RenderProxy::updateSurface(const sp<Surface>& surface) {
- mRenderThread.queue().post(
- [ this, surf = surface ]() mutable { mContext->setSurface(std::move(surf)); });
-}
-
-bool RenderProxy::pauseSurface(const sp<Surface>& surface) {
+bool RenderProxy::pause() {
return mRenderThread.queue().runSync([this]() -> bool { return mContext->pauseSurface(); });
}
@@ -103,13 +97,13 @@
mRenderThread.queue().runSync([this, stopped]() { mContext->setStopped(stopped); });
}
-void RenderProxy::setup(float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
+void RenderProxy::setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
mRenderThread.queue().post(
- [=]() { mContext->setup(lightRadius, ambientShadowAlpha, spotShadowAlpha); });
+ [=]() { mContext->setLightAlpha(ambientShadowAlpha, spotShadowAlpha); });
}
-void RenderProxy::setLightCenter(const Vector3& lightCenter) {
- mRenderThread.queue().post([=]() { mContext->setLightCenter(lightCenter); });
+void RenderProxy::setLightGeometry(const Vector3& lightCenter, float lightRadius) {
+ mRenderThread.queue().post([=]() { mContext->setLightGeometry(lightCenter, lightRadius); });
}
void RenderProxy::setOpaque(bool opaque) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index d29fcc4..6668c584 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -69,13 +69,12 @@
ANDROID_API bool loadSystemProperties();
ANDROID_API void setName(const char* name);
- ANDROID_API void initialize(const sp<Surface>& surface);
- ANDROID_API void allocateBuffers(const sp<Surface>& surface);
- ANDROID_API void updateSurface(const sp<Surface>& surface);
- ANDROID_API bool pauseSurface(const sp<Surface>& surface);
+ ANDROID_API void setSurface(const sp<Surface>& surface);
+ ANDROID_API void allocateBuffers();
+ ANDROID_API bool pause();
ANDROID_API void setStopped(bool stopped);
- ANDROID_API void setup(float lightRadius, uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
- ANDROID_API void setLightCenter(const Vector3& lightCenter);
+ ANDROID_API void setLightAlpha(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
+ ANDROID_API void setLightGeometry(const Vector3& lightCenter, float lightRadius);
ANDROID_API void setOpaque(bool opaque);
ANDROID_API void setWideGamut(bool wideGamut);
ANDROID_API int64_t* frameInfo();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 62f704b..2384f95 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -74,7 +74,7 @@
PREVENT_COPY_AND_ASSIGN(RenderThread);
public:
- // Sets a callback that fires before any RenderThread setup has occured.
+ // Sets a callback that fires before any RenderThread setup has occurred.
ANDROID_API static void setOnStartHook(void (*onStartHook)());
WorkQueue& queue() { return ThreadBase::queue(); }
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 5f5a92e..5fa008b 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -132,10 +132,10 @@
ContextFactory factory;
std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode.get(), &factory));
proxy->loadSystemProperties();
- proxy->initialize(surface);
+ proxy->setSurface(surface);
float lightX = width / 2.0;
- proxy->setup(dp(800.0f), 255 * 0.075, 255 * 0.15);
- proxy->setLightCenter((Vector3){lightX, dp(-200.0f), dp(800.0f)});
+ proxy->setLightAlpha(255 * 0.075, 255 * 0.15);
+ proxy->setLightGeometry((Vector3){lightX, dp(-200.0f), dp(800.0f)}, dp(800.0f));
// Do a few cold runs then reset the stats so that the caches are all hot
int warmupFrameCount = 5;
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 2152e1e..f179bc3 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -16,8 +16,8 @@
package android.location;
-import android.annotation.TestApi;
import android.annotation.IntDef;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -685,6 +685,12 @@
*
* <p>This includes ensuring that all half-cycle ambiguities are resolved before this value is
* reported as {@link #ADR_STATE_VALID}.
+ *
+ * <p>The alignment of the phase measurement will not be adjusted by the receiver so the
+ * in-phase and quadrature phase components will have a quarter cycle offset as they do when
+ * transmitted from the satellites. If the measurement is from a combination of the in-phase
+ * and quadrature phase components, then the alignment of the phase measurement will be aligned
+ * to the in-phase component.
*/
public double getAccumulatedDeltaRangeMeters() {
return mAccumulatedDeltaRangeMeters;
diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java
index 12352e7..ce631a433 100644
--- a/media/java/android/media/MediaCas.java
+++ b/media/java/android/media/MediaCas.java
@@ -104,7 +104,7 @@
@Override
protected IMediaCasService create() {
try {
- return IMediaCasService.getService();
+ return IMediaCasService.getService(true /*wait*/);
} catch (RemoteException e) {}
return null;
}
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index ee12b91..24b7f36 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -979,6 +979,87 @@
throws DeniedByServerException;
/**
+ * The keys in an offline license allow protected content to be played even
+ * if the device is not connected to a network. Offline licenses are stored
+ * on the device after a key request/response exchange when the key request
+ * KeyType is OFFLINE. Normally each app is responsible for keeping track of
+ * the keySetIds it has created. If an app loses the keySetId for any stored
+ * licenses that it created, however, it must be able to recover the stored
+ * keySetIds so those licenses can be removed when they expire or when the
+ * app is uninstalled.
+ * <p>
+ * This method returns a list of the keySetIds for all offline licenses.
+ * The offline license keySetId may be used to query the status of an
+ * offline license with {@link #getOfflineLicenseState} or remove it with
+ * {@link #removeOfflineLicense}.
+ *
+ * @return a list of offline license keySetIds
+ */
+ @NonNull
+ public native List<byte[]> getOfflineLicenseKeySetIds();
+
+ /**
+ * Normally offline licenses are released using a key request/response
+ * exchange using {@link #getKeyRequest} where the key type is
+ * KEY_TYPE_RELEASE, followed by {@link #provideKeyResponse}. This allows
+ * the server to cryptographically confirm that the license has been removed
+ * and then adjust the count of offline licenses allocated to the device.
+ * <p>
+ * In some exceptional situations it may be necessary to directly remove
+ * offline licenses without notifying the server, which may be performed
+ * using this method.
+ *
+ * @param keySetId the id of the offline license to remove
+ * @throws IllegalArgumentException if the keySetId does not refer to an
+ * offline license.
+ */
+ public native void removeOfflineLicense(@NonNull byte[] keySetId);
+
+ /**
+ * Offline license state is unknown, an error occurred while trying
+ * to access it.
+ */
+ public static final int OFFLINE_LICENSE_STATE_UNKNOWN = 0;
+
+ /**
+ * Offline license state is usable, the keys may be used for decryption.
+ */
+ public static final int OFFLINE_LICENSE_USABLE = 1;
+
+ /**
+ * Offline license state is inactive, the keys have been marked for
+ * release using {@link #getKeyRequest} with KEY_TYPE_RELEASE but the
+ * key response has not been received.
+ */
+ public static final int OFFLINE_LICENSE_INACTIVE = 2;
+
+ /** @hide */
+ @IntDef({
+ OFFLINE_LICENSE_STATE_UNKNOWN,
+ OFFLINE_LICENSE_USABLE,
+ OFFLINE_LICENSE_INACTIVE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface OfflineLicenseState {}
+
+ /**
+ * Request the state of an offline license. An offline license may be usable
+ * or inactive. The keys in a usable offline license are available for
+ * decryption. When the offline license state is inactive, the keys have
+ * been marked for release using {@link #getKeyRequest} with
+ * KEY_TYPE_RELEASE but the key response has not been received. The keys in
+ * an inactive offline license are not usable for decryption.
+ *
+ * @param keySetId selects the offline license
+ * @return the offline license state, one of {@link #OFFLINE_LICENSE_USABLE},
+ * {@link #OFFLINE_LICENSE_INACTIVE} or {@link #OFFLINE_LICENSE_STATE_UNKNOWN}.
+ * @throws IllegalArgumentException if the keySetId does not refer to an
+ * offline license.
+ */
+ @OfflineLicenseState
+ public native int getOfflineLicenseState(@NonNull byte[] keySetId);
+
+ /**
* Secure stops are a way to enforce limits on the number of concurrent
* streams per subscriber across devices. They provide secure monitoring of
* the lifetime of content decryption keys in MediaDrm sessions.
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 0b3c973..4e90162 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -294,7 +294,7 @@
* reached end of stream and been paused, or never started before,
* playback will start at the beginning.
*
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object play();
@@ -305,21 +305,21 @@
* After setting the datasource and the display surface, you need to
* call prepare().
*
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object prepare();
/**
* Pauses playback. Call play() to resume.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object pause();
/**
* Tries to play next data source if applicable.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object skipToNext();
@@ -404,7 +404,7 @@
* You must call this method before {@link #play()} and {@link #pause()} in order
* for the audio attributes to become effective thereafter.
* @param attributes a non-null set of audio attributes
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setAudioAttributes(@NonNull AudioAttributes attributes);
@@ -419,7 +419,7 @@
* Sets the data source as described by a DataSourceDesc.
*
* @param dsd the descriptor of data source you want to play
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setDataSource(@NonNull DataSourceDesc dsd);
@@ -429,7 +429,7 @@
* after current data source is finished.
*
* @param dsd the descriptor of data source you want to play after current one
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setNextDataSource(@NonNull DataSourceDesc dsd);
@@ -438,14 +438,14 @@
* Sets a list of data sources to be played sequentially after current data source is done.
*
* @param dsds the list of data sources you want to play after current one
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setNextDataSources(@NonNull List<DataSourceDesc> dsds);
/**
* Removes all data sources pending to be played.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object clearNextDataSources();
@@ -460,7 +460,7 @@
/**
* Configures the player to loop on the current data source.
* @param loop true if the current data source is meant to loop.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object loopCurrent(boolean loop);
@@ -473,7 +473,7 @@
* A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
* gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
* @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setPlayerVolume(float volume);
@@ -502,7 +502,7 @@
*
* @param label An application specific Object used to help to identify the completeness
* of a batch of commands.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object notifyWhenCommandLabelReached(@NonNull Object label);
@@ -518,7 +518,7 @@
* played.
*
* @param sh the SurfaceHolder to use for video display
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
public abstract Object setDisplay(SurfaceHolder sh);
@@ -538,7 +538,7 @@
*
* @param surface The {@link Surface} to be used for the video portion of
* the media.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setSurface(Surface surface);
@@ -558,7 +558,7 @@
*
* @param context the Context to use
* @param mode the power/wake mode to set
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
* @see android.os.PowerManager
*/
// This is an asynchronous call.
@@ -572,7 +572,7 @@
* access.
*
* @param screenOn Supply true to keep the screen on, false to allow it to turn off.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setScreenOnWhilePlaying(boolean screenOn);
@@ -667,22 +667,11 @@
* available for the media being handled by this instance of MediaPlayer2
* The attributes are descibed in {@link MetricsConstants}.
*
- * Additional vendor-specific fields may also be present in
- * the return value.
+ * Additional vendor-specific fields may also be present in the return value.
*/
public abstract PersistableBundle getMetrics();
/**
- * Checks whether the MediaPlayer2 is playing.
- *
- * @return true if currently playing, false otherwise
- * @throws IllegalStateException if the internal player engine has not been
- * initialized or has been released.
- * @hide
- */
- public abstract boolean isPlaying();
-
- /**
* Gets the current buffering management params used by the source component.
* Calling it only after {@code setDataSource} has been called.
* Each type of data source might have different set of default params.
@@ -690,10 +679,10 @@
* @return the current buffering management params used by the source component.
* @throws IllegalStateException if the internal player engine has not been
* initialized, or {@code setDataSource} has not been called.
- * @hide
*/
+ // TODO: make it public when ready
@NonNull
- public BufferingParams getBufferingParams() {
+ BufferingParams getBufferingParams() {
return new BufferingParams.Builder().build();
}
@@ -705,80 +694,11 @@
* The input is a hint to MediaPlayer2.
*
* @param params the buffering management params.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
- *
- * @hide
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
+ // TODO: make it public when ready
// This is an asynchronous call.
- public abstract Object setBufferingParams(@NonNull BufferingParams params);
-
- /**
- * Change playback speed of audio by resampling the audio.
- * <p>
- * Specifies resampling as audio mode for variable rate playback, i.e.,
- * resample the waveform based on the requested playback rate to get
- * a new waveform, and play back the new waveform at the original sampling
- * frequency.
- * When rate is larger than 1.0, pitch becomes higher.
- * When rate is smaller than 1.0, pitch becomes lower.
- *
- * @hide
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
-
- /**
- * Change playback speed of audio without changing its pitch.
- * <p>
- * Specifies time stretching as audio mode for variable rate playback.
- * Time stretching changes the duration of the audio samples without
- * affecting its pitch.
- * <p>
- * This mode is only supported for a limited range of playback speed factors,
- * e.g. between 1/2x and 2x.
- *
- * @hide
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
-
- /**
- * Change playback speed of audio without changing its pitch, and
- * possibly mute audio if time stretching is not supported for the playback
- * speed.
- * <p>
- * Try to keep audio pitch when changing the playback rate, but allow the
- * system to determine how to change audio playback if the rate is out
- * of range.
- *
- * @hide
- */
- public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
-
- /** @hide */
- @IntDef(flag = false, prefix = "PLAYBACK_RATE_AUDIO_MODE", value = {
- PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
- PLAYBACK_RATE_AUDIO_MODE_STRETCH,
- PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface PlaybackRateAudioMode {}
-
- /**
- * Sets playback rate and audio mode.
- *
- * @param rate the ratio between desired playback rate and normal one.
- * @param audioMode audio playback mode. Must be one of the supported
- * audio modes.
- *
- * @throws IllegalStateException if the internal player engine has not been
- * initialized.
- * @throws IllegalArgumentException if audioMode is not supported.
- *
- * @hide
- */
- @NonNull
- public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) {
- return new PlaybackParams();
- }
+ abstract Object setBufferingParams(@NonNull BufferingParams params);
/**
* Sets playback rate using {@link PlaybackParams}. The object sets its internal
@@ -787,7 +707,7 @@
* the object state.
*
* @param params the playback params.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setPlaybackParams(@NonNull PlaybackParams params);
@@ -796,6 +716,7 @@
* Gets the playback params, containing the current playback rate.
*
* @return the playback params.
+ * @throws IllegalStateException if the internal player engine has not been initialized.
*/
@NonNull
public abstract PlaybackParams getPlaybackParams();
@@ -804,7 +725,7 @@
* Sets A/V sync mode.
*
* @param params the A/V sync params to apply
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setSyncParams(@NonNull SyncParams params);
@@ -813,6 +734,7 @@
* Gets the A/V sync mode.
*
* @return the A/V sync params
+ * @throws IllegalStateException if the internal player engine has not been initialized.
*/
@NonNull
public abstract SyncParams getSyncParams();
@@ -822,7 +744,7 @@
* Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
*
* @param msec the offset in milliseconds from the start to seek to
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public Object seekTo(long msec) {
@@ -882,7 +804,8 @@
/**
* 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.
+ * When seekTo is finished, the user will be notified via
+ * {@link EventCallback#onCallCompleted} with {@link #CALL_COMPLETED_SEEK_TO}.
* 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
@@ -895,7 +818,7 @@
* 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.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object seekTo(long msec, @SeekMode int mode);
@@ -953,7 +876,7 @@
* However, it is possible to force this player to be part of an already existing audio session
* by calling this method.
* This method must be called before one of the overloaded <code> setDataSource </code> methods.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setAudioSessionId(int sessionId);
@@ -979,7 +902,7 @@
* <p>This method must be called after one of the overloaded <code> setDataSource </code>
* methods.
* @param effectId system wide unique id of the effect to attach
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object attachAuxEffect(int effectId);
@@ -996,7 +919,7 @@
* x == 0 -> level = 0
* 0 < x <= R -> level = 10^(72*(x-R)/20/R)
* @param level send level scalar
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object setAuxEffectSendLevel(float level);
@@ -1122,7 +1045,7 @@
* @param index the index of the track to be selected. The valid range of the index
* is 0..total number of track - 1. The total number of tracks as well as the type of
* each individual track can be found by calling {@link #getTrackInfo()} method.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*
* @see MediaPlayer2#getTrackInfo
*/
@@ -1139,7 +1062,7 @@
* @param index the index of the track to be deselected. The valid range of the index
* is 0..total number of tracks - 1. The total number of tracks as well as the type of
* each individual track can be found by calling {@link #getTrackInfo()} method.
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*
* @see MediaPlayer2#getTrackInfo
*/
@@ -1872,7 +1795,7 @@
* from the source through {@code getDrmInfo} or registering a
* {@link DrmEventCallback#onDrmInfo}.
*
- * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
*/
// This is an asynchronous call.
public abstract Object prepareDrm(@NonNull UUID uuid);
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index a7b8a3d..3534636 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -131,6 +131,13 @@
@GuardedBy("mTaskLock")
private Task mCurrentTask;
+ @GuardedBy("mTaskLock")
+ boolean mIsPreviousCommandSeekTo = false;
+ // |mPreviousSeekPos| and |mPreviousSeekMode| are valid only when |mIsPreviousCommandSeekTo|
+ // is true, and they are accessed on |mHandlerThread| only.
+ long mPreviousSeekPos = -1;
+ int mPreviousSeekMode = SEEK_PREVIOUS_SYNC;
+
@GuardedBy("this")
private boolean mReleased;
@@ -797,11 +804,7 @@
@Override
public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
- if (deviceInfo != null && !deviceInfo.isSink()) {
- return false;
- }
- int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
- boolean status = native_setOutputDevice(preferredDeviceId);
+ boolean status = native_setPreferredDevice(deviceInfo);
if (status == true) {
synchronized (this) {
mPreferredDevice = deviceInfo;
@@ -818,20 +821,7 @@
}
@Override
- public AudioDeviceInfo getRoutedDevice() {
- int deviceId = native_getRoutedDeviceId();
- if (deviceId == 0) {
- return null;
- }
- AudioDeviceInfo[] devices =
- AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
- for (int i = 0; i < devices.length; i++) {
- if (devices[i].getId() == deviceId) {
- return devices[i];
- }
- }
- return null;
- }
+ public native AudioDeviceInfo getRoutedDevice();
@Override
public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
@@ -851,8 +841,7 @@
native_removeDeviceCallback(listener);
}
- private native final boolean native_setOutputDevice(int deviceId);
- private native final int native_getRoutedDeviceId();
+ private native boolean native_setPreferredDevice(AudioDeviceInfo device);
private native void native_addDeviceCallback(RoutingDelegate rd);
private native void native_removeDeviceCallback(
AudioRouting.OnRoutingChangedListener listener);
@@ -944,14 +933,11 @@
private native PersistableBundle native_getMetrics();
@Override
- public native boolean isPlaying();
-
- @Override
@NonNull
- public native BufferingParams getBufferingParams();
+ native BufferingParams getBufferingParams();
@Override
- public Object setBufferingParams(@NonNull BufferingParams params) {
+ Object setBufferingParams(@NonNull BufferingParams params) {
return addTask(new Task(CALL_COMPLETED_SET_BUFFERING_PARAMS, false) {
@Override
void process() {
@@ -963,42 +949,6 @@
private native void _setBufferingParams(@NonNull BufferingParams params);
- /**
- * Sets playback rate and audio mode.
- *
- * @param rate the ratio between desired playback rate and normal one.
- * @param audioMode audio playback mode. Must be one of the supported
- * audio modes.
- *
- * @throws IllegalStateException if the internal player engine has not been
- * initialized.
- * @throws IllegalArgumentException if audioMode is not supported.
- *
- * @hide
- */
- @Override
- @NonNull
- public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) {
- PlaybackParams params = new PlaybackParams();
- params.allowDefaults();
- switch (audioMode) {
- case PLAYBACK_RATE_AUDIO_MODE_DEFAULT:
- params.setSpeed(rate).setPitch(1.0f);
- break;
- case PLAYBACK_RATE_AUDIO_MODE_STRETCH:
- params.setSpeed(rate).setPitch(1.0f)
- .setAudioFallbackMode(params.AUDIO_FALLBACK_MODE_FAIL);
- break;
- case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE:
- params.setSpeed(rate).setPitch(rate);
- break;
- default:
- final String msg = "Audio playback mode " + audioMode + " is not supported";
- throw new IllegalArgumentException(msg);
- }
- return params;
- }
-
@Override
public Object setPlaybackParams(@NonNull PlaybackParams params) {
return addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
@@ -1012,26 +962,10 @@
private native void _setPlaybackParams(@NonNull PlaybackParams params);
- /**
- * Gets the playback params, containing the current playback rate.
- *
- * @return the playback params.
- * @throws IllegalStateException if the internal player engine has not been
- * initialized.
- */
@Override
@NonNull
public native PlaybackParams getPlaybackParams();
- /**
- * Sets A/V sync mode.
- *
- * @param params the A/V sync params to apply
- *
- * @throws IllegalStateException if the internal player engine has not been
- * initialized.
- * @throws IllegalArgumentException if params are not supported.
- */
@Override
public Object setSyncParams(@NonNull SyncParams params) {
return addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
@@ -1045,48 +979,10 @@
private native void _setSyncParams(@NonNull SyncParams params);
- /**
- * Gets the A/V sync mode.
- *
- * @return the A/V sync params
- *
- * @throws IllegalStateException if the internal player engine has not been
- * initialized.
- */
@Override
@NonNull
public native SyncParams getSyncParams();
- /**
- * 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.
- */
@Override
public Object seekTo(final long msec, @SeekMode int mode) {
return addTask(new Task(CALL_COMPLETED_SEEK_TO, true) {
@@ -1107,7 +1003,23 @@
+ Integer.MIN_VALUE);
posMs = Integer.MIN_VALUE;
}
+
+ synchronized (mTaskLock) {
+ if (mIsPreviousCommandSeekTo
+ && mPreviousSeekPos == posMs
+ && mPreviousSeekMode == mode) {
+ throw new CommandSkippedException(
+ "same as previous seekTo");
+ }
+ }
+
_seekTo(posMs, mode);
+
+ synchronized (mTaskLock) {
+ mIsPreviousCommandSeekTo = true;
+ mPreviousSeekPos = posMs;
+ mPreviousSeekMode = mode;
+ }
}
});
}
@@ -1141,7 +1053,7 @@
return new MediaTimestamp(
getCurrentPosition() * 1000L,
System.nanoTime(),
- isPlaying() ? getPlaybackParams().getSpeed() : 0.f);
+ getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f);
} catch (IllegalStateException e) {
return null;
}
@@ -1169,6 +1081,11 @@
mNextSourceState = NEXT_SOURCE_STATE_INIT;
}
+ synchronized (mTaskLock) {
+ mPendingTasks.clear();
+ mIsPreviousCommandSeekTo = false;
+ }
+
stayAwake(false);
_reset();
// make sure none of the listeners get called anymore
@@ -1763,6 +1680,12 @@
case MEDIA_SEEK_COMPLETE:
{
synchronized (mTaskLock) {
+ if (!mPendingTasks.isEmpty()
+ && mPendingTasks.get(0).mMediaCallType != CALL_COMPLETED_SEEK_TO
+ && getState() == PLAYER_STATE_PLAYING) {
+ mIsPreviousCommandSeekTo = false;
+ }
+
if (mCurrentTask != null
&& mCurrentTask.mMediaCallType == CALL_COMPLETED_SEEK_TO
&& mCurrentTask.mNeedToWaitForEventToComplete) {
@@ -2770,34 +2693,6 @@
}
- // Called from the native side
- @SuppressWarnings("unused")
- private static boolean setAudioOutputDeviceById(AudioTrack track, int deviceId) {
- if (track == null) {
- return false;
- }
-
- if (deviceId == 0) {
- // Use default routing.
- track.setPreferredDevice(null);
- return true;
- }
-
- // TODO: Unhide AudioManager.getDevicesStatic.
- AudioDeviceInfo[] outputDevices =
- AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
-
- boolean success = false;
- for (AudioDeviceInfo device : outputDevices) {
- if (device.getId() == deviceId) {
- track.setPreferredDevice(device);
- success = true;
- break;
- }
- }
- return success;
- }
-
// Instantiated from the native side
@SuppressWarnings("unused")
private static class StreamEventCallback extends AudioTrack.StreamEventCallback {
@@ -3193,6 +3088,12 @@
mDSD = mCurrentDSD;
}
+ if (mMediaCallType != CALL_COMPLETED_SEEK_TO) {
+ synchronized (mTaskLock) {
+ mIsPreviousCommandSeekTo = false;
+ }
+ }
+
// TODO: Make native implementations asynchronous and let them send notifications.
if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 0cde01e..3a64f43 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1632,7 +1632,7 @@
selectionArgs = new String[] { path };
c = mMediaProvider.query(mFilesUriNoNotify, FILES_PRESCAN_PROJECTION,
where, selectionArgs, null, null);
- if (c.moveToFirst()) {
+ if (c != null && c.moveToFirst()) {
long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX);
int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX);
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index cf7bf19..fa69062 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -24,7 +24,6 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
-import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.hardware.soundtrigger.SoundTrigger;
@@ -367,15 +366,15 @@
}
/**
- * Synchronously get state of the indicated model. The model state is returned as
- * a recognition event, or null if the model is not loaded, or if this method
- * is not supported.
+ * Asynchronously get state of the indicated model. The model state is returned as
+ * a recognition event in the callback that was registered in the startRecognition
+ * method.
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
- public SoundTrigger.RecognitionEvent getModelState(UUID soundModelId) {
+ public int getModelState(UUID soundModelId) {
if (soundModelId == null) {
- return null;
+ return STATUS_ERROR;
}
try {
return mSoundTriggerService.getModelState(new ParcelUuid(soundModelId));
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 8637ada..be71dad5 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -161,6 +161,12 @@
jint kSecurityLevelHwSecureAll;
} gSecurityLevels;
+struct OfflineLicenseState {
+ jint kOfflineLicenseStateUsable;
+ jint kOfflineLicenseStateInactive;
+ jint kOfflineLicenseStateUnknown;
+} gOfflineLicenseStates;
+
struct fields_t {
jfieldID context;
@@ -740,6 +746,15 @@
GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_ALL", "I");
gSecurityLevels.kSecurityLevelHwSecureAll = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_USABLE", "I");
+ gOfflineLicenseStates.kOfflineLicenseStateUsable = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_INACTIVE", "I");
+ gOfflineLicenseStates.kOfflineLicenseStateInactive = env->GetStaticIntField(clazz, field);
+ GET_STATIC_FIELD_ID(field, clazz, "OFFLINE_LICENSE_STATE_UNKNOWN", "I");
+ gOfflineLicenseStates.kOfflineLicenseStateUnknown = env->GetStaticIntField(clazz, field);
+
+ GET_STATIC_FIELD_ID(field, clazz, "SECURITY_LEVEL_HW_SECURE_CRYPTO", "I");
+
jmethodID getMaxSecurityLevel;
GET_STATIC_METHOD_ID(getMaxSecurityLevel, clazz, "getMaxSecurityLevel", "()I");
gSecurityLevels.kSecurityLevelMax = env->CallStaticIntMethod(clazz, getMaxSecurityLevel);
@@ -890,9 +905,7 @@
JNIEnv *env, jobject thiz, jint jlevel) {
sp<IDrm> drm = GetDrm(env, thiz);
- if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "MediaDrm obj is null");
+ if (!CheckDrm(env, drm)) {
return NULL;
}
@@ -1070,6 +1083,10 @@
JNIEnv *env, jobject thiz, jbyteArray jkeysetId) {
sp<IDrm> drm = GetDrm(env, thiz);
+ if (!CheckDrm(env, drm)) {
+ return;
+ }
+
if (jkeysetId == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"keySetId is null");
@@ -1231,9 +1248,7 @@
JNIEnv *env, jobject thiz) {
sp<IDrm> drm = GetDrm(env, thiz);
- if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "MediaDrm obj is null");
+ if (!CheckDrm(env, drm)) {
return NULL;
}
@@ -1286,9 +1301,7 @@
JNIEnv *env, jobject thiz, jbyteArray ssid) {
sp<IDrm> drm = GetDrm(env, thiz);
- if (drm == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "MediaDrm obj is null");
+ if (!CheckDrm(env, drm)) {
return;
}
@@ -1437,6 +1450,65 @@
}
}
+static jobject android_media_MediaDrm_getOfflineLicenseKeySetIds(
+ JNIEnv *env, jobject thiz) {
+ sp<IDrm> drm = GetDrm(env, thiz);
+
+ if (!CheckDrm(env, drm)) {
+ return NULL;
+ }
+
+ List<Vector<uint8_t> > keySetIds;
+
+ status_t err = drm->getOfflineLicenseKeySetIds(keySetIds);
+
+ if (throwExceptionAsNecessary(env, err, "Failed to get offline key set Ids")) {
+ return NULL;
+ }
+
+ return ListOfVectorsToArrayListOfByteArray(env, keySetIds);
+}
+
+static void android_media_MediaDrm_removeOfflineLicense(
+ JNIEnv *env, jobject thiz, jbyteArray keySetId) {
+ sp<IDrm> drm = GetDrm(env, thiz);
+
+ if (!CheckDrm(env, drm)) {
+ return;
+ }
+
+ status_t err = drm->removeOfflineLicense(JByteArrayToVector(env, keySetId));
+
+ throwExceptionAsNecessary(env, err, "Failed to remove offline license");
+}
+
+static jint android_media_MediaDrm_getOfflineLicenseState(JNIEnv *env,
+ jobject thiz, jbyteArray jkeySetId) {
+ sp<IDrm> drm = GetDrm(env, thiz);
+
+ if (!CheckDrm(env, drm)) {
+ return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
+ }
+
+ Vector<uint8_t> keySetId(JByteArrayToVector(env, jkeySetId));
+
+ DrmPlugin::OfflineLicenseState state = DrmPlugin::kOfflineLicenseStateUnknown;
+
+ status_t err = drm->getOfflineLicenseState(keySetId, &state);
+
+ if (throwExceptionAsNecessary(env, err, "Failed to get offline license state")) {
+ return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
+ }
+
+ switch(state) {
+ case DrmPlugin::kOfflineLicenseStateUsable:
+ return gOfflineLicenseStates.kOfflineLicenseStateUsable;
+ case DrmPlugin::kOfflineLicenseStateInactive:
+ return gOfflineLicenseStates.kOfflineLicenseStateInactive;
+ default:
+ return gOfflineLicenseStates.kOfflineLicenseStateUnknown;
+ }
+}
static jstring android_media_MediaDrm_getPropertyString(
JNIEnv *env, jobject thiz, jstring jname) {
@@ -1718,9 +1790,8 @@
android_media_MediaDrm_native_getMetrics(JNIEnv *env, jobject thiz)
{
sp<IDrm> drm = GetDrm(env, thiz);
- if (drm == NULL ) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "MediaDrm obj is null");
+
+ if (!CheckDrm(env, drm)) {
return NULL;
}
@@ -1839,6 +1910,15 @@
{ "getSecurityLevel", "([B)I",
(void *)android_media_MediaDrm_getSecurityLevel },
+ { "removeOfflineLicense", "([B)V",
+ (void *)android_media_MediaDrm_removeOfflineLicense },
+
+ { "getOfflineLicenseKeySetIds", "()Ljava/util/List;",
+ (void *)android_media_MediaDrm_getOfflineLicenseKeySetIds },
+
+ { "getOfflineLicenseState", "([B)I",
+ (void *)android_media_MediaDrm_getOfflineLicenseState },
+
{ "getPropertyString", "(Ljava/lang/String;)Ljava/lang/String;",
(void *)android_media_MediaDrm_getPropertyString },
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index f6c74e5..0769e5c 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -598,20 +598,6 @@
process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
}
-static jboolean
-android_media_MediaPlayer2_isPlaying(JNIEnv *env, jobject thiz)
-{
- sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
- if (mp == NULL ) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
- return JNI_FALSE;
- }
- const jboolean is_playing = mp->isPlaying();
-
- ALOGV("isPlaying: %d", is_playing);
- return is_playing;
-}
-
static void
android_media_MediaPlayer2_setPlaybackParams(JNIEnv *env, jobject thiz, jobject params)
{
@@ -1279,22 +1265,22 @@
/////////////////////////////////////////////////////////////////////////////////////
// AudioRouting begin
-static jboolean android_media_MediaPlayer2_setOutputDevice(JNIEnv *env, jobject thiz, jint device_id)
+static jboolean android_media_MediaPlayer2_setPreferredDevice(JNIEnv *env, jobject thiz, jobject device)
{
sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
if (mp == NULL) {
return false;
}
- return mp->setOutputDevice(device_id) == NO_ERROR;
+ return mp->setPreferredDevice(device) == NO_ERROR;
}
-static jint android_media_MediaPlayer2_getRoutedDeviceId(JNIEnv *env, jobject thiz)
+static jobject android_media_MediaPlayer2_getRoutedDevice(JNIEnv *env, jobject thiz)
{
sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
if (mp == NULL) {
- return AUDIO_PORT_HANDLE_NONE;
+ return nullptr;
}
- return mp->getRoutedDeviceId();
+ return mp->getRoutedDevice();
}
static void android_media_MediaPlayer2_addDeviceCallback(
@@ -1420,7 +1406,6 @@
{"getSyncParams", "()Landroid/media/SyncParams;", (void *)android_media_MediaPlayer2_getSyncParams},
{"_seekTo", "(JI)V", (void *)android_media_MediaPlayer2_seekTo},
{"_pause", "()V", (void *)android_media_MediaPlayer2_pause},
- {"isPlaying", "()Z", (void *)android_media_MediaPlayer2_isPlaying},
{"getCurrentPosition", "()J", (void *)android_media_MediaPlayer2_getCurrentPosition},
{"getDuration", "()J", (void *)android_media_MediaPlayer2_getDuration},
{"_release", "()V", (void *)android_media_MediaPlayer2_release},
@@ -1443,8 +1428,8 @@
{ "_releaseDrm", "()V", (void *)android_media_MediaPlayer2_releaseDrm },
// AudioRouting
- {"native_setOutputDevice", "(I)Z", (void *)android_media_MediaPlayer2_setOutputDevice},
- {"native_getRoutedDeviceId", "()I", (void *)android_media_MediaPlayer2_getRoutedDeviceId},
+ {"native_setPreferredDevice", "(Landroid/media/AudioDeviceInfo;)Z", (void *)android_media_MediaPlayer2_setPreferredDevice},
+ {"getRoutedDevice", "()Landroid/media/AudioDeviceInfo;", (void *)android_media_MediaPlayer2_getRoutedDevice},
{"native_addDeviceCallback", "(Landroid/media/RoutingDelegate;)V", (void *)android_media_MediaPlayer2_addDeviceCallback},
{"native_removeDeviceCallback", "(Landroid/media/AudioRouting$OnRoutingChangedListener;)V",
(void *)android_media_MediaPlayer2_removeDeviceCallback},
diff --git a/native/android/Android.bp b/native/android/Android.bp
index a4306fe..5cfb09b 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -81,6 +81,8 @@
export_static_lib_headers: ["libarect"],
include_dirs: ["bionic/libc/dns/include"],
+
+ version_script: "libandroid.map.txt",
}
// Network library.
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index d45dc1c..e27fed5 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -41,7 +41,7 @@
<string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este utilizador não pode instalar aplicações desconhecidas."</string>
<string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este utilizador não tem autorização para instalar aplicações."</string>
<string name="ok" msgid="7871959885003339302">"OK"</string>
- <string name="manage_applications" msgid="5400164782453975580">"Gerir aplic."</string>
+ <string name="manage_applications" msgid="5400164782453975580">"Gerir app"</string>
<string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
<string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>. Liberte algum espaço e tente novamente."</string>
<string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplicação não encontrada"</string>
@@ -70,7 +70,7 @@
<string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Não é possível desinstalar a aplicação de administração de dispositivos ativa para <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
<string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Esta aplicação é necessária para alguns utilizadores ou perfis e foi desinstalada para outros."</string>
<string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"O perfil necessita desta aplicação e não é possível desinstalá-la."</string>
- <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Esta aplic. é exigida pelo administrador do disp. e não pode ser desinstalada."</string>
+ <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Esta app é exigida pelo administrador do disp. e não pode ser desinstalada."</string>
<string name="manage_device_administrators" msgid="3092696419363842816">"Gerir aplicações de administração de dispositivos"</string>
<string name="manage_users" msgid="1243995386982560813">"Gerir utilizadores"</string>
<string name="uninstall_failed_msg" msgid="2176744834786696012">"Não foi possível desinstalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
index 9c29ff2..5f0322f 100644
--- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
+++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml
@@ -86,7 +86,7 @@
<string name="failed_notification_title_template" msgid="2256217208186530973">"Greška štampača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"Štampač je blokirao <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="cancel" msgid="4373674107267141885">"Otkaži"</string>
- <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
+ <string name="restart" msgid="2472034227037808749">"Restartuj"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze sa štampačem"</string>
<string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Želite li da koristite <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
index cb23c3c..c2f99d9 100644
--- a/packages/PrintSpooler/res/values-sr/strings.xml
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -86,7 +86,7 @@
<string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="blocked_notification_title_template" msgid="1175435827331588646">"Штампач је блокирао <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
<string name="cancel" msgid="4373674107267141885">"Откажи"</string>
- <string name="restart" msgid="2472034227037808749">"Поново покрени"</string>
+ <string name="restart" msgid="2472034227037808749">"Рестартуј"</string>
<string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
<string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
<string name="print_service_security_warning_title" msgid="2160752291246775320">"Желите ли да користите <xliff:g id="SERVICE">%1$s</xliff:g>?"</string>
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 5161344..d1f140f 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -9,6 +9,7 @@
"androidx.preference_preference",
"androidx.appcompat_appcompat",
"androidx.lifecycle_lifecycle-runtime",
+ "androidx.mediarouter_mediarouter-nodeps",
"SettingsLibHelpUtils",
"SettingsLibRestrictedLockUtils",
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index e2a34f4..c9bcd65 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1130,4 +1130,10 @@
<!-- The notice header of Third-party licenses. not translatable -->
<string name="notice_header" translatable="false"></string>
+
+ <!-- UI debug setting: opt in to use updated graphics driver? [CHAR LIMIT=100] -->
+ <string name="updated_gfx_driver_dev_opt_in_app_summary">Opt in app to use updated graphcis driver in developement</string>
+
+ <!-- Name of the phone device [CHAR LIMIT=NONE] -->
+ <string name="media_transfer_phone_device_name">Phone speaker</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index b4e82e9..d6c6491 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -892,7 +892,7 @@
if (batteryLevelPercentageString != null) {
//device is in phone call
if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) {
- if (mIsActiveDeviceHeadset) {
+ if (mIsActiveDeviceHearingAid || mIsActiveDeviceHeadset) {
stringRes = R.string.bluetooth_active_battery_level;
} else {
stringRes = R.string.bluetooth_battery_level;
@@ -908,7 +908,7 @@
} else {
//no battery information
if (com.android.settingslib.Utils.isAudioModeOngoingCall(mContext)) {
- if (mIsActiveDeviceHeadset) {
+ if (mIsActiveDeviceHearingAid || mIsActiveDeviceHeadset) {
stringRes = R.string.bluetooth_active_no_battery_level;
}
} else {
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
index 027ca09..1aeb075 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.metrics.LogMaker;
+import android.text.TextUtils;
import android.util.Pair;
import com.android.internal.logging.MetricsLogger;
@@ -28,8 +29,7 @@
*/
public class EventLogWriter implements LogWriter {
- private final MetricsLogger mMetricsLogger = new MetricsLogger();
-
+ @Override
public void visible(Context context, int source, int category) {
final LogMaker logMaker = new LogMaker(category)
.setType(MetricsProto.MetricsEvent.TYPE_OPEN)
@@ -37,53 +37,27 @@
MetricsLogger.action(logMaker);
}
+ @Override
public void hidden(Context context, int category) {
MetricsLogger.hidden(context, category);
}
- public void action(int category, int value, Pair<Integer, Object>... taggedData) {
- if (taggedData == null || taggedData.length == 0) {
- mMetricsLogger.action(category, value);
- } else {
- final LogMaker logMaker = new LogMaker(category)
- .setType(MetricsProto.MetricsEvent.TYPE_ACTION)
- .setSubtype(value);
- for (Pair<Integer, Object> pair : taggedData) {
- logMaker.addTaggedData(pair.first, pair.second);
- }
- mMetricsLogger.write(logMaker);
- }
- }
-
- public void action(int category, boolean value, Pair<Integer, Object>... taggedData) {
- action(category, value ? 1 : 0, taggedData);
- }
-
+ @Override
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
action(context, category, "", taggedData);
}
- public void actionWithSource(Context context, int source, int category) {
- final LogMaker logMaker = new LogMaker(category)
- .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
- if (source != MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
- logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, source);
- }
- MetricsLogger.action(logMaker);
- }
-
- /** @deprecated use {@link #action(int, int, Pair[])} */
- @Deprecated
+ @Override
public void action(Context context, int category, int value) {
MetricsLogger.action(context, category, value);
}
- /** @deprecated use {@link #action(int, boolean, Pair[])} */
- @Deprecated
+ @Override
public void action(Context context, int category, boolean value) {
MetricsLogger.action(context, category, value);
}
+ @Override
public void action(Context context, int category, String pkg,
Pair<Integer, Object>... taggedData) {
if (taggedData == null || taggedData.length == 0) {
@@ -99,7 +73,20 @@
}
}
- public void count(Context context, String name, int value) {
- MetricsLogger.count(context, name, value);
+ @Override
+ public void action(int attribution, int action, int pageId, String key, int value) {
+ final LogMaker logMaker = new LogMaker(action)
+ .setType(MetricsProto.MetricsEvent.TYPE_ACTION);
+ if (attribution != MetricsProto.MetricsEvent.VIEW_UNKNOWN) {
+ logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_CONTEXT, pageId);
+ }
+ if (!TextUtils.isEmpty(key)) {
+ logMaker.addTaggedData(MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_NAME,
+ key);
+ logMaker.addTaggedData(
+ MetricsProto.MetricsEvent.FIELD_SETTINGS_PREFERENCE_CHANGE_INT_VALUE,
+ value);
+ }
+ MetricsLogger.action(logMaker);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
index a16838c..b60364e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
@@ -34,16 +34,6 @@
void hidden(Context context, int category);
/**
- * Logs a user action.
- */
- void action(int category, int value, Pair<Integer, Object>... taggedData);
-
- /**
- * Logs a user action.
- */
- void action(int category, boolean value, Pair<Integer, Object>... taggedData);
-
- /**
* Logs an user action.
*/
void action(Context context, int category, Pair<Integer, Object>... taggedData);
@@ -51,22 +41,11 @@
/**
* Logs an user action.
*/
- void actionWithSource(Context context, int source, int category);
-
- /**
- * Logs an user action.
- *
- * @deprecated use {@link #action(int, int, Pair[])}
- */
- @Deprecated
void action(Context context, int category, int value);
/**
* Logs an user action.
- *
- * @deprecated use {@link #action(int, boolean, Pair[])}
*/
- @Deprecated
void action(Context context, int category, boolean value);
/**
@@ -75,13 +54,7 @@
void action(Context context, int category, String pkg, Pair<Integer, Object>... taggedData);
/**
- * Logs a count.
+ * Generically log action.
*/
- void count(Context context, String name, int value);
-
- /**
- * Generically log action into statsd.
- */
- default void action(int attribution, int action, int pageId, String key, int value) {
- }
+ void action(int attribution, int action, int pageId, String key, int value);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
index 69c267e..188204e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
@@ -15,6 +15,8 @@
*/
package com.android.settingslib.core.instrumentation;
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -30,6 +32,11 @@
* FeatureProvider for metrics.
*/
public class MetricsFeatureProvider {
+ /**
+ * The metrics category constant for logging source when a setting fragment is opened.
+ */
+ public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics";
+
protected List<LogWriter> mLoggerWriters;
public MetricsFeatureProvider() {
@@ -41,6 +48,25 @@
mLoggerWriters.add(new EventLogWriter());
}
+ /**
+ * Returns the attribution id for specified activity. If no attribution is set, returns {@link
+ * SettingsEnums#PAGE_UNKNOWN}.
+ *
+ * <p/> Attribution is a {@link SettingsEnums} page id that indicates where the specified
+ * activity is launched from.
+ */
+ public int getAttribution(Activity activity) {
+ if (activity == null) {
+ return SettingsEnums.PAGE_UNKNOWN;
+ }
+ final Intent intent = activity.getIntent();
+ if (intent == null) {
+ return SettingsEnums.PAGE_UNKNOWN;
+ }
+ return intent.getIntExtra(EXTRA_SOURCE_METRICS_CATEGORY,
+ SettingsEnums.PAGE_UNKNOWN);
+ }
+
public void visible(Context context, int source, int category) {
for (LogWriter writer : mLoggerWriters) {
writer.visible(context, source, category);
@@ -53,12 +79,6 @@
}
}
- public void actionWithSource(Context context, int source, int category) {
- for (LogWriter writer : mLoggerWriters) {
- writer.actionWithSource(context, source, category);
- }
- }
-
public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
for (LogWriter writer : mLoggerWriters) {
writer.action(context, category, taggedData);
@@ -68,6 +88,16 @@
/**
* Logs a generic Settings event.
*/
+ public void action(Context context, int category, String pkg,
+ Pair<Integer, Object>... taggedData) {
+ for (LogWriter writer : mLoggerWriters) {
+ writer.action(context, category, pkg, taggedData);
+ }
+ }
+
+ /**
+ * Logs a generic Settings event.
+ */
public void action(int attribution, int action, int pageId, String key, int value) {
for (LogWriter writer : mLoggerWriters) {
writer.action(attribution, action, pageId, key, value);
@@ -86,19 +116,6 @@
}
}
- public void action(Context context, int category, String pkg,
- Pair<Integer, Object>... taggedData) {
- for (LogWriter writer : mLoggerWriters) {
- writer.action(context, category, pkg, taggedData);
- }
- }
-
- public void count(Context context, String name, int value) {
- for (LogWriter writer : mLoggerWriters) {
- writer.count(context, name, value);
- }
- }
-
public int getMetricsCategory(Object object) {
if (object == null || !(object instanceof Instrumentable)) {
return MetricsEvent.VIEW_UNKNOWN;
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
index 06d7c4d..aed02a2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixin.java
@@ -41,11 +41,6 @@
private int mSourceMetricsCategory = MetricsProto.MetricsEvent.VIEW_UNKNOWN;
private long mVisibleTimestamp;
- /**
- * The metrics category constant for logging source when a setting fragment is opened.
- */
- public static final String EXTRA_SOURCE_METRICS_CATEGORY = ":settings:source_metrics";
-
private VisibilityLoggerMixin() {
mMetricsCategory = METRICS_CATEGORY_UNKNOWN;
}
@@ -82,7 +77,8 @@
if (intent == null) {
return;
}
- mSourceMetricsCategory = intent.getIntExtra(EXTRA_SOURCE_METRICS_CATEGORY,
+ mSourceMetricsCategory = intent.getIntExtra(
+ MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY,
MetricsProto.MetricsEvent.VIEW_UNKNOWN);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
new file mode 100644
index 0000000..e535348
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaDevice.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+/**
+ * BluetoothMediaDevice extends MediaDevice to represents Bluetooth device.
+ */
+public class BluetoothMediaDevice extends MediaDevice {
+
+ private static final String TAG = "BluetoothMediaDevice";
+
+ private CachedBluetoothDevice mCachedDevice;
+
+ BluetoothMediaDevice(Context context, CachedBluetoothDevice device) {
+ super(context, MediaDeviceType.TYPE_BLUETOOTH_DEVICE);
+ mCachedDevice = device;
+ }
+
+ @Override
+ public String getName() {
+ return mCachedDevice.getName();
+ }
+
+ @Override
+ public int getIcon() {
+ //TODO(b/117129183): This is not final icon for bluetooth device, just for demo.
+ return R.drawable.ic_bt_headphones_a2dp;
+ }
+
+ @Override
+ public String getId() {
+ return MediaDeviceUtils.getId(mCachedDevice);
+ }
+
+ @Override
+ public void connect() {
+ //TODO(b/117129183): add callback to notify LocalMediaManager connection state.
+ mIsConnected = mCachedDevice.setActive();
+ Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+ }
+
+ @Override
+ public void disconnect() {
+ //TODO(b/117129183): disconnected last select device
+ mIsConnected = false;
+ }
+
+ /**
+ * Get current CachedBluetoothDevice
+ */
+ public CachedBluetoothDevice getCachedDevice() {
+ return mCachedDevice;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
new file mode 100644
index 0000000..04188e9
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/BluetoothMediaManager.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.app.Notification;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * BluetoothMediaManager provide interface to get Bluetooth device list.
+ */
+public class BluetoothMediaManager extends MediaManager implements BluetoothCallback {
+
+ private static final String TAG = "BluetoothMediaManager";
+
+ private final DeviceAttributeChangeCallback mCachedDeviceCallback =
+ new DeviceAttributeChangeCallback();
+
+ private LocalBluetoothManager mLocalBluetoothManager;
+ private LocalBluetoothProfileManager mProfileManager;
+
+ private MediaDevice mLastAddedDevice;
+ private MediaDevice mLastRemovedDevice;
+
+ BluetoothMediaManager(Context context, LocalBluetoothManager localBluetoothManager,
+ Notification notification) {
+ super(context, notification);
+
+ mLocalBluetoothManager = localBluetoothManager;
+ mProfileManager = mLocalBluetoothManager.getProfileManager();
+ }
+
+ @Override
+ public void startScan() {
+ mMediaDevices.clear();
+ mLocalBluetoothManager.getEventManager().registerCallback(this);
+ buildBluetoothDeviceList();
+ dispatchDeviceListAdded();
+ }
+
+ private void buildBluetoothDeviceList() {
+ addConnectedA2dpDevices();
+ addConnectedHearingAidDevices();
+ }
+
+ private void addConnectedA2dpDevices() {
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile == null) {
+ Log.w(TAG, "addConnectedA2dpDevices() a2dp profile is null!");
+ return;
+ }
+ final List<BluetoothDevice> devices = a2dpProfile.getConnectedDevices();
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+ mLocalBluetoothManager.getCachedDeviceManager();
+
+ for (BluetoothDevice device : devices) {
+ final CachedBluetoothDevice cachedDevice =
+ cachedBluetoothDeviceManager.findDevice(device);
+
+ if (cachedDevice == null) {
+ Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
+ continue;
+ }
+
+ Log.d(TAG, "addConnectedA2dpDevices() device : " + cachedDevice.getName()
+ + ", is connected : " + cachedDevice.isConnected());
+
+ if (cachedDevice.isConnected()) {
+ addMediaDevice(cachedDevice);
+ }
+ }
+ }
+
+ private void addConnectedHearingAidDevices() {
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ if (hapProfile == null) {
+ Log.w(TAG, "addConnectedA2dpDevices() hap profile is null!");
+ return;
+ }
+ final List<Long> devicesHiSyncIds = new ArrayList<>();
+ final List<BluetoothDevice> devices = hapProfile.getConnectedDevices();
+ final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+ mLocalBluetoothManager.getCachedDeviceManager();
+
+ for (BluetoothDevice device : devices) {
+ final CachedBluetoothDevice cachedDevice =
+ cachedBluetoothDeviceManager.findDevice(device);
+
+ if (cachedDevice == null) {
+ Log.w(TAG, "Can't found CachedBluetoothDevice : " + device.getName());
+ continue;
+ }
+
+ Log.d(TAG, "addConnectedHearingAidDevices() device : " + cachedDevice.getName()
+ + ", is connected : " + cachedDevice.isConnected());
+ final long hiSyncId = hapProfile.getHiSyncId(device);
+
+ // device with same hiSyncId should not be shown in the UI.
+ // So do not add it into connectedDevices.
+ if (!devicesHiSyncIds.contains(hiSyncId) && cachedDevice.isConnected()) {
+ devicesHiSyncIds.add(hiSyncId);
+ addMediaDevice(cachedDevice);
+ }
+ }
+ }
+
+ private void addMediaDevice(CachedBluetoothDevice cachedDevice) {
+ MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
+ if (mediaDevice == null) {
+ mediaDevice = new BluetoothMediaDevice(mContext, cachedDevice);
+ cachedDevice.registerCallback(mCachedDeviceCallback);
+ mLastAddedDevice = mediaDevice;
+ mMediaDevices.add(mediaDevice);
+ }
+ }
+
+ @Override
+ public void stopScan() {
+ mLocalBluetoothManager.getEventManager().unregisterCallback(this);
+ unregisterCachedDeviceCallback();
+ }
+
+ private void unregisterCachedDeviceCallback() {
+ for (MediaDevice device : mMediaDevices) {
+ if (device instanceof BluetoothMediaDevice) {
+ ((BluetoothMediaDevice) device).getCachedDevice()
+ .unregisterCallback(mCachedDeviceCallback);
+ }
+ }
+ }
+
+ @Override
+ public void onBluetoothStateChanged(int bluetoothState) {
+ if (BluetoothAdapter.STATE_ON == bluetoothState) {
+ buildBluetoothDeviceList();
+ dispatchDeviceListAdded();
+ } else if (BluetoothAdapter.STATE_OFF == bluetoothState) {
+ final List<MediaDevice> removeDevicesList = new ArrayList<>();
+ for (MediaDevice device : mMediaDevices) {
+ if (device instanceof BluetoothMediaDevice) {
+ ((BluetoothMediaDevice) device).getCachedDevice()
+ .unregisterCallback(mCachedDeviceCallback);
+ removeDevicesList.add(device);
+ }
+ }
+ mMediaDevices.removeAll(removeDevicesList);
+ dispatchDeviceListRemoved(removeDevicesList);
+ }
+ }
+
+ @Override
+ public void onDeviceAdded(CachedBluetoothDevice cachedDevice) {
+ if (isCachedDeviceConnected(cachedDevice)) {
+ addMediaDevice(cachedDevice);
+ dispatchDeviceAdded(cachedDevice);
+ }
+ }
+
+ private boolean isCachedDeviceConnected(CachedBluetoothDevice cachedDevice) {
+ final boolean isConnectedHearingAidDevice = cachedDevice.isConnectedHearingAidDevice();
+ final boolean isConnectedA2dpDevice = cachedDevice.isConnectedA2dpDevice();
+ Log.d(TAG, "isCachedDeviceConnected() cachedDevice : " + cachedDevice.getName()
+ + ", is hearing aid connected : " + isConnectedHearingAidDevice
+ + ", is a2dp connected : " + isConnectedA2dpDevice);
+
+ return isConnectedHearingAidDevice || isConnectedA2dpDevice;
+ }
+
+ private void dispatchDeviceAdded(CachedBluetoothDevice cachedDevice) {
+ if (mLastAddedDevice != null
+ && MediaDeviceUtils.getId(cachedDevice) == mLastAddedDevice.getId()) {
+ dispatchDeviceAdded(mLastAddedDevice);
+ }
+ }
+
+ @Override
+ public void onDeviceDeleted(CachedBluetoothDevice cachedDevice) {
+ if (!isCachedDeviceConnected(cachedDevice)) {
+ removeMediaDevice(cachedDevice);
+ dispatchDeviceRemoved(cachedDevice);
+ }
+ }
+
+ private void removeMediaDevice(CachedBluetoothDevice cachedDevice) {
+ final MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(cachedDevice));
+ if (mediaDevice != null) {
+ cachedDevice.unregisterCallback(mCachedDeviceCallback);
+ mLastRemovedDevice = mediaDevice;
+ mMediaDevices.remove(mediaDevice);
+ }
+ }
+
+ void dispatchDeviceRemoved(CachedBluetoothDevice cachedDevice) {
+ if (mLastRemovedDevice != null
+ && MediaDeviceUtils.getId(cachedDevice) == mLastRemovedDevice.getId()) {
+ dispatchDeviceRemoved(mLastRemovedDevice);
+ }
+ }
+
+ @Override
+ public void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state,
+ int bluetoothProfile) {
+ Log.d(TAG, "onProfileConnectionStateChanged() device: " + cachedDevice.getName()
+ + ", state: " + state + ", bluetoothProfile: " + bluetoothProfile);
+
+ if (isCachedDeviceConnected(cachedDevice)) {
+ addMediaDevice(cachedDevice);
+ dispatchDeviceAdded(cachedDevice);
+ } else {
+ removeMediaDevice(cachedDevice);
+ dispatchDeviceRemoved(cachedDevice);
+ }
+ }
+
+ @Override
+ public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
+ Log.d(TAG, "onAclConnectionStateChanged() device: " + cachedDevice.getName()
+ + ", state: " + state);
+
+ if (isCachedDeviceConnected(cachedDevice)) {
+ addMediaDevice(cachedDevice);
+ dispatchDeviceAdded(cachedDevice);
+ } else {
+ removeMediaDevice(cachedDevice);
+ dispatchDeviceRemoved(cachedDevice);
+ }
+ }
+
+ class DeviceAttributeChangeCallback implements CachedBluetoothDevice.Callback {
+ @Override
+ public void onDeviceAttributesChanged() {
+ dispatchDeviceAttributesChanged();
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
new file mode 100644
index 0000000..498a0fc
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaDevice.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+
+import androidx.mediarouter.media.MediaRouter;
+
+import com.android.settingslib.R;
+
+/**
+ * InfoMediaDevice extends MediaDevice to represents wifi device.
+ */
+public class InfoMediaDevice extends MediaDevice {
+
+ private static final String TAG = "InfoMediaDevice";
+
+ private MediaRouter.RouteInfo mRouteInfo;
+
+ InfoMediaDevice(Context context, MediaRouter.RouteInfo info) {
+ super(context, MediaDeviceType.TYPE_CAST_DEVICE);
+ mRouteInfo = info;
+ }
+
+ @Override
+ public String getName() {
+ return mRouteInfo.getName();
+ }
+
+ @Override
+ public int getIcon() {
+ //TODO(b/117129183): This is not final icon for cast device, just for demo.
+ return R.drawable.ic_settings_print;
+ }
+
+ @Override
+ public String getId() {
+ return MediaDeviceUtils.getId(mRouteInfo);
+ }
+
+ @Override
+ public void connect() {
+ //TODO(b/117129183): use MediaController2 to transfer media
+ mIsConnected = true;
+ }
+
+ @Override
+ public void disconnect() {
+ //TODO(b/117129183): disconnected last select device
+ mIsConnected = false;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
new file mode 100644
index 0000000..6907238
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/InfoMediaManager.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.app.Notification;
+import android.content.Context;
+import android.util.Log;
+
+import androidx.mediarouter.media.MediaRouteSelector;
+import androidx.mediarouter.media.MediaRouter;
+
+/**
+ * InfoMediaManager provide interface to get InfoMediaDevice list.
+ */
+public class InfoMediaManager extends MediaManager {
+
+ private static final String TAG = "InfoMediaManager";
+
+ private final MediaRouterCallback mMediaRouterCallback = new MediaRouterCallback();
+
+ private MediaRouter mMediaRouter;
+ private String mPackageName;
+
+ InfoMediaManager(Context context, String packageName, Notification notification) {
+ super(context, notification);
+
+ mMediaRouter = MediaRouter.getInstance(context);
+ mPackageName = packageName;
+ }
+
+ @Override
+ public void startScan() {
+ mMediaDevices.clear();
+ startScanCastDevice();
+ }
+
+ private void startScanCastDevice() {
+ final MediaRouteSelector selector = new MediaRouteSelector.Builder()
+ .addControlCategory(getControlCategoryByPackageName(mPackageName))
+ .build();
+
+ mMediaRouter.addCallback(selector, mMediaRouterCallback,
+ MediaRouter.CALLBACK_FLAG_REQUEST_DISCOVERY);
+ }
+
+ private String getControlCategoryByPackageName(String packageName) {
+ //TODO(b/117129183): Use package name to get ControlCategory.
+ //Since api not ready, return fixed ControlCategory for prototype.
+ return "com.google.android.gms.cast.CATEGORY_CAST/4F8B3483";
+ }
+
+ @Override
+ public void stopScan() {
+ mMediaRouter.removeCallback(mMediaRouterCallback);
+ }
+
+ class MediaRouterCallback extends MediaRouter.Callback {
+ @Override
+ public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo route) {
+ MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(route));
+ if (mediaDevice == null) {
+ mediaDevice = new InfoMediaDevice(mContext, route);
+ Log.d(TAG, "onRouteAdded() route : " + route.getName());
+ mMediaDevices.add(mediaDevice);
+ dispatchDeviceAdded(mediaDevice);
+ }
+ }
+
+ @Override
+ public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo route) {
+ final MediaDevice mediaDevice = findMediaDevice(MediaDeviceUtils.getId(route));
+ if (mediaDevice != null) {
+ Log.d(TAG, "onRouteRemoved() route : " + route.getName());
+ mMediaDevices.remove(mediaDevice);
+ dispatchDeviceRemoved(mediaDevice);
+ }
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
new file mode 100644
index 0000000..e375ea0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.app.Notification;
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.IntDef;
+
+import com.android.settingslib.bluetooth.BluetoothCallback;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * LocalMediaManager provide interface to get MediaDevice list and transfer media to MediaDevice.
+ */
+public class LocalMediaManager implements BluetoothCallback {
+
+ private static final String TAG = "LocalMediaManager";
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({MediaDeviceState.STATE_CONNECTED,
+ MediaDeviceState.STATE_CONNECTING,
+ MediaDeviceState.STATE_DISCONNECTED})
+ public @interface MediaDeviceState {
+ int STATE_CONNECTED = 1;
+ int STATE_CONNECTING = 2;
+ int STATE_DISCONNECTED = 3;
+ }
+
+ private final Collection<DeviceCallback> mCallbacks = new ArrayList<>();
+ private final MediaDeviceCallback mMediaDeviceCallback = new MediaDeviceCallback();
+
+ private Context mContext;
+ private List<MediaDevice> mMediaDevices = new ArrayList<>();
+ private BluetoothMediaManager mBluetoothMediaManager;
+ private InfoMediaManager mInfoMediaManager;
+
+ private LocalBluetoothManager mLocalBluetoothManager;
+ private MediaDevice mLastConnectedDevice;
+ private MediaDevice mPhoneDevice;
+
+ /**
+ * Register to start receiving callbacks for MediaDevice events.
+ */
+ public void registerCallback(DeviceCallback callback) {
+ synchronized (mCallbacks) {
+ mCallbacks.add(callback);
+ }
+ }
+
+ /**
+ * Unregister to stop receiving callbacks for MediaDevice events
+ */
+ public void unregisterCallback(DeviceCallback callback) {
+ synchronized (mCallbacks) {
+ mCallbacks.remove(callback);
+ }
+ }
+
+ public LocalMediaManager(Context context, String packageName, Notification notification) {
+ mContext = context;
+ mLocalBluetoothManager =
+ LocalBluetoothManager.getInstance(context, /* onInitCallback= */ null);
+ if (mLocalBluetoothManager == null) {
+ Log.e(TAG, "Bluetooth is not supported on this device");
+ return;
+ }
+
+ mBluetoothMediaManager =
+ new BluetoothMediaManager(context, mLocalBluetoothManager, notification);
+ mInfoMediaManager = new InfoMediaManager(context, packageName, notification);
+ }
+
+ /**
+ * Connect the MediaDevice to transfer media
+ * @param connectDevice the MediaDevice
+ */
+ public void connectDevice(MediaDevice connectDevice) {
+ if (connectDevice == mLastConnectedDevice) {
+ return;
+ }
+
+ if (mLastConnectedDevice != null) {
+ mLastConnectedDevice.disconnect();
+ }
+
+ connectDevice.connect();
+ if (connectDevice.isConnected()) {
+ mLastConnectedDevice = connectDevice;
+ }
+
+ final int state = connectDevice.isConnected()
+ ? MediaDeviceState.STATE_CONNECTED
+ : MediaDeviceState.STATE_DISCONNECTED;
+ dispatchSelectedDeviceStateChanged(connectDevice, state);
+ }
+
+ void dispatchSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state) {
+ synchronized (mCallbacks) {
+ for (DeviceCallback callback : mCallbacks) {
+ callback.onSelectedDeviceStateChanged(device, state);
+ }
+ }
+ }
+
+ /**
+ * Start scan connected MediaDevice
+ */
+ public void startScan() {
+ mMediaDevices.clear();
+ mBluetoothMediaManager.registerCallback(mMediaDeviceCallback);
+ mInfoMediaManager.registerCallback(mMediaDeviceCallback);
+ mBluetoothMediaManager.startScan();
+ mInfoMediaManager.startScan();
+ }
+
+ private void addPhoneDeviceIfNecessary() {
+ // add phone device to list if there have any Bluetooth device and cast device.
+ if (mMediaDevices.size() > 0 && !mMediaDevices.contains(mPhoneDevice)) {
+ if (mPhoneDevice == null) {
+ mPhoneDevice = new PhoneMediaDevice(mContext, mLocalBluetoothManager);
+ }
+ mMediaDevices.add(mPhoneDevice);
+ }
+ }
+
+ private void removePhoneMediaDeviceIfNecessary() {
+ // if PhoneMediaDevice is the last item in the list, remove it.
+ if (mMediaDevices.size() == 1 && mMediaDevices.contains(mPhoneDevice)) {
+ mMediaDevices.clear();
+ }
+ }
+
+ void dispatchDeviceListUpdate() {
+ synchronized (mCallbacks) {
+ for (DeviceCallback callback : mCallbacks) {
+ callback.onDeviceListUpdate(new ArrayList<>(mMediaDevices));
+ }
+ }
+ }
+
+ /**
+ * Stop scan MediaDevice
+ */
+ public void stopScan() {
+ mBluetoothMediaManager.unregisterCallback(mMediaDeviceCallback);
+ mInfoMediaManager.unregisterCallback(mMediaDeviceCallback);
+ mBluetoothMediaManager.stopScan();
+ mInfoMediaManager.stopScan();
+ }
+
+ class MediaDeviceCallback implements MediaManager.MediaDeviceCallback {
+ @Override
+ public void onDeviceAdded(MediaDevice device) {
+ if (!mMediaDevices.contains(device)) {
+ mMediaDevices.add(device);
+ addPhoneDeviceIfNecessary();
+ dispatchDeviceListUpdate();
+ }
+ }
+
+ @Override
+ public void onDeviceListAdded(List<MediaDevice> devices) {
+ mMediaDevices.addAll(devices);
+ addPhoneDeviceIfNecessary();
+ dispatchDeviceListUpdate();
+ }
+
+ @Override
+ public void onDeviceRemoved(MediaDevice device) {
+ if (mMediaDevices.contains(device)) {
+ mMediaDevices.remove(device);
+ removePhoneMediaDeviceIfNecessary();
+ dispatchDeviceListUpdate();
+ }
+ }
+
+ @Override
+ public void onDeviceListRemoved(List<MediaDevice> devices) {
+ mMediaDevices.removeAll(devices);
+ removePhoneMediaDeviceIfNecessary();
+ dispatchDeviceListUpdate();
+ }
+
+ @Override
+ public void onDeviceAttributesChanged() {
+ dispatchDeviceListUpdate();
+ }
+ }
+
+
+ /**
+ * Callback for notifying device information updating
+ */
+ public interface DeviceCallback {
+ /**
+ * Callback for notifying device list updated.
+ *
+ * @param devices MediaDevice list
+ */
+ void onDeviceListUpdate(List<MediaDevice> devices);
+
+ /**
+ * Callback for notifying the connected device is changed.
+ *
+ * @param device the changed connected MediaDevice
+ * @param state the current MediaDevice state, the possible values are:
+ * {@link MediaDeviceState#STATE_CONNECTED},
+ * {@link MediaDeviceState#STATE_CONNECTING},
+ * {@link MediaDeviceState#STATE_DISCONNECTED}
+ */
+ void onSelectedDeviceStateChanged(MediaDevice device, @MediaDeviceState int state);
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
new file mode 100644
index 0000000..6c536f0
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDevice.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * MediaDevice represents a media device(such like Bluetooth device, cast device and phone device).
+ */
+public abstract class MediaDevice {
+
+ private static final String TAG = "MediaDevice";
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({MediaDeviceType.TYPE_BLUETOOTH_DEVICE,
+ MediaDeviceType.TYPE_CAST_DEVICE,
+ MediaDeviceType.TYPE_PHONE_DEVICE})
+ public @interface MediaDeviceType {
+ int TYPE_BLUETOOTH_DEVICE = 1;
+ int TYPE_CAST_DEVICE = 2;
+ int TYPE_PHONE_DEVICE = 3;
+ }
+
+ protected boolean mIsConnected = false;
+ protected Context mContext;
+ protected int mType;
+
+ MediaDevice(Context context, @MediaDeviceType int type) {
+ mType = type;
+ mContext = context;
+ }
+
+ /**
+ * Check the MediaDevice is be connected to transfer.
+ *
+ * @return true if the MediaDevice is be connected to transfer, false otherwise.
+ */
+ protected boolean isConnected() {
+ return mIsConnected;
+ }
+
+ /**
+ * Get name from MediaDevice.
+ *
+ * @return name of MediaDevice.
+ */
+ public abstract String getName();
+
+ /**
+ * Get resource id of MediaDevice.
+ *
+ * @return resource id of MediaDevice.
+ */
+ public abstract int getIcon();
+
+ /**
+ * Get unique ID that represent MediaDevice
+ * @return unique id of MediaDevice
+ */
+ public abstract String getId();
+
+ /**
+ * Transfer MediaDevice for media
+ */
+ public abstract void connect();
+
+ /**
+ * Stop transfer MediaDevice
+ */
+ public abstract void disconnect();
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
new file mode 100644
index 0000000..060e9ad
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import androidx.mediarouter.media.MediaRouter;
+
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+
+/**
+ * MediaDeviceUtils provides utility function for MediaDevice
+ */
+public class MediaDeviceUtils {
+
+ /**
+ * Use CachedBluetoothDevice address to represent unique id
+ *
+ * @param cachedDevice the CachedBluetoothDevice
+ * @return CachedBluetoothDevice address
+ */
+ public static String getId(CachedBluetoothDevice cachedDevice) {
+ return cachedDevice.getAddress();
+ }
+
+ /**
+ * Use RouteInfo id to represent unique id
+ *
+ * @param route the RouteInfo
+ * @return RouteInfo id
+ */
+ public static String getId(MediaRouter.RouteInfo route) {
+ return route.getId();
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
new file mode 100644
index 0000000..72b6b09
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaManager.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.app.Notification;
+import android.content.Context;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * MediaManager provide interface to get MediaDevice list.
+ */
+public abstract class MediaManager {
+
+ private static final String TAG = "MediaManager";
+
+ protected final Collection<MediaDeviceCallback> mCallbacks = new ArrayList<>();
+ protected final List<MediaDevice> mMediaDevices = new ArrayList<>();
+
+ protected Context mContext;
+ protected Notification mNotification;
+
+ MediaManager(Context context, Notification notification) {
+ mContext = context;
+ mNotification = notification;
+ }
+
+ protected void registerCallback(MediaDeviceCallback callback) {
+ synchronized (mCallbacks) {
+ if (!mCallbacks.contains(callback)) {
+ mCallbacks.add(callback);
+ }
+ }
+ }
+
+ protected void unregisterCallback(MediaDeviceCallback callback) {
+ synchronized (mCallbacks) {
+ if (mCallbacks.contains(callback)) {
+ mCallbacks.remove(callback);
+ }
+ }
+ }
+
+ /**
+ * Start scan connected MediaDevice
+ */
+ public abstract void startScan();
+
+ /**
+ * Stop scan MediaDevice
+ */
+ public abstract void stopScan();
+
+ protected MediaDevice findMediaDevice(String id) {
+ for (MediaDevice mediaDevice : mMediaDevices) {
+ if (mediaDevice.getId().equals(id)) {
+ return mediaDevice;
+ }
+ }
+ Log.e(TAG, "findMediaDevice() can't found device");
+ return null;
+ }
+
+ protected void dispatchDeviceAdded(MediaDevice mediaDevice) {
+ synchronized (mCallbacks) {
+ for (MediaDeviceCallback callback : mCallbacks) {
+ callback.onDeviceAdded(mediaDevice);
+ }
+ }
+ }
+
+ protected void dispatchDeviceRemoved(MediaDevice mediaDevice) {
+ synchronized (mCallbacks) {
+ for (MediaDeviceCallback callback : mCallbacks) {
+ callback.onDeviceRemoved(mediaDevice);
+ }
+ }
+ }
+
+ protected void dispatchDeviceListAdded() {
+ synchronized (mCallbacks) {
+ for (MediaDeviceCallback callback : mCallbacks) {
+ callback.onDeviceListAdded(mMediaDevices);
+ }
+ }
+ }
+
+ protected void dispatchDeviceListRemoved(List<MediaDevice> devices) {
+ synchronized (mCallbacks) {
+ for (MediaDeviceCallback callback : mCallbacks) {
+ callback.onDeviceListRemoved(devices);
+ }
+ }
+ }
+
+ protected void dispatchDeviceAttributesChanged() {
+ synchronized (mCallbacks) {
+ for (MediaDeviceCallback callback : mCallbacks) {
+ callback.onDeviceAttributesChanged();
+ }
+ }
+ }
+
+ /**
+ * Callback for notifying device is added, removed and attributes changed.
+ */
+ public interface MediaDeviceCallback {
+ /**
+ * Callback for notifying MediaDevice is added.
+ *
+ * @param device the MediaDevice
+ */
+ void onDeviceAdded(MediaDevice device);
+
+ /**
+ * Callback for notifying MediaDevice list is added.
+ *
+ * @param devices the MediaDevice list
+ */
+ void onDeviceListAdded(List<MediaDevice> devices);
+
+ /**
+ * Callback for notifying MediaDevice is removed.
+ *
+ * @param device the MediaDevice
+ */
+ void onDeviceRemoved(MediaDevice device);
+
+ /**
+ * Callback for notifying MediaDevice list is removed.
+ *
+ * @param devices the MediaDevice list
+ */
+ void onDeviceListRemoved(List<MediaDevice> devices);
+
+ /**
+ * Callback for notifying MediaDevice attributes is changed.
+ */
+ void onDeviceAttributesChanged();
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
new file mode 100644
index 0000000..5e49d6b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/media/PhoneMediaDevice.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018 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.settingslib.media;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.settingslib.R;
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.HearingAidProfile;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+
+/**
+ * PhoneMediaDevice extends MediaDevice to represents Phone device.
+ */
+public class PhoneMediaDevice extends MediaDevice {
+
+ private static final String TAG = "PhoneMediaDevice";
+
+ public static final String ID = "phone_media_device_id_1";
+
+ private LocalBluetoothProfileManager mProfileManager;
+ private LocalBluetoothManager mLocalBluetoothManager;
+
+ PhoneMediaDevice(Context context, LocalBluetoothManager localBluetoothManager) {
+ super(context, MediaDeviceType.TYPE_PHONE_DEVICE);
+
+ mLocalBluetoothManager = localBluetoothManager;
+ mProfileManager = mLocalBluetoothManager.getProfileManager();
+ }
+
+ @Override
+ public String getName() {
+ return mContext
+ .getString(com.android.settingslib.R.string.media_transfer_phone_device_name);
+ }
+
+ @Override
+ public int getIcon() {
+ //TODO(b/117129183): This is not final icon for phone device, just for demo.
+ return R.drawable.ic_bt_cellphone;
+ }
+
+ @Override
+ public String getId() {
+ return ID;
+ }
+
+ @Override
+ public void connect() {
+ final HearingAidProfile hapProfile = mProfileManager.getHearingAidProfile();
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+
+ if (hapProfile != null && a2dpProfile != null) {
+ mIsConnected =
+ hapProfile.setActiveDevice(null) && a2dpProfile.setActiveDevice(null);
+ }
+ Log.d(TAG, "connect() device : " + getName() + ", is selected : " + mIsConnected);
+ }
+
+ @Override
+ public void disconnect() {
+ //TODO(b/117129183): disconnected last select device
+ mIsConnected = false;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 523361d..22d5d83 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -158,11 +158,11 @@
* These values are matched in string arrays -- changes must be kept in sync
*/
public static final int SECURITY_NONE = 0;
- public static final int SECURITY_OWE = 1;
- public static final int SECURITY_WEP = 2;
- public static final int SECURITY_PSK = 3;
- public static final int SECURITY_SAE = 4;
- public static final int SECURITY_EAP = 5;
+ public static final int SECURITY_WEP = 1;
+ public static final int SECURITY_PSK = 2;
+ public static final int SECURITY_EAP = 3;
+ public static final int SECURITY_OWE = 4;
+ public static final int SECURITY_SAE = 5;
public static final int SECURITY_EAP_SUITE_B = 6;
private static final int PSK_UNKNOWN = 0;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 7f9a5af..41aadd6 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -234,6 +234,37 @@
}
@Test
+ public void getConnectionSummary_testHearingAidInCall_active() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active}
+ // 2. Audio Manager: In Call
+ // 3. Battery Level: Unknown
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
+
+ // Act & Assert:
+ // Get "Active" result without Battery Level.
+ assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active");
+ }
+
+ @Test
+ public void getConnectionSummary_testHearingAidInCall_activeBattery10() {
+ // Arrange:
+ // 1. Profile: {HEARING_AID, Connected, Active}
+ // 2. Audio Manager: In Call
+ // 3. Battery Level: 10
+ updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.HEARING_AID);
+ mShadowAudioManager.setMode(AudioManager.MODE_IN_CALL);
+ mBatteryLevel = 10;
+
+ // Act & Assert:
+ // Get "Active, 10% battery" result with Battery Level 10.
+ assertThat(mCachedDevice.getConnectionSummary()).isEqualTo("Active, 10% battery");
+ }
+
+ @Test
public void getConnectionSummary_testMultipleProfilesActiveDevice() {
// Test without battery level
// Set A2DP and HFP profiles to be connected and test connection state summary
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
index 7a7f0d4..603f838 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
@@ -15,11 +15,15 @@
*/
package com.android.settingslib.core.instrumentation;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
+import android.app.Activity;
+import android.app.settings.SettingsEnums;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -33,6 +37,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
@@ -90,4 +95,28 @@
anyString(),
eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
}
+
+ @Test
+ public void getAttribution_noActivity_shouldReturnUnknown() {
+ assertThat(mProvider.getAttribution(null /* activity */))
+ .isEqualTo(SettingsEnums.PAGE_UNKNOWN);
+ }
+
+ @Test
+ public void getAttribution_notSet_shouldReturnUnknown() {
+ final Activity activity = Robolectric.setupActivity(Activity.class);
+
+ assertThat(mProvider.getAttribution(activity))
+ .isEqualTo(SettingsEnums.PAGE_UNKNOWN);
+ }
+
+ @Test
+ public void getAttribution_set_shouldReturnAttribution() {
+ final Intent intent = new Intent()
+ .putExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, 100);
+
+ final Activity activity = Robolectric.buildActivity(Activity.class, intent).create().get();
+
+ assertThat(mProvider.getAttribution(activity)).isEqualTo(100);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
index f78573a..b251c09 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/VisibilityLoggerMixinTest.java
@@ -72,7 +72,7 @@
@Test
public void shouldLogVisibleWithSource() {
final Intent sourceIntent = new Intent()
- .putExtra(VisibilityLoggerMixin.EXTRA_SOURCE_METRICS_CATEGORY,
+ .putExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY,
MetricsProto.MetricsEvent.SETTINGS_GESTURES);
final Activity activity = mock(Activity.class);
when(activity.getIntent()).thenReturn(sourceIntent);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index ca0267c..448a963 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -481,6 +481,9 @@
dumpSetting(s, p,
Settings.Global.EMULATE_DISPLAY_CUTOUT,
GlobalSettingsProto.Development.EMULATE_DISPLAY_CUTOUT);
+ dumpSetting(s, p,
+ Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+ GlobalSettingsProto.Development.FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS);
p.end(developmentToken);
final long deviceToken = p.start(GlobalSettingsProto.DEVICE);
@@ -675,6 +678,9 @@
dumpSetting(s, p,
Settings.Global.GPU_DEBUG_LAYERS_GLES,
GlobalSettingsProto.Gpu.DEBUG_LAYERS_GLES);
+ dumpSetting(s, p,
+ Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP,
+ GlobalSettingsProto.Gpu.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP);
p.end(gpuToken);
final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
@@ -1642,12 +1648,6 @@
dumpSetting(s, p,
Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
SecureSettingsProto.Accessibility.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_NON_INTERACTIVE_UI_TIMEOUT_MS,
- SecureSettingsProto.Accessibility.NON_INTERACTIVE_UI_TIMEOUT_MS);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_INTERACTIVE_UI_TIMEOUT_MS,
- SecureSettingsProto.Accessibility.INTERACTIVE_UI_TIMEOUT_MS);
p.end(accessibilityToken);
dumpSetting(s, p,
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
new file mode 100644
index 0000000..75c0391
--- /dev/null
+++ b/packages/Shell/OWNERS
@@ -0,0 +1,10 @@
+svetoslavganov@google.com
+hackbod@google.com
+yamasani@google.com
+moltmann@google.com
+toddke@google.com
+jsharkey@google.com
+cbrubaker@google.com
+omakoto@google.com
+nandana@google.com
+felipeal@google.com
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b2bb883..8aced61 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -90,6 +90,7 @@
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
+ <uses-permission android:name="android.permission.START_ACTIVITY_AS_CALLER" />
<uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
<uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
@@ -568,6 +569,22 @@
</intent-filter>
</activity>
+ <activity android:name=".chooser.ChooserActivity"
+ android:theme="@*android:style/Theme.NoDisplay"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true"
+ android:documentLaunchMode="never"
+ android:relinquishTaskIdentity="true"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
+ android:process=":ui"
+ android:visibleToInstantApps="true">
+ <intent-filter>
+ <action android:name="android.intent.action.CHOOSER_UI" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.VOICE" />
+ </intent-filter>
+ </activity>
+
<!-- Doze with notifications, run in main sysui process for every user -->
<service
android:name=".doze.DozeService"
diff --git a/packages/SystemUI/legacy/recents/res/values-as/strings.xml b/packages/SystemUI/legacy/recents/res/values-as/strings.xml
new file mode 100644
index 0000000..c742dab
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-as/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"অৱলোকন।"</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"শেহতীয়া-ৰ তালিকাৰ পৰা <xliff:g id="APP">%s</xliff:g>ক আঁতৰাওক।"</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"শেহতীয়া-ৰ তালিকাৰ পৰা <xliff:g id="APP">%s</xliff:g>ক আঁতৰোৱা হ’ল।"</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"শেহতীয়া-ৰ তালিকাৰ পৰা সকলো এপ্লিকেশ্বন আঁতৰোৱা হ’ল।"</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> এপ্লিকেশ্বনৰ তথ্য খোলক।"</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g>ক আৰম্ভ কৰা হৈছে।"</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"কোনো শেহতীয়া বস্তু নাই"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"আপুনি সকলো খালী কৰিলে"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"এপ্লিকেশ্বনৰ তথ্য"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"স্ক্ৰীণ পিনিং"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"সন্ধান কৰক"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g>ক আৰম্ভ কৰিব পৰা নগ’ল।"</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g>টো সুৰক্ষিত ম’ডত অক্ষম কৰা হ’ল।"</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"সকলো মচক"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"বিভাজিত স্ক্ৰীণ ব্যৱহাৰ কৰিবলৈ ইয়ালৈ টানি আনি এৰক"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"আনুভূমিকভাৱে বিভাজন কৰক"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"উলম্বভাৱে বিভাজন কৰক"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"কাষ্টম বিভাজন কৰক"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"স্ক্ৰীণখনক ওপৰফাললৈ ভাগ কৰক"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"স্ক্ৰীণখনক বাওঁফাললৈ ভাগ কৰক"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"স্ক্ৰীণখনক সোঁফাললৈ ভাগ কৰক"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-bn/strings.xml b/packages/SystemUI/legacy/recents/res/values-bn/strings.xml
new file mode 100644
index 0000000..b22672e
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-bn/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"এক নজরে।"</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> খারিজ করুন।"</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> খারিজ করা হয়েছে।"</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"সব সাম্প্রতিক অ্যাপ্লিকেশন খারিজ করা হয়েছে।"</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> অ্যাপ্লিকেশনের তথ্য খুলুন।"</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> শুরু করা হচ্ছে।"</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"কোনো সাম্প্রতিক আইটেম নেই"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"আপনি সবকিছু মুছে দিয়েছেন"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"অ্যাপ্লিকেশনের তথ্য"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"স্ক্রিন পিন করা"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"খুঁজুন"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> চালু করা যায়নি।"</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"নিরাপদ মোডে <xliff:g id="APP">%s</xliff:g> বন্ধ করা আছে।"</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"সবগুলি মুছে দিন"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"স্প্লিট স্ক্রিন ব্যবহার করতে এখানে টেনে আনুন"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"অনুভূমিক স্প্লিট করুন"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"উল্লম্ব স্প্লিট করুন"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"কাস্টম স্প্লিট করুন"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"স্ক্রিনটি উপরের দিকে স্প্লিট করুন"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"স্ক্রিনটি বাঁদিকে স্প্লিট করুন"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"স্ক্রিনটি ডানদিকে স্প্লিট করুন"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-es-rUS/strings.xml b/packages/SystemUI/legacy/recents/res/values-es-rUS/strings.xml
index 8bf3807..f212b02 100644
--- a/packages/SystemUI/legacy/recents/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-es-rUS/strings.xml
@@ -21,9 +21,9 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"Recientes"</string>
<string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"Permite descartar <xliff:g id="APP">%s</xliff:g>."</string>
- <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> descartada"</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"Se descartó <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"Se descartaron todas las aplicaciones recientes."</string>
- <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"Permite abrir la información de aplicación de <xliff:g id="APP">%s</xliff:g>."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"Permite abrir la información de la aplicación de <xliff:g id="APP">%s</xliff:g>."</string>
<string name="accessibility_recents_item_launched" msgid="4519918148638221791">"Iniciando <xliff:g id="APP">%s</xliff:g>"</string>
<string name="recents_empty_message" msgid="7967713254531861311">"No hay elementos recientes"</string>
<string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"Todo borrado"</string>
diff --git a/packages/SystemUI/legacy/recents/res/values-hi/strings.xml b/packages/SystemUI/legacy/recents/res/values-hi/strings.xml
index c9ac2a0..3f19f33 100644
--- a/packages/SystemUI/legacy/recents/res/values-hi/strings.xml
+++ b/packages/SystemUI/legacy/recents/res/values-hi/strings.xml
@@ -37,7 +37,7 @@
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"क्षैतिज रूप से दो हिस्सों में बाँटें (स्प्लिट करें)"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"लम्बवत रूप से दो हिस्सों में बाँटें (स्प्लिट करें)"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"अपने मुताबिक दो हिस्सों में बाँटें (स्प्लिट स्क्रीन करें)"</string>
- <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"ऊपर की ओर दो स्क्रीन बनाएं"</string>
- <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"बाईं ओर दो स्क्रीन बनाएं"</string>
- <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"दाईं ओर दो स्क्रीन बनाएं"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"ऊपर की ओर दूसरी स्क्रीन बनाएं"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"बाईं ओर दूसरी स्क्रीन बनाएं"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"दाईं ओर दूसरी स्क्रीन बनाएं"</string>
</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-ml/strings.xml b/packages/SystemUI/legacy/recents/res/values-ml/strings.xml
new file mode 100644
index 0000000..6dd797e
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-ml/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"അവലോകനം."</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> ഡിസ്മിസ് ചെയ്യുക."</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> ഡിസ്മിസ് ചെയ്തു."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"അടുത്തിടെയുള്ള എല്ലാ ആപ്പുകളും ഡിസ്മിസ് ചെയ്തു."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> ആപ്പ് വിവരങ്ങൾ തുറക്കുക."</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കുന്നു."</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"നിങ്ങൾ എല്ലാം മായ്ച്ചിരിക്കുന്നു"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"ആപ്പ് വിവരങ്ങൾ"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"സ്ക്രീൻ പിൻ ചെയ്യൽ"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"തിരയുക"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല"</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"സുരക്ഷിത മോഡിൽ <xliff:g id="APP">%s</xliff:g> പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"എല്ലാം മായ്ക്കുക"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"സ്പ്ലിറ്റ് സ്ക്രീൻ ഉപയോഗിക്കാൻ, ഇവിടെ വലിച്ചിടുക"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"തിരശ്ചീനമായി സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"ലംബമായി സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"ഇഷ്ടാനുസൃതമായി സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"സ്ക്രീൻ മുകളിലോട്ട് സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"സ്ക്രീൻ ഇടത്തോട്ട് സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"സ്ക്രീൻ വലത്തോട്ട് സ്പ്ലിറ്റ് ചെയ്യുക"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-ne/strings.xml b/packages/SystemUI/legacy/recents/res/values-ne/strings.xml
new file mode 100644
index 0000000..0113833
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-ne/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"परिदृश्य।"</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> खारेज गर्नुहोस्।"</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"हालका सबै अनुप्रयोगहरू खारेज गरियो।"</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> अनुप्रयोग सम्बन्धी जानकारी खोल्नुहोस्।"</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> सुरु गर्दै।"</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"हालसालैको कुनै पनि वस्तु छैन"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"तपाईंले सबै कुरा खाली गर्नुभएको छ"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"अनुप्रयोगको जानकारी"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"स्क्रिन पिनिसङ"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"खोज्नुहोस्"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> सुरु गर्न सकिएन।"</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> लाई सुरक्षित मोडमा असक्षम पारिएको छ।"</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"सबै हटाउनुहोस्"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"विभाजित स्क्रिनको प्रयोग गर्न यहाँ तान्नुहोस्"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"तेर्सो रूपमा विभाजन गर्नुहोस्"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"ठाडो रूपमा विभाजन गर्नुहोस्"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"आफू अनुकूल विभाजन गर्नुहोस्"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"विभाजित स्क्रिन शीर्ष स्थानमा राख्नुहोस्"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"विभाजित स्क्रिन बायाँतर्फ राख्नुहोस्"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"विभाजित स्क्रिन दायाँतर्फ राख्नुहोस्"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-or/strings.xml b/packages/SystemUI/legacy/recents/res/values-or/strings.xml
new file mode 100644
index 0000000..7ffcc94
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-or/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"ସଂକ୍ଷିପ୍ତ ବିବରଣୀ"</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> ଖାରଜ।"</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> ଖାରଜ କରିଦିଆଗଲା।"</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"ସମସ୍ତ ସମ୍ପ୍ରତି ଆପ୍ଲିକେସନ୍ଗୁଡ଼ିକ ଖାରଜ କରାଯାଇଛି।"</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> ଆପ୍ଲିକେସନ୍ ସୂଚନା ଖୋଲନ୍ତୁ।"</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> ଆରମ୍ଭ ହେଉଛି।"</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"ଆପଣ ସୁବୁକିଛି ଖାଲି କରିଦେଇଛନ୍ତି"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"ଆପ୍ଲିକେସନ୍ ସୂଚନା"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"ସ୍କ୍ରିନ୍ ଲକ୍"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"ଖୋଜନ୍ତୁ"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> କୁ ଆରମ୍ଭ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> ସୁରକ୍ଷିତ-ମୋଡ୍ରେ ଅକ୍ଷମ ଅଟେ।"</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"ସ୍ପ୍ଲିଟ୍ ସ୍କ୍ରିନ୍ ବ୍ୟବହାର କରିବା ପାଇଁ ଏଠାକୁ ଡ୍ରାଗ୍ କରନ୍ତୁ"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"ଭୂସମାନ୍ତରଭାବରେ ଭାଗ କରନ୍ତୁ"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"ଭୂଲମ୍ବଭାବରେ ଭାଗ କରନ୍ତୁ"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"କଷ୍ଟମ୍ କରି ଭାଗ କରନ୍ତୁ"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"ସ୍କ୍ରିନ୍କୁ ଉପର ଆଡ଼କୁ ଭାଗ କରନ୍ତୁ"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"ସ୍କ୍ରିନ୍କୁ ବାମ ଆଡ଼କୁ ଭାଗ କରନ୍ତୁ"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"ସ୍କ୍ରିନ୍କୁ ଡାହାଣ ଆଡ଼କୁ ଭାଗ କରନ୍ତୁ"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-si/strings.xml b/packages/SystemUI/legacy/recents/res/values-si/strings.xml
new file mode 100644
index 0000000..cae8357
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-si/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"දළ විශ්ලේෂණය."</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> ඉවත ලන්න."</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> ඉවත දමා ඇත."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"සියලුම මෑත යෙඳුම් ඉවත ලන ලදී."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> යෙදුම් තොරතුරු විවෘත කරයි."</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කරමින්."</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"මෑත අයිතම නැත"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"ඔබ සියලු දේ හිස් කර ඇත"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"යෙදුම් තොරතුරු"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"තිර ඇමිණීම"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"සෙවීම"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැකි විය."</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> ආරක්ෂිත ප්රකාරය තුළ අබලයි."</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"සියල්ල හිස් කරන්න"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"බෙදුම් තිරය භාවිත කිරීමට මෙතැනට අදින්න"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"තිරස්ව වෙන් කරන්න"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"සිරස්ව වෙන් කරන්න"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"අභිමත ලෙස වෙන් කරන්න"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"තිරය ඉහළට බෙදන්න"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"තිරය වමට බෙදන්න"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"තිරය දකුණට බෙදන්න"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-ta/strings.xml b/packages/SystemUI/legacy/recents/res/values-ta/strings.xml
new file mode 100644
index 0000000..91643fd
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-ta/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"மேலோட்டப் பார்வை."</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸை அகற்றும்."</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> அகற்றப்பட்டது."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"அனைத்துச் சமீபத்திய ஆப்ஸும் அகற்றப்பட்டன."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸ் பற்றிய தகவலைத் திறக்கும்."</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் தொடங்குகிறது."</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"சமீபத்தியவை எதுவுமில்லை"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"அனைத்தையும் அழித்துவிட்டீர்கள்"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"ஆப்ஸ் பற்றிய தகவல்"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"திரையைப் பின் செய்"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"தேடு"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g> ஆப்ஸைத் தொடங்க இயலவில்லை."</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"பாதுகாப்புப் பயன்முறையில் <xliff:g id="APP">%s</xliff:g> முடக்கப்பட்டது."</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"அனைத்தையும் அழி"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"\'திரைப் பிரிப்பைப்\' பயன்படுத்த இங்கே இழுக்கவும்"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"கிடைமட்டமாகப் பிரி"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"செங்குத்தாகப் பிரி"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"தனிப்பயன் விருப்பத்தில் பிரி"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"திரையை மேற்புறமாகப் பிரிக்கும்"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"திரையை இடப்புறமாகப் பிரிக்கும்"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"திரையை வலப்புறமாகப் பிரிக்கும்"</string>
+</resources>
diff --git a/packages/SystemUI/legacy/recents/res/values-te/strings.xml b/packages/SystemUI/legacy/recents/res/values-te/strings.xml
new file mode 100644
index 0000000..ea4e638
--- /dev/null
+++ b/packages/SystemUI/legacy/recents/res/values-te/strings.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="accessibility_desc_recent_apps" msgid="2427210347871321373">"అవలోకనం."</string>
+ <string name="accessibility_recents_item_will_be_dismissed" msgid="2355882496933479534">"<xliff:g id="APP">%s</xliff:g>ని తీసివేయండి."</string>
+ <string name="accessibility_recents_item_dismissed" msgid="4816790842084268400">"<xliff:g id="APP">%s</xliff:g> తీసివేయబడింది."</string>
+ <string name="accessibility_recents_all_items_dismissed" msgid="5693205751863608046">"అన్ని ఇటీవలి యాప్లు తీసివేయబడ్డాయి."</string>
+ <string name="accessibility_recents_item_open_app_info" msgid="3406797323476801016">"<xliff:g id="APP">%s</xliff:g> యాప్ సమాచారాన్ని తెరుస్తుంది."</string>
+ <string name="accessibility_recents_item_launched" msgid="4519918148638221791">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభిస్తోంది."</string>
+ <string name="recents_empty_message" msgid="7967713254531861311">"ఇటీవలి అంశాలు ఏవీ లేవు"</string>
+ <string name="recents_empty_message_dismissed_all" msgid="1850214584987361375">"మీరు అన్నింటినీ తీసివేసారు"</string>
+ <string name="recents_app_info_button_label" msgid="8732926607391786762">"యాప్ సమాచారం"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6087750201863853365">"స్క్రీన్కు పిన్ చేయడం"</string>
+ <string name="recents_search_bar_label" msgid="638132045925945941">"వెతుకు"</string>
+ <string name="recents_launch_error_message" msgid="9107963563503438012">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string>
+ <string name="recents_launch_disabled_message" msgid="826461671965217243">"<xliff:g id="APP">%s</xliff:g> సురక్షిత-మోడ్లో నిలిపివేయబడింది."</string>
+ <string name="recents_stack_action_button_label" msgid="1974273390109881497">"అన్నీ తీసివేయి"</string>
+ <string name="recents_drag_hint_message" msgid="610417221848280136">"విభజన స్క్రీన్ను ఉపయోగించడానికి ఇక్కడ లాగండి"</string>
+ <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="488987777874979435">"అడ్డంగా విభజించు"</string>
+ <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="2498375296906391117">"నిలువుగా విభజించు"</string>
+ <string name="recents_multistack_add_stack_dialog_split_custom" msgid="7368405969130304811">"అనుకూలంగా విభజించు"</string>
+ <string name="recents_accessibility_split_screen_top" msgid="8773505308411722524">"స్క్రీన్ని ఎగువకు విభజించు"</string>
+ <string name="recents_accessibility_split_screen_left" msgid="722594718192007972">"స్క్రీన్ని ఎడమ వైపుకి విభజించు"</string>
+ <string name="recents_accessibility_split_screen_right" msgid="2479764030969301514">"స్క్రీన్ని కుడి వైపుకి విభజించు"</string>
+</resources>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
index 887ea59..7cb63ea 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -49,4 +49,10 @@
* Notifies that time tick alarm from doze service fired.
*/
default void dozeTimeTick() { }
+
+ /**
+ * Set the amount (ratio) that the device has transitioned to doze.
+ * @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake.
+ */
+ default void setDarkAmount(float darkAmount) {}
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
index 814324e..99cc3a3 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -36,7 +36,7 @@
public boolean onInterceptTouchEvent(MotionEvent event);
- public void setBarState(boolean vertical, boolean isRtl);
+ public void setBarState(boolean isRtl, int navBarPosition);
public void onDraw(Canvas canvas);
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index 50dc26b..f4a3794 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -118,14 +118,14 @@
<string name="accessibility_ime_switch_button" msgid="2695096475319405612">"Skift indtastningsmetode"</string>
<string name="airplane_mode" msgid="3807209033737676010">"Flytilstand"</string>
<string name="kg_prompt_reason_restart_pattern" msgid="7246972020562621506">"Du skal angive et mønster, når du har genstartet enheden"</string>
- <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Der skal indtastes en pinkode efter genstart af enheden"</string>
- <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Der skal indtastes en adgangskode efter genstart af enheden"</string>
+ <string name="kg_prompt_reason_restart_pin" msgid="6303592361322290145">"Der skal angives en pinkode efter genstart af enheden"</string>
+ <string name="kg_prompt_reason_restart_password" msgid="6984641181515902406">"Der skal angives en adgangskode efter genstart af enheden"</string>
<string name="kg_prompt_reason_timeout_pattern" msgid="5304487696073914063">"Der kræves et mønster som ekstra beskyttelse"</string>
<string name="kg_prompt_reason_timeout_pin" msgid="8851462864335757813">"Der kræves en pinkode som ekstra beskyttelse"</string>
<string name="kg_prompt_reason_timeout_password" msgid="6563904839641583441">"Der kræves en adgangskode som ekstra beskyttelse"</string>
<string name="kg_prompt_reason_switch_profiles_pattern" msgid="3398054847288438444">"Du skal angive et mønster, når du skifter profil"</string>
- <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Der skal indtastes en pinkode, når du skifter profil"</string>
- <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Der skal indtastes en adgangskode, når du skifter profil"</string>
+ <string name="kg_prompt_reason_switch_profiles_pin" msgid="7426368139226961699">"Der skal angives en pinkode, når du skifter profil"</string>
+ <string name="kg_prompt_reason_switch_profiles_password" msgid="8383831046318421845">"Der skal angives en adgangskode, når du skifter profil"</string>
<string name="kg_prompt_reason_device_admin" msgid="3452168247888906179">"Enheden er blevet låst af administratoren"</string>
<string name="kg_prompt_reason_user_request" msgid="8236951765212462286">"Enheden blev låst manuelt"</string>
<plurals name="kg_prompt_reason_time_pattern" formatted="false" msgid="71299470072448533">
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index f138685..c86ebe7 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -152,6 +152,13 @@
android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
style="@style/TextAppearance.NotificationInfo.Button" />
<TextView
+ android:id="@+id/toggle_silent"
+ android:text="@string/inline_silent_button_silent"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
+ style="@style/TextAppearance.NotificationInfo.Button" />
+ <TextView
android:id="@+id/keep"
android:minWidth="48dp"
android:text="@string/inline_keep_button"
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index 5e952e3..ddefb6a 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -21,7 +21,8 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/ongoing_appops_chip_margin"
- android:gravity="center_vertical|end"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_gravity="center_vertical|end"
android:orientation="horizontal"
android:paddingStart="@dimen/ongoing_appops_chip_side_padding"
android:paddingEnd="@dimen/ongoing_appops_chip_side_padding"
@@ -32,13 +33,17 @@
android:id="@+id/icons_container"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- android:gravity="center_vertical|start"
+ android:layout_gravity="center_vertical|start"
+ android:gravity="center_vertical"
/>
<TextView
android:id="@+id/app_name"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- android:gravity="center_vertical|end"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_gravity="center_vertical|end"
+ android:gravity="center_vertical"
/>
</com.android.systemui.privacy.OngoingPrivacyChip>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index 007070e..e7f2c51 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -27,6 +27,13 @@
android:paddingStart="@dimen/status_bar_padding_start"
android:paddingEnd="@dimen/status_bar_padding_end" >
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:gravity="center_vertical|start" >
+
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
@@ -38,13 +45,21 @@
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
systemui:showDark="false" />
+ </LinearLayout>
<android.widget.Space
android:id="@+id/space"
android:layout_width="0dp"
android:layout_height="match_parent"
+ android:layout_gravity="center_vertical|center_horizontal"
+ android:visibility="gone" />
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
android:layout_weight="1"
- android:gravity="center_vertical|center_horizontal" />
+ android:orientation="horizontal"
+ android:gravity="center_vertical|end">
<include layout="@layout/ongoing_privacy_chip" />
@@ -53,4 +68,5 @@
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:gravity="center_vertical|end" />
+ </LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 1835a56..de1ef3d 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Probeer weer skermkiekie neem"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Kan weens beperkte bergingspasie nie skermkiekie stoor nie"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Skermopname"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Deurlopende kennisgewing vir \'n skermopnamesessie"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Begin opname"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Neem stemopname op"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Wys tikke"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Laat wag"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Hervat"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Kanselleer"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Deel"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Vee uit"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Skermopname is gekanselleer"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Skermopname is gestoor, tik om te sien"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Skermopname is uitgevee"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Kon nie skermopname uitvee nie"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Kon nie toestemmings kry nie"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-lêeroordrag-opsies"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Heg as \'n mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Heg as \'n kamera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Kennisgewings"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Jy sal nie meer hierdie kennisgewings sien nie"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Hierdie kennisgewings sal geminimeer word"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Jy maak hierdie kennisgewings gewoonlik toe. \nMoet ons aanhou om hulle te wys?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Hou aan om hierdie kennisgewings te wys?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop kennisgewings"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Hou aan wys"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimeer"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Hou aan om kennisgewings van hierdie program af te wys?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Hierdie kennisgewings kan nie afgeskakel word nie"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Hierdie program gebruik tans die kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Hierdie program gebruik tans die mikrofoon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Hierdie program wys tans bo-oor ander programme op jou skerm."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Wys persentasie wanneer gelaai word (verstek)"</item>
<item msgid="3327323682209964956">"Moenie hierdie ikoon wys nie"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Wys laeprioriteit-kennisgewingikone"</string>
<string name="other" msgid="4060683095962566764">"Ander"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Skermverdeler"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Volskerm links"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Program is oopgemaak sonder dat dit geïnstalleer is."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Program is oopgemaak sonder dat dit geïnstalleer is. Tik om meer te wete te kom."</string>
<string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Gaan na web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Gaan na blaaier"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobiele data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is af"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Instellings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Het dit"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Stort SysUI-hoop"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> gebruik tans jou <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Programme gebruik tans jou <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Kanselleer"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Goed"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Stellings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> gebruik die afgelope <xliff:g id="TIME">%3$d</xliff:g> min. jou <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> gebruik tans jou <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> gebruik tans jou <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ligging"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofoon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index dea4256..04f5d4c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ቅጽበታዊ ገጽ ዕይታን እንደገና ማንሳት ይሞክሩ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ባለው ውሱን የማከማቻ ቦታ ምክንያት ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አይችልም"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"የማያ ገጽ ቀረጻ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ለአንድ የማያ ገጽ ቀረጻ ክፍለ-ጊዜ በመካሄድ ያለ ማሳወቂያ"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"መቅረጽ ጀምር"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ድምጽን ቅረጽ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"መታ ማድረጎችን አሳይ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"አቁም"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ባለበት አቁም"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ከቆመበት ቀጥል"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ይቅር"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"አጋራ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ሰርዝ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"የማያ ገጽ ቀረጻ ተቀምጧል፣ ለመመልከት መታ ያድርጉ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"የማያ ገጽ ቀረጻ ተሰርዟል"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"የማያ ገጽ ቀረጻን መሰረዝ ላይ ስህተት"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ፈቃዶችን ማግኘት አልተቻለም"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"የUSB ፋይል ሰደዳ አማራጮች"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"እንደ ማህደረ አጫዋች (MTP) ሰካ"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"እንደ ካሜራ (PTP) ሰካ"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ማሳወቂያዎች"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"እነዚህን ማሳወቂያዎችን ከእንግዲህ አይመለከቷቸውም"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"እነዚህ ማሳወቂያዎች እንዲያንሱ ይደረጋሉ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"አብዛኛውን ጊዜ እነዚህን ማሳወቂያዎች ያሰናብቷቸዋል። \nመታየታቸው ይቀጥል??"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"እነዚህን ማሳወቂያዎች ማሳየት ይቀጥሉ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ማሳወቂያዎችን አስቁም"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ማሳየትን ቀጥል"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"አሳንስ"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ከዚህ መተግበሪያ ማሳወቂያዎችን ማሳየት ይቀጥል?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"እነዚህ ማሳወቂያዎች ሊጠፉ አይችሉም"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ይህ መተግበሪያ ካሜራውን እየተጠቀመ ነው።"</string>
<string name="appops_microphone" msgid="741508267659494555">"ይህ መተግበሪያ ማይክሮፎኑን እየተጠቀመ ነው።"</string>
<string name="appops_overlay" msgid="6165912637560323464">"ይህ መተግበሪያ በማያ ገጽዎ ላይ ባሉ ሌሎች መተግበሪያዎች ላይ እያሳየ ነው።"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"የባትሪ ኃይል በሚሞላበት ጊዜ መቶኛ አሳይ (ነባሪ)"</item>
<item msgid="3327323682209964956">"ይህን አዶ አታሳይ"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"አነስተኛ ቅድሚያ ያላቸው የማሳወቂያ አዶዎችን አሳይ"</string>
<string name="other" msgid="4060683095962566764">"ሌላ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"የተከፈለ የማያ ገጽ ከፋይ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"የግራ ሙሉ ማያ ገጽ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"መተግበሪያ ሳይጫን ተከፍቷል።"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"መተግበሪያ ሳይጫን ተከፍቷል። ተጨማሪ ለማወቅ መታ ያድርጉ።"</string>
<string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ወደ ድር ሂድ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ወደ አሳሽ ሂድ"</string>
<string name="mobile_data" msgid="7094582042819250762">"የተንቀሳቃሽ ስልክ ውሂብ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>— <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ጠፍቷል"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ቅንብሮች"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ገባኝ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI Heap አራግፍ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> የእርስዎን <xliff:g id="TYPES_LIST">%2$s</xliff:g> እየተጠቀመ ነው።"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"መተግበሪያዎች የእርስዎን <xliff:g id="TYPES_LIST">%s</xliff:g> እየተጠቀሙ ነው።"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"መተግበሪያን ክፈት"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ይቅር"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"እሺ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ቅንብሮች"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> የእርስዎን <xliff:g id="TYPE">%2$s</xliff:g> ላለፉት <xliff:g id="TIME">%3$d</xliff:g> ደቂቃዎች እየተጠቀመ ነው"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> የእርስዎን <xliff:g id="TYPE">%2$s</xliff:g> እየተጠቀመ ነው"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> የእርስዎን <xliff:g id="TYPES_LIST">%2$s</xliff:g> እየተጠቀመ ነው"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ካሜራ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"አካባቢ"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ማይክሮፎን"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index b3ac2cd..11144ee 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"جرّب أخذ لقطة الشاشة مرة أخرى"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"يتعذر حفظ لقطة الشاشة لأن مساحة التخزين المتاحة محدودة."</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"يحظر التطبيق أو تحظر مؤسستك التقاط لقطات شاشة"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"تسجيل الشاشة"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"إشعار مستمر لجلسة تسجيل شاشة"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"بدء التسجيل"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"تسجيل التعليق الصوتي"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"عرض النقرات"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"إيقاف"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"إيقاف مؤقت"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"استئناف"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"إلغاء"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"مشاركة"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"حذف"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"تمّ إلغاء تسجيل الشاشة."</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"تمّ حفظ تسجيل الشاشة، انقر لعرضه."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"تمّ حذف تسجيل الشاشة."</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"حدث خطأ أثناء حذف تسجيل الشاشة."</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"تعذّر الحصول على أذونات."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"خيارات نقل الملفات عبر USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"تثبيت كمشغل وسائط (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تثبيت ككاميرا (PTP)"</string>
@@ -304,7 +320,7 @@
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"تم تشغيل Wi-Fi"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"لا تتوفر أي شبكة Wi-Fi"</string>
<string name="quick_settings_wifi_secondary_label_transient" msgid="7748206246119760554">"جارٍ التفعيل…"</string>
- <string name="quick_settings_cast_title" msgid="7709016546426454729">"إرسال"</string>
+ <string name="quick_settings_cast_title" msgid="7709016546426454729">"الإرسال"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"جارٍ الإرسال"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"جهاز لا يحمل اسمًا"</string>
<string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"جاهز للإرسال"</string>
@@ -346,7 +362,7 @@
<string name="quick_settings_night_secondary_label_until_sunrise" msgid="4453017157391574402">"حتى شروق الشمس"</string>
<string name="quick_settings_night_secondary_label_on_at" msgid="6256314040368487637">"تفعيل الإعداد في <xliff:g id="TIME">%s</xliff:g>"</string>
<string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"حتى <xliff:g id="TIME">%s</xliff:g>"</string>
- <string name="quick_settings_nfc_label" msgid="9012153754816969325">"الاتصال القريب المدى (NFC)"</string>
+ <string name="quick_settings_nfc_label" msgid="9012153754816969325">"الاتصالات قصيرة المدى (NFC)"</string>
<string name="quick_settings_nfc_off" msgid="6883274004315134333">"تم إيقاف الاتصال القريب المدى"</string>
<string name="quick_settings_nfc_on" msgid="6680317193676884311">"تم تفعيل الاتصال القريب المدى"</string>
<string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"مرّر سريعًا لأعلى لتبديل التطبيقات"</string>
@@ -594,15 +610,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"الإشعارات"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"لن تتلقى هذه الإشعارات بعد الآن."</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"سيتم تصغير هذه الإشعارات."</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"يتم عرض هذه الإشعارات بدون تنبيه صوتي"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"يتم عرض هذه الإشعارات مع تنبيه صوتي"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"أنت تتجاهل عادةً هذه الإشعارات. \nهل تريد الاستمرار في عرضها؟"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"هل تريد الاستمرار في تلقي هذه الإشعارات؟"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"إيقاف الإشعارات"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"الاستمرار في تلقّي الإشعارات"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"تصغير"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"عرض بدون تنبيه صوتي"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"العرض والتنبيه"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"هل تريد الاستمرار في تلقي إشعارات من هذا التطبيق؟"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"يتعذَّر إيقاف هذه الإشعارات."</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"يستخدم هذا التطبيق الكاميرا."</string>
<string name="appops_microphone" msgid="741508267659494555">"يستخدم هذا التطبيق الميكروفون."</string>
<string name="appops_overlay" msgid="6165912637560323464">"يتم عرض هذا التطبيق فوق التطبيقات الأخرى على شاشتك."</string>
@@ -745,8 +763,7 @@
<item msgid="2139628951880142927">"عرض النسبة المئوية عند الشحن (تلقائي)"</item>
<item msgid="3327323682209964956">"عدم عرض هذا الرمز"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"إظهار رموز الإشعارات ذات الأولوية المنخفضة"</string>
<string name="other" msgid="4060683095962566764">"غير ذلك"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"أداة تقسيم الشاشة"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"عرض النافذة اليسرى بملء الشاشة"</string>
@@ -826,7 +843,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"تمّ فتح التطبيق بدون تثبيته."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"تمّ فتح التطبيق بدون تثبيته. انقر لمعرفة مزيد من المعلومات."</string>
<string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string>
- <string name="go_to_web" msgid="1106022723459948514">"الانتقال إلى الويب"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"الانتقال إلى المتصفح"</string>
<string name="mobile_data" msgid="7094582042819250762">"بيانات الجوّال"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"تم إيقاف شبكة Wi-Fi"</string>
@@ -858,4 +875,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"الإعدادات"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"حسنًا"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"تفريغ ذاكرة SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"التطبيق <xliff:g id="APP">%1$s</xliff:g> يستخدم <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"تستخدم التطبيقات <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"فتح التطبيق"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"إلغاء"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"موافق"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"الإعدادات"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"التطبيق <xliff:g id="APP">%1$s</xliff:g> يستخدم <xliff:g id="TYPE">%2$s</xliff:g> منذ <xliff:g id="TIME">%3$d</xliff:g> من الدقائق مضت."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"التطبيقات <xliff:g id="APPS">%1$s</xliff:g> تستخدم <xliff:g id="TYPE">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"التطبيق <xliff:g id="APP">%1$s</xliff:g> يستخدم <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"الكاميرا"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"الموقع"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"الميكروفون"</string>
</resources>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 2574838..c60d2d4 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"স্ক্ৰীণশ্বট আকৌ ল\'বলৈ চেষ্টা কৰক"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"সঞ্চয়াগাৰত সীমিত খালী ঠাই থকাৰ বাবে স্ক্ৰীণশ্বট ছেভ কৰিব পৰা নগ\'ল"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"এপটোৱে বা আপোনাৰ প্ৰতিষ্ঠানে স্ক্ৰীণশ্বট ল\'বলৈ অনুমতি নিদিয়ে"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"স্ক্রীণ ৰেকৰ্ডিং"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"স্ক্রীণ ৰেকৰ্ডিং ছেশ্বন চলি থকা সময়ত পোৱা জাননী"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ৰেকৰ্ডিং কৰা আৰম্ভ কৰক"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"পাৰ্শ্ব-ধ্বনি ৰেকৰ্ড কৰক"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"টিপা ঠাইসমূহ দেখুৱাওক"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"বন্ধ কৰক"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"প\'জ কৰক"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ৰখোৱাৰ পৰা পুনৰ আৰম্ভ কৰক"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"বাতিল কৰক"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"শ্বেয়াৰ কৰক"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"মচক"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"স্ক্রীণ ৰেকৰ্ড কৰাটো বাতিল কৰা হ\'ল"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"স্ক্রীণ ৰেকৰ্ডিং ছেভ কৰা হ\'ল, চাবলৈ টিপক"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"স্ক্রীণ ৰেকৰ্ডিং মচা হ\'ল"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"স্ক্রীণ ৰেকৰ্ডিং মচি থাকোঁতে কিবা আসোঁৱাহ হ\'ল"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"অনুমতি পাব পৰা নগ\'ল"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"ইউএছবিৰে ফাইল স্থানান্তৰণৰ বিকল্পসমূহ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"মিডিয়া প্লেয়াৰ (এমটিপি) হিচাপে সংলগ্ন কৰক"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"কেমেৰা (পিটিপি) হিচাপে সংলগ্ন কৰক"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"জাননীসমূহ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"আপোনাক এই জাননীসমূহ আৰু দেখুওৱা নহ\'ব"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"এই জাননীসমূহ মিনিমাইজ কৰি থোৱা হ\'ব"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"আপুনি সাধাৰণতে এই জাননীসমূহ অগ্ৰাহ্য কৰে। \nসেইবোৰ দেখুওৱাই থাকিব লাগিবনে?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"এই জাননীসমূহ দেখুওৱাই থাকিব লাগিবনে?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"জাননী বন্ধ কৰক"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"দেখুওৱাই থাকক"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"সৰু কৰক"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"এই এপটোৰ জাননী দেখুওৱাই থাকিব লাগিবনে?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"এই জাননীসমূহ বন্ধ কৰিব নোৱাৰি"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"এই এপে কেমেৰা ব্য়ৱহাৰ কৰি আছে।"</string>
<string name="appops_microphone" msgid="741508267659494555">"এই এপে মাইক্ৰ\'ফ\'ন ব্য়ৱহাৰ কৰি আছে।"</string>
<string name="appops_overlay" msgid="6165912637560323464">"এই এপটো আপোনাৰ স্ক্ৰীণত থকা অন্য় এপৰ ওপৰত প্ৰদৰ্শিত হৈ আছে।"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"চ্চাৰ্জ কৰি থকাৰ সময়ত শতাংশ দেখুৱাওক (ডিফ\'ল্ট)"</item>
<item msgid="3327323682209964956">"এই আইকনটো নেদেখুৱাব"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"কম গুৰুত্বপূৰ্ণ জাননীৰ আইকনসমূহ দেখুৱাওক"</string>
<string name="other" msgid="4060683095962566764">"অন্যান্য"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"স্প্লিট স্ক্ৰীণৰ বিভাজক"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"বাওঁফালৰ স্ক্ৰীণখন সম্পূৰ্ণ স্ক্ৰীণ কৰক"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ইনষ্ট\'ল নকৰাকৈয়েই এপটো খোলা হৈছে।"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ইনষ্ট\'ল নকৰাকৈয়েই এপটো খোলা হৈছে। অধিক জানিবলৈ টিপক।"</string>
<string name="app_info" msgid="6856026610594615344">"এপ্ সম্পৰ্কীয় তথ্য"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ৱেবলৈ যাওক"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ব্ৰাউজাৰলৈ যাওক"</string>
<string name="mobile_data" msgid="7094582042819250762">"ম\'বাইল ডেটা"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"ৱাই-ফাই অফ অৱস্থাত আছে"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ছেটিংবোৰ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"বুজি পালোঁ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI হীপ ডাম্প কৰক"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"এপ্লিকেশ্বনসমূহে আপোনাৰ <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যৱহাৰ কৰি আছে।"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"এপ্ খোলক"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"বাতিল কৰক"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ঠিক আছে"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ছেটিংসমূহ"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g>এ যোৱা <xliff:g id="TIME">%3$d</xliff:g> মিনিটৰ পৰা আপোনাৰ <xliff:g id="TYPE">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="TYPE">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যৱহাৰ কৰি আছে"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"কেমেৰা"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"অৱস্থান"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"মাইক্ৰ\'ফ\'ন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 58947da..b47d5ff 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Skrinşotu yenidən çəkin"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Yaddaş ehtiyatının az olması səbəbindən skrinşotu yadda saxlamaq olmur"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Skrinşot çəkməyə tətbiq və ya təşkilat tərəfindən icazə verilmir"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ekranın Video Çəkimi"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ekranın video çəkimi ərzində silinməyən bildiriş"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Ekranın Video Çəkimini Başladın"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Ekranın səsli video çəkimi"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Klikləmələri göstərin"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Dayandırın"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Dayandırın"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Davam edin"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Ləğv edin"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Paylaşın"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Silin"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekranın video çəkimi ləğv edildi"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekranın video çəkimi yadda saxlanıldı. Baxmaq üçün klikləyin"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekranın video çəkimi silindi"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Ekranın video çəkiminin silinməsi zamanı xəta baş verdi"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"İcazələr əldə edilmədi"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB fayl transferi seçimləri"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Media pleyer (MTP) kimi montaj edin"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera kimi birləşdir (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirişlər"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Artıq bu bildirişləri görməyəcəkəsiniz"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Bu bildirişlər kiçildiləcək"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Bu bildirişlər səssiz görünəcək"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Bu bildirişlər Sizi xəbərdar edəcək"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Adətən bu bildirişləri rədd edirsiniz. \nBildirişlər göstərilsin?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Bu bildirişlər göstərilməyə davam edilsin?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Bildirişləri dayandırın"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Göstərməyə davam edin"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Kiçildin"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Səssiz göstərin"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Göstərin və xəbərdar edin"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu tətbiqin bildirişləri göstərilməyə davam edilsin?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Bu bildirişlər deaktiv edilə bilməz"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> vasitəsilə"</string>
<string name="appops_camera" msgid="8100147441602585776">"Bu tətbiq kameradan istifadə edir."</string>
<string name="appops_microphone" msgid="741508267659494555">"Bu tətbiq mikrofondan istifadə edir."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Bu tətbiqdə ekranda digər tətbiqlərin üzərində göstərilir."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Quraşdırılmadan açılan tətbiq."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Quraşdırılmadan açılan tətbiq. Ətraflı məlumat üçün klikləyin."</string>
<string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Vebə keçin"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Brauzerə daxil edin"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobil data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi deaktivdir"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ayarlar"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Anladım"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> tətbiqlərindən istifadə edir."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Tətbiqlər <xliff:g id="TYPES_LIST">%s</xliff:g> istifadə edir."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Tətbiqi açın"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Ləğv edin"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Oldu"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ayarlar"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> son <xliff:g id="TIME">%3$d</xliff:g> dəqiqədir ki, <xliff:g id="TYPE">%2$s</xliff:g> tətbiqindən istifadə edir"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> <xliff:g id="TYPE">%2$s</xliff:g> tətbiqindən istifadə edir"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> tətbiqlərindən istifadə edir"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"məkan"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index b2bcda8..8538565 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Probajte da ponovo napravite snimak ekrana"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Snimanje ekrana"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Obaveštenje o sesiji snimanja ekrana je aktivno"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Započni snimanje"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Snimi prenos glasa"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Prikazuj dodire"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Zaustavi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pauziraj"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Nastavi"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Otkaži"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Deli"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Izbriši"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Snimanje ekrana je otkazano"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Snimak ekrana je sačuvan, dodirnite da biste pregledali"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Snimak ekrana je izbrisan"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Došlo je do problema pri brisanju snimka ekrana"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Preuzimanje dozvola nije uspelo"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prenosa datoteka"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Priključi kao medija plejer (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Priključi kao kameru (PTP)"</string>
@@ -585,15 +601,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Obaveštenja"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Više nećete videti ova obaveštenja"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ova obaveštenja će se umanjiti"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Obično odbacujete ova obaveštenja. \nŽelite li da se i dalje prikazuju?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Želite li da se ova obaveštenja i dalje prikazuju?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Prestani da prikazuješ obaveštenja"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Nastavi da prikazuješ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Umanji"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obaveštenja iz ove aplikacije i dalje prikazuju?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ne možete da isključite ova obaveštenja"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ova aplikacija koristi kameru."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ova aplikacija koristi mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ova aplikacija se prikazuje preko drugih aplikacija na ekranu."</string>
@@ -730,8 +752,7 @@
<item msgid="2139628951880142927">"Prikaži procenat tokom punjenja (podrazumevano)"</item>
<item msgid="3327323682209964956">"Ne prikazuj ovu ikonu"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Prikaži ikone obaveštenja niskog prioriteta"</string>
<string name="other" msgid="4060683095962566764">"Drugo"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Razdelnik podeljenog ekrana"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Režim celog ekrana za levi ekran"</string>
@@ -811,7 +832,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija se otvorila bez instaliranja."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija se otvorila bez instaliranja. Dodirnite da biste saznali više."</string>
<string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Idi na veb"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Idi na pregledač"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
@@ -843,4 +864,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Podešavanja"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Važi"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Izdvoji SysUI mem."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otvori"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Otkaži"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Potvrdi"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Podešavanja"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> tokom nekoliko poslednjih minuta (<xliff:g id="TIME">%3$d</xliff:g>) koristi <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> koriste <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kameru"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index ac430ba..e83b9be 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Паспрабуйце зрабіць здымак экрана яшчэ раз"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Немагчыма захаваць здымак экрана, бо мала месца ў сховішчы"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Рабіць здымкі экрана не дазваляе праграма ці ваша арганізацыя"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Запіс экрана"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Бягучае апавяшчэнне для сеанса запісу экрана"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Пачаць запіс"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Закадравае агучванне запісу"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Паказваць дотыкі"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Спыніць"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Прыпыніць"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Узнавіць"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Скасаваць"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Абагуліць"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Выдаліць"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Запіс экрана скасаваны"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Запіс экрана захаваны. Націсніце, каб прагледзець"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Запіс экрана выдалены"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Памылка выдалення запісу экрана"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Не ўдалося атрымаць дазволы"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Парам. перадачы файлаў па USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Падлучыць як медыяпрайгравальнік (ССП)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Падлучыць як камеру (PTP)"</string>
@@ -590,15 +606,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Апавяшчэнні"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Вы больш не будзеце бачыць гэтыя апавяшчэнні"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Апавяшчэнні будуць згорнуты"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Звычайна вы адхіляеце гэтыя апавяшчэнні. \nПаказваць іх?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Працягваць паказваць гэтыя апавяшчэнні?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Спыніць апавяшчэнні"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Працягваць паказваць"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Згарнуць"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Працягваць паказваць апавяшчэнні гэтай праграмы?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Немагчыма адключыць гэтыя апавяшчэнні"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Гэта праграма выкарыстоўвае камеру."</string>
<string name="appops_microphone" msgid="741508267659494555">"Гэта праграма выкарыстоўвае мікрафон."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Гэта праграма паказваецца на экране паверх іншых праграм."</string>
@@ -737,8 +759,7 @@
<item msgid="2139628951880142927">"Паказваць працэнты падчас зарадкі (стандартна)"</item>
<item msgid="3327323682209964956">"Не паказваць гэты значок"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Паказваць значкі апавяшчэнняў з нізкім прыярытэтам"</string>
<string name="other" msgid="4060683095962566764">"Іншае"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Раздзяляльнік падзеленага экрана"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Левы экран – поўнаэкранны рэжым"</string>
@@ -818,7 +839,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Праграма адкрыта без усталёўкі."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Праграма адкрыта без усталёўкі. Націсніце, каб даведацца больш."</string>
<string name="app_info" msgid="6856026610594615344">"Інфармацыя пра праграму"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Перайсці ў інтэрнэт"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Перайсці ў браўзер"</string>
<string name="mobile_data" msgid="7094582042819250762">"Маб. перадача даных"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi выключаны"</string>
@@ -850,4 +871,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Налады"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Зразумела"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Дамп кучы SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Праграма \"<xliff:g id="APP">%1$s</xliff:g>\" выкарыстоўвае: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Праграмы выкарыстоўваюць: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Адкрыць"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Скасаваць"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ОК"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Налады"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Праграма \"<xliff:g id="APP">%1$s</xliff:g>\" на працягу апошніх <xliff:g id="TIME">%3$d</xliff:g> хв. выкарыстоўвае: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Праграма \"<xliff:g id="APPS">%1$s</xliff:g>\" выкарыстоўвае: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Праграма \"<xliff:g id="APP">%1$s</xliff:g>\" выкарыстоўвае: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"геалакацыя"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"мікрафон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index c6bc414..bdc561a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Опитайте да направите екранна снимка отново"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Екранната снимка не може да се запази поради ограничено място в хранилището"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Правенето на екранни снимки не е разрешено от приложението или организацията ви"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Записване на екрана"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Текущо известие за сесия за записване на екрана"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Стартиране на записа"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Записване на озвучаване"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Показване на докосванията"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Спиране"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Поставяне на пауза"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Възобновяване"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Отказ"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Споделяне"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Изтриване"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Записването на екрана е анулирано"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Записът на екрана е запазен. Докоснете, за да го видите"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Записът на екрана е изтрит"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"При изтриването на записа на екрана възникна грешка"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Извличането на разрешенията не бе успешно."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Опции за пренос на файлове чрез USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Свързване като медиен плейър (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Свързване като камера (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Известия"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Вече няма да виждате тези известия"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Тези известия ще бъдат намалени"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Обикновено отхвърляте тези известия. \nИскате ли да продължат да се показват?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Тези известия да продължат ли да се показват?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Спиране на известията"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Да продължат да се показват"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Намаляване"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Да продължат ли да се показват известията от това приложение?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Тези известия не могат да бъдат изключени"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Това приложение използва камерата."</string>
<string name="appops_microphone" msgid="741508267659494555">"Това приложение използва микрофона."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Това приложение се показва върху други приложения на екрана."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Процентът да се показва при зареждане (по подразбиране)"</item>
<item msgid="3327323682209964956">"Тази икона да не се показва"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Показване на иконите за известията с нисък приоритет"</string>
<string name="other" msgid="4060683095962566764">"Друго"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Разделител в режима за разделен екран"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Ляв екран: Показване на цял екран"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Приложението се отвори, без да бъде инсталирано."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Приложението се отвори, без да бъде инсталирано. Докоснете, за да научите повече."</string>
<string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Към мрежата"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Към браузъра"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобилни данни"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Функцията за Wi‑Fi е изключена"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Настройки"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Разбрах"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> използва <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Някои приложения използват <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Отваряне"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Отказ"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Настройки"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> използва <xliff:g id="TYPE">%2$s</xliff:g> през последните <xliff:g id="TIME">%3$d</xliff:g> минути"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> използват <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> използва <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камерата"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"местополож."</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофона"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 412f90cf..b22714d 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"আবার স্ক্রিনশট নেওয়ার চেষ্টা করুন"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"বেশি জায়গা নেই তাই স্ক্রিনশটটি সেভ করা যাবে না৷"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"এই অ্যাপ বা আপনার প্রতিষ্ঠান স্ক্রিনশট নেওয়ার অনুমতি দেয়নি"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"স্ক্রিন রেকর্ডিং"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"স্ক্রিন রেকর্ডিং সেশন চলার বিজ্ঞপ্তি"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"রেকর্ডিং শুরু করুন"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ভয়েসওভার রেকর্ড করুন"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ট্যাপগুলি দেখুন"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"বন্ধ করুন"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"পজ করুন"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"আবার চালু করুন"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"বাতিল করুন"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"শেয়ার করুন"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"মুছুন"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"স্ক্রিন রেকর্ডিং বাতিল করা হয়েছে"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"স্ক্রিন রেকর্ডিং সেভ করা হয়েছে, দেখতে ট্যাপ করুন"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"স্ক্রিন রেকর্ডিং মুছে ফেলা হয়েছে"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"স্ক্রিন রেকডিং মুছে ফেলার সময় সমস্যা হয়েছে"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"অনুমতি পাওয়া যায়নি"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ফাইল স্থানান্তরের বিকল্পগুলি"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"একটি মিডিয়া প্লেয়ার হিসেবে মাউন্ট করুন (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"একটি ক্যামেরা হিসেবে মাউন্ট করুন (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"বিজ্ঞপ্তি"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"এই বিজ্ঞপ্তিগুলি আপনাকে আর দেখানো হবে না"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"এই বিজ্ঞপ্তিগুলি ছোট করে দেওয়া হবে"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"এই বিজ্ঞপ্তিগুলিকে আপনি সাধারণত বাতিল করেন। \nসেগুলি দেখতে চান?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"এই বিজ্ঞপ্তিগুলি পরেও দেখে যেতে চান?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"বিজ্ঞপ্তি বন্ধ করুন"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"দেখতে থাকুন"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ছোট করে দিন"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"এই অ্যাপের বিজ্ঞপ্তি পরেও দেখে যেতে চান?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"এই বিজ্ঞপ্তিগুলি বন্ধ করা যাবে না"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"এই অ্যাপটি ক্যামেরা ব্যবহার করছে।"</string>
<string name="appops_microphone" msgid="741508267659494555">"এই অ্যাপটি মাইক্রোফোন ব্যবহার করছে।"</string>
<string name="appops_overlay" msgid="6165912637560323464">"এই অ্যাপটি স্ক্রিনে অন্যান্য অ্যাপের উপরে দেখানো হচ্ছে।"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"চার্জ করার সময় শতাংশ দেখান (ডিফল্ট)"</item>
<item msgid="3327323682209964956">"এই আইকনটি দেখাবেন না"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"কম-গুরুত্বপূর্ণ বিজ্ঞপ্তির আইকন দেখুন"</string>
<string name="other" msgid="4060683095962566764">"অন্যান্য"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"বিভক্ত-স্ক্রিন বিভাজক"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"বাঁ দিকের অংশ নিয়ে পূর্ণ স্ক্রিন"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে।"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে। আরও জানতে ট্যাপ করুন।"</string>
<string name="app_info" msgid="6856026610594615344">"অ্যাপের তথ্য"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ওয়েবে যান"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ব্রাউজারে যান"</string>
<string name="mobile_data" msgid="7094582042819250762">"মোবাইল ডেটা"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"ওয়াই ফাই বন্ধ আছে"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"সেটিংস"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"বুঝেছি"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> আপনার <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যবহার করছে।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"অ্যাপ্লিকেশনগুলি আপনার <xliff:g id="TYPES_LIST">%s</xliff:g> ব্যবহার করছে।"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"অ্যাপ খুলুন"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"বাতিল করুন"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ঠিক আছে"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"সেটিংস"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> আপনার <xliff:g id="TYPE">%2$s</xliff:g> গত <xliff:g id="TIME">%3$d</xliff:g> মিনিট ধরে ব্যবহার করছে"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> আপনার <xliff:g id="TYPE">%2$s</xliff:g> ব্যবহার করছে"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> আপনার <xliff:g id="TYPES_LIST">%2$s</xliff:g> ব্যবহার করছে"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ক্যামেরা"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"লোকেশন"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"মাইক্রোফোন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 42616a6..bd48839 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Pokušajte ponovo snimiti ekran"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ova aplikacija ili vaša organizacija ne dozvoljavaju snimanje ekrana"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Snimanje ekrana"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Obavještenje za sesiju snimanja ekrana je u toku"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Započni snimanje"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Govor snimka"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Prikaži dodirivanja"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Zaustavi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pauza"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Nastavi"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Otkaži"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Dijeli"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Izbriši"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Snimanje ekrana je otkazano"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Snimak ekrana je sačuvan. Dodirnite za prikaz."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Snimak ekrana je izbrisan"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Greška prilikom brisanja snimka ekrana"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Dobijanje odobrenja nije uspjelo"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Reproduciranje medijskih sadržaja (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Priključiti kao kameru (PTP)"</string>
@@ -587,14 +603,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Obavještenja"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Nećete više vidjeti ova obavještenja"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ova obavještenja će se minimizirati"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Ove obavijesti prikazivat će se tiho"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Ove obavijesti imat će zvučni signal"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Obično odbacujete ova obavještenja. \nNastaviti ih prikazivati?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Nastaviti prikazivanje ovih obavještenja?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Zaustavi obavještenja"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivanje"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Prikaži tiho"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Prikaži uz zvučni signal"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Nastaviti prikazivanje obavještenja iz ove aplikacije?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ova obavještenja nije moguće isključiti"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"putem aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Ova aplikacija koristi kameru."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ova aplikacija koristi mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ova aplikacija prekriva druge aplikacije na ekranu."</string>
@@ -731,7 +750,7 @@
<item msgid="2139628951880142927">"Pokaži postotak u toku punjenja (zadano)"</item>
<item msgid="3327323682209964956">"Ne prikazuj ovu ikonu"</item>
</string-array>
- <string name="tuner_low_priority" msgid="1325884786608312358">"Prikaži ikone obavijesti niskog prioriteta"</string>
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Prikaži ikone obavještenja niskog prioriteta"</string>
<string name="other" msgid="4060683095962566764">"Ostalo"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Razdjelnik ekrana"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Lijevo cijeli ekran"</string>
@@ -811,7 +830,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je otvorena bez prethodne instalacije."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je otvorena bez prethodne instalacije. Dodirnite da saznate više."</string>
<string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Idite na internet"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Idi na preglednik"</string>
<string name="mobile_data" msgid="7094582042819250762">"Prijenos podataka"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"WiFi veza je isključena"</string>
@@ -843,4 +862,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Postavke"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Razumijem"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Izdvoji SysUI mem."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacije koriste <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otvori"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Otkaži"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Uredu"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Postavke"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPE">%2$s</xliff:g> u vremenskom periodu od <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikacije <xliff:g id="APPS">%1$s</xliff:g> koriste <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> koristi <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kameru"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d7300f6..0e91142 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prova de tornar a fer una captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"La captura de pantalla no es pot desar perquè no hi ha prou espai d\'emmagatzematge"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"L\'aplicació o la teva organització no permeten fer captures de pantalla"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Gravació de la pantalla"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificació en curs d\'una sessió de gravació de la pantalla"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Inicia la gravació"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Grava la veu en off"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostra els tocs"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Atura"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Posa en pausa"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Reprèn"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel·la"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Comparteix"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Suprimeix"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"S\'ha cancel·lat la gravació de la pantalla"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"S\'ha desat la gravació de la pantalla; toca per mostrar"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"S\'ha suprimit la gravació de la pantalla"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"S\'ha produït un error en suprimir la gravació de la pantalla"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"No s\'han pogut obtenir els permisos"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Munta com a reproductor multimèdia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Munta com a càmera (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacions"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Ja no veuràs aquestes notificacions"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Aquestes notificacions es minimitzaran"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Normalment ignores aquestes notificacions. \nVols que es continuïn mostrant?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vols continuar rebent aquestes notificacions?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Deixa d\'enviar notificacions"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continua rebent"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimitza"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Vols continuar rebent notificacions d\'aquesta aplicació?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Aquestes notificacions no es poden desactivar"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"mitjançant <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Aquesta aplicació utilitza la càmera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Aquesta aplicació utilitza el micròfon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Aquesta aplicació es mostra sobre altres aplicacions a la pantalla."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"L\'aplicació s\'ha obert sense instal·lar-se."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"L\'aplicació s\'ha obert sense instal·lar-se. Toca per obtenir més informació."</string>
<string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Ves al web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ves al navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dades mòbils"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"La Wi-Fi està desactivada"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Configuració"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"D\'acord"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Aboca espai de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Algunes aplicacions estan fent servir el següent: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Obre l\'app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel·la"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"D\'acord"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Configuració"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Durant els <xliff:g id="TIME">%3$d</xliff:g> últims minuts, <xliff:g id="APP">%1$s</xliff:g> ha estat fent servir el següent: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> estan fent servir el següent: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> està fent servir el següent: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"càmera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ubicació"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"micròfon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 0efbe7d..b246579 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Zkuste snímek pořídit znovu"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Snímek obrazovky kvůli nedostatku místa v úložišti nelze uložit"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Nahrávání obrazovky"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Trvalé oznámení o relaci nahrávání"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Spustit nahrávání"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Nahrávat komentář"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Zobrazovat klepnutí"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Zastavit"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pozastavit"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Obnovit"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Zrušit"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Sdílet"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Smazat"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Nahrávání obrazovky bylo zrušeno"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Záznam obrazovky byl uložen, zobrazíte jej klepnutím"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Záznam obrazovky byl smazán"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Při mazání záznamu obrazovky došlo k chybě"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nepodařilo se načíst oprávnění"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Připojit jako přehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Připojit jako fotoaparát (PTP)"</string>
@@ -588,15 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Oznámení"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Tato oznámení již nebudete dostávat"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Tato oznámení budou minimalizována"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Tato oznámení obvykle odmítáte. \nChcete je nadále zobrazovat?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Mají se tato oznámení nadále zobrazovat?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Přestat zobrazovat oznámení"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Nadále zobrazovat"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovat"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Mají se oznámení z této aplikace nadále zobrazovat?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Tato oznámení nelze deaktivovat"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Tato aplikace využívá fotoaparát."</string>
<string name="appops_microphone" msgid="741508267659494555">"Tato aplikace využívá mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Tato aplikace se zobrazuje přes ostatní aplikace na obrazovce."</string>
@@ -735,8 +757,7 @@
<item msgid="2139628951880142927">"Zobrazovat procento při nabíjení (výchozí nastavení)"</item>
<item msgid="3327323682209964956">"Tuto ikonu nezobrazovat"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Zobrazit ikony oznámení s nízkou prioritou"</string>
<string name="other" msgid="4060683095962566764">"Jiné"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Čára rozdělující obrazovku"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Levá část na celou obrazovku"</string>
@@ -816,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikace byla otevřena bez instalace."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikace byla otevřena bez instalace. Klepnutím zobrazíte další informace."</string>
<string name="app_info" msgid="6856026610594615344">"O aplikaci"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Přejít na web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Přejít do prohlížeče"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilní data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je vypnuta"</string>
@@ -848,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Nastavení"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Rozumím"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Výpis haldy SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Aplikace <xliff:g id="APP">%1$s</xliff:g> využívá tato oprávnění: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikace využívají tato oprávnění: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otevřít aplikaci"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Zrušit"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Nastavení"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Aplikace <xliff:g id="APP">%1$s</xliff:g> v posledních <xliff:g id="TIME">%3$d</xliff:g> min využívá toto oprávnění: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikace <xliff:g id="APPS">%1$s</xliff:g> využívají toto oprávnění: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Aplikace <xliff:g id="APP">%1$s</xliff:g> využívá tato oprávnění: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparát"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"poloha"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index d470582..c30441b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prøv at tage et screenshot igen"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Screenshottet kan ikke gemmes, fordi der er begrænset lagerplads"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Appen eller din organisation tillader ikke, at du tager screenshots"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Skærmoptagelse"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Konstant underretning om skærmoptagelse"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start optagelse"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Optag voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Vis tryk"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Sæt på pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Genoptag"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Annuller"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Del"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Slet"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Skærmoptagelsen er annulleret"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Skærmoptagelsen er gemt. Tryk for at se den."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Skærmoptagelsen er slettet"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Der opstod en fejl ved sletning af skærmoptagelsen"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Det lykkedes ikke et hente tilladelserne"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Muligheder for USB-filoverførsel"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Isæt som en medieafspiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Underretninger"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Du får ikke længere vist disse underretninger"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Disse underretninger minimeres"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Du afviser som regel disse underretninger. \nVil du blive ved med at se dem?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vil du fortsætte med at se disse underretninger?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop underretninger"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Fortsæt med at vise underretninger"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsætte med at se underretninger fra denne app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Disse underretninger kan ikke deaktiveres"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Denne app anvender kameraet."</string>
<string name="appops_microphone" msgid="741508267659494555">"Denne app anvender mikrofonen."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Denne app vises over andre apps på din skærm."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Vis procent ved opladning (standard)"</item>
<item msgid="3327323682209964956">"Vis ikke dette ikon"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Vis ikoner for underretninger med lav prioritet"</string>
<string name="other" msgid="4060683095962566764">"Andet"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Adskiller til opdelt skærm"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Vis venstre del i fuld skærm"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"En app blev åbnet uden at blive installeret."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"En app blev åbnet uden at blive installeret. Tryk for at få flere oplysninger."</string>
<string name="app_info" msgid="6856026610594615344">"Appinfo"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Gå til website"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Gå til en browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er slået fra"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Indstillinger"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Gem SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> anvender enhedens <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Apps anvender enhedens <xliff:g id="TYPES_LIST">%s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Åbn app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Luk"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Indstillinger"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> har anvendt enhedens <xliff:g id="TYPE">%2$s</xliff:g> i de sidste <xliff:g id="TIME">%3$d</xliff:g> min."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> anvender enhedens <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> anvender enhedens <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"placering"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 7fcb02c..69af8f7 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Versuche noch einmal, den Screenshot zu erstellen"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Speichern des Screenshots aufgrund von zu wenig Speicher nicht möglich"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Die App oder deine Organisation lässt das Erstellen von Screenshots nicht zu"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Bildschirmaufzeichnung"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Fortlaufende Benachrichtigung für eine Bildschirmaufzeichnung"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Aufzeichnung starten"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Voice-over aufnehmen"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Fingertipps anzeigen"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Anhalten"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausieren"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Fortsetzen"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Abbrechen"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Teilen"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Löschen"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Bildschirmaufzeichnung abgebrochen"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Bildschirmaufzeichnung gespeichert, zum Ansehen tippen"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Bildschirmaufzeichnung gelöscht"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Fehler beim Löschen der Bildschirmaufzeichnung"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Berechtigungen nicht erhalten"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Als Medienplayer (MTP) bereitstellen"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Als Kamera (PTP) bereitstellen"</string>
@@ -586,14 +602,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Benachrichtigungen"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Du erhältst diese Benachrichtigungen nicht mehr"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Diese Benachrichtigungen werden minimiert"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Normalerweise schließt du diese Benachrichtigungen. \nSollen sie trotzdem weiter angezeigt werden?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Diese Benachrichtigungen weiterhin anzeigen?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Benachrichtigungen nicht mehr anzeigen"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Weiterhin anzeigen"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimieren"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Benachrichtigungen dieser App weiterhin anzeigen?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Diese Benachrichtigungen können nicht deaktiviert werden"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"über <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Diese App verwendet die Kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Diese App verwendet das Mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Diese App wird über anderen Apps auf dem Bildschirm angezeigt."</string>
@@ -808,7 +831,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App wurde geöffnet, ohne vorher installiert zu werden."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App wurde geöffnet, ohne vorher installiert zu werden. Tippe, um weitere Informationen zu erhalten."</string>
<string name="app_info" msgid="6856026610594615344">"App-Informationen"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Web aufrufen"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Browser öffnen"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile Daten"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"WLAN ist deaktiviert"</string>
@@ -840,4 +863,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Einstellungen"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> verwendet gerade Folgendes: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Apps verwenden gerade Folgendes: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"App öffnen"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Abbrechen"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Einstellungen"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> verwendet seit <xliff:g id="TIME">%3$d</xliff:g> Minuten Folgendes: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> verwenden gerade Folgendes: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> verwendet gerade Folgendes: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"Kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"Standort"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"Mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 12f0d532..67355ef 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Δοκιμάστε να κάνετε ξανά λήψη του στιγμιότυπου οθόνης"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Αδύνατη η αποθήκευση του στιγμιότυπου οθόνης λόγω περιορισμένου αποθηκευτικού χώρου"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Η λήψη στιγμιότυπων οθόνης δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Εγγραφή οθόνης"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ειδοποίηση σε εξέλιξη για μια περίοδο λειτουργίας εγγραφής οθόνης"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Έναρξη εγγραφής"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Εγγραφή σπικάζ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Εμφάνιση πατημάτων"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Διακοπή"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Παύση"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Συνέχιση"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Ακύρωση"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Κοινοποίηση"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Διαγραφή"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Η εγγραφή οθόνης ακυρώθηκε"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Η εγγραφή οθόνης αποθηκεύτηκε. Πατήστε για προβολή."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Η εγγραφή οθόνης διαγράφηκε"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Παρουσιάστηκε σφάλμα κατά τη διαγραφή της εγγραφής οθόνης"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Η λήψη αδειών απέτυχε"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Επιλογές μεταφοράς αρχείων μέσω USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Προσάρτηση ως μονάδας αναπαραγωγής μέσων (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Προσάρτηση ως κάμερας (PTP)"</string>
@@ -130,7 +146,7 @@
<string name="accessibility_ethernet_disconnected" msgid="5896059303377589469">"Το Ethernet αποσυνδέθηκε."</string>
<string name="accessibility_ethernet_connected" msgid="2692130313069182636">"Το Ethernet συνδέθηκε."</string>
<string name="accessibility_no_signal" msgid="7064645320782585167">"Δεν υπάρχει σήμα."</string>
- <string name="accessibility_not_connected" msgid="6395326276213402883">"Δεν έχει συνδεθεί."</string>
+ <string name="accessibility_not_connected" msgid="6395326276213402883">"Μη συνδεδεμένο"</string>
<string name="accessibility_zero_bars" msgid="3806060224467027887">"Μηδέν γραμμές."</string>
<string name="accessibility_one_bar" msgid="1685730113192081895">"Μία γραμμή."</string>
<string name="accessibility_two_bars" msgid="6437363648385206679">"Δύο γραμμές."</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Ειδοποιήσεις"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Δεν θα βλέπετε πλέον αυτές τις ειδοποιήσεις"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Αυτές οι ειδοποιήσεις θα ελαχιστοποιηθούν"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Συνήθως απορρίπτετε αυτές τις ειδοποιήσεις. \nΝα εξακολουθήσουν να εμφανίζονται;"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Να συνεχίσουν να εμφανίζονται αυτές οι ειδοποιήσεις;"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Διακοπή ειδοποιήσεων"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Συνέχιση εμφάνισης"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Ελαχιστοποίηση"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Να συνεχίσουν να εμφανίζονται ειδοποιήσεις από αυτήν την εφαρμογή;"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Αδύνατη η απενεργοποίηση αυτών των ειδοποιήσεων"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Αυτή η εφαρμογή χρησιμοποιεί την κάμερα."</string>
<string name="appops_microphone" msgid="741508267659494555">"Αυτή η εφαρμογή χρησιμοποιεί το μικρόφωνο."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Αυτή η εφαρμογή εμφανίζεται πάνω σε άλλες εφαρμογές στην οθόνη σας."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Να εμφανίζεται ποσοστό κατά τη φόρτιση (προεπιλογή)"</item>
<item msgid="3327323682209964956">"Να μην εμφανίζεται αυτό το εικονίδιο"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Εμφάνιση εικονιδίων ειδοποιήσεων χαμηλής προτεραιότητας"</string>
<string name="other" msgid="4060683095962566764">"Άλλο"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Διαχωριστικό οθόνης"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Αριστερή πλήρης οθόνη"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Η εφαρμογή άνοιξε χωρίς να έχει εγκατασταθεί."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Η εφαρμογή άνοιξε χωρίς να έχει εγκατασταθεί. Πατήστε για να μάθετε περισσότερα."</string>
<string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Μετάβαση στον ιστό"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Μετάβ. σε πρόγ. περ."</string>
<string name="mobile_data" msgid="7094582042819250762">"Δεδομένα κινητής τηλεφωνίας"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Το Wi-Fi είναι ανενεργό"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ρυθμίσεις"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Το κατάλαβα"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Στιγμ. μνήμης SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> χρησιμοποιεί τις λειτουργίες <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Οι εφαρμογές χρησιμοποιούν τις λειτουργίες <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Άν. εφαρμ."</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Ακύρωση"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ΟΚ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ρυθμίσεις"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> χρησιμοποιεί τη λειτουργία <xliff:g id="TYPE">%2$s</xliff:g> εδώ και <xliff:g id="TIME">%3$d</xliff:g> λ."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Οι εφαρμογές <xliff:g id="APPS">%1$s</xliff:g> χρησιμοποιούν τη λειτουργία <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Η εφαρμογή <xliff:g id="APP">%1$s</xliff:g> χρησιμοποιεί τις λειτουργίες <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"κάμερα"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"τοποθεσία"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"μικρόφωνο"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 82c91c7..26590be 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Can\'t save screenshot due to limited storage space"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Screen Recording"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ongoing notification for a screen record session"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start Recording"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Record voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Show taps"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Resume"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Share"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Screen recording cancelled"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Screen recording saved, tap to view"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Screen recording deleted"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error deleting screen recording"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Failed to get permissions"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"You won\'t see these notifications anymore"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"These notifications will be minimised"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"These notifications will be shown silently"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"These notifications will alert you"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"You usually dismiss these notifications. \nKeep showing them?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Keep showing these notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Keep showing"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimise"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Show silently"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Show and alert"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"These notifications can\'t be turned off"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"This app is using the camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"This app is using the microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"This app is displaying over other apps on your screen."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Settings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Settings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPE">%2$s</xliff:g> for the last <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> are using your <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"location"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 361310e..2a59d07 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Can\'t save screenshot due to limited storage space"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Screen Recording"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ongoing notification for a screen record session"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start Recording"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Record voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Show taps"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Resume"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Share"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Screen recording cancelled"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Screen recording saved, tap to view"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Screen recording deleted"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error deleting screen recording"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Failed to get permissions"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"You won\'t see these notifications anymore"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"These notifications will be minimised"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"These notifications will be shown silently"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"These notifications will alert you"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"You usually dismiss these notifications. \nKeep showing them?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Keep showing these notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Keep showing"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimise"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Show silently"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Show and alert"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"These notifications can\'t be turned off"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"This app is using the camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"This app is using the microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"This app is displaying over other apps on your screen."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Settings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Settings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPE">%2$s</xliff:g> for the last <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> are using your <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"location"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 82c91c7..26590be 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Can\'t save screenshot due to limited storage space"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Screen Recording"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ongoing notification for a screen record session"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start Recording"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Record voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Show taps"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Resume"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Share"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Screen recording cancelled"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Screen recording saved, tap to view"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Screen recording deleted"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error deleting screen recording"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Failed to get permissions"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"You won\'t see these notifications anymore"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"These notifications will be minimised"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"These notifications will be shown silently"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"These notifications will alert you"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"You usually dismiss these notifications. \nKeep showing them?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Keep showing these notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Keep showing"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimise"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Show silently"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Show and alert"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"These notifications can\'t be turned off"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"This app is using the camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"This app is using the microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"This app is displaying over other apps on your screen."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Settings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Settings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPE">%2$s</xliff:g> for the last <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> are using your <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"location"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 82c91c7..26590be 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Can\'t save screenshot due to limited storage space"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organisation"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Screen Recording"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ongoing notification for a screen record session"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start Recording"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Record voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Show taps"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Resume"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Share"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Screen recording cancelled"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Screen recording saved, tap to view"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Screen recording deleted"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error deleting screen recording"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Failed to get permissions"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"You won\'t see these notifications anymore"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"These notifications will be minimised"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"These notifications will be shown silently"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"These notifications will alert you"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"You usually dismiss these notifications. \nKeep showing them?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Keep showing these notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Keep showing"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimise"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Show silently"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Show and alert"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"These notifications can\'t be turned off"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"This app is using the camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"This app is using the microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"This app is displaying over other apps on your screen."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to find out more."</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Settings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Settings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPE">%2$s</xliff:g> for the last <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> are using your <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"location"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 8005d79..35075a7 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Try taking screenshot again"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Can\'t save screenshot due to limited storage space"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Taking screenshots isn\'t allowed by the app or your organization"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Screen Recording"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ongoing notification for a screen record session"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start Recording"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Record voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Show taps"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Resume"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancel"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Share"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Screen recording canceled"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Screen recording saved, tap to view"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Screen recording deleted"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error deleting screen recording"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Failed to get permissions"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Mount as a media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Mount as a camera (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"You won\'t see these notifications anymore"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"These notifications will be minimized"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"These notifications will be shown silently"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"These notifications will alert you"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"You usually dismiss these notifications. \nKeep showing them?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Keep showing these notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stop notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Keep showing"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimize"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Show silently"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Show and alert"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Keep showing notifications from this app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"These notifications can\'t be turned off"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"via <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"This app is using the camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"This app is using the microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"This app is displaying over other apps on your screen."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App opened without being installed."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App opened without being installed. Tap to learn more."</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Go to web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Go to browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi is off"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Settings"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Got it"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Applications are using your <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Open app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancel"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Okay"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Settings"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPE">%2$s</xliff:g> for the last <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> are using your <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> is using your <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"location"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 3f3187b..54362c3 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Vuelve a hacer una captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"No se puede guardar la captura de pantalla debido a que no hay suficiente espacio de almacenamiento"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"La app o tu organización no permiten las capturas de pantalla"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Grabación de pantalla"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificación constante para una sesión de grabación de pantalla"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar grabación"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Grabar voz superpuesta"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Detener"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausar"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Reanudar"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Compartir"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Borrar"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Se canceló la grabación de pantalla"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Se guardó la grabación de pantalla; presiona para verla"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Se borró la grabación de pantalla"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error al borrar la grabación de pantalla"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Error al obtener permisos"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Ya no verás estas notificaciones"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Se minimizarán estas notificaciones"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Sueles descartar estas notificaciones. \n¿Quieres seguir recibiéndolas?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"¿Quieres seguir viendo estas notificaciones?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Detener notificaciones"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Seguir viendo"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"No se pueden desactivar estas notificaciones"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Esta app está usando la cámara."</string>
<string name="appops_microphone" msgid="741508267659494555">"Esta app está usando el micrófono."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Esta app se muestra sobre otras apps en la pantalla."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Mostrar el porcentaje durante la carga (predeterminado)"</item>
<item msgid="3327323682209964956">"No mostrar este ícono"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Mostrar íconos de notificaciones con prioridad baja"</string>
<string name="other" msgid="4060683095962566764">"Otros"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Divisor de pantalla dividida"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Pantalla izquierda completa"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"La app se abrió sin instalarse."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"La app se abrió sin instalarse. Presiona para obtener más información."</string>
<string name="app_info" msgid="6856026610594615344">"Información de apps"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Ir a la Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ir al navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Datos móviles"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Configuración"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Entendido"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Volcar pila de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Hay aplicaciones que están usando tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Aceptar"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ajustes"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> lleva <xliff:g id="TIME">%3$d</xliff:g> min usando tu <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> están usando tu <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"cámara"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ubicación"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"micrófono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 356ef45..7fb2b8e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Vuelve a intentar hacer la captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"No se puede guardar la captura de pantalla porque no hay espacio de almacenamiento suficiente"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"La aplicación o tu organización no permiten realizar capturas de pantalla"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Grabación de la pantalla"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificación continua de una sesión de grabación de la pantalla"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar grabación"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Grabar voz en off"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Detener"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausar"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Seguir"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Compartir"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Eliminar"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Se ha cancelado la grabación de la pantalla"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Se ha guardado la grabación de la pantalla; toca para verla"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Se ha eliminado la grabación de la pantalla"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"No se ha podido eliminar la grabación de la pantalla"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"No se han podido obtener los permisos"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Activar como reproductor de medios (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Activar como cámara (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificaciones"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"No volverás a ver estas notificaciones"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Se minimizarán estas notificaciones"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Estas notificaciones se mostrarán de forma silenciosa"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Estas notificaciones te avisarán con sonido"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Normalmente ignoras estas notificaciones. \n¿Quieres seguir viéndolas?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"¿Quieres seguir viendo estas notificaciones?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Detener las notificaciones"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Seguir mostrando"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Mostrar en silencio"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Mostrar y sonar"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"¿Quieres seguir viendo las notificaciones de esta aplicación?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Estas notificaciones no se pueden desactivar"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"mediante <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Esta aplicación está usando la cámara."</string>
<string name="appops_microphone" msgid="741508267659494555">"Esta aplicación está usando el micrófono."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Esta aplicación se está mostrando sobre otras aplicaciones en tu pantalla."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"La aplicación se ha abierto sin instalarse."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"La aplicación se ha abierto sin instalarse. Toca para obtener más información."</string>
<string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Ir a la Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ir al navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Datos móviles"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> ‑ <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desactivado"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ajustes"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Entendido"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Volcar pila de SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Hay aplicaciones que usan tu <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Aceptar"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ajustes"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPE">%2$s</xliff:g> desde hace <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> están usando tu <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> está usando tu <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"cámara"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ubicación"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"micrófono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index f125b84..65a42a6 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Proovige ekraanipilt uuesti jäädvustada"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Piiratud salvestusruumi tõttu ei saa ekraanipilti salvestada"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ekraanikuva salvestamine"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Pooleli märguanne ekraanikuva salvestamise seansi puhul"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Alusta salvestamist"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Salvesta hääl"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Kuva puudutused"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Peata"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Peata"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Jätka"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Tühista"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Jaga"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Kustuta"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekraanikuva salvestamine on tühistatud"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekraanikuva salvestis on salvestatud, puudutage vaatamiseks"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekraanikuva salvestis on kustutatud"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Viga ekraanikuva salvestise kustutamisel"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Lubade hankimine ebaõnnestus"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-failiedastuse valikud"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Paigalda meediumimängijana (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Paigalda kaamerana (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Märguanded"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Te ei näe enam neid märguandeid"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Need märguanded minimeeritakse"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Tavaliselt loobute nendest märguannetest. \nKas soovite neid jätkuvalt näidata?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Kas soovite nende märguannete kuvamist jätkata?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Peata märguanded"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Jätka kuvamist"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimeeri"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Kas jätkata selle rakenduse märguannete kuvamist?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Neid märguandeid ei saa välja lülitada"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"See rakendus kasutab kaamerat."</string>
<string name="appops_microphone" msgid="741508267659494555">"See rakendus kasutab mikrofoni."</string>
<string name="appops_overlay" msgid="6165912637560323464">"See rakendus kuvatakse teie ekraanil muude rakenduste peal."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Kuva protsent laadimisel (vaikimisi)"</item>
<item msgid="3327323682209964956">"Ära kuva seda ikooni"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Kuva madala prioriteediga märguande ikoonid"</string>
<string name="other" msgid="4060683095962566764">"Muu"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Ekraanijagaja"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Vasak täisekraan"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Rakendus avati installimata."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Rakendus avati installimata. Lisateabe saamiseks puudutage."</string>
<string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Avage veebis"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ava brauser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobiilne andmeside"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"WiFi on välja lülitatud"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Seaded"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Selge"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> kasutab järgmisi: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Rakendused kasutavad järgmisi: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ava rakendus"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Tühista"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Seaded"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> on viimased <xliff:g id="TIME">%3$d</xliff:g> minutit kasutanud järgmist: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> kasutavad järgmist: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> kasutab järgmisi: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kaamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"asukoht"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 6e3f094..97ba5b9 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Saiatu berriro pantaila-argazkia ateratzen"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Ezin da gorde pantaila-argazkia ez delako gelditzen tokirik"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Pantailaren grabaketa"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Pantailaren grabaketa-saioaren jakinarazpen jarraitua"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Hasi grabatzen"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Grabatu off ahotsa"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Erakutsi sakatzeak"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Utzi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausatu"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Berrekin"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Utzi"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Partekatu"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Ezabatu"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Utzi zaio pantaila grabatzeari"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Gorde da pantailaren grabaketa; sakatu ikusteko"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ezabatu da pantailaren grabaketa"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Errore bat gertatu da pantailaren grabaketa ezabatzean"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Ezin izan dira lortu baimenak"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB fitxategiak transferitzeko aukerak"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Muntatu multimedia-erreproduzigailu gisa (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Muntatu kamera gisa (PTP)"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Jakinarazpenak"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Aurrerantzean ez duzu ikusiko horrelako jakinarazpenik"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Minimizatu egingo dira jakinarazpen hauek"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Jakinarazpen hauek soinurik egin gabe erakutsiko dira"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Jakinarazpen hauek soinu bidezko alerta bidez erakutsiko dira"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Baztertu egin ohi dituzu jakinarazpen hauek. \nHaiek erakusten jarraitzea nahi duzu?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Blokeatu jakinarazpenak"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Jarraitu erakusten"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizatu"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Erakutsi soinurik egin gabepen"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Erakutsi eta egin soinua"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Aplikazio honen jakinarazpenak erakusten jarraitzea nahi duzu?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Jakinarazpen hauek ezin dira desaktibatu"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioaren bidez"</string>
<string name="appops_camera" msgid="8100147441602585776">"Kamera erabiltzen ari da aplikazioa."</string>
<string name="appops_microphone" msgid="741508267659494555">"Mikrofonoa erabiltzen ari da aplikazioa."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Pantailako beste aplikazioen gainean agertzen da aplikazioa."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Ezer instalatu gabe ireki da aplikazioa."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ezer instalatu gabe ireki da aplikazioa. Sakatu informazio gehiago lortzeko."</string>
<string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Joan sarera"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Joan arakatzailera"</string>
<string name="mobile_data" msgid="7094582042819250762">"Datu-konexioa"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi konexioa desaktibatuta dago"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ezarpenak"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ados"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> erabiltzen ari da."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikazio batzuk <xliff:g id="TYPES_LIST">%s</xliff:g> erabiltzen ari dira."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ireki aplikazioa"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Utzi"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Ados"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ezarpenak"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> aplikazioak <xliff:g id="TYPE">%2$s</xliff:g> erabili du azken <xliff:g id="TIME">%3$d</xliff:g> minutuetan"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> <xliff:g id="TYPE">%2$s</xliff:g> erabiltzen ari dira"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="TYPES_LIST">%2$s</xliff:g> erabiltzen ari da"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"kokapena"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofonoa"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index e785f76..049513a 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"دوباره عکس صفحهنمایش بگیرید"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"به دلیل محدود بودن فضای ذخیرهسازی نمیتوان عکس صفحهنمایش را ذخیره کرد"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"برنامه یا سازمان شما اجازه نمیدهند عکس صفحهنمایش بگیرید."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ضبط صفحهنمایش"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"اعلان درحال انجام برای جلسه ضبط صفحهنمایش"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"شروع ضبط"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ضبط صدا روی تصویر"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"نمایش ضربهها"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"توقف"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"مکث"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ازسرگیری"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"لغو"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"همرسانی"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"حذف"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ضبط صفحهنمایش لغو شد"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ضبط صفحهنمایش ذخیره شد، برای مشاهده ضربه بزنید"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"فایل ضبط صفحهنمایش حذف شد"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"خطا در حذف فایل ضبط صفحهنمایش"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"مجوزها دریافت نشدند"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"گزینههای انتقال فایل USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"نصب بهعنوان دستگاه پخش رسانه (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"تصب بهعنوان دوربین (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"اعلانها"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"دیگر این اعلانها را نخواهید دید"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"این اعلانها کوچک خواهد شد"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"معمولاً این اعلانها را رد میکنید. \nهمچنان نشان داده شود؟"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"نمایش این اعلانها ادامه یابد؟"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"توقف اعلانها"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"همچنان نشان داده شود"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"کوچک کردن"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"نمایش اعلان از این برنامه ادامه یابد؟"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"نمیتوان این اعلانها را خاموش کرد"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"این برنامه از دوربین استفاده میکند."</string>
<string name="appops_microphone" msgid="741508267659494555">"این برنامه از میکروفون استفاده میکند."</string>
<string name="appops_overlay" msgid="6165912637560323464">"این برنامه روی برنامههای دیگر در صفحهنمایش نشان داده میشود."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"هنگام شارژ شدن درصد نشان داده شود (پیشفرض)"</item>
<item msgid="3327323682209964956">"این نماد نشان داده نشود"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"نمایش نمادهای اعلان کماهمیت"</string>
<string name="other" msgid="4060683095962566764">"موارد دیگر"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"تقسیمکننده صفحه"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"تمامصفحه چپ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"برنامه بدون نصب شدن باز شد."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"برنامه بدون نصب شدن باز شد. برای اطلاعات بیشتر ضربه بزنید."</string>
<string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string>
- <string name="go_to_web" msgid="1106022723459948514">"رفتن به وب"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"رفتن به مرورگر"</string>
<string name="mobile_data" msgid="7094582042819250762">"داده تلفن همراه"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi خاموش است"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"تنظیمات"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"متوجه شدم"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> از <xliff:g id="TYPES_LIST">%2$s</xliff:g> شما استفاده میکند."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"برنامهها از <xliff:g id="TYPES_LIST">%s</xliff:g> شما استفاده میکنند."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"باز کردن برنامه"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"لغو"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"خوب"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"تنظیمات"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> از <xliff:g id="TYPE">%2$s</xliff:g> در <xliff:g id="TIME">%3$d</xliff:g> دقیقه آخر استفاده میکند"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> از <xliff:g id="TYPE">%2$s</xliff:g> شما استفاده میکند"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> از <xliff:g id="TYPES_LIST">%2$s</xliff:g> شما استفاده میکند"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"دوربین"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"مکان"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"میکروفون"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index af35a85..277ef5d 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Yritä ottaa kuvakaappaus uudelleen."</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Kuvakaappauksen tallennus epäonnistui, sillä tallennustilaa ei ole riittävästi"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Sovellus tai organisaatio ei salli kuvakaappauksien tallentamista."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Näytön tallennus"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Pysyvä ilmoitus näytön tallentamisesta"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Aloita tallennus"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Äänitä taustaselostus"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Näytä napautukset"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Lopeta"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Keskeytä"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Jatka"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Peruuta"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Jaa"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Poista"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Näytön tallennus peruutettu"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Näyttötallenne tallennettu, katso napauttamalla"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Näyttötallenne poistettu"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Virhe poistettaessa näyttötallennetta"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Käyttöoikeuksien hakeminen epäonnistui."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Käytä mediasoittimena (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Käytä kamerana (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Ilmoitukset"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Et näe näitä ilmoituksia enää"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Nämä ilmoitukset pienennetään"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Hylkäät yleensä nämä ilmoitukset. \nHaluatko, että niitä näytetään myös jatkossa?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Jatketaanko näiden ilmoitusten näyttämistä?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Lopeta ilmoitukset"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Jatka näyttämistä"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Pienennä"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Jatketaanko ilmoitusten näyttämistä tästä sovelluksesta?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Näitä ilmoituksia ei voi poistaa käytöstä"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Tämä sovellus käyttää kameraa."</string>
<string name="appops_microphone" msgid="741508267659494555">"Tämä sovellus käyttää mikrofonia."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Tämä sovellus näkyy näytöllä muiden sovellusten päällä."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Sovellus avattiin ilman asennusta."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Sovellus avattiin ilman asennusta. Katso lisätietoja napauttamalla."</string>
<string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Avaa verkossa"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Siirry selaimeen"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobiilitiedonsiirto"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi on pois käytöstä"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Asetukset"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Selvä"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Luo SysUI-keon vedos"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> käyttää ominaisuuksia (<xliff:g id="TYPES_LIST">%2$s</xliff:g>)."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"<xliff:g id="TYPES_LIST">%s</xliff:g> ovat sovellusten käytössä."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Avaa"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Peruuta"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Asetukset"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> on käyttänyt ominaisuutta (<xliff:g id="TYPE">%2$s</xliff:g>) <xliff:g id="TIME">%3$d</xliff:g> minuutin ajan."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> käyttävät ominaisuutta (<xliff:g id="TYPE">%2$s</xliff:g>)."</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> käyttää ominaisuuksia (<xliff:g id="TYPES_LIST">%2$s</xliff:g>)."</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"sijainti"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofoni"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 06f178a..905af5b 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Essayez de faire une autre capture d\'écran"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Enregistrement d\'écran"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notification en cours pour une session d\'enregistrement d\'écran"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Commencer l\'enregistrement"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Enregistrer la voix hors champ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Afficher les éléments sélectionnés"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Arrêter"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Reprendre"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Annuler"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Partager"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Supprimer"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"L\'enregistrement d\'écran a été annulé"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"L\'enregistrement d\'écran est terminé. Touchez ici pour l\'afficher."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"L\'enregistrement d\'écran a été supprimé"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Une erreur s\'est produite lors de la suppression de l\'enregistrement d\'écran"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Impossible d\'obtenir les autorisations"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Installer comme un lecteur multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Installer comme un appareil photo (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Vous ne verrez plus ces notifications"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ces notifications seront réduites"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Vous ignorez habituellement ces notifications. \nSouhaitez-vous continuer à les afficher?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Continuer à afficher ces notifications?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Arrêter les notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuer à afficher"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer à afficher les notifications de cette application?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ces notifications ne peuvent pas être désactivées"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Cette application utilise l\'appareil photo."</string>
<string name="appops_microphone" msgid="741508267659494555">"Cette application utilise le microphone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Cette application superpose du contenu par-dessus d\'autres applications à l\'écran."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Montrer le pourcentage durant la charge (par défaut)"</item>
<item msgid="3327323682209964956">"Ne pas afficher cette icône"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Afficher les icônes de notification de faible priorité"</string>
<string name="other" msgid="4060683095962566764">"Autre"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Séparateur d\'écran partagé"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Plein écran à la gauche"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Application ouverte sans avoir été installée."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Application ouverte sans avoir été installée. Touchez ici pour en savoir plus."</string>
<string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Accéder au Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ouvrir le navigateur"</string>
<string name="mobile_data" msgid="7094582042819250762">"Données cellulaires"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> : <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Le Wi-Fi est désactivé"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Paramètres"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Capturer mémoire SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ouv. appli"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Annuler"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Paramètres"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPE">%2$s</xliff:g> depuis <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> utilisent votre <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"appareil photo"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"position"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microphone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7157cb5..88e5f6cd 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Essayez de nouveau de faire une capture d\'écran"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Les captures d\'écran ne sont pas autorisées par l\'application ni par votre organisation"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Enregistrement de l\'écran"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notification en cours pour une session d\'enregistrement de l\'écran"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Démarrer l\'enregistrement"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Enregistrer une voix off"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Afficher les éléments sélectionnés"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Arrêter"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Reprendre"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Annuler"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Partager"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Supprimer"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Enregistrement de l\'écran annulé"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Enregistrement de l\'écran enregistré. Appuyez pour afficher"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Enregistrement de l\'écran supprimé"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Erreur lors de la suppression de l\'enregistrement de l\'écran"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Échec d\'obtention des autorisations"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Installer en tant que lecteur multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Installer en tant qu\'appareil photo (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifications"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Vous ne recevrez plus ces notifications"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ces notifications seront réduites"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Vous ignorez généralement ces notifications. \nSouhaitez-vous continuer de les recevoir ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Continuer d\'afficher ces notifications ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Arrêter les notifications"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuer d\'afficher les notifications"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Réduire"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuer d\'afficher les notifications de cette application ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ces notifications ne peuvent pas être désactivées"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Cette application utilise la caméra."</string>
<string name="appops_microphone" msgid="741508267659494555">"Cette application utilise le micro."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Cette application se superpose aux autres applications sur l\'écran."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Afficher le pourcentage lorsque l\'appareil est en charge (option par défaut)"</item>
<item msgid="3327323682209964956">"Ne plus afficher cette icône"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Afficher les icônes de notification à faible priorité"</string>
<string name="other" msgid="4060683095962566764">"Autre"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Séparateur d\'écran partagé"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Écran de gauche en plein écran"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Vous pouvez ouvrir cette application sans l\'installer."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Vous pouvez ouvrir cette application sans l\'installer. Appuyez pour en savoir plus."</string>
<string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Accéder au site Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Accéder au navigateur"</string>
<string name="mobile_data" msgid="7094582042819250762">"Données mobiles"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi désactivé"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Paramètres"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Copier mémoire SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Des applications utilisent votre <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ouvrir appli"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Annuler"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Paramètres"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPE">%2$s</xliff:g> depuis <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> utilisent votre <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> utilise votre <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"appareil photo"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"position"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"micro"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index f17243e..999c1ca 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Volve tentar crear unha captura de pantalla"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Non se puido gardar a captura de pantalla porque o espazo de almacenamento é limitado"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"A aplicación ou a túa organización non permite realizar capturas de pantalla"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Gravación de pantalla"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificación en curso sobre unha sesión de gravación de pantalla"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar gravación"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Gravar voz en off"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Deter"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Poñer en pausa"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Retomar"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Compartir"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Eliminar"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Cancelouse a gravación de pantalla"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Gardouse a gravación de pantalla; toca esta notificación para visualizala"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Eliminouse a gravación de pantalla"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Produciuse un erro ao eliminar a gravación de pantalla"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Produciuse un erro ao obter os permisos"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opcións de transferencia USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Inserir como reprodutor multimedia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Inserir como cámara (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificacións"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Deixarás de ver estas notificacións"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Minimizaranse estas notificacións"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Ignoras estas notificacións a miúdo. \nQueres seguir recibíndoas?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Queres seguir mostrando estas notificacións?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Deter notificacións"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando notificacións"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Queres seguir mostrando as notificacións desta aplicación?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Non se poden desactivar estas notificacións"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Esta aplicación está utilizando a cámara."</string>
<string name="appops_microphone" msgid="741508267659494555">"Esta aplicación está utilizando o micrófono."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Esta aplicación móstrase sobre outras aplicacións da pantalla."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Mostrar porcentaxe durante a carga (predeterminado)"</item>
<item msgid="3327323682209964956">"Non mostrar esta icona"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Mostrar iconas das notificacións que teñan baixa prioridade"</string>
<string name="other" msgid="4060683095962566764">"Outros"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Divisor de pantalla dividida"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Pantalla completa á esquerda"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Abriuse a aplicación sen ter que instalala."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Abriuse a aplicación sen ter que instalala. Tocar para obter máis información."</string>
<string name="app_info" msgid="6856026610594615344">"Info. da aplicación"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Acceder á web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ir ao navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Datos móbiles"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>-<xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"A wifi está desactivada"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Configuración"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"De acordo"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Baleirar mont. SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> está utilizando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Hai aplicacións que están utilizando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Aceptar"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Axustes"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> está utilizando <xliff:g id="TYPE">%2$s</xliff:g> desde hai <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> están utilizando <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> está utilizando <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"a cámara"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"a localiz."</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"o micrófono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 1d55555..ecaa321 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ફરીથી સ્ક્રીનશૉટ લેવાનો પ્રયાસ કરો"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"મર્યાદિત સ્ટોરેજ સ્પેસને કારણે સ્ક્રીનશૉટ સાચવી શકાતો નથી"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશૉટ લેવાની મંજૂરી નથી"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"સ્ક્રીન રેકોર્ડિંગ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"સ્ક્રીન રેકોર્ડિંગ સત્ર માટે ચાલુ નોટિફિકેશન"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"રેકોર્ડિંગ શરૂ કરો"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"વૉઇસઓવર રેકોર્ડ કરો"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ટૅપ કર્યાની સંખ્યા બતાવો"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"રોકો"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"થોભાવો"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ફરી શરૂ કરો"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"રદ કરો"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"શેર કરો"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ડિલીટ કરો"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"સ્ક્રીન રેકોર્ડિંગ રદ કર્યું"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"સ્ક્રીન રેકોર્ડિંગ સાચવ્યું, જોવા માટે ટૅપ કરો"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કર્યું"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"સ્ક્રીન રેકોર્ડિંગ ડિલીટ કરવામાં ભૂલ આવી"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"પરવાનગીઓ મેળવવામાં નિષ્ફળ રહ્યાં"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ફાઇલ ટ્રાન્સફર વિકલ્પો"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"મીડિયા પ્લેયર તરીકે માઉન્ટ કરો (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"કૅમેરા તરીકે માઉન્ટ કરો (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"નોટિફિકેશનો"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"તમને હવેથી આ નોટિફિકેશન દેખાશે નહીં"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"આ બધા નોટિફિકેશન નાના કરવામાં આવશે"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"તમે સામાન્ય રીતે આ નોટીફિકેશનને છોડી દો છો. \nતેમને બતાવવાનું ચાલુ રાખીએ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"આ નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"નોટિફિકેશન બંધ કરો"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"બતાવવાનું ચાલુ રાખો"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"નાનું કરો"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"આ ઍપમાંથી નોટિફિકેશન બતાવવાનું ચાલુ રાખીએ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"આ નોટિફિકેશન બંધ કરી શકશો નહીં"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"આ ઍપ કૅમેરાનો ઉપયોગ કરી રહી છે."</string>
<string name="appops_microphone" msgid="741508267659494555">"આ ઍપ માઇક્રોફોનનો ઉપયોગ કરી રહી છે."</string>
<string name="appops_overlay" msgid="6165912637560323464">"આ ઍપ તમારી સ્ક્રીન પરની અન્ય ઍપની ઉપર પ્રદર્શિત થઈ રહી છે."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ચાર્જ થાય ત્યારે ટકાવારી બતાવો (ડિફોલ્ટ)"</item>
<item msgid="3327323682209964956">"આ આઇકન બતાવશો નહીં"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"ઓછી પ્રાધાન્યતાનું નોટિફિકેશન આઇકન બતાવો"</string>
<string name="other" msgid="4060683095962566764">"અન્ય"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"સ્પ્લિટ-સ્ક્રીન વિભાજક"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ડાબી પૂર્ણ સ્ક્રીન"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે. વધુ જાણવા માટે ટૅપ કરો."</string>
<string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
- <string name="go_to_web" msgid="1106022723459948514">"વેબ પર જાઓ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"બ્રાઉઝર પર જાઓ"</string>
<string name="mobile_data" msgid="7094582042819250762">"મોબાઇલ ડેટા"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"વાઇ-ફાઇ બંધ છે"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"સેટિંગ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"સમજાઈ ગયું"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ઍપ તમારા <xliff:g id="TYPES_LIST">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ઍપ્લિકેશન તમારા <xliff:g id="TYPES_LIST">%s</xliff:g>નો ઉપયોગ કરી રહી છે."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ઍપ ખોલો"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"રદ કરો"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ઓકે"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"સેટિંગ"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"છેલ્લી <xliff:g id="TIME">%3$d</xliff:g> મિનિટથી <xliff:g id="APP">%1$s</xliff:g> ઍપ તમારા <xliff:g id="TYPE">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ઍપ તમારા <xliff:g id="TYPE">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> અૅપ તમારા <xliff:g id="TYPES_LIST">%2$s</xliff:g>નો ઉપયોગ કરી રહી છે"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"કૅમેરા"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"સ્થાન"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"માઇક્રોફોન"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index e6004f3..c1cb317 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"स्क्रीनशॉट दोबारा लेने की कोशिश करें"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"मेमोरी कम होने की वजह से स्क्रीनशॉट सेव नहीं किया जा सका"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ऐप्लिकेशन या आपका संगठन स्क्रीनशॉट लेने की अनुमति नहीं देता"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"स्क्रीन रिकॉर्डिंग"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"स्क्रीन रिकॉर्ड सेशन के लिए जारी सूचना"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"रिकॉर्डिंग शुरू करें"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"वॉइसओवर रिकॉर्ड करें"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"टैप दिखाएं"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"रोकें"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"रोकें"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"फिर से शुरू करें"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"रद्द करें"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"शेयर करें"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"मिटाएं"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"स्क्रीन रिकॉर्डिंग रद्द कर दी गई"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"स्क्रीन रिकॉर्डिंग सेव की गई, देखने के लिए टैप करें"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"स्क्रीन रिकॉर्डिंग मिटा दी गई"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"स्क्रीन रिकॉर्डिंग मिटाने में गड़बड़ी हुई"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"मंज़ूरी नहीं मिल सकी"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेयर के रूप में माउंट करें (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"कैमरे के रूप में माउंट करें (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"अब आपको ये सूचनाएं दिखाई नहीं देंगी"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"इन सूचनाओं को छोटा कर दिया जाएगा"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"अाप अक्सर इन सूचनाओं को खारिज कर देते हैं. \nआगे भी इन्हें देखना जारी रखना चाहते हैं?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ये सूचनाएं दिखाना जारी रखें?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"सूचनाएं दिखाना बंद करें"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"दिखाना जारी रखें"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"सूचनाएं छोटी करें"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"इस ऐप्लिकेशन से जुड़ी सूचनाएं दिखाना जारी रखें?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ये सूचनाएं दिखाया जाना बंद नहीं किया जा सकता"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"यह ऐप्लिकेशन कैमरे का इस्तेमाल कर रहा है."</string>
<string name="appops_microphone" msgid="741508267659494555">"यह ऐप्लिकेशन माइक्रोफ़ोन का इस्तेमाल कर रहा है."</string>
<string name="appops_overlay" msgid="6165912637560323464">"यह ऐप्लिकेशन आपकी स्क्रीन पर इस्तेमाल हो रहे दूसरे ऐप्लिकेशन के ऊपर दिखाया जा रहा है."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"चार्ज होते समय प्रतिशत दिखाएं (डिफ़ॉल्ट)"</item>
<item msgid="3327323682209964956">"इस आइकॉन को ना दिखाएं"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"कम प्राथमिकता वाली सूचना के आइकॉन दिखाएं"</string>
<string name="other" msgid="4060683095962566764">"अन्य"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"विभाजित स्क्रीन विभाजक"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"बाईं स्क्रीन को पूर्ण स्क्रीन बनाएं"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ऐप्लिकेशन इंस्टॉल किए बिना ही खुल गया है. ज़्यादा जानने के लिए टैप करें."</string>
<string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string>
- <string name="go_to_web" msgid="1106022723459948514">"वेब पर जाएं"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ब्राउज़र पर जाएं"</string>
<string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"वाई-फ़ाई बंद है"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"सेटिंग"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ठीक है"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> आपकी <xliff:g id="TYPES_LIST">%2$s</xliff:g> का इस्तेमाल कर रहा है."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ऐप्लिकेशन आपकी <xliff:g id="TYPES_LIST">%s</xliff:g> का इस्तेमाल कर रहे हैं."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ऐप खोलें"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"रद्द करें"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ठीक है"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"सेटिंग"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"पिछले <xliff:g id="TIME">%3$d</xliff:g> मि. से <xliff:g id="APP">%1$s</xliff:g> आपकी <xliff:g id="TYPE">%2$s</xliff:g> का इस्तेमाल कर रहा है"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> आपकी <xliff:g id="TYPE">%2$s</xliff:g> का इस्तेमाल कर रहे हैं"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> आपकी <xliff:g id="TYPES_LIST">%2$s</xliff:g> का इस्तेमाल कर रहा है"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"कैमरा"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"जगह"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"माइक्रोफ़ोन"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 777a9ff..901e2fe 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Pokušajte ponovo napraviti snimku zaslona"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Zaslon nije snimljen zbog ograničenog prostora za pohranu"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikacija ili vaša organizacija ne dopuštaju snimanje zaslona"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Snimanje zaslona"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Tekuća obavijest za sesiju snimanja zaslona"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Započni snimanje"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Snimi glasovni zapis"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Prikaži dodire"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Zaustavi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pauza"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Nastavi"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Odustani"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Dijeli"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Izbriši"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Snimanje zaslona otkazano"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Snimanje zaslona spremljeno je, dodirnite da biste ga pregledali"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Snimanje zaslona izbrisano"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Pogreška prilikom brisanja snimanja zaslona"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Dohvaćanje dopuštenja nije uspjelo"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa datoteka"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Učitaj kao media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Učitaj kao fotoaparat (PTP)"</string>
@@ -585,14 +601,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Obavijesti"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Te vam se obavijesti više neće prikazivati"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Te će se obavijesti minimizirati"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Ove obavijesti prikazivat će se tiho"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Ove obavijesti imat će zvučni signal"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Obično odbacujete te obavijesti. \nŽelite li da se nastave prikazivati?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Želite li da se obavijesti nastave prikazivati?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Zaustavi obavijesti"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Nastavi prikazivati"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimiziraj"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Prikaži tiho"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Prikaži uz zvučni signal"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite li da se obavijesti te aplikacije nastave prikazivati?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Te se obavijesti ne mogu isključiti"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"putem aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Ova aplikacija upotrebljava kameru."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ova aplikacija upotrebljava mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ova se aplikacija prikazuje preko drugih aplikacija na zaslonu."</string>
@@ -809,7 +828,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je otvorena bez instaliranja."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je otvorena bez instaliranja. Dodirnite da biste saznali više."</string>
<string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Prijeđi na web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Otvori preglednik"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilni podaci"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je isključen"</string>
@@ -841,4 +860,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Postavke"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Shvaćam"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Izdvoji mem. SysUI-a"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> upotrebljava <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacije upotrebljavaju <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otvori aplikaciju"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Odustani"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"U redu"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Postavke"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> upotrebljava <xliff:g id="TYPE">%2$s</xliff:g> unatrag <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikacije <xliff:g id="APPS">%1$s</xliff:g> upotrebljavaju <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> upotrebljava <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparat"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokaciju"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 16db000..7a5e026 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Próbálja meg újra elkészíteni a képernyőképet"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Nem menthet képernyőképet, mert kevés a tárhely"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Az alkalmazás vagy az Ön szervezete nem engedélyezi képernyőkép készítését"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Képernyőrögzítés"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Folyamatban lévő értesítés képernyőrögzítési munkamenethez"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Rögzítés indítása"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Hang rögzítése"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Koppintások megjelenítése"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Leállítás"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Szünet"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Folytatás"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Mégse"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Megosztás"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Törlés"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"A képernyő rögzítése megszakítva"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Képernyőfelvétel mentve, koppintson a megtekintéshez"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"A képernyőről készült felvétel törölve"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Hiba történt a képernyőről készült felvétel törlésekor"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nincs engedély"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB-fájlátvitel beállításai"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Csatlakoztatás médialejátszóként (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Csatlakoztatás kameraként (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Értesítések"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Többé nem jelennek meg ezek az értesítések"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ezek az értesítések kis méretben jelennek meg"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Általában elveti ezeket az értesítéseket.\nSzeretné, hogy továbbra is megjelenjenek?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Továbbra is megjelenjenek ezek az értesítések?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Értesítések letiltása"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Megjelenítés továbbra is"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Kis méret"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Továbbra is megjelenjenek az alkalmazás értesítései?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ezeket az értesítéseket nem lehet kikapcsolni"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ez az alkalmazás használja a kamerát."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ez az alkalmazás használja a mikrofont."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ez az alkalmazás a képernyőn lévő egyéb alkalmazások előtt jelenik meg."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Százalékos érték töltés közben látható (alapértelmezett)"</item>
<item msgid="3327323682209964956">"Ne jelenjen meg ez az ikon"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Alacsony prioritású értesítési ikonok mutatása"</string>
<string name="other" msgid="4060683095962566764">"Egyéb"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Elválasztó az osztott nézetben"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Bal oldali teljes képernyőre"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Az alkalmazás telepítés nélkül lett megnyitva."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Az alkalmazás telepítés nélkül lett megnyitva. Ha további információra van szüksége, koppintson ide."</string>
<string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Tovább az internetre"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ugrás a böngészőbe"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobiladatok"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"A Wi-Fi ki van kapcsolva"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Beállítások"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Értem"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI-memória-kiírás"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"A(z) <xliff:g id="APP">%1$s</xliff:g> használja a következőket: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Több alkalmazás használja a következőket: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Megnyitás"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Mégse"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Beállítás"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"A(z) <xliff:g id="APP">%1$s</xliff:g> az elmúlt <xliff:g id="TIME">%3$d</xliff:g> percben használta a következőt: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"A(z) <xliff:g id="APPS">%1$s</xliff:g> használja a következőt: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"A(z) <xliff:g id="APP">%1$s</xliff:g> használja a következőt: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"helyadatok"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index c1ee1d7..da36e62 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Փորձեք նորից"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Չհաջողվեց պահել սքրինշոթը անբավարար հիշողության պատճառով"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում սքրինշոթի ստացումը"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Էկրանի տեսագրում"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Էկրանի տեսագրման աշխատաշրջանի ընթացիկ ծանուցում"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Սկսել տեսագրումը"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Ձայնագրել ուղեկցող ձայները"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Ցույց տալ հպումները"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Կանգնեցնել"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Դադարեցնել"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Վերսկսել"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Չեղարկել"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Կիսվել"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Ջնջել"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Էկրանի տեսագրումը չեղարկվեց"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Էկրանի տեսագրությունը պահվեց։ Հպեք՝ դիտելու համար:"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Էկրանի տեսագրությունը ջնջվեց"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Չհաջողվեց ջնջել տեսագրությունը"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Չհաջողվեց ստանալ անհրաժեշտ թույլտվությունները"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ֆայլերի փոխանցման ընտրանքներ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Միացնել որպես մեդիա նվագարկիչ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Միացնել որպես ֆոտոխցիկ (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Ծանուցումներ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Դուք այլևս չեք ստանա այս ծանուցումները"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Այս ծանուցումները կծալվեն:"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Դուք սովորաբար փակում եք այս ծանուցումները: \nՇարունակե՞լ ցուցադրել դրանք:"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Ցուցադրե՞լ այս ծանուցումները։"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Չցուցադրել ծանուցումներ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Ցուցադրել"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Ծալել"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Ցուցադրե՞լ ծանուցումներ այս հավելվածից։"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Այս ծանուցումները հնարավոր չէ անջատել"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Այս հավելվածն օգտագործում է տեսախցիկը:"</string>
<string name="appops_microphone" msgid="741508267659494555">"Այս հավելվածն օգտագործում է խոսափողը:"</string>
<string name="appops_overlay" msgid="6165912637560323464">"Այս հավելվածը ցուցադրվում է մյուս հավելվածների վրայից:"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Ցույց տալ տոկոսը լիցքավորելու ժամանակ (կանխադրված է)"</item>
<item msgid="3327323682209964956">"Ցույց չտալ այս պատկերակը"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Ցուցադրել ցածր առաջնահերթության ծանուցումների պատկերակները"</string>
<string name="other" msgid="4060683095962566764">"Այլ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Տրոհված էկրանի բաժանիչ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Ձախ էկրանը՝ լիաէկրան"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Հավելվածը բացվել է առանց տեղադրման։"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Հավելվածը բացվել է առանց տեղադրման։ Հպեք՝ ավելին իմանալու համար։"</string>
<string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Բացեք համացանցում"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Անցնել դիտարկիչ"</string>
<string name="mobile_data" msgid="7094582042819250762">"Բջջային ինտերնետ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi-ն անջատված է"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Կարգավորումներ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Եղավ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է ձեր <xliff:g id="TYPES_LIST">%2$s</xliff:g>:"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Հավելվածներն օգտագործում են ձեր <xliff:g id="TYPES_LIST">%s</xliff:g>:"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Բացել հավելվածը"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Չեղարկել"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Փակել"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Պարամետրեր"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է ձեր <xliff:g id="TYPE">%2$s</xliff:g> վերջին <xliff:g id="TIME">%3$d</xliff:g> րոպեի ընթացքում"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> հավելվածներն օգտագործում են ձեր <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> հավելվածն օգտագործում է ձեր <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"տեսախցիկը"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"վայրը"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"խոսափողը"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 1cd4d30..bb0a725 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Coba ambil screenshot lagi"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Tidak dapat menyimpan screenshot karena ruang penyimpanan terbatas"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Mengambil screenshot tidak diizinkan oleh aplikasi atau organisasi"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Rekaman Layar"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notifikasi yang sedang berjalan untuk sesi rekaman layar"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Mulai Merekam"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Rekam voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Tampilkan sentuhan"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stop"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Jeda"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Lanjutkan"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Batal"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Bagikan"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Hapus"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Rekaman layar dibatalkan"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Rekaman layar disimpan, tap untuk melihat"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Rekaman layar dihapus"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error saat menghapus rekaman layar"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Gagal mendapatkan izin"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pasang sebagai kamera (PTP)"</string>
@@ -287,7 +303,7 @@
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokasi Nonaktif"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Perangkat media"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
- <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Telepon urgen saja"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Panggilan Darurat Saja"</string>
<string name="quick_settings_settings_label" msgid="5326556592578065401">"Setelan"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Waktu"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Saya"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifikasi"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Anda tidak akan melihat notifikasi ini lagi"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Notifikasi ini akan diperkecil"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Notifikasi ini akan ditampilkan tanpa suara"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Notifikasi ini akan mengingatkan Anda"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Anda biasanya menutup notifikasi ini. \nTerus tampilkan?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Terus tampilkan notifikasi ini?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Hentikan notifikasi"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Terus tampilkan"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Perkecil"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Tampilkan tanpa suara"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Tampilkan dan ingatkan"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tampilkan notifikasi dari aplikasi ini?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Notifikasi ini tidak dapat dinonaktifkan"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"melalui <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Aplikasi ini sedang menggunakan kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Aplikasi ini sedang menggunakan mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Aplikasi ini ditampilkan di atas aplikasi lain di layar."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikasi dapat dibuka tanpa perlu diinstal."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikasi dapat dibuka tanpa perlu diinstal. Tap untuk mempelajari lebih lanjut."</string>
<string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Buka di web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Buka browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Data seluler"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi nonaktif"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Setelan"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Hapus Heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikasi menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Buka apl"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Batal"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Oke"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Setelan"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> menggunakan <xliff:g id="TYPE">%2$s</xliff:g> selama <xliff:g id="TIME">%3$d</xliff:g> menit terakhir"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> menggunakan <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokasi"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 92d86ae..3d01b94 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prófaðu að taka skjámynd aftur"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Ekki tókst að vista skjámynd vegna takmarkaðs geymslupláss"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Forritið eða fyrirtækið þitt leyfir ekki skjámyndatöku"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Skjáupptaka"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Áframhaldandi tilkynning fyrir skjáupptökulotu"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Hefja upptöku"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Taka upp talsetningu"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Sýna snertingar"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stöðva"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Hlé"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Halda áfram"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Hætta við"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Deila"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Eyða"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Hætt við skjáupptöku"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Skjáupptaka vistuð, ýttu til að skoða"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Skjáupptöku eytt"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Villa við að eyða skjáupptöku"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Ekki tókst að fá heimildir"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Valkostir USB-skráaflutnings"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Tengja sem efnisspilara (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Tengja sem myndavél (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Tilkynningar"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Þú munt ekki sjá þessar tilkynningar aftur"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Þessar tilkynningar verða faldar"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Þú hunsar yfirleitt þessar tilkynningar. \nViltu halda áfram að fá þær?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Sýna áfram þessar tilkynningar?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stöðva tilkynningar"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Sýna áfram"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minnka"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Sýna áfram tilkynningar frá þessu forriti?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ekki er hægt að slökkva á þessum tilkynningum"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"með <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Þetta forrit er að nota myndavélina."</string>
<string name="appops_microphone" msgid="741508267659494555">"Þetta forrit er að nota hljóðnemann."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Þetta forrit er að birta efni yfir öðrum forritum á skjánum þínum."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Forrit opnað án þess að vera uppsett."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Forrit opnað án þess að vera uppsett. Ýttu til að fá frekari upplýsingar."</string>
<string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Fara á vefinn"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Opna vafra"</string>
<string name="mobile_data" msgid="7094582042819250762">"Farsímagögn"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Slökkt á Wi-Fi"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Stillingar"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ég skil"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Vista SysUI-gögn"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> er að nota <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Forrit eru að nota <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Opna forr."</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Hætta við"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Í lagi"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Stillingar"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> hefur verið að nota <xliff:g id="TYPE">%2$s</xliff:g> í <xliff:g id="TIME">%3$d</xliff:g> mín."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> er að nota <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> er að nota <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"myndavél"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"staðsetning"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"hljóðnemi"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 3cac6c9..b1f9230 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Riprova ad acquisire lo screenshot"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Impossibile salvare lo screenshot a causa dello spazio di archiviazione limitato"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Registrazione dello schermo"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notifica costante per una sessione di registrazione dello schermo"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Avvia registrazione"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Registra voce fuori campo"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostra tocchi"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Interrompi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausa"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Riprendi"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Annulla"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Condividi"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"CANC"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Registrazione dello schermo annullata"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Registrazione dello schermo salvata. Tocca per visualizzarla."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Registrazione dello schermo eliminata"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Errore durante l\'eliminazione della registrazione dello schermo"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Impossibile ottenere le autorizzazioni"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opzioni trasferimento file USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Monta come lettore multimediale (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Monta come videocamera (PTP)"</string>
@@ -259,7 +275,7 @@
<string name="accessibility_rotation_lock_on_landscape_changed" msgid="3135965553707519743">"Ora lo schermo è bloccato nell\'orientamento orizzontale."</string>
<string name="accessibility_rotation_lock_on_portrait_changed" msgid="8922481981834012126">"Ora lo schermo è bloccato nell\'orientamento verticale."</string>
<string name="dessert_case" msgid="1295161776223959221">"Vetrina di dolci"</string>
- <string name="start_dreams" msgid="5640361424498338327">"Screensaver"</string>
+ <string name="start_dreams" msgid="5640361424498338327">"Salvaschermo"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Tocca e tieni premuta ciascuna icona per visualizzare altre opzioni"</string>
<string name="quick_settings_dnd_label" msgid="8735855737575028208">"Non disturbare"</string>
@@ -582,14 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notifiche"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Non vedrai più queste notifiche"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Le notifiche verranno ridotte a icona"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Queste notifiche verranno mostrate in modalità silenziosa"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Queste notifiche ti avviseranno"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"In genere ignori queste notifiche. \nVuoi continuare a riceverle?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Continuare a ricevere queste notifiche?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Interrompi la ricezione di notifiche"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continua a mostrare"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Riduci a icona"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Mostra silenziosamente"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Mostra e avvisa"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuare a ricevere notifiche da questa app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Queste notifiche non possono essere disattivate"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"tramite <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Questa app sta utilizzando la fotocamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Questa app sta utilizzando il microfono."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Questa app è visualizzata sopra altre app sullo schermo."</string>
@@ -804,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App aperta senza essere stata installata."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App aperta senza essere stata installata. Tocca per avere ulteriori informazioni."</string>
<string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Vai sul Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Vai al browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dati mobili"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi disattivato"</string>
@@ -836,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Impostazioni"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Esegui dump heap SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"L\'app <xliff:g id="APP">%1$s</xliff:g> sta usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Le app stanno usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Apri app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Annulla"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Impostazioni"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"L\'app <xliff:g id="APP">%1$s</xliff:g> sta usando <xliff:g id="TYPE">%2$s</xliff:g> da <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Le app <xliff:g id="APPS">%1$s</xliff:g> stanno usando <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"L\'app <xliff:g id="APP">%1$s</xliff:g> sta usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"Fotocamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"luogo"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"un microfono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index a65b917..70ab947 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"יש לנסות שוב לבצע צילום מסך"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"לא היה מספיק מקום לשמור את צילום המסך"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"האפליקציה או הארגון שלך אינם מתירים ליצור צילומי מסך"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"הקלטת מסך"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"התראה מתמשכת לסשן הקלטת מסך"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"הפעלת ההקלטה"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"הקלטת voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"הצגת הקשות"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"עצירה"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"השהיה"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"המשך"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ביטול"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"שיתוף"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"מחיקה"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"הקלטת המסך בוטלה"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"הקלטת המסך נשמרה, יש להקיש כדי להציג"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"הקלטת המסך נמחקה"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"שגיאה במחיקת הקלטת המסך"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"קבלת ההרשאות נכשלה"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"אפשרויות העברת קבצים ב-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"טען כנגן מדיה (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"טען כמצלמה (PTP)"</string>
@@ -243,7 +259,7 @@
<string name="gps_notification_searching_text" msgid="8574247005642736060">"מחפש GPS"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
- <string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההודעות."</string>
+ <string name="accessibility_clear_all" msgid="5235938559247164925">"הסרת כל ההתראות."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
<string name="notification_group_overflow_indicator_ambient" msgid="879560382990377886">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>, +<xliff:g id="OVERFLOW">%2$s</xliff:g>"</string>
<plurals name="notification_group_overflow_description" formatted="false" msgid="4579313201268495404">
@@ -588,15 +604,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"התראות"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ההודעות האלה לא יוצגו לך יותר"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ההודעות האלה ימוזערו"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"הודעות אלה יוצגו ללא צליל"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"הודעות אלה יישלחו כהתראה"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"הודעות אלה בדרך כלל נדחות על ידיך. \nלהמשיך להציג אותן?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"שנמשיך להציג לך את ההודעות האלה?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"לא, אל תמשיכו"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"כן, המשיכו"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"מזעור"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"הצגה ללא צליל"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"הצגה ושליחת התראה"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"שנמשיך להציג לך הודעות מהאפליקציה הזאת?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"לא ניתן לכבות את ההודעות האלה"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"האפליקציה הזו משתמשת במצלמה."</string>
<string name="appops_microphone" msgid="741508267659494555">"האפליקציה הזו משתמשת במיקרופון."</string>
<string name="appops_overlay" msgid="6165912637560323464">"האפליקציה הזו מוצגת מעל אפליקציות אחרות במסך."</string>
@@ -735,8 +753,7 @@
<item msgid="2139628951880142927">"הצג באחוזים בזמן טעינה (ברירת מחדל)"</item>
<item msgid="3327323682209964956">"אל תציג את הסמל הזה"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"הצגת סמלי התראות בעדיפות נמוכה"</string>
<string name="other" msgid="4060683095962566764">"אחר"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"מחלק מסך מפוצל"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"מסך שמאלי מלא"</string>
@@ -816,7 +833,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"האפליקציה נפתחת בלי התקנה."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"האפליקציה נפתחת בלי התקנה. אפשר להקיש כדי לקבל מידע נוסף."</string>
<string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string>
- <string name="go_to_web" msgid="1106022723459948514">"התחבר לאינטרנט"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"מעבר אל הדפדפן"</string>
<string name="mobile_data" msgid="7094582042819250762">"נתונים סלולריים"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi כבוי"</string>
@@ -848,4 +865,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"הגדרות"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"הבנתי"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"ערימת Dump SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"אפליקציות משתמשות ב<xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"לאפליקציה"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ביטול"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"אישור"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"הגדרות"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPE">%2$s</xliff:g> ב-<xliff:g id="TIME">%3$d</xliff:g> הדקות האחרונות"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> משתמשות ב<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> משתמשת ב<xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"מצלמה"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"מיקום"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"מיקרופון"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 6617fdd..bd5fb37 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"スクリーンショットを撮り直してください"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"空き容量が足りないため、スクリーンショットを保存できません"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"スクリーンショットの作成はアプリまたは組織で許可されていません"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"画面の録画"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"画面の録画セッション中の通知"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"録画を開始"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ナレーションの録音"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"タップの表示"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"停止"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"一時停止"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"再開"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"キャンセル"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"共有"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"削除"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"画面の録画をキャンセルしました"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"画面の録画を保存しました。タップで表示できます"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"画面の録画を削除しました"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"画面の録画の削除中にエラーが発生しました"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"権限を取得できませんでした"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USBファイル転送オプション"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"メディアプレーヤー(MTP)としてマウント"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"カメラ(PTP)としてマウント"</string>
@@ -198,9 +214,9 @@
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"機内モードをONにしました。"</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"サイレント"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"アラームのみ"</string>
- <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"マナーモード"</string>
- <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"マナーモードを OFF にしました。"</string>
- <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"マナーモードを ON にしました。"</string>
+ <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"サイレント モード"</string>
+ <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"サイレント モードを OFF にしました。"</string>
+ <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"サイレント モードを ON にしました。"</string>
<string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"BluetoothがOFFです。"</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"BluetoothがONです。"</string>
@@ -262,7 +278,7 @@
<string name="start_dreams" msgid="5640361424498338327">"スクリーン セーバー"</string>
<string name="ethernet_label" msgid="7967563676324087464">"イーサネット"</string>
<string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"アイコンを押し続けると、その他の項目が表示されます"</string>
- <string name="quick_settings_dnd_label" msgid="8735855737575028208">"マナーモード"</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_none_label" msgid="5025477807123029478">"サイレント"</string>
@@ -415,7 +431,7 @@
<string name="media_projection_remember_text" msgid="3103510882172746752">"次回から表示しない"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"すべて消去"</string>
<string name="manage_notifications_text" msgid="2386728145475108753">"管理"</string>
- <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"マナーモードにより通知は一時停止中です"</string>
+ <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"サイレント モードにより通知は一時停止中です"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"今すぐ開始"</string>
<string name="empty_shade_text" msgid="708135716272867002">"通知はありません"</string>
<string name="profile_owned_footer" msgid="8021888108553696069">"プロファイルが監視されている可能性があります"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"今後、この通知は表示されません"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"通知を最小化します"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"通常、この通知はスワイプして非表示にしています。\n今後も表示しますか?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"この通知を今後も表示しますか?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"通知を表示しない"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"今後も表示する"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"このアプリからの通知を今後も表示しますか?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"この通知を OFF にすることはできません"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"このアプリはカメラを使用しています。"</string>
<string name="appops_microphone" msgid="741508267659494555">"このアプリはマイクを使用しています。"</string>
<string name="appops_overlay" msgid="6165912637560323464">"このアプリは画面上で他のアプリの上に重ねて表示されます。"</string>
@@ -668,9 +690,9 @@
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"カレンダー"</string>
<string name="tuner_full_zen_title" msgid="4540823317772234308">"音量調節を表示"</string>
- <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"マナーモード"</string>
+ <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"サイレント モード"</string>
<string name="volume_dnd_silent" msgid="4363882330723050727">"音量ボタンのショートカット"</string>
- <string name="volume_up_silent" msgid="7141255269783588286">"音量上げボタンでマナーモードを OFF にする"</string>
+ <string name="volume_up_silent" msgid="7141255269783588286">"音量上げボタンでサイレント モードを OFF にする"</string>
<string name="battery" msgid="7498329822413202973">"電池"</string>
<string name="clock" msgid="7416090374234785905">"時計"</string>
<string name="headset" msgid="4534219457597457353">"ヘッドセット"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"変更時に割合を表示(デフォルト)"</item>
<item msgid="3327323682209964956">"このアイコンを表示しない"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"優先度の低い通知アイコンを表示"</string>
<string name="other" msgid="4060683095962566764">"その他"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"分割画面の分割線"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"左全画面"</string>
@@ -806,15 +827,15 @@
<string name="instant_apps_message" msgid="1183313016396018086">"アプリをインストールせずに開きました。"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"アプリをインストールせずに開きました。詳細を見るにはタップしてください。"</string>
<string name="app_info" msgid="6856026610594615344">"アプリ情報"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ウェブページを開く"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ブラウザに移動"</string>
<string name="mobile_data" msgid="7094582042819250762">"モバイルデータ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi は OFF です"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Bluetooth は OFF です"</string>
- <string name="dnd_is_off" msgid="6167780215212497572">"マナーモードは OFF です"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"マナーモードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
- <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"マナーモードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"マナーモードが自動ルールまたはアプリによって ON になりました。"</string>
+ <string name="dnd_is_off" msgid="6167780215212497572">"サイレント モードは OFF です"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"サイレント モードが自動ルール(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+ <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"サイレント モードがアプリ(<xliff:g id="ID_1">%s</xliff:g>)によって ON になりました。"</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"サイレント モードが自動ルールまたはアプリによって ON になりました。"</string>
<string name="qs_dnd_until" msgid="3469471136280079874">"終了時間: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"設定を維持"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"設定を変更"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"設定"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ヒープのダンプ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g>は<xliff:g id="TYPES_LIST">%2$s</xliff:g>を使用しています。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"アプリは<xliff:g id="TYPES_LIST">%s</xliff:g>を使用しています。"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"アプリを開く"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"キャンセル"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"設定"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g>は過去 <xliff:g id="TIME">%3$d</xliff:g> 分間に<xliff:g id="TYPE">%2$s</xliff:g>を使用しています"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>は<xliff:g id="TYPE">%2$s</xliff:g>を使用しています"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>は<xliff:g id="TYPES_LIST">%2$s</xliff:g>を使用しています"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"カメラ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"現在地情報"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"マイク"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 359e689..5e2454c 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ხელახლა ცადეთ ეკრანის ანაბეჭდის გაკეთება"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ეკრანის ანაბეჭდის შენახვა ვერ მოხერხდა შეზღუდული მეხსიერების გამო"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ეკრანის ანაბეჭდების შექმნა არ არის ნებადართული აპის ან თქვენი ორგანიზაციის მიერ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ეკრანის ჩაწერა"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"უწყვეტი შეტყობინება ეკრანის ჩაწერის სესიისთვის"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ჩაწერის დაწყება"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ხმის ჩაწერა"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"შეხებების ჩვენება"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"შეწყვეტა"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"პაუზა"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"გაგრძელება"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"გაუქმება"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"გაზიარება"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"წაშლა"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ეკრანის ჩაწერა გაუქმდა"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ეკრანის ჩანაწერი შენახულია, შეეხეთ სანახავად"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ეკრანის ჩანაწერი წაიშალა"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ეკრანის ჩანაწერის წაშლისას წარმოიშვა შეცდომა"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ნებართვების მიღება ვერ მოხერხდა"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ფაილის ტრანსფერის პარამეტრები"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"მედია-საკრავად (MTP) ჩართვა"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"მიუერთეთ როგორც კამერა (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"შეტყობინებები"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ამ შეტყობინებებს აღარ დაინახავთ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"შეტყობინებები ჩაიკეცება"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"როგორც წესი, თქვენ ასეთ შეტყობინებებს ხურავთ. \nგსურთ მათი ჩვენების გაგრძელება?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"გაგრძელდეს ამ შეტყობინებათა ჩვენება?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"შეტყობინებების შეწყვეტა"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ჩვენების გაგრძელება"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ჩაკეცვა"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"გაგრძელდეს შეტყობინებათა ჩვენება ამ აპიდან?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ამ შეტყობინებათა გამორთვა ვერ მოხერხდება"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ეს აპი იყენებს კამერას."</string>
<string name="appops_microphone" msgid="741508267659494555">"ეს აპი იყენებს მიკროფონს."</string>
<string name="appops_overlay" msgid="6165912637560323464">"ეს აპი თქვენს ეკრანზე ფარავს სხვა აპებს."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"პროცენტულობის დატენვისას ჩვენება (ნაგულისხმევი)"</item>
<item msgid="3327323682209964956">"აღარ მაჩვენო ეს ხატულა"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"დაბალი პრიორიტეტის მქონე შეტყობინებების ხატულების ჩვენება"</string>
<string name="other" msgid="4060683095962566764">"სხვა"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"გაყოფილი ეკრანის რეჟიმის გამყოფი"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"მარცხენა ნაწილის სრულ ეკრანზე გაშლა"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"აპი გაიხსნა ინსტალაციის გარეშე."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"აპი გაიხსნა ინსტალაციის გარეშე. შეეხეთ მეტის გასაგებად."</string>
<string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ვებზე გადასვლა"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ბრაუზერზე გადასვლა"</string>
<string name="mobile_data" msgid="7094582042819250762">"მობილური ინტერნეტი"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi გამორთულია"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"პარამეტრები"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"გასაგებია"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI გროვის გამოტანა"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g>-ის მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"აპლიკაციების მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"აპის გახსნა"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"გაუქმება"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"კარგი"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"პარამეტრები"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g>-ის მიერ გამოიყენება თქვენი <xliff:g id="TYPE">%2$s</xliff:g> ბოლო <xliff:g id="TIME">%3$d</xliff:g> წუთის განმავლობაში"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>-ის მიერ გამოიყენება თქვენი <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>-ის მიერ გამოიყენება თქვენი <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"კამერა"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"მდებარეობა"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"მიკროფონი"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 6598bf0..f990be8 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Қайта скриншот жасап көріңіз"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Жадтағы шектеулі бос орынға байланысты скриншот сақталмайды"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Экранды бейнеге жазу"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Экранды бейнеге жазудың ағымдағы хабарландыруы"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Жазуды бастау"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Кадр сыртындағы дыбысты жазу"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Түрту әрекеттерін көрсету"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Тоқтату"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Тоқтата тұру"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Жалғастыру"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Бас тарту"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Бөлісу"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Жою"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Экранды бейнеге жазудан бас тартылды"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Экран бейне жазбасы сақталды, көру үшін түртіңіз"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Экран бейне жазбасы жойылды"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Экран бейне жазбасын жою кезінде қате кетті"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Рұқсаттар алынбады"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB файлын жіберу опциялары"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Медиа ойнатқыш (MTP) ретінде қосыңыз"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Камера ретінде (PTP) қосыңыз"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Хабарландырулар"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Хабарландырулар бұдан былай көрсетілмейді"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Хабарландырулар жасырылады"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Әдетте хабарландыруларды көрмейсіз. \nОлар көрсетілсін бе?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Хабарландырулар көрсетілсін бе?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Хабарландыруларға тыйым салу"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Көрсету"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Жасыру"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Осы қолданбаның хабарландырулары көрсетілсін бе?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Хабарландыруларды өшіру мүмкін емес"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Бұл қолданба камераны пайдалануда."</string>
<string name="appops_microphone" msgid="741508267659494555">"Бұл қолданба микрофонды пайдалануда."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Бұл қолданба экранда басқа қолданбалардың үстінен көрсетіліп тұр."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Зарядтау кезінде пайызды көрсету (әдепкі)"</item>
<item msgid="3327323682209964956">"Бұл белгішені көрсетпеу"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Маңызды емес хабарландыру белгішелерін көрсету"</string>
<string name="other" msgid="4060683095962566764">"Басқа"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Бөлінген экран бөлгіші"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Сол жағын толық экранға шығару"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Қолданба орнатылмай-ақ ашылды."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Қолданба орнатылмай-ақ ашылды. Толығырақ мәлімет алу үшін түртіңіз."</string>
<string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Вебке өту"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Браузерге өту"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобильдік деректер"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өшірулі"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Параметрлер"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Түсінікті"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> қолданбасында <xliff:g id="TYPES_LIST">%2$s</xliff:g> пайдалануда."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Қолданбаларда <xliff:g id="TYPES_LIST">%s</xliff:g> пайдаланылуда."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ашу"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Бас тарту"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Жарайды"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Параметр"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> қолданбасында <xliff:g id="TIME">%3$d</xliff:g> минут бойы <xliff:g id="TYPE">%2$s</xliff:g> пайдаланылуда"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> қолданбасында <xliff:g id="TYPE">%2$s</xliff:g> пайдаланылуда"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> қолданбасында <xliff:g id="TYPES_LIST">%2$s</xliff:g> пайдаланылуда"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"геодерек"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 8545ad6..6c584ad 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"សាកល្បងថតរូបថតអេក្រង់ម្តងទៀត"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"មិនអាចរក្សាទុករូបថតអេក្រង់បានទេ ដោយសារទំហំផ្ទុកមានកម្រិតទាប"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ការថតរូបអេក្រង់មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធីនេះ ឬស្ថាប័នរបស់អ្នក"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ការថតសកម្មភាពអេក្រង់"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ការជូនដំណឹងដែលកំពុងដំណើរការសម្រាប់រយៈពេលប្រើការថតសកម្មភាពអេក្រង់"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ចាប់ផ្តើមថត"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ថតការបញ្ចូលសំឡេង"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"បង្ហាញការចុច"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ឈប់"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ផ្អាក"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"បន្ត"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"បោះបង់"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"ចែករំលែក"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"លុប"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"បានបោះបង់ការថតសកម្មភាពអេក្រង់"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"បានរក្សាទុកការថតសកម្មភាពអេក្រង់។ សូមចុចដើម្បីមើល"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"បានលុបការថតសកម្មភាពអេក្រង់"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"មានបញ្ហាក្នុងការលុបការថតសកម្មភាពអេក្រង់"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"មិនអាចទទួលបានការអនុញ្ញាតទេ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"ជម្រើសផ្ទេរឯកសារតាមយូអេសប៊ី"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ភ្ជាប់ជាកម្មវិធីចាក់មេឌៀ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ភ្ជាប់ជាម៉ាស៊ីនថត (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ការជូនដំណឹង"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"អ្នកនឹងមិនឃើញការជូនដំណឹងទាំងនេះទៀតទេ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ការជូនដំណឹងទាំងនេះនឹងត្រូវបានបង្រួម"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"ជាធម្មតាអ្នកច្រានចោលការជូនដំណឹងទាំងនេះ។ \nបន្តបង្ហាញពួកវាទៀតដែរទេ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"បន្តបង្ហាញការជូនដំណឹងទាំងនេះ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"បញ្ឈប់ការជូនដំណឹង"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"បន្តបង្ហាញ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"បង្រួម"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"បន្តបង្ហាញការជូនដំណឹងពីកម្មវិធីនេះ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"មិនអាចបិទការជូនដំណឹងទាំងនេះបានទេ"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"កម្មវិធីនេះកំពុងប្រើកាមេរ៉ា។"</string>
<string name="appops_microphone" msgid="741508267659494555">"កម្មវិធីនេះកំពុងប្រើមីក្រូហ្វូន។"</string>
<string name="appops_overlay" msgid="6165912637560323464">"កម្មវិធីនេះកំពុងបង្ហាញពីលើកម្មវិធីផ្សេងទៀតនៅលើអេក្រង់របស់អ្នក។"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"បង្ហាញភាគរយនៅពេលសាកថ្ម (លំនាំដើម)"</item>
<item msgid="3327323682209964956">"កុំបង្ហាញរូបតំណាងនេះ"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"បង្ហាញរូបការជូនដំណឹងដែលមានអាទិភាពទាប"</string>
<string name="other" msgid="4060683095962566764">"ផ្សេងៗ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"កម្មវិធីចែកអេក្រង់បំបែក"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"អេក្រង់ពេញខាងឆ្វេង"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"កម្មវិធីត្រូវបានបើកដោយមិនចាំបាច់ដំឡើង។"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"កម្មវិធីត្រូវបានបើកដោយមិនចាំបាច់ដំឡើង។ ចុចដើម្បីស្វែងយល់បន្ថែម។"</string>
<string name="app_info" msgid="6856026610594615344">"ព័ត៌មានកម្មវិធី"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ចូលទៅកាន់បណ្តាញ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ចូលទៅកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
<string name="mobile_data" msgid="7094582042819250762">"ទិន្នន័យទូរសព្ទចល័ត"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi បានបិទ"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ការកំណត់"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"យល់ហើយ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"ចម្លង SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="TYPES_LIST">%2$s</xliff:g> របស់អ្នក។"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"កម្មវិធីកំពុងប្រើ <xliff:g id="TYPES_LIST">%s</xliff:g> របស់អ្នក។"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"បើកកម្មវិធី"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"បោះបង់"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"យល់ព្រម"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ការកំណត់"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="TYPE">%2$s</xliff:g> របស់អ្នករយៈពេល <xliff:g id="TIME">%3$d</xliff:g> នាទីចុងក្រោយ"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="TYPE">%2$s</xliff:g> របស់អ្នក"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> កំពុងប្រើ <xliff:g id="TYPES_LIST">%2$s</xliff:g> របស់អ្នក"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"កាមេរ៉ា"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ទីតាំង"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"មីក្រូហ្វូន"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ccbb31e..9269026 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಅನ್ನು ಪುನಃ ತೆಗೆದುಕೊಳ್ಳಲು ಪ್ರಯತ್ನಿಸಿ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ಪರಿಮಿತ ಸಂಗ್ರಹಣೆ ಸ್ಥಳದ ಕಾರಣದಿಂದಾಗಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ಅಪ್ಲಿಕೇಶನ್ ಅಥವಾ ಸಂಸ್ಥೆಯು ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆಯುವುದನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಸೆಶನ್ಗಾಗಿ ಚಾಲ್ತಿಯಲ್ಲಿರುವ ಅಧಿಸೂಚನೆ"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ರೆಕಾರ್ಡಿಂಗ್ ಆರಂಭಿಸಿ"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"voiceover ಅನ್ನು ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ಟ್ಯಾಪ್ಗಳನ್ನು ತೋರಿಸಿ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ನಿಲ್ಲಿಸಿ"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ವಿರಾಮಗೊಳಿಸಿ"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ಮುಂದುವರಿಸಿ"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ರದ್ದುಮಾಡಿ"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"ಹಂಚಿಕೊಳ್ಳಿ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ಅಳಿಸಿ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ರದ್ದುಮಾಡಲಾಗಿದೆ"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅನ್ನು ಉಳಿಸಲಾಗಿದೆ, ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸಲಾಗಿದೆ"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ಸ್ಕ್ರೀನ್ ರೆಕಾರ್ಡಿಂಗ್ ಅಳಿಸುವಾಗ ದೋಷ ಕಂಡುಬಂದಿದೆ"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ಅನುಮತಿಗಳನ್ನು ಪಡೆಯುವಲ್ಲಿ ವಿಫಲವಾಗಿದೆ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ಫೈಲ್ ವರ್ಗಾವಣೆ ಆಯ್ಕೆಗಳು"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ಮೀಡಿಯಾ ಪ್ಲೇಯರ್ ರೂಪದಲ್ಲಿ ಅಳವಡಿಸಿ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ಕ್ಯಾಮರಾ ರೂಪದಲ್ಲಿ ಅಳವಡಿಸಿ (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ನೀವು ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಇನ್ನು ಮುಂದೆ ನೋಡುವುದಿಲ್ಲ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಕಿರಿದುಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"ನೀವು ಸಾಮಾನ್ಯವಾಗಿ ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ವಜಾಗೊಳಿಸಿದ್ದೀರಿ. \nಅವುಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿಲ್ಲಿಸಿ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ತೋರಿಸುತ್ತಲಿರಿ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ಕಿರಿದುಗೊಳಿಸಿ"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ಈ ಅಪ್ಲಿಕೇಶನ್ನಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೋರಿಸುತ್ತಲೇ ಇರಬೇಕೆ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ಈ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸುತ್ತಿದೆ."</string>
<string name="appops_microphone" msgid="741508267659494555">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಮೈಕ್ರೊಫೋನ್ ಅನ್ನು ಬಳಸುತ್ತಿದೆ."</string>
<string name="appops_overlay" msgid="6165912637560323464">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಮೇಲಿಂದ ಪ್ರದರ್ಶಿಸುತ್ತಿದೆ."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ಚಾರ್ಜ್ ಮಾಡುವಾಗ ಪ್ರತಿಶತವನ್ನು ತೋರಿಸು (ಡಿಫಾಲ್ಟ್)"</item>
<item msgid="3327323682209964956">"ಈ ಐಕಾನ್ ತೋರಿಸಬೇಡ"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"ಕಡಿಮೆ-ಆದ್ಯತೆ ಸೂಚನೆಯ ಐಕಾನ್ಗಳನ್ನು ತೋರಿಸಿ"</string>
<string name="other" msgid="4060683095962566764">"ಇತರ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"ಸ್ಪ್ಲಿಟ್-ಪರದೆ ಡಿವೈಡರ್"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ಎಡ ಪೂರ್ಣ ಪರದೆ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡದೆ ಆ್ಯಪ್ ತೆರೆಯಲಾಗಿದೆ."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡದೆ ಆ್ಯಪ್ ತೆರೆಯಲಾಗಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
<string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ವೆಬ್ಗೆ ಹೋಗಿ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ಬ್ರೌಸರ್ಗೆ ಹೋಗಿ"</string>
<string name="mobile_data" msgid="7094582042819250762">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"ವೈ-ಫೈ ಆಫ್ ಆಗಿದೆ"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ಅರ್ಥವಾಯಿತು"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ಹೀಪ್ ಡಂಪ್ ಮಾಡಿ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APP">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%s</xliff:g> ಅನ್ನು ಆ್ಯಪ್ಗಳು ಬಳಸುತ್ತಿವೆ."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ಆ್ಯಪ್ ತೆರೆ"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ರದ್ದುಮಾಡಿ"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ಸರಿ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"ಕೊನೆಯ <xliff:g id="TIME">%3$d</xliff:g> ನಿಮಿಷಕ್ಕಾಗಿ ನಿಮ್ಮ <xliff:g id="TYPE">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APP">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"ನಿಮ್ಮ <xliff:g id="TYPE">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APPS">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"ನಿಮ್ಮ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ಅನ್ನು <xliff:g id="APP">%1$s</xliff:g> ಬಳಸುತ್ತಿದೆ"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ಕ್ಯಾಮರಾ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ಸ್ಥಳ"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ಮೈಕ್ರೋಫೋನ್"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 716e2f2..b6dda32 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"스크린샷을 다시 찍어 보세요."</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"저장용량이 부족하여 스크린샷을 저장할 수 없습니다"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"앱이나 조직에서 스크린샷 촬영을 허용하지 않습니다."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"화면 녹화"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"화면 녹화 세션에 관한 지속적인 알림"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"녹화 시작"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"음성 해설 녹음"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"탭한 항목 표시"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"중지"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"일시중지"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"재개"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"취소"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"공유"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"삭제"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"화면 녹화가 취소되었습니다."</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"화면 녹화본이 저장되었습니다. 확인하려면 탭하세요."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"화면 녹화가 삭제되었습니다."</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"화면 녹화는 삭제하는 중에 오류가 발생했습니다."</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"권한을 확보하지 못했습니다."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"미디어 플레이어로 마운트(MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"카메라로 마운트(PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"알림"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"더 이상 다음의 알림을 받지 않습니다"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"다음 알림이 최소화됩니다."</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"보통 이 알림을 닫았습니다. \n알림을 계속 표시하시겠습니까?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"이 알림을 계속 표시하시겠습니까?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"알림 중지"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"계속 표시하기"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"최소화"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"이 앱의 알림을 계속 표시하시겠습니까?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"이 알림은 끌 수 없습니다"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"앱이 카메라를 사용 중입니다."</string>
<string name="appops_microphone" msgid="741508267659494555">"앱이 마이크를 사용 중입니다."</string>
<string name="appops_overlay" msgid="6165912637560323464">"앱이 화면의 다른 앱 위에 표시되고 있습니다."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"충전할 때 퍼센트 표시(기본값)"</item>
<item msgid="3327323682209964956">"이 아이콘 표시 안함"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"우선순위가 낮은 알림 아이콘 표시"</string>
<string name="other" msgid="4060683095962566764">"기타"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"화면 분할기"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"왼쪽 화면 전체화면"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"설치 없이 앱이 실행되었습니다."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"설치 없이 앱이 실행되었습니다. 탭하여 자세히 알아보세요."</string>
<string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
- <string name="go_to_web" msgid="1106022723459948514">"웹으로 이동"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"브라우저로 이동"</string>
<string name="mobile_data" msgid="7094582042819250762">"모바일 데이터"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>, <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi가 사용 중지됨"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"설정"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"확인"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g>이(가) <xliff:g id="TYPES_LIST">%2$s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"애플리케이션이 <xliff:g id="TYPES_LIST">%s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"앱 열기"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"취소"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"확인"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"설정"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g>이(가) 지난 <xliff:g id="TIME">%3$d</xliff:g>분 동안 <xliff:g id="TYPE">%2$s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>이(가) <xliff:g id="TYPE">%2$s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>이(가) <xliff:g id="TYPES_LIST">%2$s</xliff:g>을(를) 사용 중입니다."</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"카메라"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"위치"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"마이크"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2f49cdb..f4dbcbd 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Скриншотту кайра тартып көрүңүз"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Сактагычта бош орун аз болгондуктан скриншот сакталбай жатат"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Скриншот тартууга колдонмо же ишканаңыз тыюу салган."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Экранды жаздыруу"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Экранды жаздыруу сеансы боюнча учурдагы билдирме"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Жаздырып баштоо"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Үн коштоону жаздыруу"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Басылган жерди көрсөтүү"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Токтотуу"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Тындыруу"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Улантуу"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Жокко чыгаруу"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Бөлүшүү"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Ооба"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Экранды жаздыруу жокко чыгарылды"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Экранды жаздыруу сакталды, көрүү үчүн таптап коюңуз"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Экранды жаздыруу өчүрүлдү"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Экранды жаздырууну өчүрүүдө ката кетти"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Уруксаттар алынбай калды"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB менен файл өткөрүү мүмкүнчүлүктөрү"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Медиа ойноткуч катары кошуу (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Камера катары кошуу (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Билдирмелер"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Мындан ары бул эскертмелер сизге көрсөтүлбөйт"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Бул эскертмелер кичирейтилет"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Адатта мындай эскертмелерди өткөрүп жибересиз. \nАлар көрсөтүлө берсинби?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Бул эскертмелер көрсөтүлө берсинби?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Эскертмелерди токтотуу"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Көрсөтүлө берсин"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Кичирейтүү"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Бул колдонмонун эскертмелери көрсөтүлө берсинби?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Бул эскертмелерди өчүрүүгө болбойт"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Бул колдонмо камераны колдонууда."</string>
<string name="appops_microphone" msgid="741508267659494555">"Бул колдонмо микрофонду колдонууда."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Бул колдонмо экрандагы башка терезелердин үстүнөн көрсөтүлүүдө."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Кубаттоо учурунда пайызы көрсөтүлсүн (демейки)"</item>
<item msgid="3327323682209964956">"Бул сөлөкөт көрсөтүлбөсүн"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Анча маанилүү эмес билдирменин сүрөтчөлөрүн көрсөтүү"</string>
<string name="other" msgid="4060683095962566764">"Башка"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Экранды бөлгүч"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Сол жактагы экранды толук экран режимине өткөрүү"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Колдонмо орнотулбастан ачылды."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Колдонмо орнотулбастан ачылды. Толугураак маалымат алуу үчүн таптап коюңуз."</string>
<string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Интернетке өтүү"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Серепчиге өтүү"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобилдик Интернет"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi өчүк"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Жөндөөлөр"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Түшүндүм"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүлөрдү колдонуп жатат: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Колдонмолор төмөнкүлөрдү пайдаланып жатышат: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Колдн ачуу"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Жок"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Макул"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Жөндөөлөр"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүлөрдү <xliff:g id="TIME">%3$d</xliff:g> мүн. бери колдонуп жатат: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> төмөнкүлөрдү колдонуп жатышат: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүлөрдү колдонуп жатат: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"жайгашкан жер"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index dd874d5..2a508b3 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ກະລຸນາລອງຖ່າຍຮູບໜ້າຈໍອີກຄັ້ງ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້ເນື່ອງຈາກພື້ນທີ່ຈັດເກັບຂໍ້ມູນມີຈຳກັດ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຖ່າຍຮູບໜ້າຈໍ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ການບັນທຶກໜ້າຈໍ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ການແຈ້ງເຕືອນສຳລັບເຊດຊັນການບັນທຶກໜ້າຈໍໃດໜຶ່ງ"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ເລີ່ມການບັນທຶກ"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ບັນທຶກສຽງພາກ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ສະແດງການແຕະ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ຢຸດ"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ຢຸດຊົ່ວຄາວ"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ສືບຕໍ່"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ຍົກເລີກ"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"ແບ່ງປັນ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ລຶບ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ຍົກເລີກການບັນທຶກໜ້າຈໍແລ້ວ"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ຈັດເກັບການບັນທຶກໜ້າຈໍ, ແຕະເພື່ອເບິ່ງ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ລຶບການບັນທຶກໜ້າຈໍອອກແລ້ວ"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ເກີດຄວາມຜິດພາດໃນການລຶບການບັນທຶກໜ້າຈໍ"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ໂຫຼດສິດອະນຸຍາດບໍ່ສຳເລັດ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ໂຕເລືອກການຍ້າຍໄຟລ໌"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ເຊື່ອມຕໍ່ເປັນ media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ເຊື່ອມຕໍ່ເປັນກ້ອງຖ່າຍຮູບ (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ການແຈ້ງເຕືອນ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ທ່ານຈະບໍ່ໄດ້ຮັບການແຈ້ງເຕືອນເຫຼົ່ານີ້ອີກຕໍ່ໄປ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ການແຈ້ງເຕືອນເຫຼົ່ານີ້ຈະຖືກຫຍໍ້ໄວ້"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"ການແຈ້ງເຕືອນເຫຼົ່ານີ້ຈະສະແດງແບບງຽບໆ"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"ການແຈ້ງເຕືອນເຫຼົ່ານີ້ຈະເຕືອນທ່ານ"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"ໂດຍປົກກະຕິທ່ານປິດການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄວ້. \nສືບຕໍ່ສະແດງພວກມັນບໍ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ສະແດງການແຈ້ງເຕືອນເຫຼົ່ານີ້ຕໍ່ໄປບໍ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ຢຸດການແຈ້ງເຕືອນ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ສະແດງຕໍ່ໄປ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ຫຍໍ້"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"ສະແດງແບບງຽບໆ"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"ສະແດງ ແລະ ເຕືອນ"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ສະແດງການແຈ້ງເຕືອນຈາກແອັບນີ້ຕໍ່ໄປບໍ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ບໍ່ສາມາດປິດການແຈ້ງເຕືອນເຫຼົ່ານີ້ໄດ້"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ແອັບນີ້ກຳລັງໃຊ້ກ້ອງຢູ່."</string>
<string name="appops_microphone" msgid="741508267659494555">"ແອັບນີ້ກຳລັງໃຊ້ໄມໂຄຣໂຟນຢູ່."</string>
<string name="appops_overlay" msgid="6165912637560323464">"ແອັບນີ້ກຳລັງສະແດງຜົນບັງແອັບອື່ນຢູ່ໜ້າຈໍຂອງທ່ານ."</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"ສະແດງເປີເຊັນເມື່ອກຳລັງສາກໄຟ (ຄ່າເລີ່ມຕົ້ນ)"</item>
<item msgid="3327323682209964956">"ຢ່າສະແດງໄອຄອນນີ້"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"ສະແດງໄອຄອນການແຈ້ງເຕືອນຄວາມສຳຄັນຕ່ຳ"</string>
<string name="other" msgid="4060683095962566764">"ອື່ນໆ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"ຕົວຂັ້ນການແບ່ງໜ້າຈໍ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ເຕັມໜ້າຈໍຊ້າຍ"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ເປີດແອັບໂດຍບໍ່ມີການຕິດຕັ້ງແລ້ວ."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ເປີດແອັບໂດຍບໍ່ມີການຕິດຕັ້ງແລ້ວ. ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
<string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ໄປທີ່ເວັບ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ໄປທີ່ໂປຣແກຣມທ່ອງເວັບ"</string>
<string name="mobile_data" msgid="7094582042819250762">"ອິນເຕີເນັດມືຖື"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ປິດຢູ່"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ການຕັ້ງຄ່າ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ເຂົ້າໃຈແລ້ວ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ຂອງທ່ານ."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ແອັບພລິເຄຊັນກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%s</xliff:g> ຂອງທ່ານ."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ເປີດແອັບ"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ຍົກເລີກ"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ຕົກລົງ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ການຕັ້ງຄ່າ"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="TYPE">%2$s</xliff:g> ຂອງທ່ານ <xliff:g id="TIME">%3$d</xliff:g> ນທ ທີ່ຜ່ານມາ"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="TYPE">%2$s</xliff:g> ຂອງທ່ານ"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ກຳລັງໃຊ້ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ຂອງທ່ານ"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ກ້ອງຖ່າຍຮູບ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ສະຖານທີ່"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ໄມໂຄຣໂຟນ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 68e64d3..0792bbb 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Pabandykite padaryti ekrano kopiją dar kartą"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Negalima išsaugoti ekrano kopijos dėl ribotos saugyklos vietos"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ekrano įrašymas"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Šiuo metu rodomas ekrano įrašymo sesijos pranešimas"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Pradėti įrašymą"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Įrašyti balsą už kadro"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Rodyti palietimus"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Sustabdyti"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pristabdyti"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Tęsti"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Atšaukti"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Bendrinti"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Ištrinti"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekrano įrašymas atšauktas"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekrano įrašas išsaugotas, palieskite ir peržiūrėkite"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekrano įrašas ištrintas"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Ištrinant ekrano įrašą įvyko klaida"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nepavyko gauti leidimų"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos leistuvę (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Įmontuoti kaip fotoaparatą (PTP)"</string>
@@ -588,14 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Pranešimai"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Nebematysite šių pranešimų"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Šie pranešimai bus sumažinti"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Paprastai šių pranešimų atsisakote. \nToliau juos rodyti?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Toliau rodyti šiuos pranešimus?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Sustabdyti pranešimus"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Toliau rodyti"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Sumažinti"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Toliau rodyti iš šios programos gautus pranešimus?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Šių pranešimų negalima išjungti"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"naudojant „<xliff:g id="APP_NAME">%1$s</xliff:g>“"</string>
<string name="appops_camera" msgid="8100147441602585776">"Ši programa naudoja fotoaparatą."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ši programa naudoja mikrofoną."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ši programa rodoma ekrane virš kitų programų."</string>
@@ -814,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Programa atidaryta jos neįdiegus."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Programa atidaryta jos neįdiegus. Palieskite, kad sužinotumėte daugiau."</string>
<string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Eiti į žiniatinklį"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Eiti į naršyklę"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilieji duomenys"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g>–<xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"„Wi-Fi“ išjungtas"</string>
@@ -846,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Nustatymai"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Supratau"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Pat. „SysUI“ krūvą"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ naudoja: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Programos naudoja: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Atid. pr."</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Atšaukti"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Gerai"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Nustatymai"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ pastar. <xliff:g id="TIME">%3$d</xliff:g> min. naudoja: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Programos (<xliff:g id="APPS">%1$s</xliff:g>) naudoja: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Programa „<xliff:g id="APP">%1$s</xliff:g>“ naudoja: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparatą"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"vietovę"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofoną"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index eb5e92c..14a859c 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Mēģiniet izveidot jaunu ekrānuzņēmumu."</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Nevar saglabāt ekrānuzņēmumu, jo krātuvē nepietiek vietas."</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Notiek ekrāna ierakstīšana"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Aktīvs paziņojums par ekrāna ierakstīšanas sesiju"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Sākt ierakstīšanu"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Ierakstīt balsi"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Rādīt pieskārienus"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Pārtraukt"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Apturēt"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Atsākt"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Atcelt"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Kopīgot"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Dzēst"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekrāna ierakstīšana ir atcelta."</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekrāna ieraksts ir saglabāts. Pieskarieties, lai to skatītu."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekrāna ieraksts ir izdzēsts."</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Dzēšot ekrāna ierakstu, radās kļūda."</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Neizdevās iegūt atļaujas."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB failu pārsūtīšanas opcijas"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pievienot kā multivides atskaņotāju (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pievienot kā kameru (PTP)"</string>
@@ -585,15 +601,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Paziņojumi"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Jūs vairs neredzēsiet šos paziņojumus."</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Šie paziņojumi tiks minimizēti"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Parasti jūs noraidāt šādus paziņojumus. \nVai turpināt tos rādīt?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vai turpināt rādīt šos paziņojumus?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Apturēt paziņojumu rādīšanu"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Turpināt rādīt"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizēt"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Vai turpināt rādīt paziņojumus no šīs lietotnes?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Šos paziņojumus nevar izslēgt."</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Šajā lietotnē tiek izmantota kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Šajā lietotnē tiek izmantots mikrofons."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Šī lietotne tiek rādīta ekrānā pāri citām lietotnēm."</string>
@@ -730,8 +752,7 @@
<item msgid="2139628951880142927">"Rādīt procentuālo vērtību uzlādes laikā (noklusējums)"</item>
<item msgid="3327323682209964956">"Nerādīt šo ikonu"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Rādīt zemas prioritātes paziņojumu ikonas"</string>
<string name="other" msgid="4060683095962566764">"Citi"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Ekrāna sadalītājs"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Kreisā daļa pa visu ekrānu"</string>
@@ -811,7 +832,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Lai atvērtu šo lietotni, tā nav jāinstalē."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Lai atvērtu šo lietotni, tā nav jāinstalē. Pieskarieties, lai uzzinātu vairāk."</string>
<string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Pāriet uz tīmekli"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Atvērt pārlūku"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilie dati"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ir izslēgts"</string>
@@ -843,4 +864,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Iestatījumi"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Labi"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Lietotne <xliff:g id="APP">%1$s</xliff:g> izmanto funkcijas <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Lietojumprogrammas izmanto šādas funkcijas: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Atvērt lietotni"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Atcelt"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Labi"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Iestatījumi"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Lietotne <xliff:g id="APP">%1$s</xliff:g> pēdējās <xliff:g id="TIME">%3$d</xliff:g> min izmanto funkciju <xliff:g id="TYPE">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Lietotnes <xliff:g id="APPS">%1$s</xliff:g> izmanto funkciju <xliff:g id="TYPE">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Lietotne <xliff:g id="APP">%1$s</xliff:g> izmanto funkcijas <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"atrašanās vieta"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofons"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 9c42805..cc937e9 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Повторно обидете се да направите слика од екранот"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Сликата од екранот не може да се зачува поради ограничена меморија"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Апликацијата или вашата организација не дозволува снимање слики од екранот"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Снимање на екранот"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Тековно известување за сесија за снимање на екранот"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Започни со снимање"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Снимај коментар"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Прикажувај допири"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Сопри"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Паузирај"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Продолжи"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Откажи"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Сподели"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Избриши"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Снимањето екран е откажано"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Снимката од екранот е зачувана, допрете за да ја видите"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Снимката од екранот е избришана"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Грешка при бришењето на снимката од екранот"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Не успеаја да се добијат дозволи"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Пренос на датотека со USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Монтирај како мултимедијален плеер (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Монтирај како фотоапарат (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Известувања"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Веќе нема да ги гледате овие известувања"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Овие известувања ќе се минимизираат"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Обично ги отфрлате известувањава. \nДа продолжат да се прикажуваат?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Дали да продолжат да се прикажуваат известувањава?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Запри ги известувањата"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Продолжи да ги прикажуваш"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Минимизирај"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Дали да продолжат да се прикажуваат известувања од апликацијава?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Известувањава не може да се исклучат"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Апликацијава ја користи камерата."</string>
<string name="appops_microphone" msgid="741508267659494555">"Апликацијава го користи микрофонот."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Апликацијава се прикажува врз други апликации на вашиот екран."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Прикажи процент кога се полни (стандардно)"</item>
<item msgid="3327323682209964956">"Не прикажувај ја иконава"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Прикажувај икони за известувања со низок приоритет"</string>
<string name="other" msgid="4060683095962566764">"Друго"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Разделник на поделен екран"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Левиот на цел екран"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Апликацијата беше отворена без да се инсталира."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Апликацијата беше отворена без да се инсталира. Допрете за да дознаете повеќе."</string>
<string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Одете на интернет"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Одете на прелистувач"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобилен интернет"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi е исклучено"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Поставки"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Сфатив"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Извади SysUI-слика"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Апликациите користат <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Отвори апликација"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Откажи"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Во ред"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Поставки"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPE">%2$s</xliff:g> во последните <xliff:g id="TIME">%3$d</xliff:g> мин."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> користат <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"локација"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 62196ea..b88fbd6 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ വീണ്ടും ശ്രമിക്കുക"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"സ്റ്റോറേജ് ഇടം പരിമിതമായതിനാൽ സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കാനാകുന്നില്ല"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"സ്ക്രീൻ റെക്കോർഡിംഗ്"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ഒരു സ്ക്രീൻ റെക്കോർഡിംഗ് സെഷനായി നിലവിലുള്ള അറിയിപ്പ്"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"റെക്കോര്ഡിംഗ് ആരംഭിക്കുക"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"വോയ്സ് ഓവർ റെക്കോർഡ് ചെയ്യുക"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ടാപ്പുകൾ കാണിക്കുക"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"നിർത്തുക"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"താൽക്കാലികമായി നിർത്തുക"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"പുനരാരംഭിക്കുക"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"റദ്ദാക്കുക"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"പങ്കിടുക"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ഇല്ലാതാക്കുക"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"സ്ക്രീൻ റെക്കോർഡിംഗ് റദ്ദാക്കി"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"സ്ക്രീൻ റെക്കോർഡിംഗ് സംരക്ഷിച്ചു, കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കി"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"സ്ക്രീൻ റെക്കോർഡിംഗ് ഇല്ലാതാക്കുന്നതിൽ പിശക്"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"അനുമതികൾ ലഭിച്ചില്ല"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ഫയൽ കൈമാറൽ ഓപ്ഷനുകൾ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ഒരു മീഡിയ പ്ലേയറായി (MTP) മൗണ്ടുചെയ്യുക"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ഒരു ക്യാമറയായി (PTP) മൗണ്ടുചെയ്യുക"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"അറിയിപ്പുകൾ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"നിങ്ങൾ ഇനി ഈ അറിയിപ്പുകൾ കാണില്ല"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ഈ അറിയിപ്പുകൾ ചെറുതാക്കപ്പെടും"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"സാധാരണയായി നിങ്ങൾ ഈ അറിയിപ്പുകൾ നിരാകരിക്കുന്നു. \nഅവ തുടർന്നും കാണിക്കണോ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ഈ അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"അറിയിപ്പുകൾ നിർത്തുക"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"തുടർന്നും കാണിക്കുക"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ചെറുതാക്കുക"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ഈ ആപ്പിൽ നിന്നുള്ള അറിയിപ്പുകൾ തുടർന്നും കാണിക്കണോ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ഈ അറിയിപ്പുകൾ ഓഫാക്കാനാവില്ല"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ഈ ആപ്പ് ക്യാമറ ഉപയോഗിക്കുന്നുണ്ട്."</string>
<string name="appops_microphone" msgid="741508267659494555">"ഈ ആപ്പ് മൈക്രോഫോൺ ഉപയോഗിക്കുന്നു."</string>
<string name="appops_overlay" msgid="6165912637560323464">"ഈ ആപ്പ് നിങ്ങളുടെ സ്ക്രീനിലെ മറ്റ് ആപ്പുകൾക്ക് മുകളിൽ പ്രദർശിപ്പിക്കുന്നു."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ചാർജ്ജുചെയ്യുമ്പോൾ ശതമാനം കാണിക്കുക (ഡിഫോൾട്ട്)"</item>
<item msgid="3327323682209964956">"ഈ ഐക്കൺ കാണിക്കരുത്"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"പ്രാധാന്യം കുറഞ്ഞ അറിയിപ്പ് ചിഹ്നങ്ങൾ"</string>
<string name="other" msgid="4060683095962566764">"മറ്റുള്ളവ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"സ്പ്ലിറ്റ്-സ്ക്രീൻ ഡിവൈഡർ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ഇടത് പൂർണ്ണ സ്ക്രീൻ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ഇൻസ്റ്റാൾ ചെയ്യാതെ ആപ്പ് തുറന്നു."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ഇൻസ്റ്റാൾ ചെയ്യാതെ ആപ്പ് തുറന്നു. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
<string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
- <string name="go_to_web" msgid="1106022723459948514">"വെബിൽ പോവുക"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ബ്രൗസറിലേക്ക് പോവുക"</string>
<string name="mobile_data" msgid="7094582042819250762">"മൊബൈൽ ഡാറ്റ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"വൈഫൈ ഓഫാണ്"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ക്രമീകരണം"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"മനസ്സിലായി"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ആപ്പുകൾ നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%s</xliff:g> ഉപയോഗിക്കുന്നു."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ആപ്പ് തുറക്കുക"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"റദ്ദാക്കുക"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ശരി"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ക്രമീകരണം"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"കഴിഞ്ഞ <xliff:g id="TIME">%3$d</xliff:g> മിനിറ്റായി <xliff:g id="APP">%1$s</xliff:g> നിങ്ങളുടെ <xliff:g id="TYPE">%2$s</xliff:g> ഉപയോഗിക്കുന്നു"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> നിങ്ങളുടെ <xliff:g id="TYPE">%2$s</xliff:g> ഉപയോഗിക്കുന്നു"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>നിങ്ങളുടെ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ഉപയോഗിക്കുന്നു"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ക്യാമറ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ലൊക്കേഷന്"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"മൈക്രോഫോൺ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 223f492..7033766 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Дэлгэцийн зургийг дахин дарж үзнэ үү"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Сангийн багтаамж бага байгаа тул дэлгэцээс дарсан зургийг хадгалах боломжгүй байна"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Таны апп, байгууллагад дэлгэцийн зураг авахыг зөвшөөрдөггүй"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Дэлгэцийн бичлэг"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Дэлгэц бичих горимын үргэлжилж буй мэдэгдэл"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Бичлэгийг эхлүүлэх"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Дуу оруулалтыг бичих"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Товшилтыг харуулах"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Зогсоох"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Түр зогсоох"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Үргэлжлүүлэх"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Цуцлах"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Хуваалцах"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Устгах"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Дэлгэцийн бичлэгийг цуцалсан"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Дэлгэцийн бичлэгийг хадгалсан. Харахын тулд товшино уу"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Дэлгэцийн бичлэгийг устгасан"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Дэлгэцийн бичлэгийг устгахад алдаа гарлаа"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Зөвшөөрөл авч чадсангүй"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB файл шилжүүлэх сонголт"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Медиа тоглуулагч(MTP) болгон залгах"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Камер болгон(PTP) залгах"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Мэдэгдэл"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Та эдгээр мэдэгдлийг цаашид харахгүй"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Энэ мэдэгдлийг багасгана"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Та эдгээр мэдэгдлийг ихэвчлэн хаадаг. \nЭдгээрийг харуулсан хэвээр байх уу?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Эдгээр мэдэгдлийг харуулсан хэвээр байх уу?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Мэдэгдлийг зогсоох"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Харуулсан хэвээр байх"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Багасгах"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Энэ аппаас мэдэгдэл харуулсан хэвээр байх уу?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Эдгээр мэдэгдлийг унтраах боломжгүй"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Энэ апп камерыг ашиглаж байна."</string>
<string name="appops_microphone" msgid="741508267659494555">"Энэ апп микрофоныг ашиглаж байна."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Энэ аппыг таны дэлгэцэд бусад аппын дээр харуулж байна."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Цэнэглэх үед хувийг тогтмол харуулах (өгөгдмөл)"</item>
<item msgid="3327323682209964956">"Энэ дүрс тэмдгийг бүү үзүүл"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Бага ач холбогдолтой мэдэгдлийн дүрс тэмдгийг харуулах"</string>
<string name="other" msgid="4060683095962566764">"Бусад"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"\"Дэлгэц хуваах\" хуваагч"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Зүүн талын бүтэн дэлгэц"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Аппыг суулгахгүйгээр нээсэн."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Аппыг суулгахгүйгээр нээсэн. Нэмэлт мэдээлэл авахын тулд товшино уу."</string>
<string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Вэбэд очих"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Хөтчид очих"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобайл дата"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi унтраалттай байна"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Тохиргоо"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ойлголоо"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> таны <xliff:g id="TYPES_LIST">%2$s</xliff:g>-г ашиглаж байна."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Аппууд таны <xliff:g id="TYPES_LIST">%s</xliff:g>-г ашиглаж байна."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Аппыг нээх"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Болих"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"За"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Тохиргоо"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> таны <xliff:g id="TYPE">%2$s</xliff:g>-г сүүлийн <xliff:g id="TIME">%3$d</xliff:g> минутын турш ашиглаж байна"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> таны <xliff:g id="TYPE">%2$s</xliff:g>-г ашиглаж байна"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> таны <xliff:g id="TYPES_LIST">%2$s</xliff:g>-г ашиглаж байна"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камер"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"байршил"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index da37acbf..159926a 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"स्क्रीनशॉट पुन्हा घेण्याचा प्रयत्न करा"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"मर्यादित स्टोरेज जागेमुळे स्क्रीनशॉट सेव्ह करू शकत नाही"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"अॅप किंवा आपल्या संस्थेद्वारे स्क्रीनशॉट घेण्याची अनुमती नाही"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"स्क्रीन रेकॉर्डिंग"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"स्क्रीन रेकॉर्ड सत्रासाठी सुरू असलेली सूचना"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"रेकॉर्डिंग सुरू करा"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"व्हॉइसओव्हर रेकॉर्ड करा"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"टॅप दाखवा"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"थांबवा"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"थांबवा"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"पुन्हा सुरू करा"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"रद्द करा"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"शेअर करा"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"हटवा"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"स्क्रीन रेकॉर्डिंग रद्द केले"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"स्क्रीन रेकॉर्डिंग सेव्ह केली, पाहण्यासाठी टॅप करा"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"स्क्रीन रेकॉर्डिंग हटवले"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"स्क्रीन रेकॉर्डिंग हटवताना एरर आली"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"परवानग्या मिळवता आल्या नाहीत"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB फाईल स्थानांतरण पर्याय"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"मीडिया प्लेअर म्हणून माउंट करा (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"कॅमेरा म्हणून माउंट करा (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"आता तुम्हाला या सूचना दिसणार नाहीत"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"या सूचना लहान केल्या जातील"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"तुम्ही या सूचना सामान्यतः डिसमिस करता. \nते दाखवत राहायचे?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"या सूचना दाखवणे सुरू ठेवायचे?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"सूचना थांबवा"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"दाखवणे सुरू ठेवा"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"लहान करा"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"या अॅपकडील सूचना दाखवणे सुरू ठेवायचे?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"या सूचना बंद करता येत नाहीत"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"हे अॅप कॅमेरा वापरत आहे."</string>
<string name="appops_microphone" msgid="741508267659494555">"हे अॅप मायक्रोफोन वापरत आहे."</string>
<string name="appops_overlay" msgid="6165912637560323464">"हे अॅप स्क्रीनवरील इतर अॅप्स वर प्रदर्शित होत आहे."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"चार्ज करताना टक्केवारी दर्शवा (डीफॉल्ट)"</item>
<item msgid="3327323682209964956">"हे आयकन दाखवू नका"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"कमी प्राधान्य सूचना आयकन दर्शवा"</string>
<string name="other" msgid="4060683095962566764">"अन्य"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"विभाजित-स्क्रीन विभाजक"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"डावी फुल स्क्रीन"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"इंस्टॉल केल्याशिवाय अॅप उघडले."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"इंस्टॉल केल्याशिवाय अॅप उघडले. अधिक जाणून घेण्यासाठी टॅप करा."</string>
<string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
- <string name="go_to_web" msgid="1106022723459948514">"वेबवर जा"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ब्राउझरवर जा"</string>
<string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"वाय-फाय बंद आहे"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"सेटिंग्ज"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"समजले"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI हीप डंप करा"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> तुमचे <xliff:g id="TYPES_LIST">%2$s</xliff:g> वापरत आहे."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"अॅप्लिकेशन्स तुमचे <xliff:g id="TYPES_LIST">%s</xliff:g> वापरत आहे."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"अॅप उघडा"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"रद्द करा"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ओके"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"सेटिंग्ज"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"शेवटच्या <xliff:g id="TIME">%3$d</xliff:g> मिनिटासाठी <xliff:g id="APP">%1$s</xliff:g> तुमचे <xliff:g id="TYPE">%2$s</xliff:g> वापरत आहे"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> तुमचे <xliff:g id="TYPE">%2$s</xliff:g> वापरत आहे"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> तुमचे <xliff:g id="TYPES_LIST">%2$s</xliff:g> वापरत आहे"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"कॅमेरा"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"स्थान"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"मायक्रोफोन"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index cb4dd14..dbaccac 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Cuba ambil tangkapan skrin sekali lagi"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Tidak dapat menyimpan tangkapan skrin kerana ruang storan terhad"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Pengambilan tangkapan skrin tidak dibenarkan oleh apl atau organisasi anda"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Rakaman Skrin"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Pemberitahuan breterusan untuk sesi rakaman skrin"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Mula Merakam"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Rakam suara latar"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Tunjukkan ketikan"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Berhenti"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Jeda"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Sambung semula"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Batal"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Kongsi"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Padam"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Rakaman skrin dibatalkan"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Rakaman skrin disimpan, ketik untuk melihat"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Rakaman skrin dipadamkan"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Ralat semasa memadamkan rakaman skrin"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Gagal mendapatkan kebenaran"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lekapkan sebagai pemain media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lekapkan sebagai kamera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Pemberitahuan"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Anda tidak akan melihat pemberitahuan ini lagi"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Pemberitahuan ini akan diminimumkan"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Biasanya anda mengetepikan pemberitahuan ini. \nTerus tunjukkan pemberitahuan?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Terus tunjukkan pemberitahuan ini?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Hentikan pemberitahuan"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Terus tunjukkan"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimumkan"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Terus tunjukkan pemberitahuan daripada apl ini?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Pemberitahuan ini tidak boleh dimatikan"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Apl ini sedang menggunakan kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Apl ini sedang menggunakan mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Apl ini dipaparkan di atas apl lain pada skrin anda."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Tunjukkan peratusan semasa mengecas (lalai)"</item>
<item msgid="3327323682209964956">"Jangan tunjukkan ikon ini"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Tunjukkan ikon pemberitahuan keutamaan rendah"</string>
<string name="other" msgid="4060683095962566764">"Lain-lain"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Pembahagi skrin pisah"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Skrin penuh kiri"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Apl dibuka tanpa dipasang."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Apl dibuka tanpa dipasang. Ketik untuk mengetahui lebih lanjut."</string>
<string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Pergi ke web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Pergi ke penyemak imbas"</string>
<string name="mobile_data" msgid="7094582042819250762">"Data mudah alih"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi dimatikan"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Tetapan"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Longgok Tmbunn SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g> anda."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikasi sedang menggunakan <xliff:g id="TYPES_LIST">%s</xliff:g> anda."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Buka apl"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Batal"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Okey"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Tetapan"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan <xliff:g id="TYPE">%2$s</xliff:g> anda selama <xliff:g id="TIME">%3$d</xliff:g> min yang lalu"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> sedang menggunakan <xliff:g id="TYPE">%2$s</xliff:g> anda"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> sedang menggunakan <xliff:g id="TYPES_LIST">%2$s</xliff:g> anda"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokasi"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 777d96e..2a1bf77 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"မျက်နှာပြင်ပုံကို ထပ်ရိုက်ကြည့်ပါ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"သိုလှောင်ခန်းနေရာ အကန့်အသတ်ရှိသောကြောင့် ဖန်သားပြင်ဓာတ်ပုံကို သိမ်းဆည်း၍မရပါ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ကူးခြင်းကို ဤအက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ဖန်သားပြင် ရိုက်ကူးမှု"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ဖန်သားပြင် ရိုက်ကူးသည့် စက်ရှင်အတွက် ဆက်တိုက်လာနေသော အကြောင်းကြားချက်"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"စတင် ရိုက်ကူးရန်"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"နောက်ခံစကားပြော ကူးယူရန်"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"တို့ခြင်းများကို ပြရန်"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ရပ်ရန်"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ခဏရပ်ရန်"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ဆက်လုပ်ရန်"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"မလုပ်တော့"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"မျှဝေရန်"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ဖျက်ရန်"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ဖန်သားပြင် ရိုက်ကူးမှု ပယ်ဖျက်လိုက်ပါပြီ"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ဖန်သားပြင် ရိုက်ကူးမှု သိမ်းထားသည်၊ ကြည့်ရန် တို့ပါ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ပြီးပါပြီ"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ဖန်သားပြင် ရိုက်ကူးမှု ဖျက်ရာတွင် အမှားအယွင်းရှိနေသည်"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ခွင့်ပြုချက် မရယူနိုင်ပါ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ဖိုင်ပြောင်း ရွေးမှုများ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"မီဒီယာပလေရာအနေဖြင့် တပ်ဆင်ရန် (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ကင်မရာအနေဖြင့် တပ်ဆင်ရန် (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"အကြောင်းကြားချက်များ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ဤအကြောင်းကြားချက်များကို မြင်ရတော့မည် မဟုတ်ပါ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ဤအကြောင်းကြားချက်များကို ချုံ့ထားပါမည်"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"ဤအကြောင်းကြားချက်များကို တိတ်တဆိတ် ပြပါမည်"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"ဤအကြောင်းကြားချက်များက သင့်ကို သတိပေးပါမည်"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"သင်သည် အများအားဖြင့် ဤအကြောင်းကြားချက်များကို ပယ်လေ့ရှိပါသည်။ \n၎င်းတို့ကို ဆက်လက်ပြသလိုပါသလား။"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ဤအကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"အကြောင်းကြားချက်များကို ရပ်ရန်"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ဆက်ပြရန်"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ချုံ့ရန်"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"တိတ်တဆိတ် ပြရန်"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"ပြပြီး သတိပေးရန်"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ဤအက်ပ်ထံမှ အကြောင်းကြားချက်များကို ဆက်ပြလိုပါသလား။"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ဤအကြောင်းကြားချက်များကို ပိတ်၍မရပါ"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ဤအက်ပ်က ကင်မရာကို အသုံးပြုနေသည်။"</string>
<string name="appops_microphone" msgid="741508267659494555">"ဤအက်ပ်က မိုက်ခရိုဖုန်းကို အသုံးပြုနေသည်။"</string>
<string name="appops_overlay" msgid="6165912637560323464">"ဤအက်ပ်က ဖန်သားမျက်နှာပြင်ပေါ်ရှိ အခြားအက်ပ်များ အပေါ်မှ ထပ်ပြီး ပြသနေပါသည်။"</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"အားသွင်းနေစဉ်တွင် ရာခိုင်နှုန်းကိုပြပါ (ပုံသေ)"</item>
<item msgid="3327323682209964956">"ဤသင်္ကေတပုံကို မပြပါနှင့်"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"အရေးမကြီးသော အကြောင်းကြားချက် သင်္ကေတများ ပြရန်"</string>
<string name="other" msgid="4060683095962566764">"အခြား"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"မျက်နှာပြင်ခွဲခြမ်း ပိုင်းခြားပေးသည့်စနစ်"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ဘယ်ဘက် မျက်နှာပြင်အပြည့်"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"အက်ပ်ကိုမထည့်သွင်းဘဲ ဖွင့်ထားသည်။"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"အက်ပ်ကိုမထည့်သွင်းဘဲ ဖွင့်ထားသည်။ ပိုမိုလေ့လာရန် တို့ပါ။"</string>
<string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ဝဘ်သို့ သွားရန်"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ဘရောင်ဇာသို့ သွားပါ"</string>
<string name="mobile_data" msgid="7094582042819250762">"မိုဘိုင်းဒေတာ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> —<xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ကို ပိတ်ထားသည်"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ဆက်တင်များ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ရပါပြီ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> က သင်၏ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"အပလီကေးရှင်းများက သင်၏ <xliff:g id="TYPES_LIST">%s</xliff:g> ကို အသုံးပြုနေသည်။"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ဖွင့်ရန်"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"မလုပ်တော့"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Okay"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ဆက်တင်များ"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> သည် ပြီးခဲ့သော <xliff:g id="TIME">%3$d</xliff:g> မိနစ်က သင်၏ <xliff:g id="TYPE">%2$s</xliff:g> ကို အသုံးပြုနေသည်"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> တို့က သင်၏ <xliff:g id="TYPE">%2$s</xliff:g> ကို အသုံးပြုနေသည်"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> က သင်၏ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ကို အသုံးပြုနေသည်"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ကင်မရာ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"တည်နေရာ"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"မိုက်ခရိုဖုန်း"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 9b27df5..4014957 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Prøv å ta skjermdump på nytt"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Kan ikke lagre skjermdumpen på grunn av begrenset lagringsplass"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Skjermopptak"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Vedvarende varsel for et skjermopptak"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Start opptak"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Ta opp et kommentarspor"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Vis trykk"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stopp"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Sett på pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Gjenoppta"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Avbryt"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Del"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Slett"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Skjermopptak er avbrutt"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Skjermopptaket er lagret. Trykk for å se det"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Skjermopptaket er slettet"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Feil ved sletting av skjermopptaket"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Kunne ikke få tillatelser"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Altern. for USB-filoverføring"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Sett inn som mediespiller (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Sett inn som kamera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Varsler"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Du ser ikke disse varslene lenger"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Disse varslene minimeres"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Du avviser vanligvis disse varslene. \nVil du fortsette å vise dem?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vil du fortsette å vise disse varslene?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stopp varsler"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Fortsett å vise"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimer"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Vil du fortsette å vise varsler fra denne appen?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Du kan ikke slå av disse varslene"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Denne appen bruker kameraet."</string>
<string name="appops_microphone" msgid="741508267659494555">"Denne appen bruker mikrofonen."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Denne appen vises over andre apper på skjermen."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Vis prosentandel under lading (standard)"</item>
<item msgid="3327323682209964956">"Ikke vis dette ikonet"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Vis ikoner for varsler med lav prioritet"</string>
<string name="other" msgid="4060683095962566764">"Annet"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Skilleelement for delt skjerm"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Utvid den venstre delen av skjermen til hele skjermen"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Appen ble åpnet uten at den ble installert."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Appen ble åpnet uten at den ble installert. Trykk for å finne ut mer."</string>
<string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Gå til nettstedet"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Gå til nettleser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi er av"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Innstillinger"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Greit"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> bruker <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Apper bruker <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Åpne appen"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Avbryt"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Ok"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Innst."</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> har brukt <xliff:g id="TYPE">%2$s</xliff:g> de siste <xliff:g id="TIME">%3$d</xliff:g> minuttene"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> bruker <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> bruker <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"posisjon"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 5119e5b..67e4223 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"स्क्रिनसट फेरि लिएर हेर्नुहोस्"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"भण्डारण ठाउँ सीमित भएका कारण स्क्रिनसट सुरक्षित गर्न सकिएन"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"उक्त अनुप्रयोग वा तपाईंको संगठनले स्क्रिनसटहरू लिन दिँदैन"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"स्क्रिनको रेकर्डिङ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"कुनै स्क्रिन रेकर्ड गर्ने सत्रका लागि चलिरहेको सूचना"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"रेकर्डिङ सुरु गर्नुहोस्"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"भ्वाइसओवर रेकर्ड गर्नुहोस्"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ट्यापहरू देखाउनुहोस्"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"रोक्नुहोस्"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"पज गर्नुहोस्"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"जारी राख्नुहोस्"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"रद्द गर्नुहोस्"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"आदान प्रदान गर्नुहोस्"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"मेट्नुहोस्"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"स्क्रिन रेकर्ड गर्ने कार्य रद्द गरियो"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"स्क्रिन रेकर्डिङ सुरक्षित गरियो, हेर्न ट्याप गर्नुहोस्"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"स्क्रिनको रेकर्डिङ मेटाइयो"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"स्क्रिनको रेकर्डिङ मेट्ने क्रममा त्रुटि"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"अनुमति प्राप्त गर्न सकिएन"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB फाइल सार्ने विकल्पहरू"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"मिडिया प्लेयर(MTP)को रूपमा माउन्ट गर्नुहोस्"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"क्यामेराको रूपमा माउन्ट गर्नुहोस् (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"सूचनाहरू"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"तपाईं अब उप्रान्त यी सूचनाहरू देख्नु हुने छैन"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"यी सूचनाहरू सानो बनाइने छ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"तपाईं सामान्यतया यी सूचनाहरूलाई खारेज गर्ने गर्नुहुन्छ। \nतिनलाई देखाइरहने हो?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"यी सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"सूचनाहरू देखाउन छाड्नुहोस्"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"देखाउने क्रम जारी राख्नुहोस्"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"सानो बनाउनुहोस्"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"यो अनुप्रयोगका सूचनाहरू देखाउने क्रम जारी राख्ने हो?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"यी सूचनाहरूलाई निष्क्रिय पार्न सकिँदैन"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"यो अनुप्रयोगले क्यामेराको प्रयोग गर्दै छ।"</string>
<string name="appops_microphone" msgid="741508267659494555">"यो अनुप्रयोगले माइक्रोफोनको प्रयोग गर्दै छ।"</string>
<string name="appops_overlay" msgid="6165912637560323464">"यो अनुप्रयोगले तपाईंको स्क्रिनका अन्य अनुप्रयोगहरूमाथि प्रदर्शन गर्दै छ।"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"चार्ज गर्दा प्रतिशत देखाउनुहोस् (पूर्वनिर्धारित)"</item>
<item msgid="3327323682209964956">"यो आइकन नदेखाउनुहोस्"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"कम प्राथमिकताका सूचना आइकनहरू देखाउनुहोस्"</string>
<string name="other" msgid="4060683095962566764">"अन्य"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"विभाजित-स्क्रिन छुट्याउने"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"बायाँ भाग पूर्ण स्क्रिन"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"स्थापना नगरिकनै अनुप्रयोग खोलियो।"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"स्थापना नगरिकनै अनुप्रयोग खोलियो। थप जान्न ट्याप गर्नुहोस्।"</string>
<string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string>
- <string name="go_to_web" msgid="1106022723459948514">"वेबमा जानुहोस्"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ब्राउजरमा जानुहोस्"</string>
<string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi‑Fi निष्क्रिय छ"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"सेटिङहरू"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"बुझेँ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ले तपाईंको <xliff:g id="TYPES_LIST">%2$s</xliff:g> प्रयोग गर्दै छ।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"अनुप्रयोगहरूले तपाईंको <xliff:g id="TYPES_LIST">%s</xliff:g> प्रयोग गर्दै छन्।"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"अनुप्रयोग खोल्नुहोस्"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"रद्द गर्नु…"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ठिक छ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"सेटिङहरू"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> ले विगत <xliff:g id="TIME">%3$d</xliff:g> मिनेट देखि तपाईंको <xliff:g id="TYPE">%2$s</xliff:g> प्रयोग गर्दै छन्"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ले तपाईंको <xliff:g id="TYPE">%2$s</xliff:g> प्रयोग गर्दै छन्"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ले तपाईंको <xliff:g id="TYPES_LIST">%2$s</xliff:g> प्रयोग गर्दै छ"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"क्यामेरा"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"स्थान"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"माइक्रोफोन"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 448a36e..30ccad8 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Probeer opnieuw een screenshot te maken"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Kan screenshot niet opslaan vanwege beperkte opslagruimte"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Schermopname"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Doorlopende melding voor een schermopname-sessie"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Opname starten"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Voice-over opnemen"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Tikken weergeven"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stoppen"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pauzeren"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Hervatten"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Annuleren"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Delen"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Verwijderen"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Schermopname geannuleerd"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Schermopname opgeslagen, tik om te bekijken"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Schermopname verwijderd"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Fout bij verwijderen van schermopname"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Kan machtigingen niet ophalen"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Koppelen als mediaspeler (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Koppelen als camera (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Meldingen"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Deze meldingen worden niet meer weergegeven"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Deze meldingen worden geminimaliseerd"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Deze meldingen worden zonder geluid weergegeven"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Deze meldingen stellen je op de hoogte"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Meestal sluit je deze meldingen. \nWil je ze blijven weergeven?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Deze meldingen blijven weergeven?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Meldingen stoppen"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Blijven weergeven"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimaliseren"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Zonder geluid weergeven"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Weergeven en melden"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Meldingen van deze app blijven weergeven?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Deze meldingen kunnen niet worden uitgeschakeld"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Deze app gebruikt de camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Deze app gebruikt de microfoon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Deze app wordt over andere apps op je scherm heen weergegeven."</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"Percentage weergeven tijdens opladen (standaard)"</item>
<item msgid="3327323682209964956">"Dit pictogram niet weergeven"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Pictogrammen voor meldingen met lage prioriteit weergeven"</string>
<string name="other" msgid="4060683095962566764">"Overig"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Scheiding voor gesplitst scherm"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Linkerscherm op volledig scherm"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"App geopend zonder dat deze is geïnstalleerd."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"App geopend zonder dat deze is geïnstalleerd. Tik voor meer informatie."</string>
<string name="app_info" msgid="6856026610594615344">"App-info"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Ga naar internet"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ga naar browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobiele data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wifi is uitgeschakeld"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Instellingen"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> gebruikt je <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Apps gebruiken je <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"App openen"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Annuleren"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Instellingen"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> gebruikt je <xliff:g id="TYPE">%2$s</xliff:g> gedurende de afgelopen <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> gebruiken je <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> gebruikt je <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"locatie"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microfoon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index a9441fa..1768c69a 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ପୁଣିଥରେ ସ୍କ୍ରୀନ୍ଶଟ୍ ନେବାକୁ ଚେଷ୍ଟା କରନ୍ତୁ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ସୀମିତ ଷ୍ଟୋରେଜ୍ ସ୍ପେସ୍ ହେତୁ ସ୍କ୍ରୀନଶଟ୍ ସେଭ୍ ହୋଇପାରିବ ନାହିଁ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ଆପ୍ କିମ୍ବା ସଂସ୍ଥା ଦ୍ୱାରା ସ୍କ୍ରୀନଶଟ୍ ନେବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ଏକ ସ୍କ୍ରିନ୍ ରେକର୍ଡ୍ ସେସନ୍ ପାଇଁ ଚାଲୁଥିବା ବିଜ୍ଞପ୍ତି"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ରେକର୍ଡିଂ ଆରମ୍ଭ କରନ୍ତୁ"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ଭଏସ୍ଓଭର୍ ରେକର୍ଡ କରନ୍ତୁ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ଟାପ୍ ଦେଖାନ୍ତୁ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ବିରତି କରନ୍ତୁ"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ବାତିଲ୍ କରନ୍ତୁ"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"ସେୟାର୍ କରନ୍ତୁ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ବାତିଲ୍ କରିଦିଆଯାଇଛି"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ସେଭ୍ ହୋଇଛି, ଦେଖିବାକୁ ଟାପ୍ କରନ୍ତୁ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିଦିଆଯାଇଛି"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ସ୍କ୍ରିନ୍ ରେକର୍ଡିଂ ଡିଲିଟ୍ କରିବାରେ ତ୍ରୁଟି"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ଅନୁମତି ପାଇବାରେ ଅସଫଳ ହେଲା।"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ଫାଇଲ୍ ଟ୍ରାନ୍ସଫର୍ର ବିକଳ୍ପ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ଏକ ମିଡିଆ ପ୍ଲେୟାର୍ (MTP) ଭାବରେ ଭର୍ତ୍ତି କରନ୍ତୁ"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ଏକ କ୍ୟାମେରା (PTP) ଭାବରେ ଭର୍ତ୍ତି କରନ୍ତୁ"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ବିଜ୍ଞପ୍ତି"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଆପଣ ଆଉ ଦେଖିବାକୁ ପାଇବେନାହିଁ।"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ମିନିମାଇଜ୍ ହୋଇଯିବ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"ସାଧାରଣତଃ ଆପଣ ଏହି ବିଜ୍ଞପ୍ତିକୁ ଖାରଜ କରିଦିଅନ୍ତି। \n ସେଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ବିଜ୍ଞପ୍ତିକୁ ଦେଖାଇବା ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ଦେଖାଇବା ଜାରି ରଖନ୍ତୁ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ଛୋଟ କରନ୍ତୁ"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ଏହି ଆପ୍ରୁ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଦେଖାଇବା ଜାରି ରଖିବେ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ଏହି ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ବନ୍ଦ କରିହେବ ନାହିଁ"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ଏହି ଆପ୍ କ୍ୟାମେରା ବ୍ୟବହାର କରୁଛି।"</string>
<string name="appops_microphone" msgid="741508267659494555">"ଏହି ଆପ୍, ମାଇକ୍ରୋଫୋନ୍ ବ୍ୟବହାର କରୁଛି।"</string>
<string name="appops_overlay" msgid="6165912637560323464">"ଏହି ଆପ୍, ଆପଣଙ୍କର ସ୍କ୍ରୀନ୍ ଉପରେ ଥିବା ଅନ୍ୟ ଆପ୍ ଉପରେ ପ୍ରଦର୍ଶିତ ହେଉଛି।"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ଚାର୍ଜ କରାଯିବାବେଳେ ଶତକଡ଼ା ଦେଖାନ୍ତୁ (ଡିଫଲ୍ଟ)"</item>
<item msgid="3327323682209964956">"ଏହି ଆଇକନ୍ ଦେଖାନ୍ତୁ ନାହିଁ"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"କମ୍-ଅଗ୍ରାଧିକାର ବିଜ୍ଞପ୍ତି ଆଇକନ୍ ଦେଖାନ୍ତୁ"</string>
<string name="other" msgid="4060683095962566764">"ଅନ୍ୟାନ୍ୟ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"ସ୍ପ୍ଲିଟ୍-ସ୍କ୍ରୀନ ବିଭାଜକ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ବାମ ପଟକୁ ପୂର୍ଣ୍ଣ ସ୍କ୍ରୀନ୍ କରନ୍ତୁ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ଇନ୍ଷ୍ଟଲ୍ ନହୋଇ ଆପ୍ ଖୋଲିଛି।"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ଇନ୍ଷ୍ଟଲ୍ ନହୋଇ ଆପ୍ ଖୋଲିଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ।"</string>
<string name="app_info" msgid="6856026610594615344">"ଆପ୍ ସୂଚନା"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ୱେବକୁ ଯାଆନ୍ତୁ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ବ୍ରାଉଜର୍କୁ ଯାଆନ୍ତୁ"</string>
<string name="mobile_data" msgid="7094582042819250762">"ମୋବାଇଲ୍ ଡାଟା"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"ୱାଇ-ଫାଇ ଅଫ୍ ଅଛି"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ସେଟିଙ୍ଗ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ବୁଝିଲି"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ହିପ୍ ଡମ୍ପ୍ କରନ୍ତୁ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ଆପ୍ଲିକେସନ୍ଗୁଡିକ ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ଆପ୍ ଖୋଲନ୍ତୁ"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ବାତିଲ୍"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ଠିକ୍ ଅଛି"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ସେଟିଂସ୍"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> ବିଗତ <xliff:g id="TIME">%3$d</xliff:g> ମିନିଟ୍ ହେବ ଆପଣଙ୍କ <xliff:g id="TYPE">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି।"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="TYPE">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ବ୍ୟବହାର କରୁଛନ୍ତି"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"କ୍ୟାମେରା"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ଲୋକେସନ୍"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ମାଇକ୍ରୋଫୋନ୍"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 57971eb..dbcd43c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਦੁਬਾਰਾ ਲੈ ਕੇ ਦੇਖੋ"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"ਸੀਮਿਤ ਸਟੋਰੇਜ ਹੋਣ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"ਕਿਸੇ ਸਕ੍ਰੀਨ ਰਿਕਾਰਡ ਸੈਸ਼ਨ ਲਈ ਚੱਲ ਰਹੀ ਸੂਚਨਾ"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ਰਿਕਾਰਡਿੰਗ ਸ਼ੁਰੂ ਕਰੋ"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"ਅਵਾਜ਼ ਰਿਕਾਰਡ ਕਰੋ"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"ਟੈਪਾਂ ਦਿਖਾਓ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ਬੰਦ ਕਰੋ"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"ਰੋਕੋ"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ਰੱਦ ਕਰੋ"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"ਸਾਂਝਾ ਕਰੋ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ਮਿਟਾਓ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ਸਕ੍ਰੀਨ ਦੀ ਰਿਕਾਰਡਿੰਗ ਰੱਦ ਕੀਤੀ ਗਈ"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਰੱਖਿਅਤ ਕੀਤੀ ਗਈ, ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਇਆ ਗਿਆ"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"ਸਕ੍ਰੀਨ ਰਿਕਾਰਡਿੰਗ ਨੂੰ ਮਿਟਾਉਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋਈ"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ਇਜਾਜ਼ਤਾਂ ਪ੍ਰਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਚੋਣਾਂ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ਇੱਕ ਮੀਡੀਆ ਪਲੇਅਰ (MTP) ਦੇ ਤੌਰ ਤੇ ਮਾਊਂਟ ਕਰੋ"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ਇੱਕ ਕੈਮਰੇ (PTP) ਦੇ ਤੌਰ ਤੇ ਮਾਊਂਟ ਕਰੋ"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"ਸੂਚਨਾਵਾਂ"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ਤੁਹਾਨੂੰ ਹੁਣ ਇਹ ਸੂਚਨਾਵਾਂ ਦਿਖਾਈ ਨਹੀਂ ਦੇਣਗੀਆਂ"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਛੋਟਾ ਕੀਤਾ ਜਾਵੇਗਾ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"ਤੁਸੀਂ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਆਮ ਤੌਰ \'ਤੇ ਖਾਰਜ ਕਰਦੇ ਹੋ। \nਕੀ ਇਹਨਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ਕੀ ਇਨ੍ਹਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖੋ"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ਛੋਟਾ ਕਰੋ"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ਕੀ ਇਸ ਐਪ ਤੋਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਦਿਖਾਉਣਾ ਜਾਰੀ ਰੱਖਣਾ ਹੈ?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ਇਨ੍ਹਾਂ ਸੂਚਨਾਵਾਂ ਨੂੰ ਬੰਦ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ਇਹ ਐਪ ਕੈਮਰੇ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ।"</string>
<string name="appops_microphone" msgid="741508267659494555">"ਇਹ ਐਪ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ।"</string>
<string name="appops_overlay" msgid="6165912637560323464">"ਇਹ ਐਪ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ \'ਤੇ ਹੋਰਾਂ ਐਪਾਂ ਉੱਪਰ ਦਿਖਾਈ ਜਾ ਰਹੀ ਹੈ।"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ਚਾਰਜਿੰਗ ਦੌਰਾਨ ਪ੍ਰਤੀਸ਼ਤਤਾ ਦਿਖਾਓ (ਪੂਰਵ-ਨਿਰਧਾਰਤ)"</item>
<item msgid="3327323682209964956">"ਇਸ ਪ੍ਰਤੀਕ ਨੂੰ ਨਾ ਦਿਖਾਓ"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"ਘੱਟ ਤਰਜੀਹ ਵਾਲੇ ਸੂਚਨਾ ਪ੍ਰਤੀਕਾਂ ਨੂੰ ਦਿਖਾਓ"</string>
<string name="other" msgid="4060683095962566764">"ਹੋਰ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਡਿਵਾਈਡਰ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ਖੱਬੇ ਪੂਰੀ ਸਕ੍ਰੀਨ"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ਸਥਾਪਤ ਕੀਤੇ ਬਿਨਾਂ ਐਪ ਖੋਲ੍ਹੀ ਗਈ।"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ਸਥਾਪਤ ਕੀਤੇ ਬਿਨਾਂ ਐਪ ਖੋਲ੍ਹੀ ਗਈ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
<string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ਵੈੱਬ \'ਤੇ ਜਾਓ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ਬ੍ਰਾਊਜ਼ਰ \'ਤੇ ਜਾਓ"</string>
<string name="mobile_data" msgid="7094582042819250762">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ਸੈਟਿੰਗਾਂ"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ਸਮਝ ਲਿਆ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ਹੀਪ ਡੰਪ ਕਰੋ"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ।"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ਐਪਲੀਕੇਸ਼ਨਾਂ ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ।"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ਐਪ ਖੋਲ੍ਹੋ"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ਰੱਦ ਕਰੋ"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ਠੀਕ ਹੈ"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ਸੈਟਿੰਗਾਂ"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> ਪਿਛਲੇ <xliff:g id="TIME">%3$d</xliff:g> ਮਿੰਟ ਤੋਂ ਤੁਹਾਡੇ <xliff:g id="TYPE">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="TYPE">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀਆਂ ਹਨ"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="TYPES_LIST">%2$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ਕੈਮਰਾ"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ਟਿਕਾਣਾ"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ਮਾਈਕ੍ਰੋਫ਼ੋਨ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 2510aba..f9c1c79 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Spróbuj jeszcze raz wykonać zrzut ekranu"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Nie można zapisać zrzutu ekranu, bo brakuje miejsca w pamięci"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Rejestrowanie zawartości ekranu"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Stałe powiadomienie o sesji rejestrowania zawartości ekranu"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Rozpocznij rejestrowanie"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Nagraj tekst lektora"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Pokaż dotknięcia"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Zatrzymaj"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Wstrzymaj"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Wznów"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Anuluj"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Udostępnij"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Usuń"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Anulowano rejestrowanie zawartości ekranu"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Zapisano nagranie zawartości ekranu – kliknij, by je obejrzeć"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Usunięto nagranie zawartości ekranu"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Błąd podczas usuwania nagrania zawartości ekranu"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nie udało się uzyskać uprawnień"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB – opcje przesyłania plików"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Podłącz jako odtwarzacz multimedialny (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Podłącz jako aparat (PTP)"</string>
@@ -588,15 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Powiadomienia"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Te powiadomienia nie będą już wyświetlane"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Te powiadomienia zostaną zminimalizowane"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Zwykle odrzucasz te powiadomienia. \nNadal je pokazywać?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Nadal pokazywać te powiadomienia?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Zablokuj powiadomienia"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Pokazuj nadal"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimalizuj"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Nadal pokazywać powiadomienia z tej aplikacji?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Tych powiadomień nie można wyłączyć"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ta aplikacja używa aparatu."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ta aplikacja używa mikrofonu."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ta aplikacja wyświetla się nad innymi aplikacjami na ekranie."</string>
@@ -735,8 +757,7 @@
<item msgid="2139628951880142927">"Pokazuj procent podczas ładowania (domyślnie)"</item>
<item msgid="3327323682209964956">"Nie pokazuj tej ikony"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Pokazuj ikony powiadomień o niskim priorytecie"</string>
<string name="other" msgid="4060683095962566764">"Inne"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Linia dzielenia ekranu"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Lewa część ekranu na pełnym ekranie"</string>
@@ -816,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacja została otwarta bez zainstalowania."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacja została otwarta bez zainstalowania. Kliknij, by dowiedzieć się więcej."</string>
<string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Wejdź na stronę internetową"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Otwórz przeglądarkę"</string>
<string name="mobile_data" msgid="7094582042819250762">"Komórkowa transmisja danych"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi jest wyłączone"</string>
@@ -848,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ustawienia"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Zrzut stosu SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> używa: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacje używają: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otwórz"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Anuluj"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ustawienia"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> używa: <xliff:g id="TYPE">%2$s</xliff:g> od <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikacje <xliff:g id="APPS">%1$s</xliff:g> używają: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Aplikacja <xliff:g id="APP">%1$s</xliff:g> używa: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"aparat"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokalizacja"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 507c6b0..cd469e5 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Tente fazer a captura de tela novamente"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Não é possível salvar a captura de tela, porque não há espaço suficiente"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"O app ou a organização não permitem capturas de tela"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Gravação de tela"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificação contínua para uma sessão de gravação de tela"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar gravação"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Gravar narração"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Parar"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausar"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Retomar"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Compartilhar"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Excluir"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Gravação de tela cancelada"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Gravação de tela salva, toque para ver"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Gravação de tela excluída"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Erro ao excluir a gravação de tela"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Não foi possível acessar as permissões"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Conectar como media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como uma câmera (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Você deixará de ver essas notificações"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Essas notificações serão minimizadas"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Geralmente você dispensa essas notificações. \nQuer que elas continuem a ser exibidas?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Continuar mostrando essas notificações?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Bloquear notificações"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Não é possível desativar essas notificações"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"pelo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Este app está usando a câmera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Este app está usando o microfone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Este app está sobreposto a outros apps na sua tela."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"O app é aberto sem precisar ser instalado."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"O app é aberto sem precisar ser instalado. Toque para saber mais."</string>
<string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Acessar a Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Abrir o navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Configurações"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ok"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Despejar pilha SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Ok"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Config."</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPE">%2$s</xliff:g> há <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Os apps <xliff:g id="APPS">%1$s</xliff:g> estão usando <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"câmera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"localização"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microfone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index f3c993f..8006f33 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -70,10 +70,26 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Experimente voltar a efetuar a captura de ecrã."</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Não é possível guardar a captura de ecrã devido a espaço de armazenamento limitado."</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"A aplicação ou a sua entidade não permitem tirar capturas de ecrã"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Gravação de ecrã"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificação persistente de uma sessão de gravação de ecrã"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar gravação"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Gravar voz-off"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Parar"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Colocar em pausa"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Retomar"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Partilhar"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Eliminar"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Gravação de ecrã cancelada."</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Gravação de ecrã guardada. Toque para ver."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Gravação de ecrã eliminada."</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Erro ao eliminar a gravação de ecrã."</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Falha ao obter as autorizações."</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montar como leitor de multimédia (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como câmara (PTP)"</string>
- <string name="installer_cd_button_title" msgid="2312667578562201583">"Inst. aplic. Transf. Ficheiros do Android para Mac"</string>
+ <string name="installer_cd_button_title" msgid="2312667578562201583">"Inst. app Transf. Ficheiros do Android para Mac"</string>
<string name="accessibility_back" msgid="567011538994429120">"Anterior"</string>
<string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
<string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
@@ -457,7 +473,7 @@
<string name="monitoring_description_personal_profile_named_vpn" msgid="3133980926929069283">"O seu perfil pessoal está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
<string name="monitoring_description_do_header_generic" msgid="96588491028288691">"O seu dispositivo é gerido pelo <xliff:g id="DEVICE_OWNER_APP">%1$s</xliff:g>."</string>
<string name="monitoring_description_do_header_with_name" msgid="5511133708978206460">"A <xliff:g id="ORGANIZATION_NAME">%1$s</xliff:g> utiliza o <xliff:g id="DEVICE_OWNER_APP">%2$s</xliff:g> para gerir o seu dispositivo."</string>
- <string name="monitoring_description_do_body" msgid="3639594537660975895">"O administ. pode monitorizar e gerir definições, acesso empresarial, aplic. e dados associados ao dispositivo, bem como inf. de localiz. do disp."</string>
+ <string name="monitoring_description_do_body" msgid="3639594537660975895">"O administ. pode monitorizar e gerir definições, acesso empresarial, app e dados associados ao dispositivo, bem como inf. de localiz. do disp."</string>
<string name="monitoring_description_do_learn_more_separator" msgid="3785251953067436862">" "</string>
<string name="monitoring_description_do_learn_more" msgid="1849514470437907421">"Saiba mais"</string>
<string name="monitoring_description_do_body_vpn" msgid="8255218762488901796">"Está ligado à rede <xliff:g id="VPN_APP">%1$s</xliff:g>, que pode monitorizar a sua atividade de rede, incluindo emails, aplicações e Sites."</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Nunca mais verá estas notificações."</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Estas notificações serão minimizadas."</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Normalmente, ignora estas notificações. \nPretende continuar a mostrá-las?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Pretende continuar a ver estas notificações?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Parar notificações"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuar a mostrar"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Pretende continuar a ver notificações desta aplicação?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Não é possível desativar estas notificações."</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"através da aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Esta aplicação está a utilizar a câmara."</string>
<string name="appops_microphone" msgid="741508267659494555">"Esta aplicação está a utilizar o microfone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Esta aplicação está a sobrepor-se a outras aplicações no ecrã."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"A aplicação é aberta sem ser instalada."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"A aplicação é aberta sem ser instalada. Toque para saber mais."</string>
<string name="app_info" msgid="6856026610594615344">"Info. da aplicação"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Aceder à Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Ir para o navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi desativado"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Definições"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Compreendi"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Cp ár. di. da. SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"A aplicação <xliff:g id="APP">%1$s</xliff:g> está a utilizar o(a) <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"As aplicações estão a utilizar o(a) <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir aplicação"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Definições"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"A aplicação <xliff:g id="APP">%1$s</xliff:g> está a utilizar o(a) <xliff:g id="TYPE">%2$s</xliff:g> há <xliff:g id="TIME">%3$d</xliff:g> min."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"As aplicações <xliff:g id="APPS">%1$s</xliff:g> estão a utilizar o(a) <xliff:g id="TYPE">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"A aplicação <xliff:g id="APP">%1$s</xliff:g> está a utilizar o(a) <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"câmara"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"localização"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microfone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 507c6b0..cd469e5 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Tente fazer a captura de tela novamente"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Não é possível salvar a captura de tela, porque não há espaço suficiente"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"O app ou a organização não permitem capturas de tela"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Gravação de tela"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificação contínua para uma sessão de gravação de tela"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Iniciar gravação"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Gravar narração"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Mostrar toques"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Parar"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausar"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Retomar"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Cancelar"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Compartilhar"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Excluir"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Gravação de tela cancelada"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Gravação de tela salva, toque para ver"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Gravação de tela excluída"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Erro ao excluir a gravação de tela"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Não foi possível acessar as permissões"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Conectar como media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montar como uma câmera (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificações"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Você deixará de ver essas notificações"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Essas notificações serão minimizadas"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Geralmente você dispensa essas notificações. \nQuer que elas continuem a ser exibidas?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Continuar mostrando essas notificações?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Bloquear notificações"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuar mostrando"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizar"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Continuar mostrando notificações desse app?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Não é possível desativar essas notificações"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"pelo <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Este app está usando a câmera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Este app está usando o microfone."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Este app está sobreposto a outros apps na sua tela."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"O app é aberto sem precisar ser instalado."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"O app é aberto sem precisar ser instalado. Toque para saber mais."</string>
<string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Acessar a Web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Abrir o navegador"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dados móveis"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"O Wi-Fi está desativado"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Configurações"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ok"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Despejar pilha SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplicativos estão usando <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Abrir app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Cancelar"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Ok"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Config."</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPE">%2$s</xliff:g> há <xliff:g id="TIME">%3$d</xliff:g> min"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Os apps <xliff:g id="APPS">%1$s</xliff:g> estão usando <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"O app <xliff:g id="APP">%1$s</xliff:g> está usando <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"câmera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"localização"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microfone"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 53d8277..43a0825 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Încercați să faceți din nou o captură de ecran"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Captura de ecran nu poate fi salvată din cauza spațiului de stocare limitat"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Se înregistrează ecranul"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Notificare în curs pentru o sesiune de înregistrare a ecranului"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Începeți înregistrarea"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Înregistrați vocal"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Afișați atingerile"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Opriți"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Întrerupeți"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Reluați"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Anulați"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Trimiteți"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Ștergeți"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Înregistrarea ecranului a fost anulată"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Înregistrarea ecranului a fost salvată. Atingeți pentru vizualizare"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Înregistrarea ecranului a fost ștearsă."</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Eroare la ștergerea înregistrării ecranului"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nu s-au obținut permisiunile"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opțiuni pentru transferul de fișiere prin USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montați ca player media (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montați drept cameră foto (PTP)"</string>
@@ -585,15 +601,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Notificări"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Nu veți mai vedea aceste notificări"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Aceste notificări vor fi minimizate"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"De regulă respingeți aceste notificări. \nDoriți să fie afișate în continuare?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Doriți să continuați afișarea acestor notificări?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Opriți notificările"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Continuați afișarea"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizați"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Doriți să continuați afișarea notificărilor de la această aplicație?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Aceste notificări nu pot fi dezactivate"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Această aplicație folosește camera foto."</string>
<string name="appops_microphone" msgid="741508267659494555">"Această aplicație folosește microfonul."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Această aplicație se afișează pe alte aplicații de pe ecran."</string>
@@ -730,8 +752,7 @@
<item msgid="2139628951880142927">"Afișează procentajul când se încarcă (prestabilit)"</item>
<item msgid="3327323682209964956">"Nu afișa această pictogramă"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Afișați pictogramele de notificare cu prioritate redusă"</string>
<string name="other" msgid="4060683095962566764">"Altele"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Separator pentru ecranul împărțit"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Partea stângă pe ecran complet"</string>
@@ -811,7 +832,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplicația a fost deschisă fără a fi instalată."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplicația a fost deschisă fără a fi instalată. Atingeți pentru a afla mai multe."</string>
<string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Accesați pe web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Accesați browserul"</string>
<string name="mobile_data" msgid="7094582042819250762">"Date mobile"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Conexiunea Wi-Fi este dezactivată"</string>
@@ -843,4 +864,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Setări"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Date SysUI memorie"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> folosește <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplicațiile folosesc <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Deschideți aplicația"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Anulați"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Setări"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> folosește <xliff:g id="TYPE">%2$s</xliff:g> de <xliff:g id="TIME">%3$d</xliff:g> minute"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> folosesc <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> folosește <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"cameră foto"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"locație"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"microfon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index b180f87..fb74332 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Попробуйте сделать скриншот снова."</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Не удалось сохранить скриншот: недостаточно места."</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Запись видео с экрана"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Текущее уведомление для записи видео с экрана"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Начать запись"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Записать закадровую речь"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Показывать нажатия"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Остановить"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Приостановить"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Возобновить"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Отмена"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Поделиться"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Удалить"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Запись видео с экрана отменена"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Запись видео с экрана сохранена. Чтобы открыть ее, нажмите на уведомление."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Запись видео с экрана удалена"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Не удалось удалить запись видео с экрана"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Не удалось получить необходимые разрешения"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Параметры передачи через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Подключить как мультимедийный проигрыватель (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Установить как камеру (PTP)"</string>
@@ -588,15 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Уведомления"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Эти уведомления отключены."</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Эти уведомления будут свернуты."</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Обычно вы скрываете эти уведомления.\nПоказывать их?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Показывать эти уведомления?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Отключить уведомления"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Показывать"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Свернуть"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Показывать уведомления от этого приложения?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Эти уведомления нельзя отключить."</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Это приложение использует камеру."</string>
<string name="appops_microphone" msgid="741508267659494555">"Это приложение использует микрофон."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Это приложение располагается поверх других приложений."</string>
@@ -735,8 +757,7 @@
<item msgid="2139628951880142927">"Показывать процент во время зарядки (по умолчанию)"</item>
<item msgid="3327323682209964956">"Не показывать этот значок"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Показывать значки уведомлений с низким приоритетом"</string>
<string name="other" msgid="4060683095962566764">"Другое"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Разделитель экрана"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Левый во весь экран"</string>
@@ -816,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Приложение готово к работе, установка не требуется."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Приложение готово к работе, установка не требуется. Нажмите, чтобы узнать больше."</string>
<string name="app_info" msgid="6856026610594615344">"О приложении"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Перейти в браузер"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Перейти в браузер"</string>
<string name="mobile_data" msgid="7094582042819250762">"Моб. Интернет"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Модуль Wi-Fi отключен"</string>
@@ -848,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Открыть настройки"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"ОК"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Передача SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"В приложении \"<xliff:g id="APP">%1$s</xliff:g>\" используется <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"В приложениях используется <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Открыть"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Отмена"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ОК"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Настройки"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"В приложении \"<xliff:g id="APP">%1$s</xliff:g>\" уже <xliff:g id="TIME">%3$d</xliff:g> мин. используется <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"В нескольких приложениях (<xliff:g id="APPS">%1$s</xliff:g>) используется <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"В приложении \"<xliff:g id="APP">%1$s</xliff:g>\" используется <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камера"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"местоположение"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 0eae821..3efd747 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"තිර රුව නැවත ගැනීමට උත්සාහ කරන්න"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"සීමිත ගබඩා ඉඩ නිසා තිර රුව සුරැකිය නොහැකිය"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"තිර රූ ගැනීමට යෙදුම හෝ ඔබගේ සංවිධානය ඉඩ නොදේ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"තිර පටිගත කිරීම"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"තිර පටිගත කිරීමේ සැසියක් සඳහා කෙරෙන දැනුම් දීම"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"පටිගත කිරීම ආරම්භ කරන්න"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"පසුබිම් කථනය පටිගත කරන්න"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"තට්ටු කිරීම් පෙන්වන්න"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"නතර කරන්න"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"විරාම කරන්න"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"නැවත අරඹන්න"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"අවලංගු කරන්න"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"බෙදා ගන්න"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"මකන්න"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"තිර පටිගත කිරීම අවලංගු කරන ලදී"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"තිර පටිගත කිරීම සුරකින ලදී, බැලීමට තට්ටු කරන්න"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"තිර පටිගත කිරීම මකන ලදී"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"තිර පටිගත කිරීම මැකීමේ දෝෂයකි"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"අවසර ලබා ගැනීමට අසමත් විය"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ගොනු හුවමාරු විකල්ප"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"මධ්ය ධාවකයක් (MTP) ලෙස සවි කරන්න"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"කැමරාවක් (PTP) ලෙස සවි කරන්න"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"දැනුම් දීම්"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ඔබට තවදුරටත් මෙම දැනුම්දීම් නොදකිනු ඇත"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"මෙම දැනුම්දීම් කුඩා කරනු ලැබේ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"ඔබ සාමාන්යයෙන් මෙවැනි දැනුම්දීම් ඉවත දමයි. \nඒවා දිගටම පෙන්වන්නද?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"මෙම දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"දැනුම්දීම් නවත්වන්න"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"පෙන්වමින් තබන්න"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"කුඩා කරන්න"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"මෙම යෙදුම වෙතින් දැනුම්දීම් පෙන්වමින් තබන්නද?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"මෙම දැනුම්දීම් ක්රියාවිරහිත කළ නොහැකිය"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"මෙම යෙදුම කැමරාව භාවිතා කරයි."</string>
<string name="appops_microphone" msgid="741508267659494555">"මෙම යෙදුම මයික්රෆෝනය භාවිතා කරයි."</string>
<string name="appops_overlay" msgid="6165912637560323464">"මෙම යෙදුම් ඔබගේ තිරය මත අනෙකුත් යෙදුම්වලට උඩින් සංදර්ශනය වේ."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ආරෝපණය වන විට ප්රතිශතය පෙන්වන්න (පෙරනිමි)"</item>
<item msgid="3327323682209964956">"මෙම නිරූපකය නොපෙන්වන්න"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"අඩු ප්රමුඛතා දැනුම්දීම් අයිකන පෙන්වන්න"</string>
<string name="other" msgid="4060683095962566764">"වෙනත්"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"බෙදුම්-තිර වෙන්කරණය"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"වම් පූර්ණ තිරය"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ස්ථාපනය නොකර යෙදුම විවෘත කර ඇත."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ස්ථාපනය නොකර යෙදුම විවෘත කර ඇත. තව දැන ගැනීමට තට්ටු කරන්න."</string>
<string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string>
- <string name="go_to_web" msgid="1106022723459948514">"වෙබය වෙත යන්න"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"බ්රවුසරය වෙත යන්න"</string>
<string name="mobile_data" msgid="7094582042819250762">"ජංගම දත්ත"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ක්රියා විරහිතයි"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"සැකසීම්"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"තේරුණා"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ඔබේ <xliff:g id="TYPES_LIST">%2$s</xliff:g> භාවිත කරමින් සිටී."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"යෙදුම් ඔබේ <xliff:g id="TYPES_LIST">%s</xliff:g> භාවිත කරමින් සිටී."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"යෙදුම විවෘත කරන්න"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"අවලංගු කරන්න"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"හරි"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"සැකසීම්"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> අවසන් මිනි <xliff:g id="TIME">%3$d</xliff:g> සඳහා ඔබේ <xliff:g id="TYPE">%2$s</xliff:g> භාවිත කරමින් සිටී"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ඔබේ <xliff:g id="TYPE">%2$s</xliff:g> භාවිත කරමින් සිටී"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ඔබේ <xliff:g id="TYPES_LIST">%2$s</xliff:g> භාවිත කරමින් සිටී"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"කැමරාව"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ස්ථානය"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"මයික්රෝෆෝනය"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 6c6ad14..e11acd6 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Skúste snímku urobiť znova"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Snímka obrazovky sa nedá uložiť z dôvodu nedostatku miesta v úložisku"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Záznam obrazovky"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Zobrazuje sa upozornenie týkajúce sa relácie záznamu obrazovky"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Spustiť zaznamenávanie"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Hlasový vstup počas záznamu"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Zobrazovať klepnutia"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Ukončiť"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pozastaviť"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Obnoviť"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Zrušiť"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Zdieľať"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Odstrániť"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Záznam obrazovky bol zrušený"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Záznam obrazovky bol uložený, zobrazíte ho klepnutím"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Záznam obrazovky bol odstránený"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Pri odstraňovaní záznamu obrazovky sa vyskytla chyba"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Nepodarilo sa získať povolenia"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosu súborov USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pripojiť ako prehrávač médií (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Pripojiť ako fotoaparát (PTP)"</string>
@@ -198,9 +214,9 @@
<string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Režim v lietadle je zapnutý."</string>
<string name="accessibility_quick_settings_dnd_none_on" msgid="2960643943620637020">"úplné ticho"</string>
<string name="accessibility_quick_settings_dnd_alarms_on" msgid="3357131899365865386">"iba budíky"</string>
- <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Nerušiť"</string>
- <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Stav Nerušiť je vypnutý."</string>
- <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Stav Nerušiť je zapnutý."</string>
+ <string name="accessibility_quick_settings_dnd" msgid="6607873236717185815">"Režim bez vyrušení"</string>
+ <string name="accessibility_quick_settings_dnd_changed_off" msgid="898107593453022935">"Režim bez vyrušení je vypnutý."</string>
+ <string name="accessibility_quick_settings_dnd_changed_on" msgid="4483780856613561039">"Režim bez vyrušení je zapnutý."</string>
<string name="accessibility_quick_settings_bluetooth" msgid="6341675755803320038">"Bluetooth"</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Rozhranie Bluetooth je vypnuté."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Rozhranie Bluetooth je zapnuté."</string>
@@ -264,7 +280,7 @@
<string name="start_dreams" msgid="5640361424498338327">"Šetrič obrazovky"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_header_onboarding_text" msgid="8030309023792936283">"Pridržaním ikon zobrazíte ďalšie možnosti"</string>
- <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Nerušiť"</string>
+ <string name="quick_settings_dnd_label" msgid="8735855737575028208">"Režim bez vyrušení"</string>
<string name="quick_settings_dnd_priority_label" msgid="483232950670692036">"Iba prioritné"</string>
<string name="quick_settings_dnd_alarms_label" msgid="2559229444312445858">"Iba budíky"</string>
<string name="quick_settings_dnd_none_label" msgid="5025477807123029478">"Úplné ticho"</string>
@@ -421,7 +437,7 @@
<string name="media_projection_remember_text" msgid="3103510882172746752">"Nabudúce nezobrazovať"</string>
<string name="clear_all_notifications_text" msgid="814192889771462828">"Vymazať všetko"</string>
<string name="manage_notifications_text" msgid="2386728145475108753">"Spravovať"</string>
- <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Upozornenia sú pozastavené režimom Nerušiť"</string>
+ <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Upozornenia sú pozastavené režimom bez vyrušení"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
<string name="empty_shade_text" msgid="708135716272867002">"Žiadne upozornenia"</string>
<string name="profile_owned_footer" msgid="8021888108553696069">"Profil môže byť monitorovaný"</string>
@@ -588,15 +604,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Upozornenia"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Tieto upozornenia sa už nebudú zobrazovať"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Tieto upozornenia budú minimalizované"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Tieto upozornenia sa budú zobrazovať potichu"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Tieto upozornenia vás upozornia"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Tieto upozornenia zvyčajne odmietate. \nChcete ich naďalej zobrazovať?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Majú sa tieto upozornenia naďalej zobrazovať?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Prestať zobrazovať upozornenia"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Naďalej zobrazovať"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimalizovať"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Zobraziť potichu"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Zobraziť a upozorniť"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Majú sa upozornenia z tejto aplikácie naďalej zobrazovať?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Tieto upozornenia sa nedajú vypnúť"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Táto aplikácia používa fotoaparát."</string>
<string name="appops_microphone" msgid="741508267659494555">"Táto aplikácia používa mikrofón."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Táto aplikácia sa zobrazuje cez ďalšie aplikácie na obrazovke."</string>
@@ -678,9 +696,9 @@
<string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string>
<string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendár"</string>
<string name="tuner_full_zen_title" msgid="4540823317772234308">"Zobrazovať s ovládacími prvkami hlasitosti"</string>
- <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Nerušiť"</string>
+ <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Režim bez vyrušení"</string>
<string name="volume_dnd_silent" msgid="4363882330723050727">"Skratka tlačidiel hlasitosti"</string>
- <string name="volume_up_silent" msgid="7141255269783588286">"Pri zvýšení hlasitosti ukončiť režim Nerušiť"</string>
+ <string name="volume_up_silent" msgid="7141255269783588286">"Pri zvýšení hlasitosti ukončiť režim bez vyrušení"</string>
<string name="battery" msgid="7498329822413202973">"Batéria"</string>
<string name="clock" msgid="7416090374234785905">"Hodiny"</string>
<string name="headset" msgid="4534219457597457353">"Náhlavná súprava"</string>
@@ -735,8 +753,7 @@
<item msgid="2139628951880142927">"Zobrazovať percentá počas nabíjania (predvolené)"</item>
<item msgid="3327323682209964956">"Nezobrazovať túto ikonu"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Zobraziť ikony upozornení s nízkou prioritou"</string>
<string name="other" msgid="4060683095962566764">"Ďalšie"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Rozdeľovač obrazovky"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Ľavá – na celú obrazovku"</string>
@@ -816,15 +833,15 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikácia bola otvorená bez inštalácie."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikácia bola otvorená bez inštalácie. Klepnutím zobrazíte ďalšie informácie."</string>
<string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Prejsť na internet"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Otvoriť prehliadač"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilné dáta"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Pripojenie Wi‑Fi je vypnuté"</string>
<string name="bt_is_off" msgid="2640685272289706392">"Rozhranie Bluetooth je vypnuté"</string>
- <string name="dnd_is_off" msgid="6167780215212497572">"Nastavenie Nerušiť je vypnuté"</string>
- <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Režim Nerušiť bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
- <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Režim Nerušiť bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
- <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Režim Nerušiť bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
+ <string name="dnd_is_off" msgid="6167780215212497572">"Režim bez vyrušení je vypnutý"</string>
+ <string name="qs_dnd_prompt_auto_rule" msgid="862559028345233052">"Režim bez vyrušení bol zapnutý automatickým pravidlom (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_app" msgid="7978037419334156034">"Režim bez vyrušení bol zapnutý aplikáciou (<xliff:g id="ID_1">%s</xliff:g>)."</string>
+ <string name="qs_dnd_prompt_auto_rule_app" msgid="2599343675391111951">"Režim bez vyrušení bol zapnutý automatickým pravidlom alebo aplikáciou."</string>
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Ponechať"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradiť"</string>
@@ -848,4 +865,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Nastavenia"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Dobre"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Výpis haldy SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> používa zoznam <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikácie používajú zoznam <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Otvoriť"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Zrušiť"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Nastavenia"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> používa typ <xliff:g id="TYPE">%2$s</xliff:g> posl. <xliff:g id="TIME">%3$d</xliff:g> min."</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikácie <xliff:g id="APPS">%1$s</xliff:g> používajú typ <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> používa zoznam <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparát"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"poloha"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofón"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index f94ee60..b050497 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Poskusite znova ustvariti posnetek zaslona"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Shranjevanje posnetka zaslona ni mogoče zaradi omejenega prostora za shranjevanje"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Aplikacija ali vaša organizacija ne dovoljuje posnetkov zaslona"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Snemanje zaslona"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Nenehno obveščanje o seji snemanja zaslona"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Začni snemanje"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Snemanje spremnega govora"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Prikaz dotikov"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Ustavi"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Začasno ustavi"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Nadaljuj"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Prekliči"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Deli"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Izbriši"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Snemanje zaslona je preklicano"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Videoposnetek zaslona je shranjen, dotaknite se za ogled"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Videoposnetek zaslona je izbrisan"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Napaka pri brisanju videoposnetka zaslona"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Dovoljenj ni bilo mogoče pridobiti"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosa datotek prek USB-ja"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Vpni kot predvajalnik (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Vpni kot fotoaparat (PTP)"</string>
@@ -588,15 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Obvestila"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Ta obvestila ne bodo več prikazana"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ta obvestila bodo minimirana"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Ta obvestila običajno opustite. \nAli želite, da se še naprej prikazujejo?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Želite, da so ta obvestila še naprej prikazana?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Ustavi prikazovanje obvestil"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Prikazuj še naprej"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimiraj"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Želite, da so obvestila te aplikacije še naprej prikazana?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Teh obvestil ni mogoče izklopiti"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ta aplikacija uporablja fotoaparat."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ta aplikacija uporablja mikrofon."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ta aplikacija prekriva druge aplikacije na zaslonu."</string>
@@ -735,8 +757,7 @@
<item msgid="2139628951880142927">"Prikaži odstotek med polnjenjem (privzeto)"</item>
<item msgid="3327323682209964956">"Ne prikaži te ikone"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Pokaži ikone obvestil z nizko stopnjo prednosti"</string>
<string name="other" msgid="4060683095962566764">"Drugo"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Razdelilnik zaslonov"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Levi v celozaslonski način"</string>
@@ -816,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacija je odprta brez namestitve."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacija je odprta brez namestitve. Dotaknite se, če želite izvedeti več."</string>
<string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Pojdi v splet"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Odpri brskalnik"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobilni podatki"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi je izklopljen"</string>
@@ -848,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Nastavitve"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"V redu"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Izvoz kopice SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> uporablja <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacije uporabljajo <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Odpri apl."</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Prekliči"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"V redu"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Nastavitve"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> uporablja <xliff:g id="TYPE">%2$s</xliff:g> zadnjih toliko minut: <xliff:g id="TIME">%3$d</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Aplikacije <xliff:g id="APPS">%1$s</xliff:g> uporabljajo <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Aplikacija <xliff:g id="APP">%1$s</xliff:g> uporablja <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"fotoaparat"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokacijo"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 7869cd9..146e91c 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Provo ta nxjerrësh përsëri pamjen e ekranit"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Pamja e ekranit nuk mund të ruhet për shkak të hapësirës ruajtëse të kufizuar"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Regjistrimi i ekranit"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Njoftim i vazhdueshëm për një seancë regjistrimi të ekranit"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Nis regjistrimin"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Regjistro zërin e mikrofonit"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Shfaq trokitjet"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Ndalo"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Ndërprit"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Vazhdo"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Anulo"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Ndaj"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Fshi"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Regjistrimi i ekranit u anulua"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Regjistrimi i ekranit u ruajt, trokit për ta parë"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Regjistrimi i ekranit u fshi"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Gabim gjatë fshirjes së regjistrimit të ekranit"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Marrja e lejeve dështoi"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opsionet e transferimit të dosjeve të USB-së"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lidh si një lexues \"media\" (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montoje si kamerë (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Njoftime"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Nuk do t\'i shikosh më këto njoftime"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Këto njoftime do të minimizohen"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Këto njoftime ti zakonisht i largon. \nDëshiron të vazhdosh t\'i shfaqësh ato?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Do të vazhdosh t\'i shfaqësh këto njoftime?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Ndalo njoftimet"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Vazhdo të shfaqësh"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimizo"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Do të vazhdosh t\'i shfaqësh njoftimet nga ky aplikacion?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Këto njoftime nuk mund të çaktivizohen"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ky aplikacion po përdor kamerën."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ky aplikacion po përdor mikrofonin."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ky aplikacion po shfaqet mbi aplikacionet e tjera në ekran."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Shfaq përqindjen gjatë ngarkimit (e parazgjedhur)"</item>
<item msgid="3327323682209964956">"Mos e shfaq këtë ikonë"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Shfaq ikonat e njoftimeve me përparësi të ulët"</string>
<string name="other" msgid="4060683095962566764">"Të tjera"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Ndarësi i ekranit të ndarë"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Ekrani i plotë majtas"</string>
@@ -797,7 +818,7 @@
<string name="tuner_app" msgid="3507057938640108777">"Aplikacioni <xliff:g id="APP">%1$s</xliff:g>"</string>
<string name="notification_channel_alerts" msgid="4496839309318519037">"Sinjalizimet"</string>
<string name="notification_channel_battery" msgid="5786118169182888462">"Bateria"</string>
- <string name="notification_channel_screenshot" msgid="6314080179230000938">"Pamjet e ekranit"</string>
+ <string name="notification_channel_screenshot" msgid="6314080179230000938">"Pamje ekrani"</string>
<string name="notification_channel_general" msgid="4525309436693914482">"Mesazhe të përgjithshme"</string>
<string name="notification_channel_storage" msgid="3077205683020695313">"Hapësira ruajtëse"</string>
<string name="notification_channel_hints" msgid="7323870212489152689">"Sugjerimet"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Aplikacioni u hap pa u instaluar."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Aplikacioni u hap pa u instaluar. Trokit për të mësuar më shumë."</string>
<string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Shko në ueb"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Shko te shfletuesi"</string>
<string name="mobile_data" msgid="7094582042819250762">"Të dhënat celulare"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi është joaktiv"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Cilësimet"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"E kuptova"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Hidh grumbullin SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> po përdor <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Aplikacionet po përdorin <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Hap aplikacionin"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Anulo"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Në rregull"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Cilësimet"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> po përdor <xliff:g id="TYPE">%2$s</xliff:g> për <xliff:g id="TIME">%3$d</xliff:g> minutat e fundit"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> po përdor <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> po përdor <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamerën"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"vendndodhjen"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofonin"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 420056e..a838a0b 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Пробајте да поново направите снимак екрана"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Чување снимка екрана није успело због ограниченог меморијског простора"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Апликација или организација не дозвољавају прављење снимака екрана"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Снимање екрана"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Обавештење о сесији снимања екрана је активно"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Започни снимање"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Сними пренос гласа"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Приказуј додире"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Заустави"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Паузирај"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Настави"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Откажи"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Дели"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Избриши"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Снимање екрана је отказано"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Снимак екрана је сачуван, додирните да бисте прегледали"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Снимак екрана је избрисан"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Дошло је до проблема при брисању снимка екрана"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Преузимање дозвола није успело"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Опције USB преноса датотека"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Прикључи као медија плејер (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Прикључи као камеру (PTP)"</string>
@@ -585,15 +601,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Обавештења"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Више нећете видети ова обавештења"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ова обавештења ће се умањити"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Обично одбацујете ова обавештења. \nЖелите ли да се и даље приказују?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Желите ли да се ова обавештења и даље приказују?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Престани да приказујеш обавештења"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Настави да приказујеш"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Умањи"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Желите ли да се обавештења из ове апликације и даље приказују?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Не можете да искључите ова обавештења"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ова апликација користи камеру."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ова апликација користи микрофон."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ова апликација се приказује преко других апликација на екрану."</string>
@@ -730,8 +752,7 @@
<item msgid="2139628951880142927">"Прикажи проценат током пуњења (подразумевано)"</item>
<item msgid="3327323682209964956">"Не приказуј ову икону"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Прикажи иконе обавештења ниског приоритета"</string>
<string name="other" msgid="4060683095962566764">"Друго"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Разделник подељеног екрана"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Режим целог екрана за леви екран"</string>
@@ -811,7 +832,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Апликација се отворила без инсталирања."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Апликација се отворила без инсталирања. Додирните да бисте сазнали више."</string>
<string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Иди на веб"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Иди на прегледач"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобилни подаци"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi је искључен"</string>
@@ -843,4 +864,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Подешавања"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Важи"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Издвоји SysUI мем."</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Апликације користе <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Отвори"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Откажи"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Потврди"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Подешавања"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> током неколико последњих минута (<xliff:g id="TIME">%3$d</xliff:g>) користи <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> користе <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> користи <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камеру"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"локацију"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"микрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 238cc9b..7c4e88a 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Testa att ta en skärmdump igen"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Det går inte att spara skärmdumpen eftersom lagringsutrymmet inte räcker"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Appen eller organisationen tillåter inte att du tar skärmdumpar"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Skärminspelning"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Avisering om att skärminspelning pågår"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Börja spela in"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Spela in med mikrofondubbning"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Visa tryck"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Stoppa"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pausa"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Återuppta"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Avbryt"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Dela"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Radera"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Skärminspelningen har avbrutits"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Skärminspelningen har sparats, tryck här om du vill titta på den"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Skärminspelningen har raderats"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Det gick inte att radera skärminspelningen"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Behörighet saknas"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Överföringsalternativ"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Montera som mediaspelare (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Montera som kamera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Aviseringar"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"De här aviseringarna visas inte längre"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Dessa aviseringar minimeras"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Du brukar avvisa de här aviseringarna. \nVill du fortsätta att visa dem?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Vill du fortsätta visa de här aviseringarna?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Stoppa aviseringar"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Fortsätt visa"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Minimera"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Vill du fortsätta visa aviseringar för den här appen?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"De här aviseringarna kan inte inaktiveras"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Kameran används av appen."</string>
<string name="appops_microphone" msgid="741508267659494555">"Mikrofonen används av appen."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Appen visas över andra appar på skärmen."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Visa procent under laddning (standard)"</item>
<item msgid="3327323682209964956">"Visa inte den här ikonen"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Visa ikoner för aviseringar med låg prioritet"</string>
<string name="other" msgid="4060683095962566764">"Annat"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Avdelare för delad skärm"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Helskärm på vänster skärm"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Appen öppnades utan installation."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Appen öppnades utan installation. Tryck om du vill veta mer."</string>
<string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Öppna webbplatsen"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Öppna webbläsaren"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobildata"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi är inaktiverat"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Inställningar"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dumpa SysUI-heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="TYPES_LIST">%2$s</xliff:g> används av <xliff:g id="APP">%1$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"<xliff:g id="TYPES_LIST">%s</xliff:g> används av appar."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Öppna app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Avbryt"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Inställn."</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="TYPE">%2$s</xliff:g> har använts av <xliff:g id="APP">%1$s</xliff:g> under de senaste <xliff:g id="TIME">%3$d</xliff:g> minuterna"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="TYPE">%2$s</xliff:g> används av <xliff:g id="APPS">%1$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="TYPES_LIST">%2$s</xliff:g> används av <xliff:g id="APP">%1$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"plats"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 54e8544..fbc1022 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Jaribu kupiga picha ya skrini tena"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Imeshindwa kuhifadhi picha ya skrini kwa sababu nafasi haitoshi"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Programu au shirika lako halikuruhusu kupiga picha za skrini"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Kurekodi Skrini"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Arifa inayoendelea ya kipindi cha kurekodi skrini"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Anza Kurekodi"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Rekodi sauti"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Onyesha unapogusa"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Acha"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Sitisha"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Endelea"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Ghairi"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Shiriki"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Futa"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Imeghairi mchakato wa kurekodi skrini"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Imehifadhi rekodi ya skrini, gusa ili uangalie"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Imefuta rekodi ya skrini"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Hitilafu imetokea wakati wa kufuta rekodi ya skrini"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Imeshindwa kupata ruhusa"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Machaguo ya uhamisho wa faili la USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Angika kama kichezaji cha maudhui (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Angika kama kamera (PTP)"</string>
@@ -582,14 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Arifa"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Hutaona tena arifa hizi"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Arifa hizi zitapunguzwa"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Wewe huondoa arifa hizi. \nUngependa kuzionyesha?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Ungependa kuendelea kuonyesha arifa hizi?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Acha kuonyesha arifa"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Endelea kuonyesha"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Punguza"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Ungependa kuendelea kuonyesha arifa kutoka programu hii?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Huwezi kuzima arifa hizi"</string>
- <string name="notification_delegate_header" msgid="9167022191405284627">"kupitia <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="appops_camera" msgid="8100147441602585776">"Programu hii inatumia kamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Programu hii inatumia maikrofoni."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Programu hii inachomoza kwenye programu zingine zilizo katika skrini yako."</string>
@@ -804,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Programu inafunguka bila kusakinishwa."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Programu inafunguka bila kusakinishwa. Gusa ili upate maelezo zaidi."</string>
<string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Nenda kwenye wavuti"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Tumia kivinjari"</string>
<string name="mobile_data" msgid="7094582042819250762">"Data ya simu"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g><xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi imezimwa"</string>
@@ -836,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Mipangilio"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Nimeelewa"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> inatumia <xliff:g id="TYPES_LIST">%2$s</xliff:g> yako."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Programu zinatumia <xliff:g id="TYPES_LIST">%s</xliff:g> yako."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Fungua programu"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Ghairi"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Sawa"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Mipangilio"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> imekuwa ikitumia <xliff:g id="TYPE">%2$s</xliff:g> yako kwa dakika <xliff:g id="TIME">%3$d</xliff:g> zilizopita"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> zinatumia <xliff:g id="TYPE">%2$s</xliff:g> yako"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> inatumia <xliff:g id="TYPES_LIST">%2$s</xliff:g> yako"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"mahali"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"maikrofoni"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index becd903..8ba895b 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ஸ்கிரீன் ஷாட்டை மீண்டும் எடுக்க முயலவும்"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ஸ்கிரீன் ஷாட்டுகளை எடுப்பதை, பயன்பாடு அல்லது உங்கள் நிறுவனம் அனுமதிக்கவில்லை"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"திரை ரெக்கார்டிங்"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"திரை ரெக்கார்டிங் அமர்விற்கான தொடர் அறிவிப்பு"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ரெக்கார்டிங்கைத் தொடங்கு"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"வாய்ஸ் ஓவரை ரெக்கார்டு செய்"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"தட்டல்களைக் காட்டு"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"நிறுத்து"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"இடைநிறுத்து"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"மீண்டும் தொடங்கு"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ரத்துசெய்"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"பகிர்"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"நீக்கு"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"திரை ரெக்கார்டிங் ரத்துசெய்யப்பட்டது"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"திரை ரெக்கார்டிங் சேமிக்கப்பட்டது, பார்க்கத் தட்டவும்"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"திரை ரெக்கார்டிங் நீக்கப்பட்டது"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"திரை ரெக்கார்டிங்கை நீக்குவதில் பிழை"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"அனுமதிகளைப் பெற இயலவில்லை"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB கோப்பு இடமாற்ற விருப்பங்கள்"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"(MTP) மீடியா பிளேயராக ஏற்று"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"(PTP) கேமராவாக ஏற்று"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"அறிவிப்புகள்"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"இந்த அறிவிப்புகளை இனி பார்க்கமாட்டீர்கள்"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"இந்த அறிவிப்புகள் சிறிதாக்கப்படும்"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"வழக்கமாக, இந்த அறிவிப்புகளை நிராகரிக்கிறீர்கள். \nதொடர்ந்து இவற்றைக் காட்டலாமா?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"இந்த அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"அறிவிப்புகளை நிறுத்து"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"அறிவிப்புகளைத் தொடர்ந்து காட்டு"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"சிறிதாக்கு"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"இந்தப் பயன்பாட்டின் அறிவிப்புகளைத் தொடர்ந்து காட்டவா?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"இந்த அறிவிப்புகளை ஆஃப் செய்ய முடியாது"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"இந்த ஆப்ஸானது கேமராவை உபயோகிக்கிறது."</string>
<string name="appops_microphone" msgid="741508267659494555">"இந்த ஆப்ஸானது, மைக்ரோஃபோனை உபயோகிக்கிறது."</string>
<string name="appops_overlay" msgid="6165912637560323464">"இந்த ஆப்ஸானது, உங்கள் திரையில் பிற ஆப்ஸின் இடைமுகத்தின் மேல் தோன்றுகிறது."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"சார்ஜ் செய்யும் போது சதவீதத்தைக் காட்டு (இயல்பு)"</item>
<item msgid="3327323682209964956">"இந்த ஐகானைக் காட்டாதே"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"குறைந்த முன்னுரிமை உள்ள அறிவிப்பு ஐகான்களைக் காட்டு"</string>
<string name="other" msgid="4060683095962566764">"மற்றவை"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"திரையைப் பிரிக்கும் பிரிப்பான்"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"இடது புறம் முழுத் திரை"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"நிறுவ வேண்டிய தேவையில்லாமல் ஆப்ஸ் திறக்கப்பட்டது."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"நிறுவ வேண்டிய தேவையில்லாமல் ஆப்ஸ் திறக்கப்பட்டது. மேலும் அறியத் தட்டவும்."</string>
<string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
- <string name="go_to_web" msgid="1106022723459948514">"இணையத்திற்குச் செல்"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"உலாவிக்குச் செல்"</string>
<string name="mobile_data" msgid="7094582042819250762">"மொபைல் டேட்டா"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"வைஃபை முடக்கத்தில் உள்ளது"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"அமைப்புகள்"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"சரி"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"உங்கள் <xliff:g id="TYPES_LIST">%2$s</xliff:g>ஐ <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகிறது."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"உங்கள் <xliff:g id="TYPES_LIST">%s</xliff:g> ஆகியவற்றை ஆப்ஸ் பயன்படுத்துகின்றன."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ஆப்ஸை திற"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ரத்துசெய்"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"சரி"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"அமைப்புகள்"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"கடந்த <xliff:g id="TIME">%3$d</xliff:g> நிமிடங்களாக உங்கள் <xliff:g id="TYPE">%2$s</xliff:g>ஐ <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகிறது"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"உங்கள் <xliff:g id="TYPE">%2$s</xliff:g> ஆகியவற்றை <xliff:g id="APPS">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகின்றன"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"உங்கள் <xliff:g id="TYPES_LIST">%2$s</xliff:g>ஐ <xliff:g id="APP">%1$s</xliff:g> ஆப்ஸ் பயன்படுத்துகிறது"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"கேமரா"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"இருப்பிடம்"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"மைக்ரோஃபோன்"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index b895ae6..12dd31a 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"స్క్రీన్షాట్ తీయడానికి మళ్లీ ప్రయత్నించండి"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"నిల్వ స్థలం పరిమితంగా ఉన్న కారణంగా స్క్రీన్షాట్ను సేవ్ చేయడం సాధ్యపడదు"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"స్క్రీన్షాట్లు తీయడానికి యాప్ లేదా మీ సంస్థ అనుమతించలేదు"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"స్క్రీన్ రికార్డింగ్"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"స్క్రీన్ రికార్డ్ సెషన్ కోసం ఆన్గోయింగ్ నోటిఫికేషన్"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"రికార్డింగ్ను ప్రారంభించు"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"వాయిస్ఓవర్ని రికార్డ్ చేయి"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"నొక్కినవి చూపు"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"ఆపివేయి"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"పాజ్ చేయి"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"కొనసాగించు"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"రద్దు చేయి"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"షేర్ చేయి"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"తొలగించు"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"స్క్రీన్ రికార్డ్ రద్దు చేయబడింది"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"స్క్రీన్ రికార్డింగ్ సేవ్ చేయబడింది, చూడటం కోసం నొక్కండి"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"స్క్రీన్ రికార్డింగ్ తొలగించబడింది"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"స్క్రీన్ రికార్డింగ్ని తొలగిస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"అనుమతులను పొందడం విఫలమైంది"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB ఫైల్ బదిలీ ఎంపికలు"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"మీడియా ప్లేయర్గా (MTP) మౌంట్ చేయి"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"కెమెరాగా (PTP) మౌంట్ చేయి"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"నోటిఫికేషన్లు"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"ఇకపై మీకు ఈ నోటిఫికేషన్లు కనిపించవు"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ఈ నోటిఫికేషన్లు కుదించబడ్డాయి"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"మీరు సాధారణంగా ఈ నోటిఫికేషన్లను విస్మరిస్తారు. \nవాటి ప్రదర్శనను కొనసాగించాలా?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"ఈ నోటిఫికేషన్లను చూపిస్తూ ఉండాలా?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"నోటిఫికేషన్లను ఆపివేయి"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"చూపిస్తూనే ఉండు"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"కుదించు"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"ఈ యాప్ నుండి నోటిఫికేషన్లను చూపిస్తూ ఉండాలా?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ఈ నోటిఫికేషన్లను ఆఫ్ చేయలేరు"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"ఈ యాప్ ఈ కెమెరాను ఉపయోగిస్తోంది."</string>
<string name="appops_microphone" msgid="741508267659494555">"ఈ యాప్ మైక్రోఫోన్ను ఉపయోగిస్తుంది."</string>
<string name="appops_overlay" msgid="6165912637560323464">"ఈ యాప్ మీ స్క్రీన్లోని ఇతర యాప్లపై ప్రదర్శించబడుతోంది."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"ఛార్జ్ అవుతున్నప్పుడు శాతాన్ని చూపు (డిఫాల్ట్)"</item>
<item msgid="3327323682209964956">"ఈ చిహ్నాన్ని చూపవద్దు"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string>
<string name="other" msgid="4060683095962566764">"ఇతరం"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"విభజన స్క్రీన్ విభాగిని"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"ఎడమవైపు పూర్తి స్క్రీన్"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"ఇన్స్టాల్ చేయకుండా యాప్ తెరవబడింది."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"ఇన్స్టాల్ చేయకుండా యాప్ తెరవబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
<string name="app_info" msgid="6856026610594615344">"యాప్ సమాచారం"</string>
- <string name="go_to_web" msgid="1106022723459948514">"వెబ్కు వెళ్లు"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"బ్రౌజర్కు వెళ్లండి"</string>
<string name="mobile_data" msgid="7094582042819250762">"మొబైల్ డేటా"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ఆఫ్లో ఉంది"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"సెట్టింగ్లు"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"అర్థమైంది"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"డంప్ SysUI హీప్"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> మీ <xliff:g id="TYPES_LIST">%2$s</xliff:g>ని ఉపయోగిస్తోంది."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"అప్లికేషన్లు మీ <xliff:g id="TYPES_LIST">%s</xliff:g>ని ఉపయోగిస్తున్నాయి."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"యాప్ని తెరవండి"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"రద్దు చేయండి"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"సరే"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"సెట్టింగ్లు"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"గత <xliff:g id="TIME">%3$d</xliff:g> నిమిషాలుగా <xliff:g id="APP">%1$s</xliff:g> మీ <xliff:g id="TYPE">%2$s</xliff:g>ని ఉపయోగిస్తోంది"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> మీ <xliff:g id="TYPE">%2$s</xliff:g>ని ఉపయోగిస్తున్నాయి"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> మీ <xliff:g id="TYPES_LIST">%2$s</xliff:g>ను ఉపయోగిస్తోంది"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"కెమెరా"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"స్థానం"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"మైక్రోఫోన్"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 4df01ed..8efeabe 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"ลองบันทึกภาพหน้าจออีกครั้ง"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"บันทึกภาพหน้าจอไม่ได้เนื่องจากพื้นที่เก็บข้อมูลมีจำกัด"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"แอปหรือองค์กรของคุณไม่อนุญาตให้จับภาพหน้าจอ"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"การบันทึกหน้าจอ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"การแจ้งเตือนต่อเนื่องสำหรับเซสชันการบันทึกหน้าจอ"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"เริ่มต้นการบันทึก"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"บันทึกเสียงบรรยาย"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"แสดงการแตะ"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"หยุด"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"หยุด"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"ทำต่อ"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"ยกเลิก"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"แชร์"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"ลบ"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"ยกเลิกการบันทึกหน้าจอแล้ว"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"บันทึกการบันทึกหน้าจอแล้ว แตะเพื่อดู"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"ลบการบันทึกหน้าจอแล้ว"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"เกิดข้อผิดพลาดในการลบการบันทึกหน้าจอ"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"ขอสิทธิ์ไม่สำเร็จ"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"ตัวเลือกการถ่ายโอนไฟล์ USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ต่อเชื่อมเป็นโปรแกรมเล่นสื่อ (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ต่อเชื่อมเป็นกล้องถ่ายรูป (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"การแจ้งเตือน"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"คุณจะไม่เห็นการแจ้งเตือนเหล่านี้อีก"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"การแจ้งเตือนเหล่านี้จะย่อเล็กสุด"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"โดยปกติแล้ว คุณจะปิดการแจ้งเตือนเหล่านี้ \nต้องการให้แสดงต่อไหม"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"แสดงการแจ้งเตือนเหล่านี้ต่อไปไหม"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"ปิดการแจ้งเตือน"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"แสดงต่อไป"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"ย่อเล็กสุด"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"แสดงการแจ้งเตือนจากแอปนี้ต่อไปไหม"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ปิดการแจ้งเตือนเหล่านี้ไม่ได้"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"แอปนี้กำลังใช้กล้อง"</string>
<string name="appops_microphone" msgid="741508267659494555">"แอปนี้กำลังใช้ไมโครโฟน"</string>
<string name="appops_overlay" msgid="6165912637560323464">"แอปนี้กำลังแสดงทับแอปอื่นๆ ในหน้าจอ"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"แสดงเปอร์เซ็นต์เมื่อชาร์จ (ค่าเริ่มต้น)"</item>
<item msgid="3327323682209964956">"อย่าแสดงไอคอนนี้"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"แสดงไอคอนการแจ้งเตือนลำดับความสำคัญต่ำ"</string>
<string name="other" msgid="4060683095962566764">"อื่นๆ"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"เส้นแบ่งหน้าจอ"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"เต็มหน้าจอทางซ้าย"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"เปิดแอปได้โดยไม่ต้องติดตั้ง"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"เปิดแอปได้โดยไม่ต้องติดตั้ง แตะเพื่อดูข้อมูลเพิ่มเติม"</string>
<string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ไปที่เว็บ"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"ไปที่เบราว์เซอร์"</string>
<string name="mobile_data" msgid="7094582042819250762">"เน็ตมือถือ"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi ปิดอยู่"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"การตั้งค่า"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"รับทราบ"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ใช้<xliff:g id="TYPES_LIST">%2$s</xliff:g>ของคุณอยู่"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"หลายแอปพลิเคชันใช้<xliff:g id="TYPES_LIST">%s</xliff:g>ของคุณอยู่"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"เปิดแอป"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"ยกเลิก"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ตกลง"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"การตั้งค่า"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> ใช้<xliff:g id="TYPE">%2$s</xliff:g>ของคุณอยู่ในช่วง <xliff:g id="TIME">%3$d</xliff:g> นาทีที่ผ่านมา"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ใช้<xliff:g id="TYPE">%2$s</xliff:g>ของคุณอยู่"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ใช้<xliff:g id="TYPES_LIST">%2$s</xliff:g>ของคุณอยู่"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"กล้องถ่ายรูป"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"ตำแหน่ง"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"ไมโครโฟน"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 71a26ac..db6ce32f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Subukang kumuhang muli ng screenshot"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Hindi ma-save ang screenshot dahil sa limitadong espasyo ng storage"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Hindi pinahihintulutan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Pag-record ng Screen"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Kasalukuyang notification para sa session ng pag-record ng screen"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Simulan ang Pag-record"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"I-record ang voiceover"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Ipakita ang mga pag-tap"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Ihinto"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"I-pause"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Ituloy"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Kanselahin"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Ibahagi"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"I-delete"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Kinansela ang pag-record ng screen"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Na-save ang pag-record ng screen, i-tap para tingnan"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Na-delete ang pag-record ng screen"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Error sa pag-delete sa pag-record ng screen"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Hindi nakuha ang mga pahintulot"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Opsyon paglipat ng USB file"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"I-mount bilang isang media player (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"I-mount bilang camera (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Mga Notification"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Hindi mo na makikita ang mga notification na ito"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Imi-minimize ang mga notification na ito"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Karaniwan mong dini-dismiss ang mga ganitong notification. \nPatuloy na ipakita ang mga ito?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Patuloy na ipakita ang mga notification na ito?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Ihinto ang mga notification"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Patuloy na ipakita"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"I-minimize"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Patuloy na ipakita ang mga notification mula sa app na ito?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Hindi maaaring i-off ang mga notification na ito"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ginagamit ng app na ito ang camera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ginagamit ng app na ito ang mikropono."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ipinapakita ang app na ito sa ibabaw ng iba pang app sa iyong screen."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Ipakita ang porsyento kapag nagcha-charge (default)"</item>
<item msgid="3327323682209964956">"Huwag ipakita ang icon na ito"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Ipakita ang mga icon ng notification na may mababang priority"</string>
<string name="other" msgid="4060683095962566764">"Iba pa"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Divider ng split-screen"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"I-full screen ang nasa kaliwa"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Nabuksan ang app nang hindi ini-install."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Nabuksan ang app nang hindi ini-install. I-tap para matuto pa."</string>
<string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Pumunta sa web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Pumunta sa browser"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobile data"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Naka-off ang Wi-Fi"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Mga Setting"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Itapon SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Ginagamit ng <xliff:g id="APP">%1$s</xliff:g> ang iyong <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Ginagamit ng mga application ang iyong <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Buksan: app"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Kanselahin"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Okay"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Mga Setting"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Ginagamit ng <xliff:g id="APP">%1$s</xliff:g> ang iyong <xliff:g id="TYPE">%2$s</xliff:g> para sa huling <xliff:g id="TIME">%3$d</xliff:g> (na) minuto"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Ginagamit ng <xliff:g id="APPS">%1$s</xliff:g> ang iyong <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Ginagamit ng <xliff:g id="APP">%1$s</xliff:g> ang iyong <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"camera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"lokasyon"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikropono"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b3809c4..c7a8150 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Tekrar ekran görüntüsü almayı deneyin"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Depolama alanı sınırlı olduğundan ekran görüntüsü kaydedilemiyor"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ekran Kaydı"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ekran kaydı oturumu için devam eden bildirim"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Kaydı Başlat"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Seslendirme kaydet"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Dokunmaları göster"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Durdur"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Duraklat"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Devam ettir"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"İptal"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Paylaş"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Sil"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekran kaydı iptal edildi"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekran kaydı tamamlandı, görüntülemek için dokunun"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekran kaydı silindi"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Ekran kaydı silinirken hata oluştu"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"İzinler alınamadı"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB dosya aktarım seçenekleri"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Medya oynatıcı olarak ekle (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera olarak ekle (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirimler"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Bu bildirimleri artık görmeyeceksiniz"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Bu bildirimler küçültülecek"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Bu bildirimleri genellikle kapatıyorsunuz. \nBildirimler gösterilmeye devam edilsin mi?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Bu bildirimler gösterilmeye devam edilsin mi?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Bildirimleri durdur"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Göstermeye devam et"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Küçült"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu uygulamadan gelen bildirimler gösterilmeye devam edilsin mi?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Bu bildirimler kapatılamaz"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Bu uygulama kamerayı kullanıyor."</string>
<string name="appops_microphone" msgid="741508267659494555">"Bu uygulama mikrofonu kullanıyor."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Bu uygulama, ekranınızdaki diğer uygulamaların üzerinde görüntüleniyor."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Şarj olurken yüzdeyi göster (varsayılan)"</item>
<item msgid="3327323682209964956">"Bu simgeyi gösterme"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Düşük öncelikli bildirim simgelerini göster"</string>
<string name="other" msgid="4060683095962566764">"Diğer"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Bölünmüş ekran ayırıcı"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Solda tam ekran"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Uygulama yüklenmeden açıldı."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Uygulama yüklenmeden açıldı. Daha fazla bilgi için dokunun."</string>
<string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Web\'e git"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Tarayıcıya git"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobil veriler"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Kablosuz bağlantı kapalı"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Ayarlar"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Anladım"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI Yığın Dökümü"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> şunları kullanıyor: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Uygulamalar şunları kullanıyor: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Uygulama aç"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"İptal"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Tamam"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Ayarlar"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> en az <xliff:g id="TIME">%3$d</xliff:g> dakikadır şunları kullanıyor: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> şunları kullanıyor: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> şunları kullanıyor: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"konum"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index a52ec2a..dfac474 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Спробуйте зробити знімок екрана ще раз"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Не вдалося зберегти знімок екрана через обмежений обсяг пам’яті"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Додаток або адміністратор вашої організації не дозволяють робити знімки екрана"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Запис екрана"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Сповіщення про сеанс запису екрана"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Почати запис"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Записувати голосовий супровід"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Показувати дотики"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Зупинити"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Призупинити"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Відновити"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Скасувати"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Поділитися"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Видалити"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Запис екрана скасовано"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Запис екрана збережено. Натисніть, щоб переглянути"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Запис екрана видалено"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Не вдалося видалити запис екрана"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Не вдалось отримати дозволи"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Парам.передав.файлів через USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Підключити як медіапрогравач (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Підключити як камеру (PTP)"</string>
@@ -588,15 +604,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Сповіщення"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Ви більше не бачитимете цих сповіщень"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Ці сповіщення буде згорнуто"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Ви зазвичай закриваєте ці сповіщення. \nПоказувати їх?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Чи показувати ці сповіщення надалі?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Не показувати сповіщення"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Показувати надалі"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Згорнути"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Чи показувати сповіщення з цього додатка надалі?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Ці сповіщення не можна вимкнути"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Цей додаток використовує камеру."</string>
<string name="appops_microphone" msgid="741508267659494555">"Цей додаток використовує мікрофон."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Цей додаток відображається поверх інших додатків на екрані."</string>
@@ -735,8 +757,7 @@
<item msgid="2139628951880142927">"Показувати відсотки під час заряджання (за умовчанням)"</item>
<item msgid="3327323682209964956">"Не показувати цей значок"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Показувати значки сповіщень із низьким пріоритетом"</string>
<string name="other" msgid="4060683095962566764">"Інше"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Розділювач екрана"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Ліве вікно на весь екран"</string>
@@ -816,7 +837,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Додаток відкрито без встановлення."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Додаток відкрито без встановлення. Торкніться, щоб дізнатися більше."</string>
<string name="app_info" msgid="6856026610594615344">"Про додаток"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Перейти на веб-сайт"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Веб-переглядач"</string>
<string name="mobile_data" msgid="7094582042819250762">"Мобільний трафік"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi вимкнено"</string>
@@ -848,4 +869,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Налаштування"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"Додаток <xliff:g id="APP">%1$s</xliff:g> використовує <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Додатки використовують <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Відкрити додаток"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Скасувати"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Параметри"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"Додаток <xliff:g id="APP">%1$s</xliff:g> використовує <xliff:g id="TYPE">%2$s</xliff:g> протягом стількох останніх хвилин: <xliff:g id="TIME">%3$d</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Додатки <xliff:g id="APPS">%1$s</xliff:g> використовують <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"Додаток <xliff:g id="APP">%1$s</xliff:g> використовує <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"камеру"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"місце"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"мікрофон"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index eb0c60b..8b52391 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"دوبارہ اسکرین شاٹ لینے کی کوشش کریں"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"اسٹوریج کی محدود جگہ کی وجہ سے اسکرین شاٹ کو محفوظ نہیں کیا جا سکتا"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"اسکرین ریکارڈنگ"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"اسکرین ریکارڈ سیشن کیلئے جاری اطلاع"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"ریکارڈنگ شروع کریں"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"وائس اوور ریکارڈ کریں"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"تھپتھپاہٹیں دکھائیں"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"روکیں"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"موقوف کریں"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"دوبارہ شروع کریں"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"منسوخ کریں"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"اشتراک کریں"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"حذف کریں"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"اسکرین ریکارڈنگ منسوخ ہو گئی"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"اسکرین ریکارڈنگ محفوظ ہو گئی، دیکھنے کیلئے تھپتھپائیں"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"اسکرین ریکارڈنگ حذف ہو گئی"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"اسکرین ریکارڈنگ کو حذف کرنے میں خرابی"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"اجازتیں حاصل کرنے میں ناکامی"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB فائل منتقل کرنیکے اختیارات"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"ایک میڈیا پلیئر (MTP) کے بطور ماؤنٹ کریں"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"ایک کیمرہ (PTP) کے بطور ماؤنٹ کریں"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"اطلاعات"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"آپ کو یہ اطلاعات مزید دکھائی نہیں دیں گی"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"ان اطلاعات کو چھوٹا کر دیا جائے گا"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"آپ عام طور پر ان اطلاعات کو مسترد کرتے ہیں۔ \nان کو دکھاتے رہیں؟"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"یہ اطلاعات دکھانا جاری رکھیں؟"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"اطلاعات روک دیں"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"دکھانا جاری رکھیں"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"چھوٹا کریں"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"اس ایپ کی طرف سے اطلاعات دکھانا جاری رکھیں؟"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"ان اطلاعات کو آف نہیں کیا جا سکتا"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"یہ ایپ کیمرے کا استعمال کر رہی ہے۔"</string>
<string name="appops_microphone" msgid="741508267659494555">"یہ ایپ مائیکروفون کا استعمال کر رہی ہے۔"</string>
<string name="appops_overlay" msgid="6165912637560323464">"یہ ایپ آپ کی اسکرین پر دیگر ایپس پر ڈسپلے کر رہی ہے۔"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"چارج ہوتے وقت فیصد دکھائیں (ڈیفالٹ)"</item>
<item msgid="3327323682209964956">"یہ آئیکن نہ دکھائیں"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"کم ترجیحی اطلاع کے آئیکنز دکھائیں"</string>
<string name="other" msgid="4060683095962566764">"دیگر"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"سپلٹ اسکرین تقسیم کار"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"بائیں فل اسکرین"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"انسٹال کیے بغیر کھلنے والی ایپ۔"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"انسٹال کیے بغیر کھلنے والی ایپ۔ مزید جاننے کے لیے تھپتھپائيں۔"</string>
<string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
- <string name="go_to_web" msgid="1106022723459948514">"ویب پر جائیں"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"براؤزر پر جائیں"</string>
<string name="mobile_data" msgid="7094582042819250762">"موبائل ڈیٹا"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi آف ہے"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"ترتیبات"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"سمجھ آ گئی"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> آپ کی <xliff:g id="TYPES_LIST">%2$s</xliff:g> کا استعمال کر رہی ہے۔"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"ایپلیکیشنز آپ کی <xliff:g id="TYPES_LIST">%s</xliff:g> کا استعمال کر رہی ہیں۔"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"ایپ کھولیں"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"منسوخ کریں"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"ٹھیک ہے"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"ترتیبات"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> گزشتہ <xliff:g id="TIME">%3$d</xliff:g> منٹ سے آپ کی <xliff:g id="TYPE">%2$s</xliff:g> کا استعمال کر رہی ہے۔"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> آپ کی <xliff:g id="TYPE">%2$s</xliff:g> کا استعمال کر رہی ہیں"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> آپ کی <xliff:g id="TYPES_LIST">%2$s</xliff:g> کا استعمال کر رہی ہے"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"کیمرا"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"مقام"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"مائیکروفون"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index e7c3300..4c3909b 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Qayta skrinshot olib ko‘ring"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Xotirada joy kamligi uchun skrinshot saqlanmadi"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ekrandan video yozib olish"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Ekrandan yozib olish seansi uchun joriy bildirishnoma"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Yozuvni boshlash"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Kadrorti nutqini yozib olish"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Bosishlarni ko‘rsatish"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"To‘xtatish"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Pauza"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Davom etish"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Bekor qilish"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Ulashish"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"O‘chirish"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ekrandan yozib olish bekor qilindi"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ekrandan yozib olingan video saqlandi. Uni ochish uchun bildirishnomani bosing."</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ekrandan yozib olingan video o‘chirib tashlandi"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Ekrandan yozib olingan vi olib tashlanmadi"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Zarur ruxsatlar olinmadi"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB fayl ko‘chirish moslamalari"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Media pleyer sifatida ulash (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Kamera sifatida ulash (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Bildirishnomalar"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Bu bildirishnomalar endi chiqmaydi"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Bu bildirishnomalar kichraytiriladi"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Bu bildirishnomalar ovozsiz chiqariladi"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Bu bildirishnomalar sizni ogohlantiradi"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Odatda bunday bildirishnomalarni yopasiz. \nUlar ochiq tursinmi?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Mazkur bildirishnomalar chiqaversinmi?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Chiqmasin"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Ha"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Kichraytirish"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Ovozsiz"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Chiqarish va ogohlantirish"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Bu ilovadan keladigan bildirishnomalar chiqaversinmi?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Bu bildirishnomalarni chiqmaydigan qilish imkonsiz"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Bu ilova kameradan foydalanmoqda."</string>
<string name="appops_microphone" msgid="741508267659494555">"Bu ilova mikrofondan foydalanmoqda."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Bu ilova ekranda boshqa ilovalar ustidan ochilgan."</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"Quvvat olayotganda foizda ko‘rsatilsin (birlamchi)"</item>
<item msgid="3327323682209964956">"Bu belgi boshqa ko‘rsatilmasin"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Muhim boʻlmagan bildirishnoma ikonkalarini koʻrsatish"</string>
<string name="other" msgid="4060683095962566764">"Boshqa"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Ekranni ikkiga bo‘lish chizig‘i"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Chapda to‘liq ekran"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Ilova o‘rnatilmasdan ochildi."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ilova o‘rnatilmasdan ochildi. Batafsil axborot uchun bu yerga bosing."</string>
<string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Brauzerga o‘tish"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Brauzerni ochish"</string>
<string name="mobile_data" msgid="7094582042819250762">"Mobil internet"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> – <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi o‘chiq"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Sozlamalar"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> ishlatmoqda: <xliff:g id="TYPES_LIST">%2$s</xliff:g>."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Ilovalarda ishlatilmoqda: <xliff:g id="TYPES_LIST">%s</xliff:g>."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Ilovani ochish"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Bekor qilish"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Sozlamalar"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> oxirgi <xliff:g id="TIME">%3$d</xliff:g> daqiqadan beri ishlatmoqda: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> ishlatmoqda: <xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> ishlatmoqda: <xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"kamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"joylashuv"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"mikrofon"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 4356ac5..5fbccf0 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Hãy thử chụp lại màn hình"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Không thể lưu ảnh chụp màn hình do giới hạn dung lượng bộ nhớ"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Đang ghi màn hình"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Thông báo đang diễn ra về phiên ghi màn hình"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Bắt đầu ghi"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Ghi phần thuyết minh"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Hiển thị số lần nhấn"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Dừng"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Tạm dừng"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Tiếp tục"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Hủy"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Chia sẻ"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Xóa"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Đã hủy bản ghi màn hình"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Đã lưu bản ghi màn hình, nhấn để xem"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Đã xóa bản ghi màn hình"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Lỗi khi xóa bản ghi màn hình"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Không được cấp đủ quyền"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Gắn như một trình phát đa phương tiện (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Gắn như một máy ảnh (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Thông báo"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Bạn sẽ không thấy các thông báo này nữa"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Các thông báo này sẽ được thu nhỏ"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"Bạn thường bỏ qua những thông báo này. \nTiếp tục hiển thị thông báo?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Tiếp tục hiển thị các thông báo này?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Dừng thông báo"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Tiếp tục hiển thị"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Thu nhỏ"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Tiếp tục hiển thị các thông báo từ ứng dụng này?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Không thể tắt các thông báo này"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Ứng dụng này đang sử dụng máy ảnh."</string>
<string name="appops_microphone" msgid="741508267659494555">"Ứng dụng này đang sử dụng micrô."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Ứng dụng này đang hiển thị chồng lên các ứng dụng khác trên màn hình."</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"Hiển thị phần trăm khi sạc (mặc định)"</item>
<item msgid="3327323682209964956">"Không hiển thị biểu tượng này"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Hiển thị biểu tượng thông báo có mức ưu tiên thấp"</string>
<string name="other" msgid="4060683095962566764">"Khác"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Bộ chia chia đôi màn hình"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Toàn màn hình bên trái"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Ứng dụng được mở mà không cần cài đặt."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ứng dụng được mở mà không cần cài đặt. Nhấn để tìm hiểu thêm."</string>
<string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Truy cập web"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Đi tới trình duyệt"</string>
<string name="mobile_data" msgid="7094582042819250762">"Dữ liệu di động"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi tắt"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Cài đặt"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"Trích xuất bộ nhớ SysUI"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g> đang dùng <xliff:g id="TYPES_LIST">%2$s</xliff:g> của bạn."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Các ứng dụng đang dùng <xliff:g id="TYPES_LIST">%s</xliff:g> của bạn."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Mở ứng dụng"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Hủy"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"OK"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Cài đặt"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g> đang dùng <xliff:g id="TYPE">%2$s</xliff:g> của bạn trong <xliff:g id="TIME">%3$d</xliff:g> phút qua"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g> đang dùng <xliff:g id="TYPE">%2$s</xliff:g> của bạn"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g> đang dùng <xliff:g id="TYPES_LIST">%2$s</xliff:g> của bạn"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"máy ảnh"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"vị trí"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"micrô"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 5424266..8ab6905 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"请再次尝试截屏"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"由于存储空间有限,无法保存屏幕截图"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"此应用或您所在的单位不允许进行屏幕截图"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"屏幕录制"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"持续显示屏幕录制会话通知"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"开始录制"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"录制旁白"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"显示点按操作反馈"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"停止"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"暂停"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"继续"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"取消"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"分享"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"删除"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"已取消录制屏幕"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"屏幕录制内容已保存,点按即可查看"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"已删除屏幕录制内容"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"删除屏幕录制内容时出错"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"无法获取权限"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB文件传输选项"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"作为媒体播放器(MTP)装载"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"作为相机(PTP)装载"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"您将不会再看到这些通知"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"系统将会最小化这些通知"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"您通常会关闭这些通知。\n是否继续显示通知?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"要继续显示这些通知吗?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"停止通知"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"继续显示"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"要继续显示来自此应用的通知吗?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"无法关闭这些通知"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"此应用正在使用摄像头。"</string>
<string name="appops_microphone" msgid="741508267659494555">"此应用正在使用麦克风。"</string>
<string name="appops_overlay" msgid="6165912637560323464">"此应用正显示在屏幕上其他应用的上层。"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"充电时显示百分比(默认)"</item>
<item msgid="3327323682209964956">"不显示此图标"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"显示低优先级的通知图标"</string>
<string name="other" msgid="4060683095962566764">"其他"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"分屏分隔线"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"左侧全屏"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"已打开免安装应用。"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"已打开免安装应用。点按即可了解详情。"</string>
<string name="app_info" msgid="6856026610594615344">"应用信息"</string>
- <string name="go_to_web" msgid="1106022723459948514">"转到网页版"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"转到浏览器"</string>
<string name="mobile_data" msgid="7094582042819250762">"移动数据"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"WLAN 已关闭"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"设置"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"知道了"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"转储 SysUI 堆"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"<xliff:g id="APP">%1$s</xliff:g>正在使用您的<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"有多个应用正在使用您的<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"打开应用"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"取消"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"确定"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"设置"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"<xliff:g id="APP">%1$s</xliff:g>在过去 <xliff:g id="TIME">%3$d</xliff:g> 分钟内一直在使用您的<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>正在使用您的<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"<xliff:g id="APP">%1$s</xliff:g>正在使用您的<xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"相机"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"位置信息"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"麦克风"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 38e8b3cd..19450af 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"請再嘗試拍攝螢幕擷取畫面"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"由於儲存空間有限,因此無法儲存螢幕擷取畫面"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"應用程式或您的機構不允許擷取螢幕畫面"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"錄影畫面"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"持續顯示錄影畫面工作階段通知"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"開始錄影"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"錄製畫面外的音效"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"顯示輕按選項"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"停止"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"暫停"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"繼續"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"取消"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"分享"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"刪除"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"已取消錄影畫面"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"已儲存錄影畫面,輕按即可查看"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"已刪除錄影畫面"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"刪除錄影畫面時發生錯誤"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"無法獲得權限"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"掛接為媒體播放器 (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"掛接為相機 (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"您不會再看到這些通知"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"這些通知將會縮到最小"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"系統會顯示這些通知,但不發出音效"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"這些通知會提醒您"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"您通常會關閉這些通知。\n要繼續顯示通知嗎?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"要繼續顯示這些通知嗎?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"停止通知"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"顯示通知但不發出音效"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"顯示並提醒"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示此應用程式的通知嗎?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"無法關閉這些通知"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"此應用程式目前使用相機。"</string>
<string name="appops_microphone" msgid="741508267659494555">"此應用程式目前使用麥克風。"</string>
<string name="appops_overlay" msgid="6165912637560323464">"此應用程式目前透過其他應用程式在畫面上顯示內容。"</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"充電時顯示百分比 (預設)"</item>
<item msgid="3327323682209964956">"不顯示這個圖示"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"顯示低優先順序通知圖示"</string>
<string name="other" msgid="4060683095962566764">"其他"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"分割畫面分隔線"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"左邊全螢幕"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"已開啟免安裝應用程式。"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"已開啟免安裝應用程式。輕按即可瞭解詳情。"</string>
<string name="app_info" msgid="6856026610594615344">"應用程式資料"</string>
- <string name="go_to_web" msgid="1106022723459948514">"前往網頁版"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"前往瀏覽器"</string>
<string name="mobile_data" msgid="7094582042819250762">"流動數據"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"設定"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"知道了"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"傾印 SysUI 記憶體快照"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"開啟應用程式"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"取消"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"確定"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"設定"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"「<xliff:g id="APP">%1$s</xliff:g>」在過去 <xliff:g id="TIME">%3$d</xliff:g> 分鐘內一直使用<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"<xliff:g id="APPS">%1$s</xliff:g>正在使用<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"相機"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"位置"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"麥克風"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index e399c44..6adc9d9 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"請再次嘗試拍攝螢幕擷取畫面"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"由於儲存空間有限,因此無法儲存螢幕擷取畫面"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"這個應用程式或貴機構不允許擷取螢幕畫面"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"錄製螢幕畫面"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"持續顯示螢幕畫面錄製工作階段通知"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"開始錄製"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"錄製畫面外的音效"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"顯示觸控回應"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"停止"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"暫停"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"繼續"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"取消"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"分享"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"刪除"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"已取消錄製螢幕畫面"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"已儲存螢幕畫面錄製內容,輕觸即可查看"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"已刪除螢幕畫面錄製內容"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"刪除螢幕畫面錄製內容時發生錯誤"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"無法取得權限"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"掛接為媒體播放器 (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"掛接為相機 (PTP)"</string>
@@ -582,15 +598,21 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"通知"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"你不會再看到這些通知"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"系統將最小化這些通知"</string>
+ <!-- no translation found for notification_channel_silenced (2877199534497961942) -->
+ <skip />
+ <!-- no translation found for notification_channel_unsilenced (4790904571552394137) -->
+ <skip />
<string name="inline_blocking_helper" msgid="3055064577771478591">"你通常會關閉這些通知。\n要繼續顯示通知嗎?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"要繼續顯示這些通知嗎?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"停止顯示通知"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"繼續顯示"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"最小化"</string>
+ <!-- no translation found for inline_silent_button_silent (4411510650503783646) -->
+ <skip />
+ <!-- no translation found for inline_silent_button_alert (2967599358027208807) -->
+ <skip />
<string name="inline_keep_showing_app" msgid="1723113469580031041">"要繼續顯示這個應用程式的通知嗎?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"無法關閉這些通知"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"這個應用程式正在使用相機。"</string>
<string name="appops_microphone" msgid="741508267659494555">"這個應用程式正在使用麥克風。"</string>
<string name="appops_overlay" msgid="6165912637560323464">"這個應用程式顯示在畫面上其他應用程式的上層。"</string>
@@ -725,8 +747,7 @@
<item msgid="2139628951880142927">"充電時顯示百分比 (預設)"</item>
<item msgid="3327323682209964956">"不顯示這個圖示"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"顯示低優先順序通知圖示"</string>
<string name="other" msgid="4060683095962566764">"其他"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"分割畫面分隔線"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"以全螢幕顯示左側畫面"</string>
@@ -806,7 +827,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"已開啟免安裝應用程式。"</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"已開啟免安裝應用程式。輕觸即可瞭解詳情。"</string>
<string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string>
- <string name="go_to_web" msgid="1106022723459948514">"前往網頁版"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"前往瀏覽器"</string>
<string name="mobile_data" msgid="7094582042819250762">"行動數據"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> - <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"Wi-Fi 已關閉"</string>
@@ -838,4 +859,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"設定"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"我知道了"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"傾印 SysUI 記憶體快照"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>。"</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"有多個應用程式正在使用<xliff:g id="TYPES_LIST">%s</xliff:g>。"</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"開啟應用程式"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"取消"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"確定"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"設定"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"「<xliff:g id="APP">%1$s</xliff:g>」過去 <xliff:g id="TIME">%3$d</xliff:g> 分鐘一直在使用<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"「<xliff:g id="APPS">%1$s</xliff:g>」正在使用<xliff:g id="TYPE">%2$s</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"「<xliff:g id="APP">%1$s</xliff:g>」正在使用<xliff:g id="TYPES_LIST">%2$s</xliff:g>"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"相機"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"位置"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"麥克風"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 3887f14..b96b075 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -70,6 +70,22 @@
<string name="screenshot_failed_to_save_unknown_text" msgid="3637758096565605541">"Zama ukuthatha isithombe-skrini futhi"</string>
<string name="screenshot_failed_to_save_text" msgid="3041612585107107310">"Ayikwazi ukulondoloza isithombe-skrini ngenxa yesikhala sesitoreji esikhawulelwe"</string>
<string name="screenshot_failed_to_capture_text" msgid="173674476457581486">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho"</string>
+ <string name="screenrecord_name" msgid="4196719243134204796">"Ukurekhoda isikrini"</string>
+ <string name="screenrecord_channel_description" msgid="4630777331970993858">"Isaziso esiqhubekayo seseshini yokurekhoda isikrini"</string>
+ <string name="screenrecord_start_label" msgid="5177739269492196055">"Qala ukurekhoda"</string>
+ <string name="screenrecord_mic_label" msgid="4522870600914810019">"Rekhoda izwi elingaphezulu"</string>
+ <string name="screenrecord_taps_label" msgid="1776467076607964790">"Bonisa amathebhu"</string>
+ <string name="screenrecord_stop_label" msgid="2544887572381260038">"Misa"</string>
+ <string name="screenrecord_pause_label" msgid="7162476078856786227">"Phumula"</string>
+ <string name="screenrecord_resume_label" msgid="3605818317015993314">"Qalisa kabusha"</string>
+ <string name="screenrecord_cancel_label" msgid="3385204992871088609">"Khansela"</string>
+ <string name="screenrecord_share_label" msgid="4197867360204019389">"Yabelana"</string>
+ <string name="screenrecord_delete_label" msgid="7893716870917824013">"Susa"</string>
+ <string name="screenrecord_cancel_success" msgid="7768976011702614782">"Ukurekhoda isikrini kukhanseliwe"</string>
+ <string name="screenrecord_save_message" msgid="4733982661301846778">"Ukurekhoda isikrini kulondoloziwe, thepha ukuze ubuke"</string>
+ <string name="screenrecord_delete_description" msgid="5743190456090354585">"Ukurekhoda isikrini kususiwe"</string>
+ <string name="screenrecord_delete_error" msgid="8154904464563560282">"Iphutha lokususa ukurekhoda isikrini"</string>
+ <string name="screenrecord_permission_error" msgid="1526755299469001000">"Yehlulekile ukuthola izimvume"</string>
<string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Lengisa njengesidlali semediya (MTP)"</string>
<string name="use_ptp_button_title" msgid="7517127540301625751">"Lengisa ikhamera (PTP)"</string>
@@ -582,15 +598,17 @@
<string name="notification_header_default_channel" msgid="7506845022070889909">"Izaziso"</string>
<string name="notification_channel_disabled" msgid="344536703863700565">"Ngeke usabona lezi zaziso"</string>
<string name="notification_channel_minimized" msgid="1664411570378910931">"Lezi zaziso zizokwehlisa"</string>
+ <string name="notification_channel_silenced" msgid="2877199534497961942">"Lezi zaziso zizoboniswa ngokuthulile"</string>
+ <string name="notification_channel_unsilenced" msgid="4790904571552394137">"Lezi zaziso zizokuxwayisa"</string>
<string name="inline_blocking_helper" msgid="3055064577771478591">"Uvamise ukucashisa lezi zaziso. \nQhubeka ulokhu uzibonisa?"</string>
<string name="inline_keep_showing" msgid="8945102997083836858">"Qhubeka nokubonisa lezi zaziso?"</string>
<string name="inline_stop_button" msgid="4172980096860941033">"Misa izaziso"</string>
<string name="inline_keep_button" msgid="6665940297019018232">"Qhubeka nokubonisa"</string>
<string name="inline_minimize_button" msgid="966233327974702195">"Nciphisa"</string>
+ <string name="inline_silent_button_silent" msgid="4411510650503783646">"Bonisa ngokuthulile"</string>
+ <string name="inline_silent_button_alert" msgid="2967599358027208807">"Bonisa futhi xwayisa"</string>
<string name="inline_keep_showing_app" msgid="1723113469580031041">"Qhubeka nokubonisa izaziso kusuka kulolu hlelo lokusebenza?"</string>
<string name="notification_unblockable_desc" msgid="1037434112919403708">"Lezi zaziso azikwazi ukuvalwa"</string>
- <!-- no translation found for notification_delegate_header (9167022191405284627) -->
- <skip />
<string name="appops_camera" msgid="8100147441602585776">"Lolu hlelo lokusebenza lusebenzisa ikhamera."</string>
<string name="appops_microphone" msgid="741508267659494555">"Lolu hlelo lokusebenza lusebenzisa imakrofoni."</string>
<string name="appops_overlay" msgid="6165912637560323464">"Lolu hlelo lokusebenza luboniswa ngaphezulu kwezinye izinhlelo zokusebenza kusikrini sakho."</string>
@@ -725,8 +743,7 @@
<item msgid="2139628951880142927">"Bonisa iphesentheji uma ishaja (okuzenzakalelayo)"</item>
<item msgid="3327323682209964956">"Ungabonisi lesi sithonjana"</item>
</string-array>
- <!-- no translation found for tuner_low_priority (1325884786608312358) -->
- <skip />
+ <string name="tuner_low_priority" msgid="1325884786608312358">"Bonisa izithonjana zesaziso zokubaluleka okuncane"</string>
<string name="other" msgid="4060683095962566764">"Okunye"</string>
<string name="accessibility_divider" msgid="5903423481953635044">"Isihlukanisi sokuhlukanisa isikrini"</string>
<string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Isikrini esigcwele esingakwesokunxele"</string>
@@ -806,7 +823,7 @@
<string name="instant_apps_message" msgid="1183313016396018086">"Uhlelo lokusebenza luvulwe ngaphndle kokufakwa."</string>
<string name="instant_apps_message_with_help" msgid="6179830437630729747">"Uhlelo lokusebenza luvulwe ngaphandle kokufakwa. Thepha ukuze ufunde kabanzi."</string>
<string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
- <string name="go_to_web" msgid="1106022723459948514">"Iya kuwebhu"</string>
+ <string name="go_to_web" msgid="2650669128861626071">"Iya kusiphequluli"</string>
<string name="mobile_data" msgid="7094582042819250762">"Idatha yeselula"</string>
<string name="mobile_data_text_format" msgid="3526214522670876454">"<xliff:g id="ID_1">%1$s</xliff:g> — <xliff:g id="ID_2">%2$s</xliff:g>"</string>
<string name="wifi_is_off" msgid="1838559392210456893">"I-Wi-Fi ivaliwe"</string>
@@ -838,4 +855,16 @@
<string name="open_saver_setting_action" msgid="8314624730997322529">"Izilungiselelo"</string>
<string name="auto_saver_okay_action" msgid="2701221740227683650">"Ngiyezwa"</string>
<string name="heap_dump_tile_name" msgid="9141031328971226374">"I-Dump SysUI Heap"</string>
+ <string name="ongoing_privacy_chip_content_single_app" msgid="4479560741898690064">"I-<xliff:g id="APP">%1$s</xliff:g> isebenzisa i-<xliff:g id="TYPES_LIST">%2$s</xliff:g> yakho."</string>
+ <string name="ongoing_privacy_chip_content_multiple_apps" msgid="8640691753867990511">"Izinhlelo zokusebenza zisebenzisa i-<xliff:g id="TYPES_LIST">%s</xliff:g> yakho."</string>
+ <string name="ongoing_privacy_dialog_open_app" msgid="2483886665314567948">"Vula uhlelo lokusebenza"</string>
+ <string name="ongoing_privacy_dialog_cancel" msgid="5479124524931216790">"Khansela"</string>
+ <string name="ongoing_privacy_dialog_okay" msgid="5823914553907253532">"Kulungile"</string>
+ <string name="ongoing_privacy_dialog_open_settings" msgid="6382622467527049074">"Izilungiselelo"</string>
+ <string name="ongoing_privacy_dialog_app_item" msgid="486085465491760739">"I-<xliff:g id="APP">%1$s</xliff:g> isebenzisa i-<xliff:g id="TYPE">%2$s</xliff:g> yakho ngeminithi lokugcina elingu-<xliff:g id="TIME">%3$d</xliff:g>"</string>
+ <string name="ongoing_privacy_dialog_apps_item" msgid="9207187236823950491">"Ama-<xliff:g id="APPS">%1$s</xliff:g> asebenzisa i-<xliff:g id="TYPE">%2$s</xliff:g> yakho"</string>
+ <string name="ongoing_privacy_dialog_single_app" msgid="3884812469179810924">"I-<xliff:g id="APP">%1$s</xliff:g> isebenzisa i-<xliff:g id="TYPES_LIST">%2$s</xliff:g> yakho"</string>
+ <string name="privacy_type_camera" msgid="1676604631892420333">"ikhamera"</string>
+ <string name="privacy_type_location" msgid="6435497989657286700">"indawo"</string>
+ <string name="privacy_type_microphone" msgid="4153045784928554506">"imakrofoni"</string>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3050e79..0e41a7fd 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -215,6 +215,9 @@
<!-- The width of the view containing navigation buttons -->
<dimen name="navigation_key_width">70dp</dimen>
+ <!-- The width/height of the icon of a navigation button -->
+ <dimen name="navigation_icon_size">32dp</dimen>
+
<dimen name="navigation_key_padding">0dp</dimen>
<!-- The width of the view containing the menu/ime navigation bar icons -->
@@ -478,6 +481,9 @@
<!-- The height of the divider between the individual notifications when the notification wants it to be increased. This is currently the case for notification groups -->
<dimen name="notification_divider_height_increased">6dp</dimen>
+ <!-- The height of the gap between adjacent notification sections. -->
+ <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen>
+
<!-- The minimum amount of top overscroll to go to the quick settings. -->
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
@@ -858,7 +864,6 @@
<dimen name="nav_content_padding">0dp</dimen>
<dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>
<dimen name="nav_quick_scrub_track_thickness">10dp</dimen>
- <dimen name="nav_home_back_gesture_drag_limit">40dp</dimen>
<!-- Navigation bar shadow params. -->
<dimen name="nav_key_button_shadow_offset_x">0dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 6f5d657..50454fc 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1540,6 +1540,12 @@
<!-- Notification inline controls: Shown when a channel's notifications are minimized -->
<string name="notification_channel_minimized">These notifications will be minimized</string>
+ <!-- Notification inline controls: Shown when a channel's notifications are silenced [CHAR_LIMIT=100] -->
+ <string name="notification_channel_silenced">These notifications will be shown silently</string>
+
+ <!-- Notification inline controls: Shown when a channel's notifications are set to alert [CHAR_LIMIT=100] -->
+ <string name="notification_channel_unsilenced">These notifications will alert you</string>
+
<!-- Notification Inline controls: continue receiving notifications prompt, channel level -->
<string name="inline_blocking_helper">You usually dismiss these notifications.
\nKeep showing them?</string>
@@ -1556,6 +1562,12 @@
<!-- Notification inline controls: minimize notifications button -->
<string name="inline_minimize_button">Minimize</string>
+ <!-- Notification inline controls: show notifications silently button [CHAR_LIMIT=25] -->
+ <string name="inline_silent_button_silent">Show silently</string>
+
+ <!-- Notification inline controls: show and alert button [CHAR_LIMIT=25] -->
+ <string name="inline_silent_button_alert">Show and alert</string>
+
<!-- Notification Inline controls: continue receiving notifications prompt, app level -->
<string name="inline_keep_showing_app">Keep showing notifications from this app?</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 8881f8a..b439c6c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -126,6 +126,16 @@
mClockView.setFormat24Hour(format);
}
+ /**
+ * Set the amount (ratio) that the device has transitioned to doze.
+ * @param darkAmount Amount of transition to doze: 1f for doze and 0f for awake.
+ */
+ public void setDarkAmount(float darkAmount) {
+ if (mClockPlugin != null) {
+ mClockPlugin.setDarkAmount(darkAmount);
+ }
+ }
+
public Paint getPaint() {
return mClockView.getPaint();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index cb8c119..f400f60 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -68,12 +68,18 @@
protected void setPasswordEntryEnabled(boolean enabled) {
mPasswordEntry.setEnabled(enabled);
mOkButton.setEnabled(enabled);
+ if (enabled && !mPasswordEntry.hasFocus()) {
+ mPasswordEntry.requestFocus();
+ }
}
@Override
protected void setPasswordEntryInputEnabled(boolean enabled) {
mPasswordEntry.setEnabled(enabled);
mOkButton.setEnabled(enabled);
+ if (enabled && !mPasswordEntry.hasFocus()) {
+ mPasswordEntry.requestFocus();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index f701e22..be795d2 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -385,6 +385,7 @@
return;
}
mDarkAmount = darkAmount;
+ mClockView.setDarkAmount(darkAmount);
updateDark();
}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index b7844bc..fbcf068 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -44,14 +44,15 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.plugins.PluginInitializerImpl;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.shared.plugins.PluginManager;
-import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.power.PowerNotificationWarnings;
import com.android.systemui.power.PowerUI;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.plugins.PluginManagerImpl;
+import com.android.systemui.statusbar.DisplayNavigationBarController;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
@@ -362,6 +363,9 @@
mProviders.put(AppOpsController.class, () ->
new AppOpsControllerImpl(mContext, getDependency(BG_LOOPER)));
+ mProviders.put(DisplayNavigationBarController.class, () ->
+ new DisplayNavigationBarController(mContext, getDependency(MAIN_HANDLER)));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
index d6472b7..d294012 100644
--- a/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
+++ b/packages/SystemUI/src/com/android/systemui/analytics/SensorLoggerSession.java
@@ -16,17 +16,17 @@
package com.android.systemui.analytics;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.SensorEvent;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.TouchEvent;
+
import android.os.Build;
import android.util.Log;
import android.view.MotionEvent;
import java.util.ArrayList;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.SensorEvent;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.TouchEvent;
-
/**
* Collects touch, sensor and phone events and converts the data to
* TouchAnalyticsProto.Session.
@@ -104,6 +104,7 @@
proto.startTimestampMillis = mStartTimestampMillis;
proto.durationMillis = mEndTimestampMillis - mStartTimestampMillis;
proto.build = Build.FINGERPRINT;
+ proto.deviceId = Build.DEVICE;
proto.result = mResult;
proto.type = mType;
proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
diff --git a/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java b/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java
new file mode 100644
index 0000000..158deb4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/chooser/ChooserActivity.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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.chooser;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.util.Log;
+
+import com.android.systemui.R;
+
+import java.lang.Thread;
+import java.util.ArrayList;
+
+/**
+ * Activity for selecting which application ought to handle an ACTION_SEND intent.
+ */
+public final class ChooserActivity extends Activity {
+
+ private static final String TAG = "ChooserActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ChooserHelper.onChoose(this);
+ finish();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java b/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java
new file mode 100644
index 0000000..a7df6f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/chooser/ChooserHelper.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 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.chooser;
+
+import android.app.Activity;
+import android.app.ActivityTaskManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+
+/**
+ * When a target is chosen from the SystemUI Chooser activity, unpack its arguments and
+ * startActivityAsCaller to handle the now-chosen intent.
+ */
+public class ChooserHelper {
+
+ private static final String TAG = "ChooserHelper";
+
+ static void onChoose(Activity activity) {
+ final Intent thisIntent = activity.getIntent();
+ final Bundle thisExtras = thisIntent.getExtras();
+ final Intent chosenIntent = thisIntent.getParcelableExtra(Intent.EXTRA_INTENT);
+ final Bundle options = thisIntent.getParcelableExtra(ActivityTaskManager.EXTRA_OPTIONS);
+ final IBinder permissionToken =
+ thisExtras.getBinder(ActivityTaskManager.EXTRA_PERMISSION_TOKEN);
+ final boolean ignoreTargetSecurity =
+ thisIntent.getBooleanExtra(ActivityTaskManager.EXTRA_IGNORE_TARGET_SECURITY, false);
+ final int userId = thisIntent.getIntExtra(Intent.EXTRA_USER_ID, -1);
+ activity.startActivityAsCaller(
+ chosenIntent, options, permissionToken, ignoreTargetSecurity, userId);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 5d99c57..ce84b84 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -31,6 +31,9 @@
import android.provider.Settings;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
+
+import java.util.concurrent.atomic.AtomicBoolean;
/**
* Controls the screen brightness when dozing.
@@ -63,6 +66,7 @@
* --ei brightness_bucket 1}
*/
private int mDebugBrightnessBucket = -1;
+ private AtomicBoolean mIsDestroyed = new AtomicBoolean();
@VisibleForTesting
public DozeScreenBrightness(Context context, DozeMachine.Service service,
@@ -82,9 +86,13 @@
mSensorToScrimOpacity = sensorToScrimOpacity;
if (mDebuggable) {
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_AOD_BRIGHTNESS);
- mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, null);
+ Dependency.get(Dependency.BG_HANDLER).post(()-> {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_AOD_BRIGHTNESS);
+ if (!mIsDestroyed.get()) {
+ mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, handler);
+ }
+ });
}
}
@@ -121,6 +129,7 @@
}
private void onDestroy() {
+ mIsDestroyed.set(true);
setLightSensorEnabled(false);
if (mDebuggable) {
mContext.unregisterReceiver(this);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 82b79ac..e78951a 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -25,7 +25,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.drawable.Icon;
import android.icu.text.DateFormat;
import android.icu.text.DisplayContext;
import android.net.Uri;
@@ -35,6 +34,13 @@
import android.service.notification.ZenModeConfig;
import android.text.TextUtils;
+import androidx.core.graphics.drawable.IconCompat;
+import androidx.slice.Slice;
+import androidx.slice.SliceProvider;
+import androidx.slice.builders.ListBuilder;
+import androidx.slice.builders.ListBuilder.RowBuilder;
+import androidx.slice.builders.SliceAction;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -46,13 +52,6 @@
import java.util.Locale;
import java.util.concurrent.TimeUnit;
-import androidx.core.graphics.drawable.IconCompat;
-import androidx.slice.Slice;
-import androidx.slice.SliceProvider;
-import androidx.slice.builders.ListBuilder;
-import androidx.slice.builders.ListBuilder.RowBuilder;
-import androidx.slice.builders.SliceAction;
-
/**
* Simple Slice provider that shows the current date.
*/
@@ -226,7 +225,7 @@
private void updateNextAlarm() {
if (withinNHours(mNextAlarmInfo, ALARM_VISIBILITY_HOURS)) {
String pattern = android.text.format.DateFormat.is24HourFormat(getContext(),
- ActivityManager.getCurrentUser()) ? "H:mm" : "h:mm";
+ ActivityManager.getCurrentUser()) ? "HH:mm" : "h:mm";
mNextAlarm = android.text.format.DateFormat.format(pattern,
mNextAlarmInfo.getTriggerTime()).toString();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
index 3953139d..fc1baef 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
@@ -14,21 +14,14 @@
package com.android.systemui.privacy
-import android.app.ActivityManager
-import android.app.AppOpsManager
import android.content.Context
import android.graphics.Color
-import android.os.UserHandle
-import android.os.UserManager
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
-import com.android.systemui.Dependency
import com.android.systemui.R
-import com.android.systemui.appops.AppOpItem
-import com.android.systemui.appops.AppOpsController
class OngoingPrivacyChip @JvmOverloads constructor(
context: Context,
@@ -37,37 +30,15 @@
defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttrs, defStyleRes) {
- companion object {
- val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
- AppOpsManager.OP_RECORD_AUDIO,
- AppOpsManager.OP_COARSE_LOCATION,
- AppOpsManager.OP_FINE_LOCATION)
- }
-
private lateinit var appName: TextView
private lateinit var iconsContainer: LinearLayout
- private var privacyList = emptyList<PrivacyItem>()
- private val appOpsController = Dependency.get(AppOpsController::class.java)
- private val userManager = context.getSystemService(UserManager::class.java)
- private val currentUser = ActivityManager.getCurrentUser()
- private val currentUserIds = userManager.getProfiles(currentUser).map { it.id }
- private var listening = false
-
- var builder = PrivacyDialogBuilder(context, privacyList)
-
- private val callback = object : AppOpsController.Callback {
- override fun onActiveStateChanged(
- code: Int,
- uid: Int,
- packageName: String,
- active: Boolean
- ) {
- val userId = UserHandle.getUserId(uid)
- if (userId in currentUserIds) {
- updatePrivacyList()
- }
+ var builder = PrivacyDialogBuilder(context, emptyList<PrivacyItem>())
+ var privacyList = emptyList<PrivacyItem>()
+ set(value) {
+ field = value
+ builder = PrivacyDialogBuilder(context, value)
+ updateView()
}
- }
override fun onFinishInflate() {
super.onFinishInflate()
@@ -76,36 +47,6 @@
iconsContainer = findViewById(R.id.icons_container)
}
- fun setListening(listen: Boolean) {
- if (listening == listen) return
- listening = listen
- if (listening) {
- appOpsController.addCallback(OPS, callback)
- updatePrivacyList()
- } else {
- appOpsController.removeCallback(OPS, callback)
- }
- }
-
- private fun updatePrivacyList() {
- privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
- .mapNotNull { toPrivacyItem(it) }
- builder = PrivacyDialogBuilder(context, privacyList)
- updateView()
- }
-
- private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
- val type: PrivacyType = when (appOpItem.code) {
- AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
- AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
- AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
- AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
- else -> return null
- }
- val app = PrivacyApplication(appOpItem.packageName, context)
- return PrivacyItem(type, app, appOpItem.timeStarted)
- }
-
// Should only be called if the builder icons or app changed
private fun updateView() {
fun setIcons(dialogBuilder: PrivacyDialogBuilder, iconsContainer: ViewGroup) {
@@ -121,11 +62,9 @@
}
if (privacyList.isEmpty()) {
- visibility = GONE
return
} else {
generateContentDescription()
- visibility = VISIBLE
setIcons(builder, iconsContainer)
appName.visibility = GONE
builder.app?.let {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
new file mode 100644
index 0000000..5141e50
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2018 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.privacy
+
+import android.app.ActivityManager
+import android.app.AppOpsManager
+import android.content.Context
+import android.os.Handler
+import android.os.UserHandle
+import android.os.UserManager
+import com.android.systemui.Dependency
+import com.android.systemui.appops.AppOpItem
+import com.android.systemui.appops.AppOpsController
+
+class PrivacyItemController(val context: Context, val callback: Callback) {
+
+ companion object {
+ val OPS = intArrayOf(AppOpsManager.OP_CAMERA,
+ AppOpsManager.OP_RECORD_AUDIO,
+ AppOpsManager.OP_COARSE_LOCATION,
+ AppOpsManager.OP_FINE_LOCATION)
+ }
+
+ private var privacyList = emptyList<PrivacyItem>()
+ private val appOpsController = Dependency.get(AppOpsController::class.java)
+ private val userManager = context.getSystemService(UserManager::class.java)
+ private val currentUser = ActivityManager.getCurrentUser()
+ private val currentUserIds = userManager.getProfiles(currentUser).map { it.id }
+ private val bgHandler = Handler(Dependency.get(Dependency.BG_LOOPER))
+ private val uiHandler = Dependency.get(Dependency.MAIN_HANDLER)
+ private val notifyChanges = Runnable {
+ callback.privacyChanged(privacyList)
+ }
+ private val updateListAndNotifyChanges = Runnable {
+ updatePrivacyList()
+ uiHandler.post(notifyChanges)
+ }
+
+ private var listening = false
+
+ private val cb = object : AppOpsController.Callback {
+ override fun onActiveStateChanged(
+ code: Int,
+ uid: Int,
+ packageName: String,
+ active: Boolean
+ ) {
+ val userId = UserHandle.getUserId(uid)
+ if (userId in currentUserIds) {
+ update()
+ }
+ }
+ }
+
+ private fun update() {
+ bgHandler.post(updateListAndNotifyChanges)
+ }
+
+ fun setListening(listen: Boolean) {
+ if (listening == listen) return
+ listening = listen
+ if (listening) {
+ appOpsController.addCallback(OPS, cb)
+ update()
+ } else {
+ appOpsController.removeCallback(OPS, cb)
+ }
+ }
+
+ private fun updatePrivacyList() {
+ privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
+ .mapNotNull { toPrivacyItem(it) }
+ }
+
+ private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
+ val type: PrivacyType = when (appOpItem.code) {
+ AppOpsManager.OP_CAMERA -> PrivacyType.TYPE_CAMERA
+ AppOpsManager.OP_COARSE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_FINE_LOCATION -> PrivacyType.TYPE_LOCATION
+ AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE
+ else -> return null
+ }
+ val app = PrivacyApplication(appOpItem.packageName, context)
+ return PrivacyItem(type, app, appOpItem.timeStarted)
+ }
+
+ // Used by containing class to get notified of changes
+ interface Callback {
+ fun privacyChanged(privacyItems: List<PrivacyItem>)
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 3ee6195..7929099 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -39,12 +39,15 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
+import android.view.DisplayCutout;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
+import android.widget.Space;
import android.widget.TextView;
import androidx.annotation.VisibleForTesting;
@@ -57,6 +60,8 @@
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.privacy.OngoingPrivacyChip;
import com.android.systemui.privacy.OngoingPrivacyDialog;
+import com.android.systemui.privacy.PrivacyItem;
+import com.android.systemui.privacy.PrivacyItemController;
import com.android.systemui.qs.QSDetail.Callback;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -70,6 +75,7 @@
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import java.util.List;
import java.util.Locale;
import java.util.Objects;
@@ -125,9 +131,11 @@
private Clock mClockView;
private DateView mDateView;
private OngoingPrivacyChip mPrivacyChip;
+ private Space mSpace;
private NextAlarmController mAlarmController;
private ZenModeController mZenController;
+ private PrivacyItemController mPrivacyItemController;
/** Counts how many times the long press tooltip has been shown to the user. */
private int mShownCount;
@@ -138,16 +146,26 @@
updateStatusText();
}
};
+ private boolean mHasTopCutout = false;
/**
* Runnable for automatically fading out the long press tooltip (as if it were animating away).
*/
private final Runnable mAutoFadeOutTooltipRunnable = () -> hideLongPressTooltip(false);
+ private PrivacyItemController.Callback mPICCallback = new PrivacyItemController.Callback() {
+ @Override
+ public void privacyChanged(List<PrivacyItem> privacyItems) {
+ mPrivacyChip.setPrivacyList(privacyItems);
+ setChipVisibility(!privacyItems.isEmpty());
+ }
+ };
+
public QuickStatusBarHeader(Context context, AttributeSet attrs) {
super(context, attrs);
mAlarmController = Dependency.get(NextAlarmController.class);
mZenController = Dependency.get(ZenModeController.class);
+ mPrivacyItemController = new PrivacyItemController(context, mPICCallback);
mShownCount = getStoredShownCount();
}
@@ -194,6 +212,7 @@
mDateView = findViewById(R.id.date);
mPrivacyChip = findViewById(R.id.privacy_chip);
mPrivacyChip.setOnClickListener(this);
+ mSpace = findViewById(R.id.space);
}
private void updateStatusText() {
@@ -208,6 +227,16 @@
}
}
+ private void setChipVisibility(boolean chipVisible) {
+ mBatteryMeterView.setVisibility(View.VISIBLE);
+ if (chipVisible) {
+ mPrivacyChip.setVisibility(View.VISIBLE);
+ if (mHasTopCutout) mBatteryMeterView.setVisibility(View.GONE);
+ } else {
+ mPrivacyChip.setVisibility(View.GONE);
+ }
+ }
+
private boolean updateRingerStatus() {
boolean isOriginalVisible = mRingerModeTextView.getVisibility() == View.VISIBLE;
CharSequence originalRingerText = mRingerModeTextView.getText();
@@ -411,8 +440,9 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ DisplayCutout cutout = insets.getDisplayCutout();
Pair<Integer, Integer> padding = PhoneStatusBarView.cornerCutoutMargins(
- insets.getDisplayCutout(), getDisplay());
+ cutout, getDisplay());
if (padding == null) {
mSystemIconsView.setPaddingRelative(
getResources().getDimensionPixelSize(R.dimen.status_bar_padding_start), 0,
@@ -421,6 +451,22 @@
mSystemIconsView.setPadding(padding.first, 0, padding.second, 0);
}
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mSpace.getLayoutParams();
+ if (cutout != null) {
+ Rect topCutout = cutout.getBoundingRectTop();
+ if (topCutout.isEmpty()) {
+ mHasTopCutout = false;
+ lp.width = 0;
+ mSpace.setVisibility(View.GONE);
+ } else {
+ mHasTopCutout = true;
+ lp.width = topCutout.width();
+ mSpace.setVisibility(View.VISIBLE);
+ }
+ }
+ mSpace.setLayoutParams(lp);
+ // Decide whether to show BatteryMeterView
+ setChipVisibility(mPrivacyChip.getVisibility() == View.VISIBLE);
return super.onApplyWindowInsets(insets);
}
@@ -437,7 +483,7 @@
return;
}
mHeaderQsPanel.setListening(listening);
- mPrivacyChip.setListening(listening);
+ mPrivacyItemController.setListening(listening);
mListening = listening;
if (listening) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 5eaee54..97534ed 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -18,6 +18,7 @@
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+
import static com.android.systemui.screenshot.GlobalScreenshot.EXTRA_ACTION_INTENT;
import static com.android.systemui.screenshot.GlobalScreenshot.EXTRA_CANCEL_NOTIFICATION;
import static com.android.systemui.screenshot.GlobalScreenshot.EXTRA_DISALLOW_ENTER_PIP;
@@ -35,6 +36,8 @@
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
+import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -66,7 +69,6 @@
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewGroup;
@@ -74,6 +76,7 @@
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.Toast;
+
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
@@ -81,6 +84,7 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.NotificationChannels;
+
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
@@ -290,6 +294,12 @@
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/png");
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
+ // Include URI in ClipData also, so that grantPermission picks it up.
+ // We don't use setData here because some apps interpret this as "to:".
+ ClipData clipdata = new ClipData(new ClipDescription("content",
+ new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}),
+ new ClipData.Item(uri));
+ sharingIntent.setClipData(clipdata);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
@@ -298,7 +308,8 @@
PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Intent sharingChooserIntent = Intent.createChooser(sharingIntent, null,
chooserAction.getIntentSender())
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// Create a share action for the notification
PendingIntent shareAction = PendingIntent.getBroadcastAsUser(context, 0,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java
new file mode 100644
index 0000000..3b611a31
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DisplayNavigationBarController.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2018 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 static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Handler;
+import android.util.SparseArray;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManagerGlobal;
+
+import com.android.systemui.statusbar.phone.NavigationBarFragment;
+
+/**
+ * A controller to handle external navigation bars
+ */
+public class DisplayNavigationBarController implements DisplayListener {
+
+ private final Context mContext;
+ private final Handler mHandler;
+ private final DisplayManager mDisplayManager;
+
+ /** A displayId - nav bar mapping */
+ private SparseArray<NavigationBarFragment> mExternalNavigationBarMap = new SparseArray<>();
+
+ public DisplayNavigationBarController(Context context, Handler handler) {
+ mContext = context;
+ mHandler = handler;
+ mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+
+ registerListener();
+ }
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ final Display display = mDisplayManager.getDisplay(displayId);
+ addExternalNavigationBar(display);
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ final NavigationBarFragment navBar = mExternalNavigationBarMap.get(displayId);
+ if (navBar != null) {
+ final View navigationView = navBar.getView().getRootView();
+ WindowManagerGlobal.getInstance().removeView(navigationView, true);
+ mExternalNavigationBarMap.remove(displayId);
+ }
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ }
+
+ /** Create external navigation bars when car/status bar initializes */
+ public void createNavigationBars() {
+ // Add external navigation bars if more than one displays exist.
+ final Display[] displays = mDisplayManager.getDisplays();
+ for (Display display : displays) {
+ addExternalNavigationBar(display);
+ }
+ }
+
+ /** remove external navigation bars and unset everything related to external navigation bars */
+ public void destroy() {
+ unregisterListener();
+ if (mExternalNavigationBarMap.size() > 0) {
+ for (int i = 0; i < mExternalNavigationBarMap.size(); i++) {
+ final View navigationWindow = mExternalNavigationBarMap.valueAt(i)
+ .getView().getRootView();
+ WindowManagerGlobal.getInstance()
+ .removeView(navigationWindow, true /* immediate */);
+ }
+ mExternalNavigationBarMap.clear();
+ }
+ }
+
+ private void registerListener() {
+ mDisplayManager.registerDisplayListener(this, mHandler);
+ }
+
+ private void unregisterListener() {
+ mDisplayManager.unregisterDisplayListener(this);
+ }
+
+ /**
+ * Add a phone navigation bar on an external display if the display supports system decorations.
+ *
+ * @param display the display to add navigation bar on
+ */
+ private void addExternalNavigationBar(Display display) {
+ if (display == null || display.getDisplayId() == DEFAULT_DISPLAY
+ || !display.supportsSystemDecorations()) {
+ return;
+ }
+
+ final int displayId = display.getDisplayId();
+ final Context externalDisplayContext = mContext.createDisplayContext(display);
+ NavigationBarFragment.create(externalDisplayContext,
+ (tag, fragment) -> {
+ final NavigationBarFragment navBar = (NavigationBarFragment) fragment;
+ // TODO(b/115978725): handle external nav bars sysuiVisibility
+ navBar.setCurrentSysuiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
+ mExternalNavigationBarMap.append(displayId, navBar);
+ }
+ );
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index e3bc5b9..f7cc9cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -15,7 +15,6 @@
*/
package com.android.systemui.statusbar;
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import android.app.ActivityManager;
@@ -295,9 +294,7 @@
}
boolean exceedsPriorityThreshold;
if (NotificationUtils.useNewInterruptionModel(mContext)) {
- exceedsPriorityThreshold =
- getEntryManager().getNotificationData().getImportance(sbn.getKey())
- >= IMPORTANCE_DEFAULT;
+ exceedsPriorityThreshold = getEntryManager().getNotificationData().isHighPriority(sbn);
} else {
exceedsPriorityThreshold =
!getEntryManager().getNotificationData().isAmbient(sbn.getKey());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index c437b14..fc1e94a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -280,7 +280,10 @@
if (metaDataChanged) {
getEntryManager().updateNotifications();
}
- mPresenter.updateMediaMetaData(metaDataChanged, true);
+
+ if (mPresenter != null) {
+ mPresenter.updateMediaMetaData(metaDataChanged, true);
+ }
}
public void clearCurrentMediaNotification() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index bf33614..b3be714 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -95,6 +95,7 @@
private float mFirstElementRoundness;
private Rect mClipRect = new Rect();
private int mCutoutHeight;
+ private int mGapHeight;
private final StateListener mStateListener = this::setStatusBarState;
@@ -154,6 +155,7 @@
mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+ mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
if (!mShowNotificationShelf) {
setVisibility(GONE);
@@ -276,6 +278,7 @@
int baseZHeight = mAmbientState.getBaseZHeight();
int backgroundTop = 0;
float firstElementRoundness = 0.0f;
+ ExpandableNotificationRow previousRow = null;
for (int i = 0; i < mHostLayout.getChildCount(); i++) {
ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
@@ -343,8 +346,27 @@
+ " \n number of notifications: " + mHostLayout.getChildCount() );
}
}
+ if (row.isFirstInSection() && previousRow != null && previousRow.isLastInSection()) {
+ // If the top of the shelf is between the view before a gap and the view after a gap
+ // then we need to adjust the shelf's top roundness.
+ float distanceToGapBottom = row.getTranslationY() - getTranslationY();
+ float distanceToGapTop = getTranslationY()
+ - (previousRow.getTranslationY() + previousRow.getActualHeight());
+ if (distanceToGapTop > 0) {
+ // We interpolate our top roundness so that it's fully rounded if we're at the
+ // bottom of the gap, and not rounded at all if we're at the top of the gap
+ // (directly up against the bottom of previousRow)
+ // Then we apply the same roundness to the bottom of previousRow so that the
+ // corners join together as the shelf approaches previousRow.
+ firstElementRoundness = (float) Math.min(1.0, distanceToGapTop / mGapHeight);
+ previousRow.setBottomRoundness(firstElementRoundness,
+ false /* don't animate */);
+ backgroundTop = (int) distanceToGapBottom;
+ }
+ }
notGoneIndex++;
previousColor = ownColorUntinted;
+ previousRow = row;
}
clipTransientViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index bc3638e..4bff5ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -21,7 +21,6 @@
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
import android.util.Log;
-import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -269,13 +268,7 @@
buildNavBarContent();
attachNavBarWindows();
- // Add external navigation bars if more than one displays exist.
- final Display[] displays = mDisplayManager.getDisplays();
-
- for (Display display : displays) {
- // TODO(115978725): Add phone navigationBar for now
- addExternalNavigationBar(display);
- }
+ mNavigationBarController.createNavigationBars();
}
private void buildNavBarContent() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
index b84b77c..4e712a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -102,6 +102,8 @@
public StatusBarNotification notification;
public NotificationChannel channel;
public boolean audiblyAlerted;
+ public boolean noisy;
+ public int importance;
public StatusBarIconView icon;
public StatusBarIconView expandedIcon;
public ExpandableNotificationRow row; // the outer expanded view
@@ -140,6 +142,16 @@
*/
private boolean hasSentReply;
+ /**
+ * Whether this notification should be displayed as a bubble.
+ */
+ private boolean mIsBubble;
+
+ /**
+ * Whether the user has dismissed this notification when it was in bubble form.
+ */
+ private boolean mUserDismissedBubble;
+
public Entry(StatusBarNotification n) {
this(n, null);
}
@@ -155,6 +167,8 @@
public void populateFromRanking(@NonNull Ranking ranking) {
channel = ranking.getChannel();
audiblyAlerted = ranking.audiblyAlerted();
+ noisy = ranking.isNoisy();
+ importance = ranking.getImportance();
snoozeCriteria = ranking.getSnoozeCriteria();
userSentiment = ranking.getUserSentiment();
smartActions = ranking.getSmartActions() == null
@@ -172,6 +186,22 @@
return interruption;
}
+ public void setIsBubble(boolean bubbleable) {
+ mIsBubble = bubbleable;
+ }
+
+ public boolean isBubble() {
+ return mIsBubble;
+ }
+
+ public void setBubbleDismissed(boolean userDismissed) {
+ mUserDismissedBubble = userDismissed;
+ }
+
+ public boolean isBubbleDismissed() {
+ return mUserDismissedBubble;
+ }
+
/**
* Resets the notification entry to be re-used.
*/
@@ -563,6 +593,20 @@
}
}
+ /**
+ * Returns true if this notification should be displayed in the high-priority notifications
+ * section (and on the lockscreen and status bar).
+ */
+ public boolean isHighPriority(StatusBarNotification statusBarNotification) {
+ if (mRankingMap != null) {
+ getRanking(statusBarNotification.getKey(), mTmpRanking);
+ return mTmpRanking.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT
+ || statusBarNotification.getNotification().isForegroundService()
+ || statusBarNotification.getNotification().hasMediaSession();
+ }
+ return false;
+ }
+
public boolean isAmbient(String key) {
if (mRankingMap != null) {
getRanking(key, mTmpRanking);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
index 28c07a3..43b5503 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationCounters.java
@@ -30,6 +30,9 @@
/** Counter tag for when the user hits 'stop notifications' in the blocking helper. */
public static final String BLOCKING_HELPER_STOP_NOTIFICATIONS =
"blocking_helper_stop_notifications";
+ /** Counter tag for when the user hits 'show silently' in the blocking helper. */
+ public static final String BLOCKING_HELPER_TOGGLE_SILENT =
+ "blocking_helper_toggle_silent";
/** Counter tag for when the user hits 'keep showing' in the blocking helper. */
public static final String BLOCKING_HELPER_KEEP_SHOWING =
"blocking_helper_keep_showing";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 58db03c..3380b38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -40,9 +40,9 @@
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.phone.DoubleTapHelper;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.DoubleTapHelper;
/**
* Base class for both {@link ExpandableNotificationRow} and {@link NotificationShelf}
@@ -134,6 +134,8 @@
private float mAppearAnimationFraction = -1.0f;
private float mAppearAnimationTranslation;
private int mNormalColor;
+ private boolean mLastInSection;
+ private boolean mFirstInSection;
private boolean mIsBelowSpeedBump;
private FalsingManager mFalsingManager;
@@ -533,6 +535,32 @@
mBackgroundDimmed.setDistanceToTopRoundness(distanceToTopRoundness);
}
+ public boolean isLastInSection() {
+ return mLastInSection;
+ }
+
+ public boolean isFirstInSection() {
+ return mFirstInSection;
+ }
+
+ /** Sets whether this view is the last notification in a section. */
+ public void setLastInSection(boolean lastInSection) {
+ if (lastInSection != mLastInSection) {
+ mLastInSection = lastInSection;
+ mBackgroundNormal.setLastInSection(lastInSection);
+ mBackgroundDimmed.setLastInSection(lastInSection);
+ }
+ }
+
+ /** Sets whether this view is the first notification in a section. */
+ public void setFirstInSection(boolean firstInSection) {
+ if (firstInSection != mFirstInSection) {
+ mFirstInSection = firstInSection;
+ mBackgroundNormal.setFirstInSection(firstInSection);
+ mBackgroundDimmed.setFirstInSection(firstInSection);
+ }
+ }
+
/**
* Set an override tint color that is used for the background.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 1ed726d..62d596b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -46,6 +46,8 @@
private int mTintColor;
private float[] mCornerRadii = new float[8];
private boolean mBottomIsRounded;
+ private boolean mLastInSection;
+ private boolean mFirstInSection;
private int mBackgroundTop;
private boolean mBottomAmountClips = true;
private boolean mExpandAnimationRunning;
@@ -79,7 +81,10 @@
if (drawable != null) {
int top = mBackgroundTop;
int bottom = mActualHeight;
- if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning) {
+ if (mBottomIsRounded
+ && mBottomAmountClips
+ && !mExpandAnimationRunning
+ && !mLastInSection) {
bottom -= mClipBottomAmount;
}
int left = 0;
@@ -90,8 +95,10 @@
}
if (mTopAmountRounded) {
int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
- top += clipTop;
- if (clipTop >= 0) {
+ if (clipTop >= 0 || !mFirstInSection) {
+ top += clipTop;
+ }
+ if (clipTop >= 0 && !mLastInSection) {
bottom += clipTop;
}
}
@@ -216,19 +223,23 @@
mBackground.setAlpha(drawableAlpha);
}
- public void setRoundness(float topRoundness, float bottomRoundNess) {
- if (topRoundness == mCornerRadii[0] && bottomRoundNess == mCornerRadii[4]) {
+ /**
+ * Sets the current top and bottom roundness amounts for this background, between 0.0 (not
+ * rounded) and 1.0 (maximally rounded).
+ */
+ public void setRoundness(float topRoundness, float bottomRoundness) {
+ if (topRoundness == mCornerRadii[0] && bottomRoundness == mCornerRadii[4]) {
return;
}
- mBottomIsRounded = bottomRoundNess != 0.0f;
+ mBottomIsRounded = bottomRoundness != 0.0f;
mCornerRadii[0] = topRoundness;
mCornerRadii[1] = topRoundness;
mCornerRadii[2] = topRoundness;
mCornerRadii[3] = topRoundness;
- mCornerRadii[4] = bottomRoundNess;
- mCornerRadii[5] = bottomRoundNess;
- mCornerRadii[6] = bottomRoundNess;
- mCornerRadii[7] = bottomRoundNess;
+ mCornerRadii[4] = bottomRoundness;
+ mCornerRadii[5] = bottomRoundness;
+ mCornerRadii[6] = bottomRoundness;
+ mCornerRadii[7] = bottomRoundness;
updateBackgroundRadii();
}
@@ -239,6 +250,18 @@
}
}
+ /** Sets whether this background belongs to the last notification in a section. */
+ public void setLastInSection(boolean lastInSection) {
+ mLastInSection = lastInSection;
+ invalidate();
+ }
+
+ /** Sets whether this background belongs to the first notification in a section. */
+ public void setFirstInSection(boolean firstInSection) {
+ mFirstInSection = firstInSection;
+ invalidate();
+ }
+
private void updateBackgroundRadii() {
if (mDontModifyCorners) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
index 0a197da..fbe9c5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGuts.java
@@ -23,7 +23,6 @@
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import androidx.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -31,6 +30,8 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
+import androidx.annotation.Nullable;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
@@ -98,6 +99,11 @@
* Return whether something changed and needs to be saved, possibly requiring a bouncer.
*/
boolean shouldBeSaved();
+
+ /**
+ * Called when the guts view has finished its close animation.
+ */
+ default void onFinishedClosing() {}
}
public interface OnGutsClosedListener {
@@ -304,7 +310,7 @@
x, y, r, 0);
a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
- a.addListener(new AnimateCloseListener(this /* view */));
+ a.addListener(new AnimateCloseListener(this /* view */, mGutsContent));
a.start();
} else {
// Fade in the blocking helper.
@@ -312,11 +318,12 @@
.alpha(0f)
.setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
.setInterpolator(Interpolators.ALPHA_OUT)
- .setListener(new AnimateCloseListener(this /* view */))
+ .setListener(new AnimateCloseListener(this, /* view */mGutsContent))
.start();
}
} else {
Log.w(TAG, "Failed to animate guts close");
+ mGutsContent.onFinishedClosing();
}
}
@@ -414,15 +421,18 @@
/** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */
private static class AnimateCloseListener extends AnimatorListenerAdapter {
final View mView;
+ private final GutsContent mGutsContent;
- private AnimateCloseListener(View view) {
+ private AnimateCloseListener(View view, GutsContent gutsContent) {
mView = view;
+ mGutsContent = gutsContent;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mView.setVisibility(View.GONE);
+ mGutsContent.onFinishedClosing();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 2499952..b838c9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -28,7 +28,6 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.Uri;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.provider.Settings;
@@ -46,15 +45,13 @@
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -298,7 +295,9 @@
mDeviceProvisionedController.isDeviceProvisioned(),
row.getIsNonblockable(),
isForBlockingHelper,
- row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE);
+ row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE,
+ row.getEntry().noisy,
+ row.getEntry().importance);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 903c272..522da4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -16,13 +16,18 @@
package com.android.systemui.statusbar.notification.row;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
+import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
@@ -54,6 +59,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import java.util.List;
@@ -65,6 +71,17 @@
public class NotificationInfo extends LinearLayout implements NotificationGuts.GutsContent {
private static final String TAG = "InfoGuts";
+ @IntDef(prefix = { "SWAP_CONTENT_" }, value = {
+ SWAP_CONTENT_UNDO,
+ SWAP_CONTENT_TOGGLE_SILENT,
+ SWAP_CONTENT_BLOCK,
+ })
+ @interface SwapContentAction {}
+
+ private static final int SWAP_CONTENT_UNDO = 0;
+ private static final int SWAP_CONTENT_TOGGLE_SILENT = 1;
+ private static final int SWAP_CONTENT_BLOCK = 2;
+
private INotificationManager mINotificationManager;
private PackageManager mPm;
private MetricsLogger mMetricsLogger;
@@ -74,7 +91,8 @@
private int mAppUid;
private int mNumUniqueChannelsInRow;
private NotificationChannel mSingleNotificationChannel;
- private int mStartingUserImportance;
+ private int mStartingChannelImportance;
+ private int mStartingChannelOrNotificationImportance;
private int mChosenImportance;
private boolean mIsSingleDefaultChannel;
private boolean mIsNonblockable;
@@ -82,6 +100,7 @@
private AnimatorSet mExpandAnimation;
private boolean mIsForeground;
private boolean mIsDeviceProvisioned;
+ private boolean mIsNoisy;
private CheckSaveListener mCheckSaveListener;
private OnSettingsClickListener mOnSettingsClickListener;
@@ -102,10 +121,22 @@
closeControls(v);
};
+ private OnClickListener mOnToggleSilent = v -> {
+ Runnable saveImportance = () -> {
+ mExitReason = NotificationCounters.BLOCKING_HELPER_TOGGLE_SILENT;
+ swapContent(SWAP_CONTENT_TOGGLE_SILENT);
+ };
+ if (mCheckSaveListener != null) {
+ mCheckSaveListener.checkSave(saveImportance, mSbn);
+ } else {
+ saveImportance.run();
+ }
+ };
+
private OnClickListener mOnStopOrMinimizeNotifications = v -> {
Runnable saveImportance = () -> {
mExitReason = NotificationCounters.BLOCKING_HELPER_STOP_NOTIFICATIONS;
- swapContent(false);
+ swapContent(SWAP_CONTENT_BLOCK);
};
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(saveImportance, mSbn);
@@ -118,7 +149,7 @@
// Reset exit counter that we'll log and record an undo event separately (not an exit event)
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
- swapContent(true);
+ swapContent(SWAP_CONTENT_UNDO);
};
public NotificationInfo(Context context, AttributeSet attrs) {
@@ -152,12 +183,15 @@
final OnSettingsClickListener onSettingsClick,
final OnAppSettingsClickListener onAppSettingsClick,
boolean isDeviceProvisioned,
- boolean isNonblockable)
+ boolean isNonblockable,
+ boolean isNoisy,
+ int importance)
throws RemoteException {
bindNotification(pm, iNotificationManager, pkg, notificationChannel,
numUniqueChannelsInRow, sbn, checkSaveListener, onSettingsClick,
onAppSettingsClick, isDeviceProvisioned, isNonblockable,
- false /* isBlockingHelper */, false /* isUserSentimentNegative */);
+ false /* isBlockingHelper */, false /* isUserSentimentNegative */, isNoisy,
+ importance);
}
public void bindNotification(
@@ -173,7 +207,9 @@
boolean isDeviceProvisioned,
boolean isNonblockable,
boolean isForBlockingHelper,
- boolean isUserSentimentNegative)
+ boolean isUserSentimentNegative,
+ boolean isNoisy,
+ int importance)
throws RemoteException {
mINotificationManager = iNotificationManager;
mMetricsLogger = Dependency.get(MetricsLogger.class);
@@ -186,7 +222,10 @@
mCheckSaveListener = checkSaveListener;
mOnSettingsClickListener = onSettingsClick;
mSingleNotificationChannel = notificationChannel;
- mStartingUserImportance = mChosenImportance = mSingleNotificationChannel.getImportance();
+ int channelImportance = mSingleNotificationChannel.getImportance();
+ mStartingChannelImportance = mChosenImportance = channelImportance;
+ mStartingChannelOrNotificationImportance =
+ channelImportance == IMPORTANCE_UNSPECIFIED ? importance : channelImportance;
mNegativeUserSentiment = isUserSentimentNegative;
mIsNonblockable = isNonblockable;
mIsForeground =
@@ -194,6 +233,7 @@
mIsForBlockingHelper = isForBlockingHelper;
mAppUid = mSbn.getUid();
mIsDeviceProvisioned = isDeviceProvisioned;
+ mIsNoisy = isNoisy;
int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */);
@@ -306,7 +346,8 @@
}
private boolean hasImportanceChanged() {
- return mSingleNotificationChannel != null && mStartingUserImportance != mChosenImportance;
+ return mSingleNotificationChannel != null
+ && mStartingChannelImportance != mChosenImportance;
}
private void saveImportance() {
@@ -320,34 +361,46 @@
*/
private void updateImportance() {
MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE,
- mChosenImportance - mStartingUserImportance);
+ mChosenImportance - mStartingChannelImportance);
Handler bgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
bgHandler.post(new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
mNumUniqueChannelsInRow == 1 ? mSingleNotificationChannel : null,
- mStartingUserImportance, mChosenImportance));
+ mStartingChannelImportance, mChosenImportance));
}
private void bindButtons() {
// Set up stay-in-notification actions
View block = findViewById(R.id.block);
TextView keep = findViewById(R.id.keep);
+ TextView silent = findViewById(R.id.toggle_silent);
View minimize = findViewById(R.id.minimize);
findViewById(R.id.undo).setOnClickListener(mOnUndo);
block.setOnClickListener(mOnStopOrMinimizeNotifications);
keep.setOnClickListener(mOnKeepShowing);
+ silent.setOnClickListener(mOnToggleSilent);
minimize.setOnClickListener(mOnStopOrMinimizeNotifications);
if (mIsNonblockable) {
keep.setText(android.R.string.ok);
block.setVisibility(GONE);
+ silent.setVisibility(GONE);
minimize.setVisibility(GONE);
} else if (mIsForeground) {
block.setVisibility(GONE);
+ silent.setVisibility(GONE);
minimize.setVisibility(VISIBLE);
- } else if (!mIsForeground) {
+ } else {
block.setVisibility(VISIBLE);
+ boolean showToggleSilent = mIsNoisy
+ && NotificationUtils.useNewInterruptionModel(mContext);
+ silent.setVisibility(showToggleSilent ? VISIBLE : GONE);
+ boolean isCurrentlyAlerting =
+ mStartingChannelOrNotificationImportance >= IMPORTANCE_DEFAULT;
+ silent.setText(isCurrentlyAlerting
+ ? R.string.inline_silent_button_silent
+ : R.string.inline_silent_button_alert);
minimize.setVisibility(GONE);
}
@@ -368,7 +421,7 @@
}
}
- private void swapContent(boolean showPrompt) {
+ private void swapContent(@SwapContentAction int action) {
if (mExpandAnimation != null) {
mExpandAnimation.cancel();
}
@@ -378,26 +431,43 @@
TextView confirmationText = findViewById(R.id.confirmation_text);
View header = findViewById(R.id.header);
- if (showPrompt) {
- mChosenImportance = mStartingUserImportance;
- } else if (mIsForeground) {
- mChosenImportance = IMPORTANCE_MIN;
- confirmationText.setText(R.string.notification_channel_minimized);
- } else {
- mChosenImportance = IMPORTANCE_NONE;
- confirmationText.setText(R.string.notification_channel_disabled);
+ switch (action) {
+ case SWAP_CONTENT_UNDO:
+ mChosenImportance = mStartingChannelImportance;
+ break;
+ case SWAP_CONTENT_TOGGLE_SILENT:
+ if (mStartingChannelOrNotificationImportance >= IMPORTANCE_DEFAULT) {
+ mChosenImportance = IMPORTANCE_LOW;
+ confirmationText.setText(R.string.notification_channel_silenced);
+ } else {
+ mChosenImportance = IMPORTANCE_HIGH;
+ confirmationText.setText(R.string.notification_channel_unsilenced);
+ }
+ break;
+ case SWAP_CONTENT_BLOCK:
+ if (mIsForeground) {
+ mChosenImportance = IMPORTANCE_MIN;
+ confirmationText.setText(R.string.notification_channel_minimized);
+ } else {
+ mChosenImportance = IMPORTANCE_NONE;
+ confirmationText.setText(R.string.notification_channel_disabled);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException();
}
+ boolean isUndo = action == SWAP_CONTENT_UNDO;
ObjectAnimator promptAnim = ObjectAnimator.ofFloat(prompt, View.ALPHA,
- prompt.getAlpha(), showPrompt ? 1f : 0f);
- promptAnim.setInterpolator(showPrompt ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
+ prompt.getAlpha(), isUndo ? 1f : 0f);
+ promptAnim.setInterpolator(isUndo ? Interpolators.ALPHA_IN : Interpolators.ALPHA_OUT);
ObjectAnimator confirmAnim = ObjectAnimator.ofFloat(confirmation, View.ALPHA,
- confirmation.getAlpha(), showPrompt ? 0f : 1f);
- confirmAnim.setInterpolator(showPrompt ? Interpolators.ALPHA_OUT : Interpolators.ALPHA_IN);
+ confirmation.getAlpha(), isUndo ? 0f : 1f);
+ confirmAnim.setInterpolator(isUndo ? Interpolators.ALPHA_OUT : Interpolators.ALPHA_IN);
- prompt.setVisibility(showPrompt ? VISIBLE : GONE);
- confirmation.setVisibility(showPrompt ? GONE : VISIBLE);
- header.setVisibility(showPrompt ? VISIBLE : GONE);
+ prompt.setVisibility(isUndo ? VISIBLE : GONE);
+ confirmation.setVisibility(isUndo ? GONE : VISIBLE);
+ header.setVisibility(isUndo ? VISIBLE : GONE);
mExpandAnimation = new AnimatorSet();
mExpandAnimation.playTogether(promptAnim, confirmAnim);
@@ -413,8 +483,8 @@
@Override
public void onAnimationEnd(Animator animation) {
if (!cancelled) {
- prompt.setVisibility(showPrompt ? VISIBLE : GONE);
- confirmation.setVisibility(showPrompt ? GONE : VISIBLE);
+ prompt.setVisibility(isUndo ? VISIBLE : GONE);
+ confirmation.setVisibility(isUndo ? GONE : VISIBLE);
}
}
});
@@ -428,6 +498,25 @@
}
@Override
+ public void onFinishedClosing() {
+ mStartingChannelImportance = mChosenImportance;
+ if (mChosenImportance != IMPORTANCE_UNSPECIFIED) {
+ mStartingChannelOrNotificationImportance = mChosenImportance;
+ }
+ mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
+
+ View prompt = findViewById(R.id.prompt);
+ ViewGroup confirmation = findViewById(R.id.confirmation);
+ View header = findViewById(R.id.header);
+ prompt.setVisibility(VISIBLE);
+ prompt.setAlpha(1f);
+ confirmation.setVisibility(GONE);
+ confirmation.setAlpha(1f);
+ header.setVisibility(VISIBLE);
+ header.setAlpha(1f);
+ }
+
+ @Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
if (mGutsContainer != null &&
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 0577841..ff1a6fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -22,27 +22,32 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.NotificationShelf;
import java.util.ArrayList;
+import java.util.List;
/**
* A global state to track all input states for the algorithm.
*/
public class AmbientState {
- private ArrayList<View> mDraggedViews = new ArrayList<View>();
+
+ private static final int NO_SECTION_BOUNDARY = -1;
+
+ private ArrayList<View> mDraggedViews = new ArrayList<>();
private int mScrollY;
private boolean mDimmed;
private ActivatableNotificationView mActivatedChild;
private float mOverScrollTopAmount;
private float mOverScrollBottomAmount;
private int mSpeedBumpIndex = -1;
+ private final List<Integer> mSectionBoundaryIndices = new ArrayList<>();
private boolean mDark;
private boolean mHideSensitive;
private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
@@ -75,6 +80,7 @@
private boolean mAppearing;
public AmbientState(Context context) {
+ mSectionBoundaryIndices.add(NO_SECTION_BOUNDARY);
reload(context);
}
@@ -208,6 +214,27 @@
mSpeedBumpIndex = shelfIndex;
}
+ /**
+ * Returns the index of the boundary between two sections, where the first section is at index
+ * {@code boundaryNum}.
+ */
+ public int getSectionBoundaryIndex(int boundaryNum) {
+ return mSectionBoundaryIndices.get(boundaryNum);
+ }
+
+ /** Returns true if the item at {@code index} is directly below a section boundary. */
+ public boolean beginsNewSection(int index) {
+ return mSectionBoundaryIndices.contains(index);
+ }
+
+ /**
+ * Sets the index of the boundary between the section at {@code boundaryNum} and the following
+ * section to {@code boundaryIndex}.
+ */
+ public void setSectionBoundaryIndex(int boundaryNum, int boundaryIndex) {
+ mSectionBoundaryIndices.set(boundaryNum, boundaryIndex);
+ }
+
public float getStackTranslation() {
return mStackTranslation;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index e32df42..c867a41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.notification.stack;
+import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+ .NUM_SECTIONS;
+
import android.view.View;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -30,46 +33,92 @@
class NotificationRoundnessManager implements OnHeadsUpChangedListener {
private boolean mExpanded;
- private ActivatableNotificationView mFirst;
- private ActivatableNotificationView mLast;
+ private ActivatableNotificationView[] mFirstInSectionViews;
+ private ActivatableNotificationView[] mLastInSectionViews;
+ private ActivatableNotificationView[] mTmpFirstInSectionViews;
+ private ActivatableNotificationView[] mTmpLastInSectionViews;
private HashSet<View> mAnimatedChildren;
private Runnable mRoundingChangedCallback;
private ExpandableNotificationRow mTrackedHeadsUp;
private float mAppearFraction;
+ NotificationRoundnessManager() {
+ mFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
+ mLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
+ mTmpFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
+ mTmpLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
+ }
+
@Override
public void onHeadsUpPinned(ExpandableNotificationRow headsUp) {
- updateRounding(headsUp, false /* animate */);
+ updateView(headsUp, false /* animate */);
}
@Override
public void onHeadsUpUnPinned(ExpandableNotificationRow headsUp) {
- updateRounding(headsUp, true /* animate */);
+ updateView(headsUp, true /* animate */);
}
public void onHeadsupAnimatingAwayChanged(ExpandableNotificationRow row,
boolean isAnimatingAway) {
- updateRounding(row, false /* animate */);
+ updateView(row, false /* animate */);
}
- private void updateRounding(ActivatableNotificationView view, boolean animate) {
- float topRoundness = getRoundness(view, true /* top */);
- float bottomRoundness = getRoundness(view, false /* top */);
- boolean firstChanged = view.setTopRoundness(topRoundness, animate);
- boolean secondChanged = view.setBottomRoundness(bottomRoundness, animate);
- if ((view == mFirst || view == mLast) && (firstChanged || secondChanged)) {
+ private void updateView(ActivatableNotificationView view, boolean animate) {
+ boolean changed = updateViewWithoutCallback(view, animate);
+ if (changed) {
mRoundingChangedCallback.run();
}
}
+ private boolean updateViewWithoutCallback(ActivatableNotificationView view,
+ boolean animate) {
+ float topRoundness = getRoundness(view, true /* top */);
+ float bottomRoundness = getRoundness(view, false /* top */);
+ boolean topChanged = view.setTopRoundness(topRoundness, animate);
+ boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);
+ boolean firstInSection = isFirstInSection(view, false /* exclude first section */);
+ boolean lastInSection = isLastInSection(view, false /* exclude last section */);
+ view.setFirstInSection(firstInSection);
+ view.setLastInSection(lastInSection);
+ return (firstInSection || lastInSection) && (topChanged || bottomChanged);
+ }
+
+ private boolean isFirstInSection(ActivatableNotificationView view,
+ boolean includeFirstSection) {
+ int numNonEmptySections = 0;
+ for (int i = 0; i < mFirstInSectionViews.length; i++) {
+ if (view == mFirstInSectionViews[i]) {
+ return includeFirstSection || numNonEmptySections > 0;
+ }
+ if (mFirstInSectionViews[i] != null) {
+ numNonEmptySections++;
+ }
+ }
+ return false;
+ }
+
+ private boolean isLastInSection(ActivatableNotificationView view, boolean includeLastSection) {
+ int numNonEmptySections = 0;
+ for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
+ if (view == mLastInSectionViews[i]) {
+ return includeLastSection || numNonEmptySections > 0;
+ }
+ if (mLastInSectionViews[i] != null) {
+ numNonEmptySections++;
+ }
+ }
+ return false;
+ }
+
private float getRoundness(ActivatableNotificationView view, boolean top) {
if ((view.isPinned() || view.isHeadsUpAnimatingAway()) && !mExpanded) {
return 1.0f;
}
- if (view == mFirst && top) {
+ if (isFirstInSection(view, true /* include first section */) && top) {
return 1.0f;
}
- if (view == mLast && !top) {
+ if (isLastInSection(view, true /* include last section */) && !top) {
return 1.0f;
}
if (view == mTrackedHeadsUp && mAppearFraction <= 0.0f) {
@@ -84,34 +133,82 @@
mExpanded = expandedHeight != 0.0f;
mAppearFraction = appearFraction;
if (mTrackedHeadsUp != null) {
- updateRounding(mTrackedHeadsUp, true);
+ updateView(mTrackedHeadsUp, true);
}
}
- public void setFirstAndLastBackgroundChild(ActivatableNotificationView first,
- ActivatableNotificationView last) {
- boolean firstChanged = mFirst != first;
- boolean lastChanged = mLast != last;
- if (!firstChanged && !lastChanged) {
- return;
+ public void updateRoundedChildren(NotificationSection[] sections) {
+ boolean anyChanged = false;
+ for (int i = 0; i < NUM_SECTIONS; i++) {
+ mTmpFirstInSectionViews[i] = mFirstInSectionViews[i];
+ mTmpLastInSectionViews[i] = mLastInSectionViews[i];
+ mFirstInSectionViews[i] = sections[i].getFirstVisibleChild();
+ mLastInSectionViews[i] = sections[i].getLastVisibleChild();
}
- ActivatableNotificationView oldFirst = mFirst;
- ActivatableNotificationView oldLast = mLast;
- mFirst = first;
- mLast = last;
- if (firstChanged && oldFirst != null && !oldFirst.isRemoved()) {
- updateRounding(oldFirst, oldFirst.isShown());
+ anyChanged |= handleRemovedOldViews(sections, mTmpFirstInSectionViews, true);
+ anyChanged |= handleRemovedOldViews(sections, mTmpLastInSectionViews, false);
+ anyChanged |= handleAddedNewViews(sections, mTmpFirstInSectionViews, true);
+ anyChanged |= handleAddedNewViews(sections, mTmpLastInSectionViews, false);
+ if (anyChanged) {
+ mRoundingChangedCallback.run();
}
- if (lastChanged && oldLast != null && !oldLast.isRemoved()) {
- updateRounding(oldLast, oldLast.isShown());
+ }
+
+ private boolean handleRemovedOldViews(NotificationSection[] sections,
+ ActivatableNotificationView[] oldViews, boolean first) {
+ boolean anyChanged = false;
+ for (ActivatableNotificationView oldView : oldViews) {
+ if (oldView != null) {
+ boolean isStillPresent = false;
+ boolean adjacentSectionChanged = false;
+ for (NotificationSection section : sections) {
+ ActivatableNotificationView newView =
+ (first ? section.getFirstVisibleChild()
+ : section.getLastVisibleChild());
+ if (newView == oldView) {
+ isStillPresent = true;
+ if (oldView.isFirstInSection() != isFirstInSection(oldView,
+ false /* exclude first section */)
+ || oldView.isLastInSection() != isLastInSection(oldView,
+ false /* exclude last section */)) {
+ adjacentSectionChanged = true;
+ }
+ break;
+ }
+ }
+ if (!isStillPresent || adjacentSectionChanged) {
+ anyChanged = true;
+ if (!oldView.isRemoved()) {
+ updateViewWithoutCallback(oldView, oldView.isShown());
+ }
+ }
+ }
}
- if (mFirst != null) {
- updateRounding(mFirst, mFirst.isShown() && !mAnimatedChildren.contains(mFirst));
+ return anyChanged;
+ }
+
+ private boolean handleAddedNewViews(NotificationSection[] sections,
+ ActivatableNotificationView[] oldViews, boolean first) {
+ boolean anyChanged = false;
+ for (NotificationSection section : sections) {
+ ActivatableNotificationView newView =
+ (first ? section.getFirstVisibleChild() : section.getLastVisibleChild());
+ if (newView != null) {
+ boolean wasAlreadyPresent = false;
+ for (ActivatableNotificationView oldView : oldViews) {
+ if (oldView == newView) {
+ wasAlreadyPresent = true;
+ break;
+ }
+ }
+ if (!wasAlreadyPresent) {
+ anyChanged = true;
+ updateViewWithoutCallback(newView,
+ newView.isShown() && !mAnimatedChildren.contains(newView));
+ }
+ }
}
- if (mLast != null) {
- updateRounding(mLast, mLast.isShown() && !mAnimatedChildren.contains(mLast));
- }
- mRoundingChangedCallback.run();
+ return anyChanged;
}
public void setAnimatedChildren(HashSet<View> animatedChildren) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
new file mode 100644
index 0000000..40cfd4d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2018 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.notification.stack;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.graphics.Rect;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.notification.ShadeViewRefactor;
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+
+/**
+ * Represents the bounds of a section of the notification shade and handles animation when the
+ * bounds change.
+ */
+class NotificationSection {
+ private View mOwningView;
+ private Rect mBounds = new Rect();
+ private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
+ private Rect mStartAnimationRect = new Rect();
+ private Rect mEndAnimationRect = new Rect();
+ private ObjectAnimator mTopAnimator = null;
+ private ObjectAnimator mBottomAnimator = null;
+ private ActivatableNotificationView mFirstVisibleChild;
+ private ActivatableNotificationView mLastVisibleChild;
+
+ NotificationSection(View owningView) {
+ mOwningView = owningView;
+ }
+
+ public void cancelAnimators() {
+ if (mBottomAnimator != null) {
+ mBottomAnimator.cancel();
+ }
+ if (mTopAnimator != null) {
+ mTopAnimator.cancel();
+ }
+ }
+
+ public Rect getCurrentBounds() {
+ return mCurrentBounds;
+ }
+
+ public Rect getBounds() {
+ return mBounds;
+ }
+
+ public boolean didBoundsChange() {
+ return !mCurrentBounds.equals(mBounds);
+ }
+
+ public boolean areBoundsAnimating() {
+ return mBottomAnimator != null || mTopAnimator != null;
+ }
+
+ public void startBackgroundAnimation(boolean animateTop, boolean animateBottom) {
+ // Left and right bounds are always applied immediately.
+ mCurrentBounds.left = mBounds.left;
+ mCurrentBounds.right = mBounds.right;
+ startBottomAnimation(animateBottom);
+ startTopAnimation(animateTop);
+ }
+
+
+ @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
+ private void startTopAnimation(boolean animate) {
+ int previousEndValue = mEndAnimationRect.top;
+ int newEndValue = mBounds.top;
+ ObjectAnimator previousAnimator = mTopAnimator;
+ if (previousAnimator != null && previousEndValue == newEndValue) {
+ return;
+ }
+ if (!animate) {
+ // just a local update was performed
+ if (previousAnimator != null) {
+ // we need to increase all animation keyframes of the previous animator by the
+ // relative change to the end value
+ int previousStartValue = mStartAnimationRect.top;
+ PropertyValuesHolder[] values = previousAnimator.getValues();
+ values[0].setIntValues(previousStartValue, newEndValue);
+ mStartAnimationRect.top = previousStartValue;
+ mEndAnimationRect.top = newEndValue;
+ previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+ return;
+ } else {
+ // no new animation needed, let's just apply the value
+ setBackgroundTop(newEndValue);
+ return;
+ }
+ }
+ if (previousAnimator != null) {
+ previousAnimator.cancel();
+ }
+ ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
+ mCurrentBounds.top, newEndValue);
+ Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+ animator.setInterpolator(interpolator);
+ animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ // remove the tag when the animation is finished
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStartAnimationRect.top = -1;
+ mEndAnimationRect.top = -1;
+ mTopAnimator = null;
+ }
+ });
+ animator.start();
+ mStartAnimationRect.top = mCurrentBounds.top;
+ mEndAnimationRect.top = newEndValue;
+ mTopAnimator = animator;
+ }
+
+ @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.STATE_RESOLVER)
+ private void startBottomAnimation(boolean animate) {
+ int previousStartValue = mStartAnimationRect.bottom;
+ int previousEndValue = mEndAnimationRect.bottom;
+ int newEndValue = mBounds.bottom;
+ ObjectAnimator previousAnimator = mBottomAnimator;
+ if (previousAnimator != null && previousEndValue == newEndValue) {
+ return;
+ }
+ if (!animate) {
+ // just a local update was performed
+ if (previousAnimator != null) {
+ // we need to increase all animation keyframes of the previous animator by the
+ // relative change to the end value
+ PropertyValuesHolder[] values = previousAnimator.getValues();
+ values[0].setIntValues(previousStartValue, newEndValue);
+ mStartAnimationRect.bottom = previousStartValue;
+ mEndAnimationRect.bottom = newEndValue;
+ previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+ return;
+ } else {
+ // no new animation needed, let's just apply the value
+ setBackgroundBottom(newEndValue);
+ return;
+ }
+ }
+ if (previousAnimator != null) {
+ previousAnimator.cancel();
+ }
+ ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
+ mCurrentBounds.bottom, newEndValue);
+ Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
+ animator.setInterpolator(interpolator);
+ animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ // remove the tag when the animation is finished
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mStartAnimationRect.bottom = -1;
+ mEndAnimationRect.bottom = -1;
+ mBottomAnimator = null;
+ }
+ });
+ animator.start();
+ mStartAnimationRect.bottom = mCurrentBounds.bottom;
+ mEndAnimationRect.bottom = newEndValue;
+ mBottomAnimator = animator;
+ }
+
+ @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
+ private void setBackgroundTop(int top) {
+ mCurrentBounds.top = top;
+ mOwningView.invalidate();
+ }
+
+ @ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.SHADE_VIEW)
+ private void setBackgroundBottom(int bottom) {
+ mCurrentBounds.bottom = bottom;
+ mOwningView.invalidate();
+ }
+
+ public ActivatableNotificationView getFirstVisibleChild() {
+ return mFirstVisibleChild;
+ }
+
+ public ActivatableNotificationView getLastVisibleChild() {
+ return mLastVisibleChild;
+ }
+
+ public void setFirstVisibleChild(ActivatableNotificationView child) {
+ mFirstVisibleChild = child;
+ }
+
+ public void setLastVisibleChild(ActivatableNotificationView child) {
+ mLastVisibleChild = child;
+ }
+
+ public void resetCurrentBounds() {
+ mCurrentBounds.set(mBounds);
+ }
+
+ /**
+ * Returns true if {@code top} is equal to the top of this section (if not currently animating)
+ * or where the top of this section will be when animation completes.
+ */
+ public boolean isTargetTop(int top) {
+ return (mTopAnimator == null && mCurrentBounds.top == top)
+ || (mTopAnimator != null && mEndAnimationRect.top == top);
+ }
+
+ /**
+ * Returns true if {@code bottom} is equal to the bottom of this section (if not currently
+ * animating) or where the bottom of this section will be when animation completes.
+ */
+ public boolean isTargetBottom(int bottom) {
+ return (mBottomAnimator == null && mCurrentBounds.bottom == bottom)
+ || (mBottomAnimator != null && mEndAnimationRect.bottom == bottom);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index c3bf16e..9daba83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -22,13 +22,10 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
import android.animation.TimeAnimator;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.NotificationManager;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
@@ -155,6 +152,12 @@
* Sentinel value for no current active pointer. Used by {@link #mActivePointerId}.
*/
private static final int INVALID_POINTER = -1;
+ static final int NUM_SECTIONS = 2;
+ /**
+ * The distance in pixels between sections when the sections are directly adjacent (no visible
+ * gap is drawn between them). In this case we don't want to round their corners.
+ */
+ private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1;
private ExpandHelper mExpandHelper;
private final NotificationSwipeHelper mSwipeHelper;
@@ -328,16 +331,10 @@
return true;
}
};
- private Rect mBackgroundBounds = new Rect();
- private Rect mStartAnimationRect = new Rect();
- private Rect mEndAnimationRect = new Rect();
- private Rect mCurrentBounds = new Rect(-1, -1, -1, -1);
- private boolean mAnimateNextBackgroundBottom;
+ private NotificationSection[] mSections = new NotificationSection[NUM_SECTIONS];
private boolean mAnimateNextBackgroundTop;
- private ObjectAnimator mBottomAnimator = null;
- private ObjectAnimator mTopAnimator = null;
- private ActivatableNotificationView mFirstVisibleBackgroundChild = null;
- private ActivatableNotificationView mLastVisibleBackgroundChild = null;
+ private boolean mAnimateNextBackgroundBottom;
+ private boolean mAnimateNextSectionBoundsChange;
private int mBgColor;
private float mDimAmount;
private ValueAnimator mDimAnimator;
@@ -480,6 +477,10 @@
super(context, attrs, defStyleAttr, defStyleRes);
Resources res = getResources();
+ for (int i = 0; i < NUM_SECTIONS; i++) {
+ mSections[i] = new NotificationSection(this);
+ }
+
mAmbientState = new AmbientState(context);
mBgColor = context.getColor(R.color.notification_shade_background_color);
int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
@@ -656,7 +657,9 @@
@ShadeViewRefactor(RefactorComponent.DECORATOR)
protected void onDraw(Canvas canvas) {
if (mShouldDrawNotificationBackground
- && (mCurrentBounds.top < mCurrentBounds.bottom || mAmbientState.isDark())) {
+ && (mSections[0].getCurrentBounds().top
+ < mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom
+ || mAmbientState.isDark())) {
drawBackground(canvas);
}
@@ -674,8 +677,8 @@
private void drawBackground(Canvas canvas) {
int lockScreenLeft = mSidePaddings;
int lockScreenRight = getWidth() - mSidePaddings;
- int lockScreenTop = mCurrentBounds.top;
- int lockScreenBottom = mCurrentBounds.bottom;
+ int lockScreenTop = mSections[0].getCurrentBounds().top;
+ int lockScreenBottom = mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom;
int darkLeft = getWidth() / 2;
int darkTop = mRegularTopPadding;
@@ -683,21 +686,79 @@
float xProgress = mDarkXInterpolator.getInterpolation(
(1 - mLinearDarkAmount) * mBackgroundXFactor);
+ int left = (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress);
+ int right = (int) MathUtils.lerp(darkLeft, lockScreenRight, xProgress);
+ int top = (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress);
+ int bottom = (int) MathUtils.lerp(darkTop, lockScreenBottom, yProgress);
mBackgroundAnimationRect.set(
- (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress),
- (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress),
- (int) MathUtils.lerp(darkLeft, lockScreenRight, xProgress),
- (int) MathUtils.lerp(darkTop, lockScreenBottom, yProgress));
+ left,
+ top,
+ right,
+ bottom);
- if (!mAmbientState.isDark() || mFirstVisibleBackgroundChild != null) {
- canvas.drawRoundRect(mBackgroundAnimationRect.left, mBackgroundAnimationRect.top,
- mBackgroundAnimationRect.right, mBackgroundAnimationRect.bottom,
- mCornerRadius, mCornerRadius, mBackgroundPaint);
+ int backgroundTopAnimationOffset = top - lockScreenTop;
+ // TODO(kprevas): this may not be necessary any more since we don't display the shelf in AOD
+ boolean anySectionHasVisibleChild = false;
+ for (NotificationSection section : mSections) {
+ if (section.getFirstVisibleChild() != null) {
+ anySectionHasVisibleChild = true;
+ break;
+ }
+ }
+ if (!mAmbientState.isDark() || anySectionHasVisibleChild) {
+ drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
}
updateClipping();
}
+ /**
+ * Draws round rects for each background section.
+ *
+ * We want to draw a round rect for each background section as defined by {@link #mSections}.
+ * However, if two sections are directly adjacent with no gap between them (e.g. on the
+ * lockscreen where the shelf can appear directly below the high priority section, or while
+ * scrolling the shade so that the top of the shelf is right at the bottom of the high priority
+ * section), we don't want to round the adjacent corners.
+ *
+ * Since {@link Canvas} doesn't provide a way to draw a half-rounded rect, this means that we
+ * need to coalesce the backgrounds for adjacent sections and draw them as a single round rect.
+ * This method tracks the top of each rect we need to draw, then iterates through the visible
+ * sections. If a section is not adjacent to the previous section, we draw the previous rect
+ * behind the sections we've accumulated up to that point, then start a new rect at the top of
+ * the current section. When we're done iterating we will always have one rect left to draw.
+ */
+ private void drawBackgroundRects(Canvas canvas, int left, int right, int top,
+ int animationYOffset) {
+ int backgroundRectTop = top;
+ int lastSectionBottom =
+ mSections[0].getCurrentBounds().bottom + animationYOffset;
+ for (NotificationSection section : mSections) {
+ if (section.getFirstVisibleChild() == null) {
+ continue;
+ }
+ int sectionTop = section.getCurrentBounds().top + animationYOffset;
+ // If sections are directly adjacent to each other, we don't want to draw them
+ // as separate roundrects, as the rounded corners right next to each other look
+ // bad.
+ if (sectionTop - lastSectionBottom > DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX) {
+ canvas.drawRoundRect(left,
+ backgroundRectTop,
+ right,
+ lastSectionBottom,
+ mCornerRadius, mCornerRadius, mBackgroundPaint);
+ backgroundRectTop = sectionTop;
+ }
+ lastSectionBottom =
+ section.getCurrentBounds().bottom + animationYOffset;
+ }
+ canvas.drawRoundRect(left,
+ backgroundRectTop,
+ right,
+ lastSectionBottom,
+ mCornerRadius, mCornerRadius, mBackgroundPaint);
+ }
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateBackgroundDimming() {
// No need to update the background color if it's not being drawn.
@@ -1067,7 +1128,8 @@
translationY = height - appearStartPosition + getExpandTranslationStart();
}
if (isHeadsUpTransition()) {
- stackHeight = mFirstVisibleBackgroundChild.getPinnedHeadsUpHeight();
+ stackHeight =
+ getFirstVisibleSection().getFirstVisibleChild().getPinnedHeadsUpHeight();
translationY = MathUtils.lerp(mHeadsUpInset - mTopPadding, 0, appearFraction);
} else {
stackHeight = (int) (height - translationY);
@@ -1124,7 +1186,7 @@
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private float getExpandTranslationStart() {
- return -mTopPadding + getMinExpansionHeight();
+ return -mTopPadding + getMinExpansionHeight() - mShelf.getIntrinsicHeight();
}
/**
@@ -1134,7 +1196,8 @@
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private float getAppearStartPosition() {
if (isHeadsUpTransition()) {
- return mHeadsUpInset + mFirstVisibleBackgroundChild.getPinnedHeadsUpHeight();
+ return mHeadsUpInset
+ + getFirstVisibleSection().getFirstVisibleChild().getPinnedHeadsUpHeight();
}
return getMinExpansionHeight();
}
@@ -1187,8 +1250,9 @@
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private boolean isHeadsUpTransition() {
- return mTrackingHeadsUp && mFirstVisibleBackgroundChild != null
- && mAmbientState.isAboveShelf(mFirstVisibleBackgroundChild);
+ NotificationSection firstVisibleSection = getFirstVisibleSection();
+ return mTrackingHeadsUp && firstVisibleSection != null
+ && mAmbientState.isAboveShelf(firstVisibleSection.getFirstVisibleChild());
}
/**
@@ -2013,9 +2077,9 @@
}
updateBackgroundBounds();
- if (!mCurrentBounds.equals(mBackgroundBounds)) {
- boolean animate = mAnimateNextBackgroundTop || mAnimateNextBackgroundBottom
- || areBoundsAnimating();
+ if (didSectionBoundsChange()) {
+ boolean animate = mAnimateNextSectionBoundsChange || mAnimateNextBackgroundTop
+ || mAnimateNextBackgroundBottom || areSectionBoundsAnimating();
if (!isExpanded()) {
abortBackgroundAnimators();
animate = false;
@@ -2023,148 +2087,60 @@
if (animate) {
startBackgroundAnimation();
} else {
- mCurrentBounds.set(mBackgroundBounds);
+ for (NotificationSection section : mSections) {
+ section.resetCurrentBounds();
+ }
invalidate();
}
} else {
abortBackgroundAnimators();
}
- mAnimateNextBackgroundBottom = false;
mAnimateNextBackgroundTop = false;
+ mAnimateNextBackgroundBottom = false;
+ mAnimateNextSectionBoundsChange = false;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void abortBackgroundAnimators() {
- if (mBottomAnimator != null) {
- mBottomAnimator.cancel();
- }
- if (mTopAnimator != null) {
- mTopAnimator.cancel();
+ for (NotificationSection section : mSections) {
+ section.cancelAnimators();
}
}
+ private boolean didSectionBoundsChange() {
+ for (NotificationSection section : mSections) {
+ if (section.didBoundsChange()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private boolean areBoundsAnimating() {
- return mBottomAnimator != null || mTopAnimator != null;
+ private boolean areSectionBoundsAnimating() {
+ for (NotificationSection section : mSections) {
+ if (section.areBoundsAnimating()) {
+ return true;
+ }
+ }
+ return false;
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void startBackgroundAnimation() {
- // left and right are always instantly applied
- mCurrentBounds.left = mBackgroundBounds.left;
- mCurrentBounds.right = mBackgroundBounds.right;
- startBottomAnimation();
- startTopAnimation();
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void startTopAnimation() {
- int previousEndValue = mEndAnimationRect.top;
- int newEndValue = mBackgroundBounds.top;
- ObjectAnimator previousAnimator = mTopAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
+ // TODO(kprevas): do we still need separate fields for top/bottom?
+ // or can each section manage its own animation state?
+ NotificationSection firstVisibleSection = getFirstVisibleSection();
+ NotificationSection lastVisibleSection = getLastVisibleSection();
+ for (NotificationSection section : mSections) {
+ section.startBackgroundAnimation(
+ section == firstVisibleSection
+ ? mAnimateNextBackgroundTop
+ : mAnimateNextSectionBoundsChange,
+ section == lastVisibleSection
+ ? mAnimateNextBackgroundBottom
+ : mAnimateNextSectionBoundsChange);
}
- if (!mAnimateNextBackgroundTop) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- int previousStartValue = mStartAnimationRect.top;
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.top = previousStartValue;
- mEndAnimationRect.top = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundTop(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundTop",
- mCurrentBounds.top, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.top = -1;
- mEndAnimationRect.top = -1;
- mTopAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.top = mCurrentBounds.top;
- mEndAnimationRect.top = newEndValue;
- mTopAnimator = animator;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void startBottomAnimation() {
- int previousStartValue = mStartAnimationRect.bottom;
- int previousEndValue = mEndAnimationRect.bottom;
- int newEndValue = mBackgroundBounds.bottom;
- ObjectAnimator previousAnimator = mBottomAnimator;
- if (previousAnimator != null && previousEndValue == newEndValue) {
- return;
- }
- if (!mAnimateNextBackgroundBottom) {
- // just a local update was performed
- if (previousAnimator != null) {
- // we need to increase all animation keyframes of the previous animator by the
- // relative change to the end value
- PropertyValuesHolder[] values = previousAnimator.getValues();
- values[0].setIntValues(previousStartValue, newEndValue);
- mStartAnimationRect.bottom = previousStartValue;
- mEndAnimationRect.bottom = newEndValue;
- previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
- return;
- } else {
- // no new animation needed, let's just apply the value
- setBackgroundBottom(newEndValue);
- return;
- }
- }
- if (previousAnimator != null) {
- previousAnimator.cancel();
- }
- ObjectAnimator animator = ObjectAnimator.ofInt(this, "backgroundBottom",
- mCurrentBounds.bottom, newEndValue);
- Interpolator interpolator = Interpolators.FAST_OUT_SLOW_IN;
- animator.setInterpolator(interpolator);
- animator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- // remove the tag when the animation is finished
- animator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mStartAnimationRect.bottom = -1;
- mEndAnimationRect.bottom = -1;
- mBottomAnimator = null;
- }
- });
- animator.start();
- mStartAnimationRect.bottom = mCurrentBounds.bottom;
- mEndAnimationRect.bottom = newEndValue;
- mBottomAnimator = animator;
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void setBackgroundTop(int top) {
- mCurrentBounds.top = top;
- invalidate();
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setBackgroundBottom(int bottom) {
- mCurrentBounds.bottom = bottom;
- invalidate();
}
/**
@@ -2173,32 +2149,38 @@
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateBackgroundBounds() {
getLocationInWindow(mTempInt2);
- mBackgroundBounds.left = mTempInt2[0] + mSidePaddings;
- mBackgroundBounds.right = mTempInt2[0] + getWidth() - mSidePaddings;
+ int left = mTempInt2[0] + mSidePaddings;
+ int right = mTempInt2[0] + getWidth() - mSidePaddings;
+ for (NotificationSection section : mSections) {
+ section.getBounds().left = left;
+ section.getBounds().right = right;
+ }
if (!mIsExpanded) {
- mBackgroundBounds.top = 0;
- mBackgroundBounds.bottom = 0;
+ for (NotificationSection section : mSections) {
+ section.getBounds().top = 0;
+ section.getBounds().bottom = 0;
+ }
return;
}
- ActivatableNotificationView firstView = mFirstVisibleBackgroundChild;
+ NotificationSection firstSection = getFirstVisibleSection();
int top = 0;
- if (firstView != null) {
+ if (firstSection != null) {
+ ActivatableNotificationView firstView = firstSection.getFirstVisibleChild();
// Round Y up to avoid seeing the background during animation
int finalTranslationY = (int) Math.ceil(ViewState.getFinalTranslationY(firstView));
- if (mAnimateNextBackgroundTop
- || mTopAnimator == null && mCurrentBounds.top == finalTranslationY
- || mTopAnimator != null && mEndAnimationRect.top == finalTranslationY) {
+ if (mAnimateNextBackgroundTop || firstSection.isTargetTop(finalTranslationY)) {
// we're ending up at the same location as we are now, lets just skip the animation
top = finalTranslationY;
} else {
top = (int) Math.ceil(firstView.getTranslationY());
}
}
+ NotificationSection lastSection = getLastVisibleSection();
ActivatableNotificationView lastView =
mShelf.hasItemsInStableShelf() && mShelf.getVisibility() != GONE
? mShelf
- : mLastVisibleBackgroundChild;
+ : lastSection == null ? null : lastSection.getLastVisibleChild();
int bottom;
if (lastView != null) {
int finalTranslationY;
@@ -2209,9 +2191,7 @@
}
int finalHeight = ExpandableViewState.getFinalActualHeight(lastView);
int finalBottom = finalTranslationY + finalHeight - lastView.getClipBottomAmount();
- if (mAnimateNextBackgroundBottom
- || mBottomAnimator == null && mCurrentBounds.bottom == finalBottom
- || mBottomAnimator != null && mEndAnimationRect.bottom == finalBottom) {
+ if (mAnimateNextBackgroundBottom || lastSection.isTargetBottom(finalBottom)) {
// we're ending up at the same location as we are now, lets just skip the animation
bottom = finalBottom;
} else {
@@ -2228,8 +2208,38 @@
// otherwise the animation from the shade to the keyguard will jump as it's maxed
top = Math.max(0, top);
}
- mBackgroundBounds.top = top;
- mBackgroundBounds.bottom = Math.max(bottom, top);
+ bottom = Math.max(bottom, top);
+
+ setSectionBoundsByPriority(left, right, top, bottom, mSections[0], mSections[1]);
+ }
+
+ private void setSectionBoundsByPriority(int left, int right, int top, int bottom,
+ NotificationSection highPrioritySection, NotificationSection lowPrioritySection) {
+ if (NotificationUtils.useNewInterruptionModel(mContext)) {
+ // TODO(kprevas): can we use section boundary indices from mAmbientState instead?
+ ActivatableNotificationView lastChildAboveGap = getLastHighPriorityChild();
+ ActivatableNotificationView firstChildBelowGap = getFirstLowPriorityChild();
+ if (lastChildAboveGap != null && firstChildBelowGap != null) {
+ int gapTop =
+ (int) Math.max(top,
+ Math.min(lastChildAboveGap.getTranslationY()
+ + lastChildAboveGap.getActualHeight(),
+ bottom));
+ int gapBottom = (int) Math.max(top,
+ Math.min(firstChildBelowGap.getTranslationY(), bottom));
+ highPrioritySection.getBounds().set(left, top, right, gapTop);
+ lowPrioritySection.getBounds().set(left, gapBottom, right, bottom);
+ } else if (lastChildAboveGap != null) {
+ highPrioritySection.getBounds().set(left, top, right, bottom);
+ lowPrioritySection.getBounds().set(left, bottom, right, bottom);
+ } else {
+ highPrioritySection.getBounds().set(left, top, right, top);
+ lowPrioritySection.getBounds().set(left, top, right, bottom);
+ }
+ } else {
+ highPrioritySection.getBounds().set(left, top, right, bottom);
+ lowPrioritySection.getBounds().set(left, bottom, right, bottom);
+ }
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
@@ -2248,6 +2258,25 @@
return null;
}
+ private NotificationSection getFirstVisibleSection() {
+ for (NotificationSection section : mSections) {
+ if (section.getFirstVisibleChild() != null) {
+ return section;
+ }
+ }
+ return null;
+ }
+
+ private NotificationSection getLastVisibleSection() {
+ for (int i = mSections.length - 1; i >= 0; i--) {
+ NotificationSection section = mSections[i];
+ if (section.getLastVisibleChild() != null) {
+ return section;
+ }
+ }
+ return null;
+ }
+
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private ActivatableNotificationView getLastChildWithBackground() {
int childCount = getChildCount();
@@ -2274,6 +2303,43 @@
return null;
}
+ @ShadeViewRefactor(RefactorComponent.COORDINATOR)
+ @Nullable
+ private ActivatableNotificationView getLastHighPriorityChild() {
+ ActivatableNotificationView lastChildBeforeGap = null;
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child.getVisibility() != View.GONE && child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ if (mEntryManager.getNotificationData().isHighPriority(
+ row.getStatusBarNotification())) {
+ break;
+ } else {
+ lastChildBeforeGap = row;
+ }
+ }
+ }
+ return lastChildBeforeGap;
+ }
+
+ @ShadeViewRefactor(RefactorComponent.COORDINATOR)
+ @Nullable
+ private ActivatableNotificationView getFirstLowPriorityChild() {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child.getVisibility() != View.GONE && child instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+ if (!mEntryManager.getNotificationData().isHighPriority(
+ row.getStatusBarNotification())) {
+ return row;
+ }
+ }
+ }
+ return null;
+ }
+
/**
* Fling the scroll view
*
@@ -2391,7 +2457,7 @@
final int firstChildMinHeight = firstChild != null ? firstChild.getCollapsedHeight()
: mCollapsedSize;
int shelfHeight = 0;
- if (mLastVisibleBackgroundChild != null && mShelf.getVisibility() != GONE) {
+ if (getLastVisibleSection() != null && mShelf.getVisibility() != GONE) {
shelfHeight = mShelf.getIntrinsicHeight();
}
return mIntrinsicPadding + firstChildMinHeight + shelfHeight;
@@ -2700,23 +2766,68 @@
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateFirstAndLastBackgroundViews() {
+ NotificationSection firstSection = getFirstVisibleSection();
+ NotificationSection lastSection = getLastVisibleSection();
+
ActivatableNotificationView firstChild = getFirstChildWithBackground();
ActivatableNotificationView lastChild = getLastChildWithBackground();
+ boolean sectionViewsChanged = updateFirstAndLastViewsInSectionsByPriority(
+ mSections[0], mSections[1], firstChild, lastChild);
+
if (mAnimationsEnabled && mIsExpanded) {
- mAnimateNextBackgroundTop = firstChild != mFirstVisibleBackgroundChild;
- mAnimateNextBackgroundBottom = lastChild != mLastVisibleBackgroundChild;
+ mAnimateNextBackgroundTop =
+ firstSection == null || firstChild != firstSection.getFirstVisibleChild();
+ mAnimateNextBackgroundBottom =
+ lastSection == null || lastChild != lastSection.getLastVisibleChild();
+ mAnimateNextSectionBoundsChange = sectionViewsChanged;
} else {
mAnimateNextBackgroundTop = false;
mAnimateNextBackgroundBottom = false;
+ mAnimateNextSectionBoundsChange = false;
}
- mFirstVisibleBackgroundChild = firstChild;
- mLastVisibleBackgroundChild = lastChild;
mAmbientState.setLastVisibleBackgroundChild(lastChild);
- mRoundnessManager.setFirstAndLastBackgroundChild(mFirstVisibleBackgroundChild,
- mLastVisibleBackgroundChild);
+ mRoundnessManager.updateRoundedChildren(mSections);
invalidate();
}
+ /** @return {@code true} if the last view in the top section changed (so we need to animate). */
+ private boolean updateFirstAndLastViewsInSectionsByPriority(
+ final NotificationSection highPrioritySection,
+ final NotificationSection lowPrioritySection,
+ ActivatableNotificationView firstChild,
+ ActivatableNotificationView lastChild) {
+ if (NotificationUtils.useNewInterruptionModel(mContext)) {
+ ActivatableNotificationView previousLastHighPriorityChild =
+ highPrioritySection.getLastVisibleChild();
+ ActivatableNotificationView previousFirstLowPriorityChild =
+ lowPrioritySection.getFirstVisibleChild();
+ ActivatableNotificationView lastHighPriorityChild = getLastHighPriorityChild();
+ ActivatableNotificationView firstLowPriorityChild = getFirstLowPriorityChild();
+ if (lastHighPriorityChild != null && firstLowPriorityChild != null) {
+ highPrioritySection.setFirstVisibleChild(firstChild);
+ highPrioritySection.setLastVisibleChild(lastHighPriorityChild);
+ lowPrioritySection.setFirstVisibleChild(firstLowPriorityChild);
+ lowPrioritySection.setLastVisibleChild(lastChild);
+ } else if (lastHighPriorityChild != null) {
+ highPrioritySection.setFirstVisibleChild(firstChild);
+ highPrioritySection.setLastVisibleChild(lastChild);
+ lowPrioritySection.setFirstVisibleChild(null);
+ lowPrioritySection.setLastVisibleChild(null);
+ } else {
+ highPrioritySection.setFirstVisibleChild(null);
+ highPrioritySection.setLastVisibleChild(null);
+ lowPrioritySection.setFirstVisibleChild(firstChild);
+ lowPrioritySection.setLastVisibleChild(lastChild);
+ }
+ return lastHighPriorityChild != previousLastHighPriorityChild
+ || firstLowPriorityChild != previousFirstLowPriorityChild;
+ } else {
+ highPrioritySection.setFirstVisibleChild(firstChild);
+ highPrioritySection.setLastVisibleChild(lastChild);
+ return false;
+ }
+ }
+
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private void onViewAddedInternal(View child) {
updateHideSensitiveForChild(child);
@@ -3903,9 +4014,14 @@
ExpandableNotificationRow row = view instanceof ExpandableNotificationRow
? (ExpandableNotificationRow) view
: null;
- if (row != null && (row == mFirstVisibleBackgroundChild
- || row.getNotificationParent() == mFirstVisibleBackgroundChild)) {
- updateAlgorithmLayoutMinHeight();
+ NotificationSection firstSection = getFirstVisibleSection();
+ ActivatableNotificationView firstVisibleChild =
+ firstSection == null ? null : firstSection.getFirstVisibleChild();
+ if (row != null) {
+ if (row == firstVisibleChild
+ || row.getNotificationParent() == firstVisibleChild) {
+ updateAlgorithmLayoutMinHeight();
+ }
}
if (needsAnimation) {
requestAnimationOnViewResize(row);
@@ -3933,7 +4049,10 @@
endPosition += row.getNotificationParent().getTranslationY();
}
int layoutEnd = mMaxLayoutHeight + (int) mStackTranslation;
- if (row != mLastVisibleBackgroundChild && mShelf.getVisibility() != GONE) {
+ NotificationSection lastSection = getLastVisibleSection();
+ ActivatableNotificationView lastVisibleChild =
+ lastSection == null ? null : lastSection.getLastVisibleChild();
+ if (row != lastVisibleChild && mShelf.getVisibility() != GONE) {
layoutEnd -= mShelf.getIntrinsicHeight() + mPaddingBetweenElements;
}
if (endPosition > layoutEnd) {
@@ -4014,6 +4133,11 @@
return mAmbientState.isDimmed();
}
+ @VisibleForTesting
+ int getSectionBoundaryIndex(int boundaryNum) {
+ return mAmbientState.getSectionBoundaryIndex(boundaryNum);
+ }
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void setDimAmount(float dimAmount) {
mDimAmount = dimAmount;
@@ -5091,9 +5215,8 @@
beforeSpeedBump = !mEntryManager.getNotificationData().isAmbient(
row.getStatusBarNotification().getKey());
} else {
- beforeSpeedBump = mEntryManager.getNotificationData().getImportance(
- row.getStatusBarNotification().getKey())
- >= NotificationManager.IMPORTANCE_DEFAULT;
+ beforeSpeedBump = mEntryManager.getNotificationData().isHighPriority(
+ row.getStatusBarNotification());
}
if (beforeSpeedBump) {
speedBumpIndex = currentIndex;
@@ -5103,6 +5226,33 @@
updateSpeedBumpIndex(speedBumpIndex, noAmbient);
}
+ /** Updates the indices of the boundaries between sections. */
+ @ShadeViewRefactor(RefactorComponent.INPUT)
+ public void updateSectionBoundaries() {
+ int gapIndex = -1;
+ if (NotificationUtils.useNewInterruptionModel(mContext)) {
+ int currentIndex = 0;
+ final int n = getChildCount();
+ for (int i = 0; i < n; i++) {
+ View view = getChildAt(i);
+ if (view.getVisibility() == View.GONE
+ || !(view instanceof ExpandableNotificationRow)) {
+ continue;
+ }
+ ExpandableNotificationRow row = (ExpandableNotificationRow) view;
+ if (!mEntryManager.getNotificationData().isHighPriority(
+ row.getStatusBarNotification())) {
+ if (currentIndex > 0) {
+ gapIndex = currentIndex;
+ }
+ break;
+ }
+ currentIndex++;
+ }
+ }
+ mAmbientState.setSectionBoundaryIndex(0, gapIndex);
+ }
+
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void updateContinuousShadowDrawing() {
boolean continuousShadowUpdate = mAnimationRunning
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 742d89d..8c13489 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -21,13 +21,14 @@
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.row.FooterView;
-import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.notification.NotificationUtils;
import java.util.ArrayList;
import java.util.HashMap;
@@ -44,6 +45,7 @@
private int mPaddingBetweenElements;
private int mIncreasedPaddingBetweenElements;
+ private int mGapHeight;
private int mCollapsedSize;
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
@@ -74,6 +76,7 @@
R.dimen.heads_up_status_bar_padding);
mPinnedZTranslationExtra = res.getDimensionPixelSize(
R.dimen.heads_up_pinned_elevation);
+ mGapHeight = res.getDimensionPixelSize(R.dimen.notification_section_divider_height);
}
public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
@@ -387,6 +390,9 @@
childViewState.location = ExpandableViewState.LOCATION_UNKNOWN;
int paddingAfterChild = getPaddingAfterChild(algorithmState, child);
int childHeight = getMaxAllowedChildHeight(child);
+ if (ambientState.beginsNewSection(i)) {
+ currentYPosition += mGapHeight;
+ }
childViewState.yTranslation = currentYPosition;
boolean isFooterView = child instanceof FooterView;
boolean isEmptyShadeView = child instanceof EmptyShadeView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 4eca6bb..119f01a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -263,6 +263,16 @@
}
}
+ public void setTranslation(int x, int y, int z) {
+ final int N = mViews.size();
+ for (int i = 0; i < N; i++) {
+ final View view = mViews.get(i);
+ view.setTranslationX(x);
+ view.setTranslationY(y);
+ view.setTranslationZ(z);
+ }
+ }
+
public ArrayList<View> getViews() {
return mViews;
}
@@ -276,6 +286,11 @@
if (mImageDrawable != null) {
mImageDrawable.setCallback(mCurrentView);
}
+ if (mCurrentView != null) {
+ mCurrentView.setTranslationX(0);
+ mCurrentView.setTranslationY(0);
+ mCurrentView.setTranslationZ(0);
+ }
}
public void setVertical(boolean vertical) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index d4de8fc..3b13fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -46,7 +46,8 @@
* and keyguard state. Also manages lifecycle to make sure the views it contains are being
* updated by the StatusBarIconController and DarkIconManager while it is attached.
*/
-public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks {
+public class CollapsedStatusBarFragment extends Fragment implements CommandQueue.Callbacks,
+ StatusBarStateController.StateListener {
public static final String TAG = "CollapsedStatusBarFragment";
private static final String EXTRA_PANEL_STATE = "panel_state";
@@ -120,12 +121,14 @@
public void onResume() {
super.onResume();
mCommandQueue.addCallbacks(this);
+ mStatusBarStateController.addListener(this);
}
@Override
public void onPause() {
super.onPause();
mCommandQueue.removeCallbacks(this);
+ mStatusBarStateController.removeListener(this);
}
@Override
@@ -351,4 +354,14 @@
mOperatorNameFrame = stub.inflate();
}
}
+
+ @Override
+ public void onStateChanged(int newState) {
+
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ disable(mDisabled1, mDisabled1, false /* animate */);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
new file mode 100644
index 0000000..1002f9e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
+
+import android.annotation.NonNull;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.view.HapticFeedbackConstants;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import com.android.systemui.recents.OverviewProxyService;
+
+/**
+ * A back action when triggered will execute a back command
+ */
+public class NavigationBackAction extends NavigationGestureAction {
+
+ private static final String PULL_HOME_GO_BACK_PROP = "quickstepcontroller_homegoesback";
+ private static final String BACK_AFTER_END_PROP =
+ "quickstepcontroller_homegoesbackwhenend";
+ private static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled";
+ private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60;
+ private static final long BACK_GESTURE_POLL_TIMEOUT = 1000;
+
+ private final Handler mHandler = new Handler();
+
+ private final Runnable mExecuteBackRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (isEnabled() && canPerformAction()) {
+ performBack();
+ mHandler.postDelayed(this, BACK_GESTURE_POLL_TIMEOUT);
+ }
+ }
+ };
+
+ public NavigationBackAction(@NonNull NavigationBarView navigationBarView,
+ @NonNull OverviewProxyService service) {
+ super(navigationBarView, service);
+ }
+
+ @Override
+ public int requiresTouchDownHitTarget() {
+ return HIT_TARGET_HOME;
+ }
+
+ @Override
+ public boolean requiresDragWithHitTarget() {
+ return true;
+ }
+
+ @Override
+ public boolean canPerformAction() {
+ return mProxySender.getBackButtonAlpha() > 0;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return swipeHomeGoBackGestureEnabled();
+ }
+
+ @Override
+ protected void onGestureStart(MotionEvent event) {
+ if (!QuickStepController.shouldhideBackButton(getContext())) {
+ mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
+ BACK_BUTTON_FADE_OUT_ALPHA);
+ }
+ mHandler.removeCallbacks(mExecuteBackRunnable);
+ if (!shouldExecuteBackOnUp()) {
+ performBack();
+ mHandler.postDelayed(mExecuteBackRunnable, BACK_GESTURE_POLL_TIMEOUT);
+ }
+ }
+
+ @Override
+ protected void onGestureEnd() {
+ mHandler.removeCallbacks(mExecuteBackRunnable);
+ if (!QuickStepController.shouldhideBackButton(getContext())) {
+ mNavigationBarView.getBackButton().setAlpha(
+ mProxySender.getBackButtonAlpha(), true /* animate */);
+ }
+ if (shouldExecuteBackOnUp()) {
+ performBack();
+ }
+ }
+
+ private void performBack() {
+ sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
+ sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
+ mNavigationBarView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+ }
+
+ private boolean swipeHomeGoBackGestureEnabled() {
+ return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED)
+ && getGlobalBoolean(PULL_HOME_GO_BACK_PROP);
+ }
+
+ private boolean shouldExecuteBackOnUp() {
+ return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED)
+ && getGlobalBoolean(BACK_AFTER_END_PROP);
+ }
+
+ private void sendEvent(int action, int code) {
+ long when = SystemClock.uptimeMillis();
+ final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
+ 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
+ KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
+ InputDevice.SOURCE_KEYBOARD);
+ InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ }
+}
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 6728f08..2c3c27f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -38,9 +38,11 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.MotionEvent;
@@ -49,6 +51,7 @@
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.inputmethod.InputMethodManager;
@@ -143,6 +146,10 @@
private RecentsOnboarding mRecentsOnboarding;
private NotificationPanelView mPanelView;
+ private QuickScrubAction mQuickScrubAction;
+ private QuickStepAction mQuickStepAction;
+ private NavigationBackAction mBackAction;
+
/**
* Helper that is responsible for showing the right toast when a disallowed activity operation
* occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
@@ -299,6 +306,10 @@
mButtonDispatchers.put(R.id.rotate_suggestion, rotateSuggestionButton);
mButtonDispatchers.put(R.id.menu_container, mContextualButtonGroup);
mDeadZone = new DeadZone(this);
+
+ mQuickScrubAction = new QuickScrubAction(this, mOverviewProxyService);
+ mQuickStepAction = new QuickStepAction(this, mOverviewProxyService);
+ mBackAction = new NavigationBackAction(this, mOverviewProxyService);
}
public BarTransitions getBarTransitions() {
@@ -313,6 +324,8 @@
mPanelView = panel;
if (mGestureHelper instanceof QuickStepController) {
((QuickStepController) mGestureHelper).setComponents(this);
+ ((QuickStepController) mGestureHelper).setGestureActions(mQuickStepAction,
+ null /* swipeDownAction*/, mBackAction, mQuickScrubAction);
}
}
@@ -756,24 +769,6 @@
mRecentsOnboarding.hide(true);
}
- /**
- * @return the button at the given {@param x} and {@param y}.
- */
- ButtonDispatcher getButtonAtPosition(int x, int y) {
- for (int i = 0; i < mButtonDispatchers.size(); i++) {
- ButtonDispatcher button = mButtonDispatchers.valueAt(i);
- View buttonView = button.getCurrentView();
- if (buttonView != null) {
- buttonView.getHitRect(mTmpRect);
- offsetDescendantRectToMyCoords(buttonView, mTmpRect);
- if (mTmpRect.contains(x, y)) {
- return button;
- }
- }
- }
- return null;
- }
-
@Override
public void onFinishInflate() {
mNavigationInflaterView = findViewById(R.id.navigation_inflater);
@@ -908,7 +903,13 @@
private void updateTaskSwitchHelper() {
if (mGestureHelper == null) return;
boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
- mGestureHelper.setBarState(mVertical, isRtl);
+ int navBarPos = 0;
+ try {
+ navBarPos = WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to get nav bar position.", e);
+ }
+ mGestureHelper.setBarState(isRtl, navBarPos);
}
@Override
@@ -1112,6 +1113,14 @@
mContextualButtonGroup.dump(pw);
if (mGestureHelper != null) {
+ pw.println("Navigation Gesture Actions {");
+ pw.print(" "); pw.println("QuickScrub Enabled=" + mQuickScrubAction.isEnabled());
+ pw.print(" "); pw.println("QuickScrub Active=" + mQuickScrubAction.isActive());
+ pw.print(" "); pw.println("QuickStep Enabled=" + mQuickStepAction.isEnabled());
+ pw.print(" "); pw.println("QuickStep Active=" + mQuickStepAction.isActive());
+ pw.print(" "); pw.println("Back Gesture Enabled=" + mBackAction.isEnabled());
+ pw.print(" "); pw.println("Back Gesture Active=" + mBackAction.isActive());
+ pw.println("}");
mGestureHelper.dump(pw);
}
mRecentsOnboarding.dump(pw);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
new file mode 100644
index 0000000..593bfae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.view.MotionEvent;
+
+import android.view.WindowManagerPolicyConstants;
+import com.android.systemui.recents.OverviewProxyService;
+
+/**
+ * A gesture action that would be triggered and reassigned by {@link QuickStepController}
+ */
+public abstract class NavigationGestureAction {
+
+ protected final NavigationBarView mNavigationBarView;
+ protected final OverviewProxyService mProxySender;
+
+ protected int mNavigationBarPosition;
+ protected boolean mDragHorizontalPositive;
+ protected boolean mDragVerticalPositive;
+ private boolean mIsActive;
+
+ public NavigationGestureAction(@NonNull NavigationBarView navigationBarView,
+ @NonNull OverviewProxyService service) {
+ mNavigationBarView = navigationBarView;
+ mProxySender = service;
+ }
+
+ /**
+ * Pass event that the state of the bar (such as rotation) has changed
+ * @param changed if rotation or drag positive direction (such as ltr) has changed
+ * @param navBarPos position of navigation bar
+ * @param dragHorPositive direction of positive horizontal drag, could change with ltr changes
+ * @param dragVerPositive direction of positive vertical drag, could change with ltr changes
+ */
+ public void setBarState(boolean changed, int navBarPos, boolean dragHorPositive,
+ boolean dragVerPositive) {
+ mNavigationBarPosition = navBarPos;
+ mDragHorizontalPositive = dragHorPositive;
+ mDragVerticalPositive = dragVerPositive;
+ }
+
+ /**
+ * Resets the state of the action. Called when touch down occurs over the Navigation Bar.
+ */
+ public void reset() {
+ mIsActive = false;
+ }
+
+ /**
+ * Start the gesture and the action will be active
+ * @param event the event that caused the gesture
+ */
+ public void startGesture(MotionEvent event) {
+ mIsActive = true;
+ onGestureStart(event);
+ }
+
+ /**
+ * Gesture has ended with action cancel or up and this action will not be active
+ */
+ public void endGesture() {
+ mIsActive = false;
+ onGestureEnd();
+ }
+
+ /**
+ * If the action is currently active based on the gesture that triggered it. Only one action
+ * can occur at a time
+ * @return whether or not if this action has been triggered
+ */
+ public boolean isActive() {
+ return mIsActive;
+ }
+
+ /**
+ * @return whether or not this action can run if notification shade is shown
+ */
+ public boolean canRunWhenNotificationsShowing() {
+ return true;
+ }
+
+ /**
+ * @return whether or not this action triggers when starting a gesture from a certain hit target
+ * If {@link HIT_TARGET_NONE} is specified then action does not need to be triggered by button
+ */
+ public int requiresTouchDownHitTarget() {
+ return HIT_TARGET_NONE;
+ }
+
+ /**
+ * @return whether or not to move the button that started gesture over with user input drag
+ */
+ public boolean requiresDragWithHitTarget() {
+ return false;
+ }
+
+ /**
+ * Tell if the action is able to execute. Note that {@link #isEnabled()} must be true for this
+ * to be checked. The difference between this and {@link #isEnabled()} is that this dependent
+ * on the state of the navigation bar
+ * @return true if action can execute after gesture activates based on current states
+ */
+ public boolean canPerformAction() {
+ return true;
+ }
+
+ /**
+ * Tell if action is enabled. Compared to {@link #canPerformAction()} this is based on settings
+ * if the action is disabled for a particular gesture. For example a back action can be enabled
+ * however if there is nothing to back to then {@link #canPerformAction()} should return false.
+ * In this way if the action requires {@link #requiresDragWithHitTarget()} then if enabled, the
+ * button can be dragged with a large dampening factor during the gesture but will not activate
+ * the action.
+ * @return true if this action is enabled and can run
+ */
+ public abstract boolean isEnabled();
+
+ protected void onDarkIntensityChange(float intensity) {
+ }
+
+ protected void onDraw(Canvas canvas) {
+ }
+
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ }
+
+ /**
+ * When gesture starts, this will run to execute the action
+ * @param event the event that triggered the gesture
+ */
+ protected abstract void onGestureStart(MotionEvent event);
+
+ /**
+ * Channels motion move events to the action to track the user inputs
+ * @param x the x position
+ * @param y the y position
+ */
+ public void onGestureMove(int x, int y) {
+ }
+
+ /**
+ * When gesture ends, this will run from action up or cancel
+ */
+ protected void onGestureEnd() {
+ }
+
+ protected Context getContext() {
+ return mNavigationBarView.getContext();
+ }
+
+ protected boolean isNavBarVertical() {
+ return mNavigationBarPosition == NAV_BAR_LEFT || mNavigationBarPosition == NAV_BAR_RIGHT;
+ }
+
+ protected boolean getGlobalBoolean(@NonNull String key) {
+ return QuickStepController.getBoolGlobalSetting(getContext(), key);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 8e90f98..184766c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -2,7 +2,6 @@
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
-import android.app.NotificationManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
@@ -190,8 +189,7 @@
return false;
}
if (!showLowPriority
- && mEntryManager.getNotificationData().getImportance(entry.key)
- < NotificationManager.IMPORTANCE_DEFAULT) {
+ && !mEntryManager.getNotificationData().isHighPriority(entry.notification)) {
return false;
}
if (!StatusBar.isTopLevelChild(entry)) {
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 f4c2e27..ecf6b6a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2981,6 +2981,7 @@
}
public void updateNotificationViews() {
+ mNotificationStackScroller.updateSectionBoundaries();
mNotificationStackScroller.updateSpeedBumpIndex();
mNotificationStackScroller.updateFooter();
updateShowEmptyShadeView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
new file mode 100644
index 0000000..c64e124
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static com.android.systemui.Interpolators.ALPHA_IN;
+import static com.android.systemui.Interpolators.ALPHA_OUT;
+import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
+import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.annotation.NonNull;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.os.RemoteException;
+
+import android.util.FloatProperty;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.android.systemui.R;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.recents.utilities.Utilities;
+
+/**
+ * QuickScrub action to send to launcher to start quickscrub gesture
+ */
+public class QuickScrubAction extends NavigationGestureAction {
+ private static final String TAG = "QuickScrubAction";
+
+ private static final float TRACK_SCALE = 0.95f;
+ private static final float GRADIENT_WIDTH = .75f;
+ private static final int ANIM_IN_DURATION_MS = 150;
+ private static final int ANIM_OUT_DURATION_MS = 134;
+
+ private AnimatorSet mTrackAnimator;
+ private View mCurrentNavigationBarView;
+
+ private float mTrackScale = TRACK_SCALE;
+ private float mTrackAlpha;
+ private float mHighlightCenter;
+ private float mDarkIntensity;
+
+ private final int mTrackThickness;
+ private final int mTrackEndPadding;
+ private final Paint mTrackPaint = new Paint();
+ private final Rect mTrackRect = new Rect();
+
+ private final FloatProperty<QuickScrubAction> mTrackAlphaProperty =
+ new FloatProperty<QuickScrubAction>("TrackAlpha") {
+ @Override
+ public void setValue(QuickScrubAction action, float alpha) {
+ mTrackAlpha = alpha;
+ mNavigationBarView.invalidate();
+ }
+
+ @Override
+ public Float get(QuickScrubAction action) {
+ return mTrackAlpha;
+ }
+ };
+
+ private final FloatProperty<QuickScrubAction> mTrackScaleProperty =
+ new FloatProperty<QuickScrubAction>("TrackScale") {
+ @Override
+ public void setValue(QuickScrubAction action, float scale) {
+ mTrackScale = scale;
+ mNavigationBarView.invalidate();
+ }
+
+ @Override
+ public Float get(QuickScrubAction action) {
+ return mTrackScale;
+ }
+ };
+
+ private final FloatProperty<QuickScrubAction> mNavBarAlphaProperty =
+ new FloatProperty<QuickScrubAction>("NavBarAlpha") {
+ @Override
+ public void setValue(QuickScrubAction action, float alpha) {
+ if (mCurrentNavigationBarView != null) {
+ mCurrentNavigationBarView.setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public Float get(QuickScrubAction action) {
+ if (mCurrentNavigationBarView != null) {
+ return mCurrentNavigationBarView.getAlpha();
+ }
+ return 1f;
+ }
+ };
+
+ private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mCurrentNavigationBarView != null) {
+ mCurrentNavigationBarView.setAlpha(1f);
+ }
+ mCurrentNavigationBarView = null;
+ updateHighlight();
+ }
+ };
+
+ public QuickScrubAction(@NonNull NavigationBarView navigationBarView,
+ @NonNull OverviewProxyService service) {
+ super(navigationBarView, service);
+ mTrackPaint.setAntiAlias(true);
+ mTrackPaint.setDither(true);
+
+ final Resources res = navigationBarView.getResources();
+ mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness);
+ mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
+ }
+
+ @Override
+ public void setBarState(boolean changed, int navBarPos, boolean dragHorPositive,
+ boolean dragVerPositive) {
+ super.setBarState(changed, navBarPos, dragHorPositive, dragVerPositive);
+ if (changed && isActive()) {
+ // End quickscrub if the state changes mid-transition
+ endQuickScrub(false /* animate */);
+ }
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+
+ // End any existing quickscrub animations before starting the new transition
+ if (mTrackAnimator != null) {
+ mTrackAnimator.end();
+ mTrackAnimator = null;
+ }
+ mCurrentNavigationBarView = mNavigationBarView.getCurrentView();
+ }
+
+ @Override
+ public void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ final int paddingLeft = mNavigationBarView.getPaddingLeft();
+ final int paddingTop = mNavigationBarView.getPaddingTop();
+ final int paddingRight = mNavigationBarView.getPaddingRight();
+ final int paddingBottom = mNavigationBarView.getPaddingBottom();
+ final int width = (right - left) - paddingRight - paddingLeft;
+ final int height = (bottom - top) - paddingBottom - paddingTop;
+ final int x1, x2, y1, y2;
+ if (isNavBarVertical()) {
+ x1 = (width - mTrackThickness) / 2 + paddingLeft;
+ x2 = x1 + mTrackThickness;
+ y1 = paddingTop + mTrackEndPadding;
+ y2 = y1 + height - 2 * mTrackEndPadding;
+ } else {
+ y1 = (height - mTrackThickness) / 2 + paddingTop;
+ y2 = y1 + mTrackThickness;
+ x1 = mNavigationBarView.getPaddingStart() + mTrackEndPadding;
+ x2 = x1 + width - 2 * mTrackEndPadding;
+ }
+ mTrackRect.set(x1, y1, x2, y2);
+ }
+
+ @Override
+ public void onDarkIntensityChange(float intensity) {
+ mDarkIntensity = intensity;
+ updateHighlight();
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ if (!isEnabled()) {
+ return;
+ }
+ mTrackPaint.setAlpha(Math.round(255f * mTrackAlpha));
+
+ // Scale the track, but apply the inverse scale from the nav bar
+ final float radius = mTrackRect.height() / 2;
+ canvas.save();
+ float translate = Utilities.clamp(mHighlightCenter, mTrackRect.left, mTrackRect.right);
+ canvas.translate(translate, 0);
+ canvas.scale(mTrackScale / mNavigationBarView.getScaleX(),
+ 1f / mNavigationBarView.getScaleY(),
+ mTrackRect.centerX(), mTrackRect.centerY());
+ canvas.drawRoundRect(mTrackRect.left - translate, mTrackRect.top,
+ mTrackRect.right - translate, mTrackRect.bottom, radius, radius, mTrackPaint);
+ canvas.restore();
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return mNavigationBarView.isQuickScrubEnabled();
+ }
+
+ @Override
+ protected void onGestureStart(MotionEvent event) {
+ updateHighlight();
+ ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f),
+ PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f));
+ trackAnimator.setInterpolator(ALPHA_IN);
+ trackAnimator.setDuration(ANIM_IN_DURATION_MS);
+ ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f);
+ navBarAnimator.setInterpolator(ALPHA_OUT);
+ navBarAnimator.setDuration(ANIM_OUT_DURATION_MS);
+ mTrackAnimator = new AnimatorSet();
+ mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
+ mTrackAnimator.start();
+
+ // Disable slippery for quick scrub to not cancel outside the nav bar
+ mNavigationBarView.updateSlippery();
+
+ try {
+ mProxySender.getProxy().onQuickScrubStart();
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Scrub Start");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send start of quick scrub.", e);
+ }
+ mProxySender.notifyQuickScrubStarted();
+ }
+
+ @Override
+ public void onGestureMove(int x, int y) {
+ int trackSize, offset;
+ if (isNavBarVertical()) {
+ trackSize = mTrackRect.height();
+ offset = y - mTrackRect.top;
+ } else {
+ offset = x - mTrackRect.left;
+ trackSize = mTrackRect.width();
+ }
+ if (!mDragHorizontalPositive || !mDragVerticalPositive) {
+ offset -= isNavBarVertical() ? mTrackRect.height() : mTrackRect.width();
+ }
+ float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
+ try {
+ mProxySender.getProxy().onQuickScrubProgress(scrubFraction);
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send progress of quick scrub.", e);
+ }
+ mHighlightCenter = x;
+ mNavigationBarView.invalidate();
+ }
+
+ @Override
+ protected void onGestureEnd() {
+ endQuickScrub(true /* animate */);
+ }
+
+ private void endQuickScrub(boolean animate) {
+ animateEnd();
+ try {
+ mProxySender.getProxy().onQuickScrubEnd();
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Scrub End");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send end of quick scrub.", e);
+ }
+ if (!animate) {
+ if (mTrackAnimator != null) {
+ mTrackAnimator.end();
+ mTrackAnimator = null;
+ }
+ }
+ }
+
+ private void updateHighlight() {
+ if (mTrackRect.isEmpty()) {
+ return;
+ }
+ int colorBase, colorGrad;
+ if (mDarkIntensity > 0.5f) {
+ colorBase = getContext().getColor(R.color.quick_step_track_background_background_dark);
+ colorGrad = getContext().getColor(R.color.quick_step_track_background_foreground_dark);
+ } else {
+ colorBase = getContext().getColor(R.color.quick_step_track_background_background_light);
+ colorGrad = getContext().getColor(R.color.quick_step_track_background_foreground_light);
+ }
+ final RadialGradient mHighlight = new RadialGradient(0, mTrackRect.height() / 2,
+ mTrackRect.width() * GRADIENT_WIDTH, colorGrad, colorBase,
+ Shader.TileMode.CLAMP);
+ mTrackPaint.setShader(mHighlight);
+ }
+
+ private void animateEnd() {
+ if (mTrackAnimator != null) {
+ mTrackAnimator.cancel();
+ }
+
+ ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f),
+ PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE));
+ trackAnimator.setInterpolator(ALPHA_OUT);
+ trackAnimator.setDuration(ANIM_OUT_DURATION_MS);
+ ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f);
+ navBarAnimator.setInterpolator(ALPHA_IN);
+ navBarAnimator.setDuration(ANIM_IN_DURATION_MS);
+ mTrackAnimator = new AnimatorSet();
+ mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
+ mTrackAnimator.addListener(mQuickScrubEndListener);
+ mTrackAnimator.start();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java
new file mode 100644
index 0000000..b18b79e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
+import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
+
+import android.annotation.NonNull;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import com.android.systemui.recents.OverviewProxyService;
+
+/**
+ * QuickStep action to send to launcher to start overview
+ */
+public class QuickStepAction extends NavigationGestureAction {
+ private static final String TAG = "QuickStepAction";
+
+ public QuickStepAction(@NonNull NavigationBarView navigationBarView,
+ @NonNull OverviewProxyService service) {
+ super(navigationBarView, service);
+ }
+
+ @Override
+ public boolean canRunWhenNotificationsShowing() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return mNavigationBarView.isQuickStepSwipeUpEnabled();
+ }
+
+ @Override
+ public void onGestureStart(MotionEvent event) {
+ try {
+ mProxySender.getProxy().onQuickStep(event);
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Step Start");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send quick step started.", e);
+ }
+ mProxySender.notifyQuickStepStarted();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 3980126..37c4c58a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -18,187 +18,99 @@
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static com.android.systemui.Interpolators.ALPHA_IN;
-import static com.android.systemui.Interpolators.ALPHA_OUT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+
import static com.android.systemui.recents.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
import static com.android.systemui.recents.OverviewProxyService.TAG_OPS;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.RadialGradient;
-import android.graphics.Rect;
-import android.graphics.Shader;
-import android.hardware.input.InputManager;
-import android.os.Handler;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.provider.Settings;
-import android.util.FloatProperty;
import android.util.Log;
-import android.util.Slog;
-import android.view.HapticFeedbackConstants;
-import android.view.InputDevice;
-import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
-import android.view.WindowManagerGlobal;
+
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
-import com.android.systemui.recents.OverviewProxyService;
-import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
+import com.android.systemui.R;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.system.NavigationBarCompat;
+
import java.io.PrintWriter;
/**
* Class to detect gestures on the navigation bar and implement quick scrub.
+ * Note that the variables in this class horizontal and vertical represents horizontal always
+ * aligned with along the navigation bar.
*/
public class QuickStepController implements GestureHelper {
private static final String TAG = "QuickStepController";
- private static final int ANIM_IN_DURATION_MS = 150;
- private static final int ANIM_OUT_DURATION_MS = 134;
- private static final float TRACK_SCALE = 0.95f;
- private static final float GRADIENT_WIDTH = .75f;
/** Experiment to swipe home button left to execute a back key press */
- private static final String PULL_HOME_GO_BACK_PROP = "quickstepcontroller_homegoesback";
private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
- private static final String BACK_AFTER_END_PROP
- = "quickstepcontroller_homegoesbackwhenend";
- private static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled";
- private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60;
private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
- private static final long BACK_GESTURE_POLL_TIMEOUT = 1000;
/** When the home-swipe-back gesture is disallowed, make it harder to pull */
- private static final float DISALLOW_GESTURE_DAMPING_FACTOR = 0.16f;
+ private static final float HORIZONTAL_GESTURE_DAMPING = 0.3f;
+ private static final float VERTICAL_GESTURE_DAMPING = 0.15f;
+ private static final float HORIZONTAL_DISABLED_GESTURE_DAMPING = 0.16f;
+ private static final float VERTICAL_DISABLED_GESTURE_DAMPING = 0.06f;
+
+ private static final int ACTION_SWIPE_UP_INDEX = 0;
+ private static final int ACTION_SWIPE_DOWN_INDEX = 1;
+ private static final int ACTION_SWIPE_LEFT_INDEX = 2;
+ private static final int ACTION_SWIPE_RIGHT_INDEX = 3;
+ private static final int MAX_GESTURES = 4;
private NavigationBarView mNavigationBarView;
- private boolean mQuickScrubActive;
private boolean mAllowGestureDetection;
- private boolean mBackGestureActive;
- private boolean mCanPerformBack;
- private boolean mQuickStepStarted;
private boolean mNotificationsVisibleOnDown;
private int mTouchDownX;
private int mTouchDownY;
- private boolean mDragPositive;
- private boolean mIsVertical;
+ private boolean mDragHPositive;
+ private boolean mDragVPositive;
private boolean mIsRTL;
- private float mTrackAlpha;
- private float mTrackScale = TRACK_SCALE;
+ private int mNavBarPosition;
private float mDarkIntensity;
- private RadialGradient mHighlight;
- private float mHighlightCenter;
- private AnimatorSet mTrackAnimator;
- private ViewPropertyAnimator mHomeAnimator;
+ private ViewPropertyAnimator mDragBtnAnimator;
private ButtonDispatcher mHitTarget;
- private View mCurrentNavigationBarView;
private boolean mIsInScreenPinning;
+ private boolean mGestureHorizontalDragsButton;
+ private boolean mGestureVerticalDragsButton;
+ private float mMaxDragLimit;
+ private float mMinDragLimit;
+ private float mDragDampeningFactor;
- private final Handler mHandler = new Handler();
- private final Rect mTrackRect = new Rect();
+ private NavigationGestureAction mCurrentAction;
+ private NavigationGestureAction[] mGestureActions = new NavigationGestureAction[MAX_GESTURES];
+
private final OverviewProxyService mOverviewEventSender;
- private final int mTrackThickness;
- private final int mTrackEndPadding;
- private final int mHomeBackGestureDragLimit;
private final Context mContext;
private final StatusBar mStatusBar;
private final Matrix mTransformGlobalMatrix = new Matrix();
private final Matrix mTransformLocalMatrix = new Matrix();
- private final Paint mTrackPaint = new Paint();
-
- private final FloatProperty<QuickStepController> mTrackAlphaProperty =
- new FloatProperty<QuickStepController>("TrackAlpha") {
- @Override
- public void setValue(QuickStepController controller, float alpha) {
- mTrackAlpha = alpha;
- mNavigationBarView.invalidate();
- }
-
- @Override
- public Float get(QuickStepController controller) {
- return mTrackAlpha;
- }
- };
-
- private final FloatProperty<QuickStepController> mTrackScaleProperty =
- new FloatProperty<QuickStepController>("TrackScale") {
- @Override
- public void setValue(QuickStepController controller, float scale) {
- mTrackScale = scale;
- mNavigationBarView.invalidate();
- }
-
- @Override
- public Float get(QuickStepController controller) {
- return mTrackScale;
- }
- };
-
- private final FloatProperty<QuickStepController> mNavBarAlphaProperty =
- new FloatProperty<QuickStepController>("NavBarAlpha") {
- @Override
- public void setValue(QuickStepController controller, float alpha) {
- if (mCurrentNavigationBarView != null) {
- mCurrentNavigationBarView.setAlpha(alpha);
- }
- }
-
- @Override
- public Float get(QuickStepController controller) {
- if (mCurrentNavigationBarView != null) {
- return mCurrentNavigationBarView.getAlpha();
- }
- return 1f;
- }
- };
-
- private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- resetQuickScrub();
- }
- };
-
- private final Runnable mExecuteBackRunnable = new Runnable() {
- @Override
- public void run() {
- if (canPerformHomeBackGesture()) {
- performBack();
- mHandler.postDelayed(this, BACK_GESTURE_POLL_TIMEOUT);
- }
- }
- };
public QuickStepController(Context context) {
final Resources res = context.getResources();
mContext = context;
mStatusBar = SysUiServiceProvider.getComponent(context, StatusBar.class);
mOverviewEventSender = Dependency.get(OverviewProxyService.class);
- mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness);
- mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
- mHomeBackGestureDragLimit =
- res.getDimensionPixelSize(R.dimen.nav_home_back_gesture_drag_limit);
- mTrackPaint.setAntiAlias(true);
- mTrackPaint.setDither(true);
}
public void setComponents(NavigationBarView navigationBarView) {
@@ -210,6 +122,31 @@
}
/**
+ * Set each gesture an action. After set the gestures triggered will run the actions attached.
+ * @param swipeUpAction action after swiping up
+ * @param swipeDownAction action after swiping down
+ * @param swipeLeftAction action after swiping left
+ * @param swipeRightAction action after swiping right
+ */
+ public void setGestureActions(@Nullable NavigationGestureAction swipeUpAction,
+ @Nullable NavigationGestureAction swipeDownAction,
+ @Nullable NavigationGestureAction swipeLeftAction,
+ @Nullable NavigationGestureAction swipeRightAction) {
+ mGestureActions[ACTION_SWIPE_UP_INDEX] = swipeUpAction;
+ mGestureActions[ACTION_SWIPE_DOWN_INDEX] = swipeDownAction;
+ mGestureActions[ACTION_SWIPE_LEFT_INDEX] = swipeLeftAction;
+ mGestureActions[ACTION_SWIPE_RIGHT_INDEX] = swipeRightAction;
+
+ // Set the current state to all actions
+ for (NavigationGestureAction action: mGestureActions) {
+ if (action != null) {
+ action.setBarState(true, mNavBarPosition, mDragHPositive, mDragVPositive);
+ action.onDarkIntensityChange(mDarkIntensity);
+ }
+ }
+ }
+
+ /**
* @return true if we want to intercept touch events for quick scrub and prevent proxying the
* event to the overview service.
*/
@@ -242,8 +179,10 @@
private boolean handleTouchEvent(MotionEvent event) {
final boolean deadZoneConsumed =
mNavigationBarView.getDownHitTarget() == HIT_TARGET_DEAD_ZONE;
- if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled()
- && !mNavigationBarView.isQuickStepSwipeUpEnabled())) {
+
+ // Requires proxy and an active gesture or able to perform any gesture to continue
+ if (mOverviewEventSender.getProxy() == null
+ || (mCurrentAction == null && !canPerformAnyAction())) {
return deadZoneConsumed;
}
mNavigationBarView.requestUnbufferedDispatch(event);
@@ -255,33 +194,45 @@
int y = (int) event.getY();
mIsInScreenPinning = mNavigationBarView.inScreenPinning();
- // End any existing quickscrub animations before starting the new transition
- if (mTrackAnimator != null) {
- mTrackAnimator.end();
- mTrackAnimator = null;
+ for (NavigationGestureAction gestureAction: mGestureActions) {
+ if (gestureAction != null) {
+ gestureAction.reset();
+ }
}
- mCurrentNavigationBarView = mNavigationBarView.getCurrentView();
- mHitTarget = mNavigationBarView.getButtonAtPosition(x, y);
+ // Valid buttons to drag over
+ switch (mNavigationBarView.getDownHitTarget()) {
+ case HIT_TARGET_BACK:
+ mHitTarget = mNavigationBarView.getBackButton();
+ break;
+ case HIT_TARGET_HOME:
+ mHitTarget = mNavigationBarView.getHomeButton();
+ break;
+ case HIT_TARGET_OVERVIEW:
+ mHitTarget = mNavigationBarView.getRecentsButton();
+ break;
+ default:
+ mHitTarget = null;
+ break;
+ }
if (mHitTarget != null) {
// Pre-emptively delay the touch feedback for the button that we just touched
mHitTarget.setDelayTouchFeedback(true);
}
mTouchDownX = x;
mTouchDownY = y;
+ mGestureHorizontalDragsButton = false;
+ mGestureVerticalDragsButton = false;
mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
mTransformLocalMatrix.set(Matrix.IDENTITY_MATRIX);
mNavigationBarView.transformMatrixToGlobal(mTransformGlobalMatrix);
mNavigationBarView.transformMatrixToLocal(mTransformLocalMatrix);
- mQuickStepStarted = false;
- mBackGestureActive = false;
mAllowGestureDetection = true;
mNotificationsVisibleOnDown = !mNavigationBarView.isNotificationsFullyCollapsed();
- mCanPerformBack = canPerformHomeBackGesture();
break;
}
case MotionEvent.ACTION_MOVE: {
- if (mQuickStepStarted || !mAllowGestureDetection){
+ if (!mAllowGestureDetection) {
break;
}
int x = (int) event.getX();
@@ -289,108 +240,120 @@
int xDiff = Math.abs(x - mTouchDownX);
int yDiff = Math.abs(y - mTouchDownY);
- boolean exceededScrubTouchSlop, exceededSwipeUpTouchSlop;
- int pos, touchDown, offset, trackSize;
+ boolean exceededSwipeHorizontalTouchSlop, exceededSwipeVerticalTouchSlop;
+ int posH, touchDownH, posV, touchDownV;
- if (mIsVertical) {
- exceededScrubTouchSlop =
+ if (isNavBarVertical()) {
+ exceededSwipeHorizontalTouchSlop =
yDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && yDiff > xDiff;
- exceededSwipeUpTouchSlop =
+ exceededSwipeVerticalTouchSlop =
xDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && xDiff > yDiff;
- pos = y;
- touchDown = mTouchDownY;
- offset = pos - mTrackRect.top;
- trackSize = mTrackRect.height();
+ posH = y;
+ touchDownH = mTouchDownY;
+ posV = x;
+ touchDownV = mTouchDownX;
} else {
- exceededScrubTouchSlop =
+ exceededSwipeHorizontalTouchSlop =
xDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && xDiff > yDiff;
- exceededSwipeUpTouchSlop =
+ exceededSwipeVerticalTouchSlop =
yDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && yDiff > xDiff;
- pos = x;
- touchDown = mTouchDownX;
- offset = pos - mTrackRect.left;
- trackSize = mTrackRect.width();
- }
- // Decide to start quickstep if dragging away from the navigation bar, otherwise in
- // the parallel direction, decide to start quickscrub. Only one may run.
- if (!mBackGestureActive && !mQuickScrubActive && exceededSwipeUpTouchSlop) {
- if (mNavigationBarView.isQuickStepSwipeUpEnabled()
- && !mNotificationsVisibleOnDown) {
- startQuickStep(event);
- }
- break;
+ posH = x;
+ touchDownH = mTouchDownX;
+ posV = y;
+ touchDownV = mTouchDownY;
}
- // Do not handle quick scrub if disabled
- if (!mNavigationBarView.isQuickScrubEnabled()) {
- break;
- }
-
- if (!mDragPositive) {
- offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
- }
-
- final boolean allowDrag = !mDragPositive
- ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
- float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
- if (!mQuickScrubActive && !mBackGestureActive && exceededScrubTouchSlop) {
- // Passing the drag slop then touch slop will start quick step
- if (allowDrag) {
- startQuickScrub();
- } else if (swipeHomeGoBackGestureEnabled(mContext)
- && mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME
- && mDragPositive ? pos < touchDown : pos > touchDown) {
- startBackGesture();
- }
- }
-
- if (mQuickScrubActive && (mDragPositive && offset >= 0
- || !mDragPositive && offset <= 0)) {
- try {
- mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
+ if (mCurrentAction != null) {
+ // Gesture started, provide positions to the current action
+ mCurrentAction.onGestureMove(x, y);
+ } else {
+ // Detect gesture and try to execute an action, only one can run at a time
+ if (exceededSwipeVerticalTouchSlop) {
+ if (mDragVPositive ? (posV < touchDownV) : (posV > touchDownV)) {
+ // Swiping up gesture
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_UP_INDEX],
+ false /* alignedWithNavBar */, false /* positiveDirection */,
+ event);
+ } else {
+ // Swiping down gesture
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_DOWN_INDEX],
+ false /* alignedWithNavBar */, true /* positiveDirection */,
+ event);
}
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send progress of quick scrub.", e);
- }
- mHighlightCenter = x;
- mNavigationBarView.invalidate();
- } else if (mBackGestureActive) {
- int diff = pos - touchDown;
- // If dragging the incorrect direction after starting back gesture or unable
- // to execute back functionality, then move home but dampen its distance
- if (!mCanPerformBack || (mDragPositive ? diff > 0 : diff < 0)) {
- diff *= DISALLOW_GESTURE_DAMPING_FACTOR;
- } if (Math.abs(diff) > mHomeBackGestureDragLimit) {
- // Once the user drags the home button past a certain limit, the distance
- // will lessen as the home button dampens showing that it was pulled too far
- float distanceAfterDragLimit = (Math.abs(diff) - mHomeBackGestureDragLimit)
- * DISALLOW_GESTURE_DAMPING_FACTOR;
- diff = (int)(distanceAfterDragLimit + mHomeBackGestureDragLimit);
- if (mDragPositive) {
- diff *= -1;
+ } else if (exceededSwipeHorizontalTouchSlop) {
+ if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
+ // Swiping left (ltr) gesture
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
+ true /* alignedWithNavBar */, false /* positiveDirection */,
+ event);
+ } else {
+ // Swiping right (ltr) gesture
+ tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
+ true /* alignedWithNavBar */, true /* positiveDirection */,
+ event);
}
}
- moveHomeButton(diff);
}
+
+ handleDragHitTarget(mGestureHorizontalDragsButton ? posH : posV,
+ mGestureHorizontalDragsButton ? touchDownH : touchDownV);
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- endQuickScrub(true /* animate */);
- endBackGesture();
+ if (mCurrentAction != null) {
+ mCurrentAction.endGesture();
+ mCurrentAction = null;
+ }
+
+ // Return the hit target back to its original position
+ if (mHitTarget != null) {
+ final View button = mHitTarget.getCurrentView();
+ if (mGestureHorizontalDragsButton || mGestureVerticalDragsButton) {
+ mDragBtnAnimator = button.animate().setDuration(BACK_BUTTON_FADE_IN_ALPHA)
+ .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ if (mGestureVerticalDragsButton ^ isNavBarVertical()) {
+ mDragBtnAnimator.translationY(0);
+ } else {
+ mDragBtnAnimator.translationX(0);
+ }
+ mDragBtnAnimator.start();
+ }
+ }
break;
}
if (shouldProxyEvents(action)) {
proxyMotionEvents(event);
}
- return mBackGestureActive || mQuickScrubActive || mQuickStepStarted || deadZoneConsumed;
+ return mCurrentAction != null || deadZoneConsumed;
+ }
+
+ private void handleDragHitTarget(int position, int touchDown) {
+ // Drag the hit target if gesture action requires it
+ if (mHitTarget != null && (mGestureVerticalDragsButton || mGestureHorizontalDragsButton)) {
+ final View button = mHitTarget.getCurrentView();
+ if (mDragBtnAnimator != null) {
+ mDragBtnAnimator.cancel();
+ mDragBtnAnimator = null;
+ }
+
+ // Clamp drag to the bounding box of the navigation bar
+ float diff = (position - touchDown) * mDragDampeningFactor;
+ diff = Utilities.clamp(diff, mMinDragLimit, mMaxDragLimit);
+ if (mGestureVerticalDragsButton ^ isNavBarVertical()) {
+ button.setTranslationY(diff);
+ } else {
+ button.setTranslationX(diff);
+ }
+ }
}
private boolean shouldProxyEvents(int action) {
- if (!mBackGestureActive && !mQuickScrubActive && !mIsInScreenPinning) {
+ final boolean actionValid = (mCurrentAction == null
+ || (mGestureActions[ACTION_SWIPE_UP_INDEX] != null
+ && mGestureActions[ACTION_SWIPE_UP_INDEX].isActive()));
+ if (actionValid && !mIsInScreenPinning) {
// Allow down, cancel and up events, move and other events are passed if notifications
// are not showing and disabled gestures (such as long press) are not executed
switch (action) {
@@ -407,46 +370,18 @@
@Override
public void onDraw(Canvas canvas) {
- if (!mNavigationBarView.isQuickScrubEnabled()) {
- return;
+ if (mCurrentAction != null) {
+ mCurrentAction.onDraw(canvas);
}
- mTrackPaint.setAlpha(Math.round(255f * mTrackAlpha));
-
- // Scale the track, but apply the inverse scale from the nav bar
- final float radius = mTrackRect.height() / 2;
- canvas.save();
- float translate = Utilities.clamp(mHighlightCenter, mTrackRect.left, mTrackRect.right);
- canvas.translate(translate, 0);
- canvas.scale(mTrackScale / mNavigationBarView.getScaleX(),
- 1f / mNavigationBarView.getScaleY(),
- mTrackRect.centerX(), mTrackRect.centerY());
- canvas.drawRoundRect(mTrackRect.left - translate, mTrackRect.top,
- mTrackRect.right - translate, mTrackRect.bottom, radius, radius, mTrackPaint);
- canvas.restore();
}
@Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final int paddingLeft = mNavigationBarView.getPaddingLeft();
- final int paddingTop = mNavigationBarView.getPaddingTop();
- final int paddingRight = mNavigationBarView.getPaddingRight();
- final int paddingBottom = mNavigationBarView.getPaddingBottom();
- final int width = (right - left) - paddingRight - paddingLeft;
- final int height = (bottom - top) - paddingBottom - paddingTop;
- final int x1, x2, y1, y2;
- if (mIsVertical) {
- x1 = (width - mTrackThickness) / 2 + paddingLeft;
- x2 = x1 + mTrackThickness;
- y1 = paddingTop + mTrackEndPadding;
- y2 = y1 + height - 2 * mTrackEndPadding;
- } else {
- y1 = (height - mTrackThickness) / 2 + paddingTop;
- y2 = y1 + mTrackThickness;
- x1 = mNavigationBarView.getPaddingStart() + mTrackEndPadding;
- x2 = x1 + width - 2 * mTrackEndPadding;
+ for (NavigationGestureAction action: mGestureActions) {
+ if (action != null) {
+ action.onLayout(changed, left, top, right, bottom);
+ }
}
- mTrackRect.set(x1, y1, x2, y2);
- updateHighlight();
}
@Override
@@ -456,119 +391,126 @@
// When in quick scrub, invalidate gradient if changing intensity from black to white and
// vice-versa
- if (mNavigationBarView.isQuickScrubEnabled()
+ if (mCurrentAction != null && mNavigationBarView.isQuickScrubEnabled()
&& Math.round(intensity) != Math.round(oldIntensity)) {
- updateHighlight();
+ mCurrentAction.onDarkIntensityChange(mDarkIntensity);
}
mNavigationBarView.invalidate();
}
@Override
- public void setBarState(boolean isVertical, boolean isRTL) {
- final boolean changed = (mIsVertical != isVertical) || (mIsRTL != isRTL);
- if (changed) {
- // End quickscrub if the state changes mid-transition
- endQuickScrub(false /* animate */);
- }
- mIsVertical = isVertical;
+ public void setBarState(boolean isRTL, int navBarPosition) {
+ final boolean changed = (mIsRTL != isRTL) || (mNavBarPosition != navBarPosition);
mIsRTL = isRTL;
- try {
- int navbarPos = WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
- mDragPositive = navbarPos == NAV_BAR_LEFT || navbarPos == NAV_BAR_BOTTOM;
- if (isRTL) {
- mDragPositive = !mDragPositive;
+ mNavBarPosition = navBarPosition;
+
+ // Determine the drag directions depending on location of nav bar
+ switch (navBarPosition) {
+ case NAV_BAR_LEFT:
+ mDragHPositive = !isRTL;
+ mDragVPositive = false;
+ break;
+ case NAV_BAR_RIGHT:
+ mDragHPositive = isRTL;
+ mDragVPositive = true;
+ break;
+ case NAV_BAR_BOTTOM:
+ mDragHPositive = !isRTL;
+ mDragVPositive = true;
+ break;
+ }
+
+ for (NavigationGestureAction action: mGestureActions) {
+ if (action != null) {
+ action.setBarState(changed, mNavBarPosition, mDragHPositive, mDragVPositive);
}
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to get nav bar position.", e);
}
}
@Override
public void onNavigationButtonLongPress(View v) {
mAllowGestureDetection = false;
- mHandler.removeCallbacksAndMessages(null);
}
@Override
public void dump(PrintWriter pw) {
pw.println("QuickStepController {");
- pw.print(" "); pw.println("mQuickScrubActive=" + mQuickScrubActive);
- pw.print(" "); pw.println("mQuickStepStarted=" + mQuickStepStarted);
pw.print(" "); pw.println("mAllowGestureDetection=" + mAllowGestureDetection);
- pw.print(" "); pw.println("mBackGestureActive=" + mBackGestureActive);
- pw.print(" "); pw.println("mCanPerformBack=" + mCanPerformBack);
pw.print(" "); pw.println("mNotificationsVisibleOnDown=" + mNotificationsVisibleOnDown);
- pw.print(" "); pw.println("mIsVertical=" + mIsVertical);
+ pw.print(" "); pw.println("mNavBarPosition=" + mNavBarPosition);
pw.print(" "); pw.println("mIsRTL=" + mIsRTL);
pw.print(" "); pw.println("mIsInScreenPinning=" + mIsInScreenPinning);
pw.println("}");
}
- private void startQuickStep(MotionEvent event) {
- if (mIsInScreenPinning) {
- mNavigationBarView.showPinningEscapeToast();
- mAllowGestureDetection = false;
- return;
- }
-
- mQuickStepStarted = true;
- event.transform(mTransformGlobalMatrix);
- try {
- mOverviewEventSender.getProxy().onQuickStep(event);
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Step Start");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send quick step started.", e);
- } finally {
- event.transform(mTransformLocalMatrix);
- }
- mOverviewEventSender.notifyQuickStepStarted();
- mHandler.removeCallbacksAndMessages(null);
-
- if (mHitTarget != null) {
- mHitTarget.abortCurrentGesture();
- }
-
- if (mQuickScrubActive) {
- animateEnd();
- }
+ public NavigationGestureAction getCurrentAction() {
+ return mCurrentAction;
}
- private void startQuickScrub() {
+ private void tryToStartGesture(NavigationGestureAction action, boolean alignedWithNavBar,
+ boolean positiveDirection, MotionEvent event) {
+ if (action == null) {
+ return;
+ }
if (mIsInScreenPinning) {
mNavigationBarView.showPinningEscapeToast();
mAllowGestureDetection = false;
return;
}
- if (!mQuickScrubActive) {
- updateHighlight();
- mQuickScrubActive = true;
- ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
- PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f),
- PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f));
- trackAnimator.setInterpolator(ALPHA_IN);
- trackAnimator.setDuration(ANIM_IN_DURATION_MS);
- ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f);
- navBarAnimator.setInterpolator(ALPHA_OUT);
- navBarAnimator.setDuration(ANIM_OUT_DURATION_MS);
- mTrackAnimator = new AnimatorSet();
- mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
- mTrackAnimator.start();
+ // Start new action from gesture if is able to start and depending on notifications
+ // visibility and starting touch down target. If the action is enabled, then also check if
+ // can perform the action so that if action requires the button to be dragged, then the
+ // gesture will have a large dampening factor and prevent action from running.
+ final boolean validHitTarget = action.requiresTouchDownHitTarget() == HIT_TARGET_NONE
+ || action.requiresTouchDownHitTarget() == mNavigationBarView.getDownHitTarget();
+ if (mCurrentAction == null && validHitTarget && action.isEnabled()
+ && (!mNotificationsVisibleOnDown || action.canRunWhenNotificationsShowing())) {
+ if (action.canPerformAction()) {
+ mCurrentAction = action;
+ event.transform(mTransformGlobalMatrix);
+ action.startGesture(event);
+ event.transform(mTransformLocalMatrix);
- // Disable slippery for quick scrub to not cancel outside the nav bar
- mNavigationBarView.updateSlippery();
+ // Calculate the bounding limits of drag to avoid dragging off nav bar's window
+ if (action.requiresDragWithHitTarget() && mHitTarget != null) {
+ final int[] buttonCenter = new int[2];
+ View button = mHitTarget.getCurrentView();
+ button.getLocationInWindow(buttonCenter);
+ buttonCenter[0] += button.getWidth() / 2;
+ buttonCenter[1] += button.getHeight() / 2;
+ final int x = isNavBarVertical() ? buttonCenter[1] : buttonCenter[0];
+ final int y = isNavBarVertical() ? buttonCenter[0] : buttonCenter[1];
+ final int iconHalfSize = mContext.getResources()
+ .getDimensionPixelSize(R.dimen.navigation_icon_size) / 2;
- try {
- mOverviewEventSender.getProxy().onQuickScrubStart();
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Scrub Start");
+ if (alignedWithNavBar) {
+ mMinDragLimit = iconHalfSize - x;
+ mMaxDragLimit = -x - iconHalfSize + (isNavBarVertical()
+ ? mNavigationBarView.getHeight() : mNavigationBarView.getWidth());
+ } else {
+ mMinDragLimit = iconHalfSize - y;
+ mMaxDragLimit = -y - iconHalfSize + (isNavBarVertical()
+ ? mNavigationBarView.getWidth() : mNavigationBarView.getHeight());
+ }
}
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send start of quick scrub.", e);
}
- mOverviewEventSender.notifyQuickScrubStarted();
+
+ // Handle direction of the hit target drag from the axis that started the gesture
+ // Also calculate the dampening factor, weaker dampening if there is an active action
+ if (action.requiresDragWithHitTarget()) {
+ if (alignedWithNavBar) {
+ mGestureHorizontalDragsButton = true;
+ mGestureVerticalDragsButton = false;
+ mDragDampeningFactor = action.isActive()
+ ? HORIZONTAL_GESTURE_DAMPING : HORIZONTAL_DISABLED_GESTURE_DAMPING;
+ } else {
+ mGestureVerticalDragsButton = true;
+ mGestureHorizontalDragsButton = false;
+ mDragDampeningFactor = action.isActive()
+ ? VERTICAL_GESTURE_DAMPING : VERTICAL_DISABLED_GESTURE_DAMPING;
+ }
+ }
if (mHitTarget != null) {
mHitTarget.abortCurrentGesture();
@@ -576,148 +518,13 @@
}
}
- private void endQuickScrub(boolean animate) {
- if (mQuickScrubActive) {
- animateEnd();
- try {
- mOverviewEventSender.getProxy().onQuickScrubEnd();
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Scrub End");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send end of quick scrub.", e);
+ private boolean canPerformAnyAction() {
+ for (NavigationGestureAction action: mGestureActions) {
+ if (action != null && action.isEnabled()) {
+ return true;
}
}
- if (!animate) {
- if (mTrackAnimator != null) {
- mTrackAnimator.end();
- mTrackAnimator = null;
- }
- }
- }
-
- private void startBackGesture() {
- if (!mBackGestureActive) {
- mBackGestureActive = true;
- mNavigationBarView.getHomeButton().abortCurrentGesture();
- final boolean runBackMidGesture = !shouldExecuteBackOnUp(mContext);
- if (mCanPerformBack) {
- if (!shouldhideBackButton(mContext)) {
- mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
- BACK_BUTTON_FADE_OUT_ALPHA);
- }
- if (runBackMidGesture) {
- performBack();
- }
- }
- mHandler.removeCallbacks(mExecuteBackRunnable);
- if (runBackMidGesture) {
- mHandler.postDelayed(mExecuteBackRunnable, BACK_GESTURE_POLL_TIMEOUT);
- }
- }
- }
-
- private void endBackGesture() {
- if (mBackGestureActive) {
- mHandler.removeCallbacks(mExecuteBackRunnable);
- mHomeAnimator = mNavigationBarView.getHomeButton().getCurrentView()
- .animate()
- .setDuration(BACK_BUTTON_FADE_IN_ALPHA)
- .setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
- if (mIsVertical) {
- mHomeAnimator.translationY(0);
- } else {
- mHomeAnimator.translationX(0);
- }
- mHomeAnimator.start();
- if (!shouldhideBackButton(mContext)) {
- mNavigationBarView.getBackButton().setAlpha(
- mOverviewEventSender.getBackButtonAlpha(), true /* animate */);
- }
- if (shouldExecuteBackOnUp(mContext)) {
- performBack();
- }
- }
- }
-
- private void animateEnd() {
- if (mTrackAnimator != null) {
- mTrackAnimator.cancel();
- }
-
- ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
- PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f),
- PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE));
- trackAnimator.setInterpolator(ALPHA_OUT);
- trackAnimator.setDuration(ANIM_OUT_DURATION_MS);
- ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f);
- navBarAnimator.setInterpolator(ALPHA_IN);
- navBarAnimator.setDuration(ANIM_IN_DURATION_MS);
- mTrackAnimator = new AnimatorSet();
- mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
- mTrackAnimator.addListener(mQuickScrubEndListener);
- mTrackAnimator.start();
- }
-
- private void resetQuickScrub() {
- mQuickScrubActive = false;
- mAllowGestureDetection = false;
- if (mCurrentNavigationBarView != null) {
- mCurrentNavigationBarView.setAlpha(1f);
- }
- mCurrentNavigationBarView = null;
- updateHighlight();
- }
-
- private void moveHomeButton(float pos) {
- if (mHomeAnimator != null) {
- mHomeAnimator.cancel();
- mHomeAnimator = null;
- }
- final View homeButton = mNavigationBarView.getHomeButton().getCurrentView();
- if (mIsVertical) {
- homeButton.setTranslationY(pos);
- } else {
- homeButton.setTranslationX(pos);
- }
- }
-
- private void updateHighlight() {
- if (mTrackRect.isEmpty()) {
- return;
- }
- int colorBase, colorGrad;
- if (mDarkIntensity > 0.5f) {
- colorBase = mContext.getColor(R.color.quick_step_track_background_background_dark);
- colorGrad = mContext.getColor(R.color.quick_step_track_background_foreground_dark);
- } else {
- colorBase = mContext.getColor(R.color.quick_step_track_background_background_light);
- colorGrad = mContext.getColor(R.color.quick_step_track_background_foreground_light);
- }
- mHighlight = new RadialGradient(0, mTrackRect.height() / 2,
- mTrackRect.width() * GRADIENT_WIDTH, colorGrad, colorBase,
- Shader.TileMode.CLAMP);
- mTrackPaint.setShader(mHighlight);
- }
-
- private boolean canPerformHomeBackGesture() {
- return swipeHomeGoBackGestureEnabled(mContext)
- && mOverviewEventSender.getBackButtonAlpha() > 0;
- }
-
- private void performBack() {
- sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
- sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
- mNavigationBarView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
- }
-
- private void sendEvent(int action, int code) {
- long when = SystemClock.uptimeMillis();
- final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */,
- 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */,
- KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
- InputDevice.SOURCE_KEYBOARD);
- InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
+ return false;
}
private boolean proxyMotionEvents(MotionEvent event) {
@@ -740,22 +547,15 @@
return false;
}
- private static boolean getBoolGlobalSetting(Context context, String key) {
+ protected boolean isNavBarVertical() {
+ return mNavBarPosition == NAV_BAR_LEFT || mNavBarPosition == NAV_BAR_RIGHT;
+ }
+
+ static boolean getBoolGlobalSetting(Context context, String key) {
return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
}
- public static boolean swipeHomeGoBackGestureEnabled(Context context) {
- return !getBoolGlobalSetting(context, NAVBAR_EXPERIMENTS_DISABLED)
- && getBoolGlobalSetting(context, PULL_HOME_GO_BACK_PROP);
- }
-
public static boolean shouldhideBackButton(Context context) {
- return swipeHomeGoBackGestureEnabled(context)
- && getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
- }
-
- public static boolean shouldExecuteBackOnUp(Context context) {
- return !getBoolGlobalSetting(context, NAVBAR_EXPERIMENTS_DISABLED)
- && getBoolGlobalSetting(context, BACK_AFTER_END_PROP);
+ return getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 966a346..12fbf2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -22,7 +22,6 @@
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -72,7 +71,6 @@
import android.graphics.PointF;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
-import android.hardware.display.DisplayManager.DisplayListener;
import android.media.AudioAttributes;
import android.metrics.LogMaker;
import android.net.Uri;
@@ -99,7 +97,6 @@
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
-import android.util.SparseArray;
import android.view.Display;
import android.view.IWindowManager;
import android.view.KeyEvent;
@@ -172,6 +169,7 @@
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
+import com.android.systemui.statusbar.DisplayNavigationBarController;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyboardShortcuts;
@@ -567,32 +565,6 @@
private NavigationBarFragment mNavigationBar;
private View mNavigationBarView;
- /** A displayId - nav bar mapping */
- private SparseArray<NavigationBarFragment> mExternalNavigationBarMap = new SparseArray<>();
-
- // TODO(b/115978725): Move it to DisplayNavigationBarController
- private final DisplayListener mDisplayListener = new DisplayListener() {
- @Override
- public void onDisplayAdded(int displayId) {
- final Display display = mDisplayManager.getDisplay(displayId);
- addExternalNavigationBar(display);
- }
-
- @Override
- public void onDisplayRemoved(int displayId) {
- final NavigationBarFragment navBar = mExternalNavigationBarMap.get(displayId);
- if (navBar != null) {
- final View navigationView = navBar.getView().getRootView();
- WindowManagerGlobal.getInstance().removeView(navigationView, true);
- mExternalNavigationBarMap.remove(displayId);
- }
- }
-
- @Override
- public void onDisplayChanged(int displayId) {
- }
- };
-
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private boolean mVibrateOnOpening;
private VibratorHelper mVibratorHelper;
@@ -639,6 +611,7 @@
mKeyguardViewMediator = getComponent(KeyguardViewMediator.class);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+ mNavigationBarController = Dependency.get(DisplayNavigationBarController.class);
mColorExtractor.addOnColorsChangedListener(this);
mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
@@ -650,9 +623,6 @@
mDisplay = mWindowManager.getDefaultDisplay();
updateDisplaySize();
- // get display service to detect display status
- mDisplayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
-
Resources res = mContext.getResources();
mVibrateOnOpening = mContext.getResources().getBoolean(
R.bool.config_vibrateOnIconAnimation);
@@ -695,7 +665,6 @@
// If the system process isn't there we're doomed anyway.
}
- mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
createAndAddWindows();
// Make sure we always have the most current wallpaper info.
@@ -1084,33 +1053,6 @@
}
mNavigationBar.setCurrentSysuiVisibility(mSystemUiVisibility);
});
-
- // Add external navigation bars if more than one displays exist.
- final Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
- addExternalNavigationBar(display);
- }
- }
-
- /**
- * Add a phone navigation bar on an external display if the display supports system decorations.
- *
- * @param display the display to add navigation bar on
- */
- protected void addExternalNavigationBar(Display display) {
- if (display == null || display.getDisplayId() == DEFAULT_DISPLAY
- || !display.supportsSystemDecorations()) {
- return;
- }
-
- final int displayId = display.getDisplayId();
- final Context externalDisplayContext = mContext.createDisplayContext(display);
- NavigationBarFragment.create(externalDisplayContext,
- (tag, fragment) -> {
- final NavigationBarFragment navBar = (NavigationBarFragment) fragment;
- navBar.setCurrentSysuiVisibility(mSystemUiVisibility);
- mExternalNavigationBarMap.append(displayId, navBar);
- });
}
/**
@@ -2925,16 +2867,7 @@
mWindowManager.removeViewImmediate(mNavigationBarView);
mNavigationBarView = null;
}
- mDisplayManager.unregisterDisplayListener(mDisplayListener);
- if (mExternalNavigationBarMap.size() > 0) {
- for (int i = 0; i < mExternalNavigationBarMap.size(); i++) {
- final View navigationWindow = mExternalNavigationBarMap.valueAt(i)
- .getView().getRootView();
- WindowManagerGlobal.getInstance()
- .removeView(navigationWindow, true /* immediate */);
- }
- mExternalNavigationBarMap.clear();
- }
+ mNavigationBarController.destroy();
mContext.unregisterReceiver(mBroadcastReceiver);
mContext.unregisterReceiver(mDemoReceiver);
mAssistManager.destroy();
@@ -4179,6 +4112,8 @@
private DeviceProvisionedController mDeviceProvisionedController
= Dependency.get(DeviceProvisionedController.class);
+ protected DisplayNavigationBarController mNavigationBarController;
+
// UI-specific methods
protected WindowManager mWindowManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto b/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
index 50fd52a..cfb633d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/touch_analytics.proto
@@ -134,4 +134,6 @@
optional int32 touchAreaHeight = 10;
optional Type type = 11;
repeated PhoneEvent phoneEvents = 12;
+
+ optional string device_id = 13;
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java
new file mode 100644
index 0000000..19ad7ca
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/chooser/ChooserHelperTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.chooser;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyBoolean;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Activity;
+import android.app.ActivityTaskManager;
+import android.content.Intent;
+import android.os.Binder;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ChooserHelperTest extends SysuiTestCase {
+
+ @Test
+ public void testOnChoose_CallsStartActivityAsCallerWithToken() {
+ final Intent intent = new Intent();
+ final Binder token = new Binder();
+ intent.putExtra(ActivityTaskManager.EXTRA_PERMISSION_TOKEN, token);
+
+ final Activity mockActivity = mock(Activity.class);
+ when(mockActivity.getIntent()).thenReturn(intent);
+
+ ChooserHelper.onChoose(mockActivity);
+ verify(mockActivity, times(1)).startActivityAsCaller(
+ any(), any(), eq(token), anyBoolean(), anyInt());
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
new file mode 100644
index 0000000..48491d7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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.privacy
+
+import android.app.AppOpsManager
+import android.os.Handler
+import android.support.test.filters.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.testing.TestableLooper.RunWithLooper
+import com.android.systemui.Dependency
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.appops.AppOpItem
+import com.android.systemui.appops.AppOpsController
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.anyList
+import org.mockito.ArgumentMatchers.eq
+import org.mockito.Mock
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.verify
+
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@RunWithLooper
+class PrivacyItemControllerTest : SysuiTestCase() {
+
+ @Mock
+ private lateinit var appOpsController: AppOpsController
+ @Mock
+ private lateinit var callback: PrivacyItemController.Callback
+
+ private lateinit var testableLooper: TestableLooper
+ private lateinit var privacyItemController: PrivacyItemController
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ testableLooper = TestableLooper.get(this)
+
+ appOpsController = mDependency.injectMockDependency(AppOpsController:: class.java)
+ mDependency.injectTestDependency(Dependency.BG_LOOPER, testableLooper.looper)
+ mDependency.injectTestDependency(Dependency.MAIN_HANDLER, Handler(testableLooper.looper))
+
+ doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, 0, "", 0)))
+ .`when`(appOpsController).getActiveAppOpsForUser(anyInt())
+
+ privacyItemController = PrivacyItemController(mContext, callback)
+ }
+ @Test
+ fun testSetListeningTrue() {
+ privacyItemController.setListening(true)
+ verify(appOpsController).addCallback(eq(PrivacyItemController.OPS),
+ any(AppOpsController.Callback::class.java))
+ testableLooper.processAllMessages()
+ verify(callback).privacyChanged(anyList())
+ }
+
+ @Test
+ fun testSetListeningFalse() {
+ privacyItemController.setListening(true)
+ privacyItemController.setListening(false)
+ verify(appOpsController).removeCallback(eq(PrivacyItemController.OPS),
+ any(AppOpsController.Callback:: class.java))
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
index 0251f64..8e6bfe3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
@@ -437,15 +437,15 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), true,
- false, null, null);
+ false, false, null, null);
} else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
outRanking.getVisibilityOverride(), 255,
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
- outRanking.canShowBadge(), outRanking.getUserSentiment(), true, false, null,
- null);
+ outRanking.canShowBadge(), outRanking.getUserSentiment(), true, false,
+ false, null, null);
} else {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
@@ -453,8 +453,7 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), false, false,
- null,
- null);
+ false, null, null);
}
return true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 9c68e7d..9f8a5cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -167,7 +167,7 @@
0,
NotificationManager.IMPORTANCE_DEFAULT,
null, null,
- null, null, null, true, sentiment, false, false, null, null);
+ null, null, null, true, sentiment, false, false, false, null, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
@@ -186,7 +186,7 @@
null, null,
null, null, null, true,
NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL, false, false,
- smartActions, null);
+ false, smartActions, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index ee35449..626726d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -19,8 +19,10 @@
import static android.app.AppOpsManager.OP_CAMERA;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_NEGATIVE;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
@@ -34,15 +36,14 @@
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
-import android.app.NotificationManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -57,11 +58,12 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager
+ .OnSettingsClickListener;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -71,8 +73,8 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
-import org.mockito.junit.MockitoRule;
import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
/**
* Tests for {@link NotificationGutsManager}.
@@ -84,7 +86,7 @@
private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
- TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
+ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT);
private TestableLooper mTestableLooper;
private Handler mHandler;
private NotificationTestHelper mHelper;
@@ -297,7 +299,9 @@
eq(false),
eq(false),
eq(true) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */);
+ eq(true) /* isUserSentimentNegative */,
+ eq(false) /*isNoisy */,
+ eq(0));
}
@Test
@@ -324,7 +328,69 @@
eq(false),
eq(false),
eq(false) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */);
+ eq(true) /* isUserSentimentNegative */,
+ eq(false) /*isNoisy */,
+ eq(0));
+ }
+
+ @Test
+ public void testInitializeNotificationInfoView_noisy() throws Exception {
+ NotificationInfo notificationInfoView = mock(NotificationInfo.class);
+ ExpandableNotificationRow row = spy(mHelper.createRow());
+ row.setBlockingHelperShowing(true);
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ row.getEntry().noisy = true;
+ when(row.getIsNonblockable()).thenReturn(false);
+ StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+
+ mGutsManager.initializeNotificationInfo(row, notificationInfoView);
+
+ verify(notificationInfoView).bindNotification(
+ any(PackageManager.class),
+ any(INotificationManager.class),
+ eq(statusBarNotification.getPackageName()),
+ any(NotificationChannel.class),
+ anyInt(),
+ eq(statusBarNotification),
+ any(NotificationInfo.CheckSaveListener.class),
+ any(NotificationInfo.OnSettingsClickListener.class),
+ any(NotificationInfo.OnAppSettingsClickListener.class),
+ eq(false),
+ eq(false),
+ eq(true) /* isForBlockingHelper */,
+ eq(true) /* isUserSentimentNegative */,
+ eq(true) /*isNoisy */,
+ eq(0));
+ }
+
+ @Test
+ public void testInitializeNotificationInfoView_importance() throws Exception {
+ NotificationInfo notificationInfoView = mock(NotificationInfo.class);
+ ExpandableNotificationRow row = spy(mHelper.createRow());
+ row.setBlockingHelperShowing(true);
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ row.getEntry().importance = IMPORTANCE_DEFAULT;
+ when(row.getIsNonblockable()).thenReturn(false);
+ StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+
+ mGutsManager.initializeNotificationInfo(row, notificationInfoView);
+
+ verify(notificationInfoView).bindNotification(
+ any(PackageManager.class),
+ any(INotificationManager.class),
+ eq(statusBarNotification.getPackageName()),
+ any(NotificationChannel.class),
+ anyInt(),
+ eq(statusBarNotification),
+ any(NotificationInfo.CheckSaveListener.class),
+ any(NotificationInfo.OnSettingsClickListener.class),
+ any(NotificationInfo.OnAppSettingsClickListener.class),
+ eq(false),
+ eq(false),
+ eq(true) /* isForBlockingHelper */,
+ eq(true) /* isUserSentimentNegative */,
+ eq(false) /*isNoisy */,
+ eq(IMPORTANCE_DEFAULT));
}
@Test
@@ -352,7 +418,9 @@
eq(true),
eq(false),
eq(false) /* isForBlockingHelper */,
- eq(true) /* isUserSentimentNegative */);
+ eq(true) /* isUserSentimentNegative */,
+ eq(false) /*isNoisy */,
+ eq(0));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index ca968a8..3744196 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -17,11 +17,14 @@
package com.android.systemui.statusbar.notification.row;
import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE;
+import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
+import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
+import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
@@ -56,6 +59,7 @@
import android.graphics.drawable.Drawable;
import android.os.IBinder;
import android.os.UserHandle;
+import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -72,6 +76,7 @@
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -150,6 +155,15 @@
IMPORTANCE_LOW);
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
new Notification(), UserHandle.CURRENT, null, 0);
+
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+ }
+
+ @After
+ public void tearDown() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
}
// TODO: if tests are taking too long replace this with something that makes the animation
@@ -172,7 +186,8 @@
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
assertEquals(VISIBLE, mNotificationInfo.findViewById(R.id.header).getVisibility());
@@ -184,7 +199,8 @@
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final ImageView iconView = mNotificationInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -192,7 +208,8 @@
@Test
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
assertEquals(GONE, groupNameView.getVisibility());
final TextView groupDividerView = mNotificationInfo.findViewById(R.id.pkg_group_divider);
@@ -208,7 +225,8 @@
eq("test_group_id"), eq(TEST_PACKAGE_NAME), eq(TEST_UID)))
.thenReturn(notificationChannelGroup);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final TextView groupNameView = mNotificationInfo.findViewById(R.id.group_name);
assertEquals(View.VISIBLE, groupNameView.getVisibility());
assertEquals("Test Group Name", groupNameView.getText());
@@ -219,7 +237,8 @@
@Test
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@@ -228,7 +247,7 @@
public void testBindNotification_DefaultChannelDoesNotUseChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mDefaultNotificationChannel, 1, mSbn, null, null, null, true,
- false);
+ false, false, IMPORTANCE_DEFAULT);
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(GONE, textView.getVisibility());
}
@@ -241,7 +260,7 @@
eq(TEST_PACKAGE_NAME), eq(TEST_UID), anyBoolean())).thenReturn(10);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mDefaultNotificationChannel, 1, mSbn, null, null, null, true,
- false);
+ false, false, IMPORTANCE_DEFAULT);
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(VISIBLE, textView.getVisibility());
}
@@ -249,7 +268,8 @@
@Test
public void testBindNotification_UnblockablePackageUsesChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(VISIBLE, textView.getVisibility());
}
@@ -257,18 +277,71 @@
@Test
public void testBindNotification_BlockButton() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final View block = mNotificationInfo.findViewById(R.id.block);
+ final View toggleSilent = mNotificationInfo.findViewById(R.id.toggle_silent);
final View minimize = mNotificationInfo.findViewById(R.id.minimize);
assertEquals(VISIBLE, block.getVisibility());
+ assertEquals(GONE, toggleSilent.getVisibility());
assertEquals(GONE, minimize.getVisibility());
}
@Test
+ public void testBindNotification_SilenceButton() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+ final TextView toggleSilent = mNotificationInfo.findViewById(R.id.toggle_silent);
+ assertEquals(VISIBLE, toggleSilent.getVisibility());
+ assertEquals(
+ mContext.getString(R.string.inline_silent_button_silent), toggleSilent.getText());
+ }
+
+ @Test
+ public void testBindNotification_UnSilenceButton() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_LOW);
+ final TextView toggleSilent = mNotificationInfo.findViewById(R.id.toggle_silent);
+ assertEquals(VISIBLE, toggleSilent.getVisibility());
+ assertEquals(
+ mContext.getString(R.string.inline_silent_button_alert), toggleSilent.getText());
+ }
+
+ @Test
+ public void testBindNotification_SilenceButton_ChannelImportanceUnspecified() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+ final TextView toggleSilent = mNotificationInfo.findViewById(R.id.toggle_silent);
+ assertEquals(VISIBLE, toggleSilent.getVisibility());
+ assertEquals(
+ mContext.getString(R.string.inline_silent_button_silent), toggleSilent.getText());
+ }
+
+ @Test
+ public void testBindNotification_UnSilenceButton_ChannelImportanceUnspecified()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_LOW);
+ final TextView toggleSilent = mNotificationInfo.findViewById(R.id.toggle_silent);
+ assertEquals(VISIBLE, toggleSilent.getVisibility());
+ assertEquals(
+ mContext.getString(R.string.inline_silent_button_alert), toggleSilent.getText());
+ }
+
+ @Test
public void testBindNotification_MinButton() throws Exception {
mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final View block = mNotificationInfo.findViewById(R.id.block);
final View minimize = mNotificationInfo.findViewById(R.id.minimize);
assertEquals(GONE, block.getVisibility());
@@ -283,7 +356,7 @@
(View v, NotificationChannel c, int appUid) -> {
assertEquals(mNotificationChannel, c);
latch.countDown();
- }, null, true, false);
+ }, null, true, false, false, IMPORTANCE_DEFAULT);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
settingsButton.performClick();
@@ -294,7 +367,8 @@
@Test
public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
}
@@ -306,7 +380,7 @@
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null,
(View v, NotificationChannel c, int appUid) -> {
assertEquals(mNotificationChannel, c);
- }, null, false, false);
+ }, null, false, false, false, IMPORTANCE_DEFAULT);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertTrue(settingsButton.getVisibility() != View.VISIBLE);
}
@@ -314,11 +388,12 @@
@Test
public void testBindNotification_SettingsButtonReappearsAfterSecondBind() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null,
(View v, NotificationChannel c, int appUid) -> {
- }, null, true, false);
+ }, null, true, false, false, IMPORTANCE_DEFAULT);
final View settingsButton = mNotificationInfo.findViewById(R.id.info);
assertEquals(View.VISIBLE, settingsButton.getVisibility());
}
@@ -326,7 +401,8 @@
@Test
public void testLogBlockingHelperCounter_doesntLogForNormalGutsView() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verify(mMetricsLogger, times(0)).count(anyString(), anyInt());
}
@@ -335,7 +411,7 @@
public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true,
- true, true);
+ true, true, false, IMPORTANCE_DEFAULT);
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verify(mMetricsLogger, times(1)).count(anyString(), anyInt());
}
@@ -348,7 +424,7 @@
(View v, NotificationChannel c, int appUid) -> {
assertEquals(null, c);
latch.countDown();
- }, null, true, true);
+ }, null, true, true, false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.info).performClick();
// Verify that listener was triggered.
@@ -361,7 +437,7 @@
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null,
- null, true, true);
+ null, true, true, false, IMPORTANCE_DEFAULT);
final TextView channelNameView =
mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(GONE, channelNameView.getVisibility());
@@ -372,7 +448,7 @@
public void testStopInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, mSbn, null, null,
- null, true, true);
+ null, true, true, false, IMPORTANCE_DEFAULT);
final TextView blockView = mNotificationInfo.findViewById(R.id.block);
assertEquals(GONE, blockView.getVisibility());
}
@@ -381,7 +457,7 @@
public void testbindNotification_BlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, false,
- true, true);
+ true, true, false, IMPORTANCE_DEFAULT);
final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(mContext.getString(R.string.inline_blocking_helper), view.getText());
@@ -390,7 +466,8 @@
@Test
public void testbindNotification_UnblockableTextVisibleWhenAppUnblockable() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(mContext.getString(R.string.notification_unblockable_desc),
@@ -400,7 +477,8 @@
@Test
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any());
@@ -410,7 +488,8 @@
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
mTestableLooper.processAllMessages();
@@ -423,7 +502,8 @@
throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
mTestableLooper.processAllMessages();
@@ -432,11 +512,40 @@
}
@Test
+ public void testDoesNotUpdateNotificationChannelAfterImportanceChangedSilenced()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ mTestableLooper.processAllMessages();
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), any());
+ }
+
+ @Test
+ public void testDoesNotUpdateNotificationChannelAfterImportanceChangedUnSilenced()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ mTestableLooper.processAllMessages();
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), any());
+ }
+
+ @Test
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
int originalImportance = mNotificationChannel.getImportance();
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.handleCloseControls(true, false);
mTestableLooper.processAllMessages();
@@ -450,7 +559,8 @@
throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.handleCloseControls(true, false);
@@ -468,7 +578,7 @@
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */ ,
- true, false /* isNonblockable */);
+ true, false /* isNonblockable */, false, /* isNoisy */IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -489,7 +599,7 @@
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */ ,
- true, false /* isNonblockable */);
+ true, false /* isNonblockable */, false, /* isNoisy */IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -510,7 +620,7 @@
null /* onSettingsClick */, null /* onAppSettingsClick */ ,
true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */);
+ true /* isUserSentimentNegative */, false, /* isNoisy */IMPORTANCE_DEFAULT);
NotificationGuts guts = spy(new NotificationGuts(mContext, null));
when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
@@ -538,7 +648,7 @@
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */ , true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */);
+ true /* isUserSentimentNegative */, false, /* isNoisy */IMPORTANCE_DEFAULT);
NotificationGuts guts = spy(new NotificationGuts(mContext, null));
when(guts.getWindowToken()).thenReturn(mock(IBinder.class));
@@ -566,7 +676,8 @@
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
null /* onSettingsClick */, null /* onAppSettingsClick */ ,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true, true /* isUserSentimentNegative */);
+ true, true /* isUserSentimentNegative */, false, /* isNoisy */
+ IMPORTANCE_DEFAULT);
mNotificationInfo.handleCloseControls(true /* save */, false /* force */);
@@ -585,7 +696,7 @@
null /* onSettingsClick */, null /* onAppSettingsClick */,
true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */);
+ true /* isUserSentimentNegative */, false, /* isNoisy */IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
mTestableLooper.processAllMessages();
@@ -607,7 +718,8 @@
false /* isNonblockable */,
true /* isForBlockingHelper */,
true,
- false /* isUserSentimentNegative */);
+ false /* isUserSentimentNegative */,
+ false, /* isNoisy */IMPORTANCE_DEFAULT);
NotificationGuts guts = mock(NotificationGuts.class);
doCallRealMethod().when(guts).closeControls(anyInt(), anyInt(), anyBoolean(), anyBoolean());
mNotificationInfo.setGutsParent(guts);
@@ -621,7 +733,8 @@
public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -634,7 +747,8 @@
public void testBlockChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -666,7 +780,8 @@
true /*provisioned */,
false /* isNonblockable */,
true /* isForBlockingHelper */,
- true /* isUserSentimentNegative */);
+ true /* isUserSentimentNegative */,
+ false, /* isNoisy */IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -687,7 +802,8 @@
public void testNonBlockableAppDoesNotBecomeMin() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
@@ -701,7 +817,8 @@
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
@@ -721,7 +838,8 @@
public void testKeepUpdatesNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.handleCloseControls(true, false);
@@ -738,7 +856,8 @@
public void testBlockUndoDoesNotBlockNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -759,7 +878,8 @@
public void testMinUndoDoesNotMinNotificationChannel() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
@@ -777,10 +897,97 @@
}
@Test
+ public void testSilenceCallsUpdateNotificationChannel() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
+
+ mTestableLooper.processAllMessages();
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
+ }
+
+ @Test
+ public void testUnSilenceCallsUpdateNotificationChannel() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
+
+ mTestableLooper.processAllMessages();
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ }
+
+ @Test
+ public void testSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
+
+ mTestableLooper.processAllMessages();
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
+ }
+
+ @Test
+ public void testUnSilenceCallsUpdateNotificationChannel_channelImportanceUnspecified()
+ throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_UNSPECIFIED);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ false, IMPORTANCE_LOW);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ mNotificationInfo.handleCloseControls(true, false);
+
+ mTestableLooper.processAllMessages();
+ ArgumentCaptor<NotificationChannel> updated =
+ ArgumentCaptor.forClass(NotificationChannel.class);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ anyString(), eq(TEST_UID), updated.capture());
+ assertTrue((updated.getValue().getUserLockedFields()
+ & USER_LOCKED_IMPORTANCE) != 0);
+ assertEquals(IMPORTANCE_HIGH, updated.getValue().getImportance());
+ }
+
+ @Test
public void testCloseControlsDoesNotUpdateiMinIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
@@ -795,7 +1002,8 @@
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -812,7 +1020,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
(Runnable saveImportance, StatusBarNotification sbn) -> {
- }, null, null, true, true);
+ }, null, null, true, true, false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
mTestableLooper.processAllMessages();
@@ -830,7 +1038,7 @@
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
(Runnable saveImportance, StatusBarNotification sbn) -> {
saveImportance.run();
- }, null, null, true, false);
+ }, null, null, true, false, false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
mTestableLooper.processAllMessages();
@@ -866,7 +1074,7 @@
TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null,
(View v, Intent intent) -> {
latch.countDown();
- }, true, false);
+ }, true, false, false, IMPORTANCE_DEFAULT);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(View.VISIBLE, settingsLink.getVisibility());
settingsLink.performClick();
@@ -894,7 +1102,7 @@
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, sbn, null, null,
(View v, Intent intent) -> {
latch.countDown();
- }, true, false);
+ }, true, false, false, IMPORTANCE_DEFAULT);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(View.VISIBLE, settingsLink.getVisibility());
settingsLink.performClick();
@@ -913,7 +1121,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, MULTIPLE_CHANNEL_COUNT, sbn, null, null,
- null, true, false);
+ null, true, false, false, IMPORTANCE_DEFAULT);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(GONE, settingsLink.getVisibility());
}
@@ -933,7 +1141,8 @@
0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, true, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, true, false,
+ false, IMPORTANCE_DEFAULT);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(GONE, settingsLink.getVisibility());
}
@@ -956,7 +1165,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, false, true,
- true, true);
+ true, true, false, IMPORTANCE_DEFAULT);
final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
assertEquals(GONE, settingsLink.getVisibility());
}
@@ -972,7 +1181,8 @@
mSbn.getNotification().flags = Notification.FLAG_FOREGROUND_SERVICE;
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
@@ -984,7 +1194,8 @@
public void testUndoText_block() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -993,10 +1204,39 @@
}
@Test
+ public void testUndoText_silence() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_DEFAULT);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
+ assertEquals(mContext.getString(R.string.notification_channel_silenced),
+ confirmationText.getText());
+ }
+
+ @Test
+ public void testUndoText_unsilence() throws Exception {
+ mNotificationChannel.setImportance(IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ true, IMPORTANCE_DEFAULT);
+
+ mNotificationInfo.findViewById(R.id.toggle_silent).performClick();
+ waitForUndoButton();
+ TextView confirmationText = mNotificationInfo.findViewById(R.id.confirmation_text);
+ assertEquals(mContext.getString(R.string.notification_channel_unsilenced),
+ confirmationText.getText());
+ }
+
+ @Test
public void testNoHeaderOnConfirmation() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
@@ -1007,7 +1247,8 @@
public void testHeaderOnUndo() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
+ false, IMPORTANCE_DEFAULT);
mNotificationInfo.findViewById(R.id.block).performClick();
waitForUndoButton();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index f2431b4..a4a111a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -18,7 +18,10 @@
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -26,8 +29,8 @@
import android.view.View;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import org.junit.Assert;
import org.junit.Before;
@@ -58,39 +61,105 @@
-> mRoundnessManager.onHeadsupAnimatingAwayChanged(mSecond, animatingAway));
mRoundnessManager.setOnRoundingChangedCallback(mRoundnessCallback);
mRoundnessManager.setAnimatedChildren(mAnimatedChildren);
- mRoundnessManager.setFirstAndLastBackgroundChild(mFirst, mFirst);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(null, null)
+ });
mRoundnessManager.setExpanded(1.0f, 1.0f);
+ reset(mRoundnessCallback);
}
@Test
public void testCallbackCalledWhenSecondChanged() {
- mRoundnessManager.setFirstAndLastBackgroundChild(mFirst, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mSecond),
+ createSection(null, null)
+ });
verify(mRoundnessCallback, atLeast(1)).run();
}
@Test
public void testCallbackCalledWhenFirstChanged() {
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mFirst);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mFirst),
+ createSection(null, null)
+ });
verify(mRoundnessCallback, atLeast(1)).run();
}
@Test
+ public void testCallbackCalledWhenSecondSectionFirstChanged() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(mSecond, null)
+ });
+ verify(mRoundnessCallback, atLeast(1)).run();
+ }
+
+ @Test
+ public void testCallbackCalledWhenSecondSectionLastChanged() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(null, mSecond)
+ });
+ verify(mRoundnessCallback, atLeast(1)).run();
+ }
+
+ @Test
+ public void testCallbackNotCalledWhenFirstChangesSections() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(null, mFirst),
+ createSection(mFirst, null)
+ });
+ verify(mRoundnessCallback, never()).run();
+ }
+
+ @Test
public void testRoundnessSetOnLast() {
- mRoundnessManager.setFirstAndLastBackgroundChild(mFirst, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(1.0f, mSecond.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0.0f, mSecond.getCurrentTopRoundness(), 0.0f);
}
@Test
+ public void testRoundnessSetOnSecondSectionLast() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(null, mSecond)
+ });
+ Assert.assertEquals(1.0f, mSecond.getCurrentBottomRoundness(), 0.0f);
+ Assert.assertEquals(0.0f, mSecond.getCurrentTopRoundness(), 0.0f);
+ }
+
+ @Test
+ public void testRoundnessSetOnSecondSectionFirst() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(mSecond, null)
+ });
+ Assert.assertEquals(0.0f, mSecond.getCurrentBottomRoundness(), 0.0f);
+ Assert.assertEquals(1.0f, mSecond.getCurrentTopRoundness(), 0.0f);
+ }
+
+ @Test
public void testRoundnessSetOnNew() {
- mRoundnessManager.setFirstAndLastBackgroundChild(mFirst, null);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, null),
+ createSection(null, null)
+ });
Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@Test
public void testCompleteReplacement() {
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -98,7 +167,10 @@
@Test
public void testNotCalledWhenRemoved() {
mFirst.setRemoved();
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(1.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -107,7 +179,10 @@
public void testRoundedWhenPinnedAndCollapsed() {
mFirst.setPinned(true);
mRoundnessManager.setExpanded(0.0f /* expandedHeight */, 0.0f /* appearFraction */);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(1.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -116,7 +191,10 @@
public void testRoundedWhenGoingAwayAndCollapsed() {
mFirst.setHeadsUpAnimatingAway(true);
mRoundnessManager.setExpanded(0.0f /* expandedHeight */, 0.0f /* appearFraction */);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(1.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -125,7 +203,10 @@
public void testRoundedNormalRoundingWhenExpanded() {
mFirst.setHeadsUpAnimatingAway(true);
mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.0f /* appearFraction */);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -134,7 +215,10 @@
public void testTrackingHeadsUpRoundedIfPushingUp() {
mRoundnessManager.setExpanded(1.0f /* expandedHeight */, -0.5f /* appearFraction */);
mRoundnessManager.setTrackingHeadsUp(mFirst);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(1.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -143,7 +227,10 @@
public void testTrackingHeadsUpNotRoundedIfPushingDown() {
mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.5f /* appearFraction */);
mRoundnessManager.setTrackingHeadsUp(mFirst);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@@ -151,7 +238,10 @@
@Test
public void testRoundingUpdatedWhenAnimatingAwayTrue() {
mRoundnessManager.setExpanded(0.0f, 0.0f);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
mFirst.setHeadsUpAnimatingAway(true);
Assert.assertEquals(1.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1.0f, mFirst.getCurrentTopRoundness(), 0.0f);
@@ -161,10 +251,49 @@
@Test
public void testRoundingUpdatedWhenAnimatingAwayFalse() {
mRoundnessManager.setExpanded(0.0f, 0.0f);
- mRoundnessManager.setFirstAndLastBackgroundChild(mSecond, mSecond);
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mSecond, mSecond),
+ createSection(null, null)
+ });
mFirst.setHeadsUpAnimatingAway(true);
mFirst.setHeadsUpAnimatingAway(false);
Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
}
+
+ @Test
+ public void testNoViewsFirstOrLastInSectionWhenSecondSectionEmpty() {
+ Assert.assertFalse(mFirst.isFirstInSection());
+ Assert.assertFalse(mFirst.isLastInSection());
+ }
+
+ @Test
+ public void testNoViewsFirstOrLastInSectionWhenFirstSectionEmpty() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(null, null),
+ createSection(mSecond, mSecond)
+ });
+ Assert.assertFalse(mSecond.isFirstInSection());
+ Assert.assertFalse(mSecond.isLastInSection());
+ }
+
+ @Test
+ public void testFirstAndLastViewsInSectionSetWhenBothSectionsNonEmpty() {
+ mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
+ createSection(mFirst, mFirst),
+ createSection(mSecond, mSecond)
+ });
+ Assert.assertFalse(mFirst.isFirstInSection());
+ Assert.assertTrue(mFirst.isLastInSection());
+ Assert.assertTrue(mSecond.isFirstInSection());
+ Assert.assertFalse(mSecond.isLastInSection());
+ }
+
+ private NotificationSection createSection(ExpandableNotificationRow first,
+ ExpandableNotificationRow last) {
+ NotificationSection section = mock(NotificationSection.class);
+ when(section.getFirstVisibleChild()).thenReturn(first);
+ when(section.getLastVisibleChild()).thenReturn(last);
+ return section;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index fdd89de..74ce5f6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -13,6 +13,8 @@
package com.android.systemui.statusbar.notification.stack;
+import static android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL;
+
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
@@ -23,6 +25,7 @@
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doNothing;
@@ -36,6 +39,7 @@
import android.os.IPowerManager;
import android.os.Looper;
import android.os.PowerManager;
+import android.provider.Settings;
import android.service.dreams.IDreamManager;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
@@ -67,6 +71,7 @@
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
+import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -102,6 +107,7 @@
@Mock private IDreamManager mDreamManager;
private PowerManager mPowerManager;
private TestableNotificationEntryManager mEntryManager;
+ private int mOriginalInterruptionModelSetting;
@Before
@UiThreadTest
@@ -147,6 +153,17 @@
doNothing().when(mGroupManager).collapseAllGroups();
doNothing().when(mExpandHelper).cancelImmediately();
doNothing().when(notificationShelf).setAnimationsEnabled(anyBoolean());
+
+ mOriginalInterruptionModelSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1);
+ }
+
+ @After
+ public void tearDown() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, mOriginalInterruptionModelSetting);
}
@Test
@@ -318,6 +335,64 @@
}
@Test
+ public void testUpdateGapIndex_allHighPriority() {
+ when(mStackScroller.getChildCount()).thenReturn(3);
+ for (int i = 0; i < 3; i++) {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class,
+ RETURNS_DEEP_STUBS);
+ String key = Integer.toString(i);
+ when(row.getStatusBarNotification().getKey()).thenReturn(key);
+ when(mNotificationData.isHighPriority(row.getStatusBarNotification())).thenReturn(true);
+ when(mStackScroller.getChildAt(i)).thenReturn(row);
+ }
+
+ mStackScroller.updateSectionBoundaries();
+ assertEquals(-1, mStackScroller.getSectionBoundaryIndex(0));
+ }
+
+ @Test
+ public void testUpdateGapIndex_allLowPriority() {
+ when(mStackScroller.getChildCount()).thenReturn(3);
+ for (int i = 0; i < 3; i++) {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class,
+ RETURNS_DEEP_STUBS);
+ String key = Integer.toString(i);
+ when(row.getStatusBarNotification().getKey()).thenReturn(key);
+ when(mNotificationData.isHighPriority(row.getStatusBarNotification()))
+ .thenReturn(false);
+ when(mStackScroller.getChildAt(i)).thenReturn(row);
+ }
+
+ mStackScroller.updateSectionBoundaries();
+ assertEquals(-1, mStackScroller.getSectionBoundaryIndex(0));
+ }
+
+ @Test
+ public void testUpdateGapIndex_gapExists() {
+ when(mStackScroller.getChildCount()).thenReturn(6);
+ for (int i = 0; i < 6; i++) {
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class,
+ RETURNS_DEEP_STUBS);
+ String key = Integer.toString(i);
+ when(row.getStatusBarNotification().getKey()).thenReturn(key);
+ when(mNotificationData.isHighPriority(row.getStatusBarNotification()))
+ .thenReturn(i < 3);
+ when(mStackScroller.getChildAt(i)).thenReturn(row);
+ }
+
+ mStackScroller.updateSectionBoundaries();
+ assertEquals(3, mStackScroller.getSectionBoundaryIndex(0));
+ }
+
+ @Test
+ public void testUpdateGapIndex_empty() {
+ when(mStackScroller.getChildCount()).thenReturn(0);
+
+ mStackScroller.updateSectionBoundaries();
+ assertEquals(-1, mStackScroller.getSectionBoundaryIndex(0));
+ }
+
+ @Test
public void testOnDensityOrFontScaleChanged_reInflatesFooterViews() {
clearInvocations(mStackScroller);
mStackScroller.onDensityOrFontScaleChanged();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index 098fa62..dcd5946 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -44,6 +44,7 @@
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,6 +56,7 @@
* Tests for {@link NotificationSwipeHelper}.
*/
@SmallTest
+@Ignore
@RunWith(AndroidJUnit4.class)
@UiThreadTest
public class NotificationSwipeHelperTest extends SysuiTestCase {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index 231cdf5..93d8aad 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -18,24 +18,25 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
import android.app.StatusBarManager;
import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
import android.view.View;
import android.view.ViewPropertyAnimator;
import com.android.systemui.R;
-import android.testing.AndroidTestingRunner;
-
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.tuner.TunerService;
-import android.testing.TestableLooper.RunWithLooper;
import org.junit.Before;
-import org.junit.runner.RunWith;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.mockito.Mockito;
@RunWith(AndroidTestingRunner.class)
@@ -45,6 +46,7 @@
private NotificationIconAreaController mMockNotificiationAreaController;
private View mNotificationAreaInner;
+ private StatusBarStateController mStatusBarStateController;
public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class);
@@ -55,6 +57,8 @@
mSysuiContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
mSysuiContext.putComponent(StatusBar.class, mock(StatusBar.class));
mSysuiContext.putComponent(TunerService.class, mock(TunerService.class));
+ mStatusBarStateController = mDependency
+ .injectMockDependency(StatusBarStateController.class);
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
mMockNotificiationAreaController = mock(NotificationIconAreaController.class);
mNotificationAreaInner = mock(View.class);
@@ -127,4 +131,23 @@
assertEquals(View.VISIBLE, mFragment.getView().findViewById(R.id.clock).getVisibility());
}
+
+ @Test
+ public void testOnDozingChanged() throws Exception {
+ mFragments.dispatchResume();
+ processAllMessages();
+
+ CollapsedStatusBarFragment fragment = (CollapsedStatusBarFragment) mFragment;
+ fragment.initNotificationIconArea(mMockNotificiationAreaController);
+ fragment.disable(StatusBarManager.DISABLE_NOTIFICATION_ICONS, 0, false);
+
+ Mockito.verify(mNotificationAreaInner).setVisibility(eq(View.INVISIBLE));
+
+ reset(mStatusBarStateController);
+ when(mStatusBarStateController.isDozing()).thenReturn(true);
+ fragment.onDozingChanged(true);
+
+ Mockito.verify(mStatusBarStateController).isDozing();
+ Mockito.verify(mNotificationAreaInner, atLeast(1)).setVisibility(eq(View.VISIBLE));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
new file mode 100644
index 0000000..4177cd1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 2018 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.phone;
+
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_DEAD_ZONE;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyFloat;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import com.android.systemui.R;
+import com.android.systemui.recents.OverviewProxyService;
+import com.android.systemui.shared.recents.IOverviewProxy;
+import com.android.systemui.SysuiTestCase;
+
+import android.content.res.Resources;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
+
+/** atest QuickStepControllerTest */
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+public class QuickStepControllerTest extends SysuiTestCase {
+ private QuickStepController mController;
+ private NavigationBarView mNavigationBarView;
+ private StatusBar mStatusBar;
+ private OverviewProxyService mProxyService;
+ private IOverviewProxy mProxy;
+ private Resources mResources;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ final ButtonDispatcher backButton = mock(ButtonDispatcher.class);
+ mResources = mock(Resources.class);
+
+ mProxyService = mock(OverviewProxyService.class);
+ mProxy = mock(IOverviewProxy.Stub.class);
+ doReturn(mProxy).when(mProxyService).getProxy();
+ mDependency.injectTestDependency(OverviewProxyService.class, mProxyService);
+
+ mStatusBar = mock(StatusBar.class);
+ doReturn(false).when(mStatusBar).isKeyguardShowing();
+ mContext.putComponent(StatusBar.class, mStatusBar);
+
+ mNavigationBarView = mock(NavigationBarView.class);
+ doReturn(false).when(mNavigationBarView).inScreenPinning();
+ doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
+ doReturn(true).when(mNavigationBarView).isQuickScrubEnabled();
+ doReturn(HIT_TARGET_NONE).when(mNavigationBarView).getDownHitTarget();
+ doReturn(backButton).when(mNavigationBarView).getBackButton();
+ doReturn(mResources).when(mNavigationBarView).getResources();
+
+ mController = new QuickStepController(mContext);
+ mController.setComponents(mNavigationBarView);
+ mController.setBarState(false /* isRTL */, NAV_BAR_BOTTOM);
+ }
+
+ @Test
+ public void testNoActionsNoGestures() throws Exception {
+ MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+ assertFalse(mController.onInterceptTouchEvent(ev));
+ verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
+ assertNull(mController.getCurrentAction());
+ }
+
+ @Test
+ public void testHasActionDetectGesturesTouchdown() throws Exception {
+ MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+
+ // Add enabled gesture action
+ NavigationGestureAction action = mockAction(true);
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ assertFalse(mController.onInterceptTouchEvent(ev));
+ verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
+ verify(action, times(1)).reset();
+ verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
+ verify(mProxy, times(1)).onMotionEvent(ev);
+ assertNull(mController.getCurrentAction());
+ }
+
+ @Test
+ public void testProxyDisconnectedNoGestures() throws Exception {
+ MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+
+ // Add enabled gesture action
+ mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Set the gesture on deadzone
+ doReturn(null).when(mProxyService).getProxy();
+
+ assertFalse(mController.onInterceptTouchEvent(ev));
+ verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
+ assertNull(mController.getCurrentAction());
+ }
+
+ @Test
+ public void testNoActionsNoGesturesOverDeadzone() throws Exception {
+ MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+
+ // Touched over deadzone
+ doReturn(HIT_TARGET_DEAD_ZONE).when(mNavigationBarView).getDownHitTarget();
+
+ assertTrue(mController.onInterceptTouchEvent(ev));
+ verify(mNavigationBarView, never()).requestUnbufferedDispatch(ev);
+ assertNull(mController.getCurrentAction());
+ }
+
+ @Test
+ public void testOnTouchIgnoredDownEventAfterOnIntercept() {
+ mController.setGestureActions(mockAction(true), null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ MotionEvent ev = event(MotionEvent.ACTION_DOWN, 1, 1);
+ assertFalse(touch(ev));
+ verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
+
+ // OnTouch event for down is ignored, so requestUnbufferedDispatch ran once from before
+ assertFalse(mNavigationBarView.onTouchEvent(ev));
+ verify(mNavigationBarView, times(1)).requestUnbufferedDispatch(ev);
+ }
+
+ @Test
+ public void testGesturesCallCorrectAction() throws Exception {
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // Swipe Up
+ assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
+ // Swipe Down
+ assertGestureTriggersAction(swipeDown, 1, 1, 5, 100);
+ // Swipe Left
+ assertGestureTriggersAction(swipeLeft, 100, 1, 5, 1);
+ // Swipe Right
+ assertGestureTriggersAction(swipeRight, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testGesturesCallCorrectActionLandscape() throws Exception {
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // In landscape
+ mController.setBarState(false /* isRTL */, NAV_BAR_RIGHT);
+
+ // Swipe Up
+ assertGestureTriggersAction(swipeRight, 1, 100, 5, 1);
+ // Swipe Down
+ assertGestureTriggersAction(swipeLeft, 1, 1, 5, 100);
+ // Swipe Left
+ assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
+ // Swipe Right
+ assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testGesturesCallCorrectActionSeascape() throws Exception {
+ mController.setBarState(false /* isRTL */, NAV_BAR_LEFT);
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // Swipe Up
+ assertGestureTriggersAction(swipeLeft, 1, 100, 5, 1);
+ // Swipe Down
+ assertGestureTriggersAction(swipeRight, 1, 1, 5, 100);
+ // Swipe Left
+ assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
+ // Swipe Right
+ assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testGesturesCallCorrectActionRTL() throws Exception {
+ mController.setBarState(true /* isRTL */, NAV_BAR_BOTTOM);
+
+ // The swipe gestures below are for LTR, so RTL in portrait will be swapped
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // Swipe Up in RTL
+ assertGestureTriggersAction(swipeUp, 1, 100, 5, 1);
+ // Swipe Down in RTL
+ assertGestureTriggersAction(swipeDown, 1, 1, 5, 100);
+ // Swipe Left in RTL
+ assertGestureTriggersAction(swipeRight, 100, 1, 5, 1);
+ // Swipe Right in RTL
+ assertGestureTriggersAction(swipeLeft, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testGesturesCallCorrectActionLandscapeRTL() throws Exception {
+ mController.setBarState(true /* isRTL */, NAV_BAR_RIGHT);
+
+ // The swipe gestures below are for LTR, so RTL in landscape will be swapped
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // Swipe Up
+ assertGestureTriggersAction(swipeLeft, 1, 100, 5, 1);
+ // Swipe Down
+ assertGestureTriggersAction(swipeRight, 1, 1, 5, 100);
+ // Swipe Left
+ assertGestureTriggersAction(swipeUp, 100, 1, 5, 1);
+ // Swipe Right
+ assertGestureTriggersAction(swipeDown, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testGesturesCallCorrectActionSeascapeRTL() throws Exception {
+ mController.setBarState(true /* isRTL */, NAV_BAR_LEFT);
+
+ // The swipe gestures below are for LTR, so RTL in seascape will be swapped
+ NavigationGestureAction swipeUp = mockAction(true);
+ NavigationGestureAction swipeDown = mockAction(true);
+ NavigationGestureAction swipeLeft = mockAction(true);
+ NavigationGestureAction swipeRight = mockAction(true);
+ mController.setGestureActions(swipeUp, swipeDown, swipeLeft, swipeRight);
+
+ // Swipe Up
+ assertGestureTriggersAction(swipeRight, 1, 100, 5, 1);
+ // Swipe Down
+ assertGestureTriggersAction(swipeLeft, 1, 1, 5, 100);
+ // Swipe Left
+ assertGestureTriggersAction(swipeDown, 100, 1, 5, 1);
+ // Swipe Right
+ assertGestureTriggersAction(swipeUp, 1, 1, 100, 5);
+ }
+
+ @Test
+ public void testActionPreventByPinnedState() throws Exception {
+ // Screen is pinned
+ doReturn(true).when(mNavigationBarView).inScreenPinning();
+
+ // Add enabled gesture action
+ NavigationGestureAction action = mockAction(true);
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Touch down to begin swipe
+ MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, 1, 100);
+ assertFalse(touch(downEvent));
+ verify(mProxy, never()).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
+ verify(mProxy, never()).onMotionEvent(downEvent);
+
+ // Move to start gesture, but pinned so it should not trigger action
+ MotionEvent moveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
+ assertFalse(touch(moveEvent));
+ assertNull(mController.getCurrentAction());
+ verify(mNavigationBarView, times(1)).showPinningEscapeToast();
+ verify(action, never()).onGestureStart(moveEvent);
+ }
+
+ @Test
+ public void testActionPreventedNotificationsShown() throws Exception {
+ NavigationGestureAction action = mockAction(true);
+ doReturn(false).when(action).canRunWhenNotificationsShowing();
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Show the notifications
+ doReturn(false).when(mNavigationBarView).isNotificationsFullyCollapsed();
+
+ // Swipe up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
+ assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
+ assertNull(mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+
+ // Hide the notifications
+ doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
+
+ // Swipe up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
+ assertTrue(touch(MotionEvent.ACTION_MOVE, 1, 1));
+ assertEquals(action, mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+ }
+
+ @Test
+ public void testActionCannotPerform() throws Exception {
+ NavigationGestureAction action = mockAction(true);
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Cannot perform action
+ doReturn(false).when(action).canPerformAction();
+
+ // Swipe up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
+ assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
+ assertNull(mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+
+ // Cannot perform action
+ doReturn(true).when(action).canPerformAction();
+
+ // Swipe up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
+ assertTrue(touch(MotionEvent.ACTION_MOVE, 1, 1));
+ assertEquals(action, mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+ }
+
+ @Test
+ public void testQuickScrub() throws Exception {
+ QuickScrubAction action = spy(new QuickScrubAction(mNavigationBarView, mProxyService));
+ mController.setGestureActions(null /* swipeUpAction */, null /* swipeDownAction */,
+ null /* swipeLeftAction */, action);
+ int y = 20;
+
+ // Set the layout and other padding to make sure the scrub fraction is calculated correctly
+ action.onLayout(true, 0, 0, 400, 100);
+ doReturn(0).when(mNavigationBarView).getPaddingLeft();
+ doReturn(0).when(mNavigationBarView).getPaddingRight();
+ doReturn(0).when(mNavigationBarView).getPaddingStart();
+ doReturn(0).when(mResources)
+ .getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
+
+ // Quickscrub disabled, so the action should be disabled
+ doReturn(false).when(mNavigationBarView).isQuickScrubEnabled();
+ assertFalse(action.isEnabled());
+ doReturn(true).when(mNavigationBarView).isQuickScrubEnabled();
+
+ // Touch down
+ MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, 0, y);
+ assertFalse(touch(downEvent));
+ assertNull(mController.getCurrentAction());
+ verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
+ verify(mProxy, times(1)).onMotionEvent(downEvent);
+
+ // Move to start trigger action from gesture
+ MotionEvent moveEvent1 = event(MotionEvent.ACTION_MOVE, 100, y);
+ assertTrue(touch(moveEvent1));
+ assertEquals(action, mController.getCurrentAction());
+ verify(action, times(1)).onGestureStart(moveEvent1);
+ verify(mProxy, times(1)).onQuickScrubStart();
+ verify(mProxyService, times(1)).notifyQuickScrubStarted();
+ verify(mNavigationBarView, times(1)).updateSlippery();
+
+ // Move again for scrub
+ MotionEvent moveEvent2 = event(MotionEvent.ACTION_MOVE, 200, y);
+ assertTrue(touch(moveEvent2));
+ assertEquals(action, mController.getCurrentAction());
+ verify(action, times(1)).onGestureMove(200, y);
+ verify(mProxy, times(1)).onQuickScrubProgress(1f / 2);
+
+ // Action up
+ MotionEvent upEvent = event(MotionEvent.ACTION_UP, 1, y);
+ assertFalse(touch(upEvent));
+ assertNull(mController.getCurrentAction());
+ verify(action, times(1)).onGestureEnd();
+ verify(mProxy, times(1)).onQuickScrubEnd();
+ }
+
+ @Test
+ public void testQuickStep() throws Exception {
+ QuickStepAction action = new QuickStepAction(mNavigationBarView, mProxyService);
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Notifications are up, should prevent quickstep
+ doReturn(false).when(mNavigationBarView).isNotificationsFullyCollapsed();
+
+ // Swipe up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 1, 100));
+ assertNull(mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_MOVE, 1, 1));
+ assertNull(mController.getCurrentAction());
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+ doReturn(true).when(mNavigationBarView).isNotificationsFullyCollapsed();
+
+ // Quickstep disabled, so the action should be disabled
+ doReturn(false).when(mNavigationBarView).isQuickStepSwipeUpEnabled();
+ assertFalse(action.isEnabled());
+ doReturn(true).when(mNavigationBarView).isQuickStepSwipeUpEnabled();
+
+ // Swipe up should call proxy events
+ MotionEvent downEvent = event(MotionEvent.ACTION_DOWN, 1, 100);
+ assertFalse(touch(downEvent));
+ assertNull(mController.getCurrentAction());
+ verify(mProxy, times(1)).onPreMotionEvent(mNavigationBarView.getDownHitTarget());
+ verify(mProxy, times(1)).onMotionEvent(downEvent);
+
+ MotionEvent moveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
+ assertTrue(touch(moveEvent));
+ assertEquals(action, mController.getCurrentAction());
+ verify(mProxy, times(1)).onQuickStep(moveEvent);
+ verify(mProxyService, times(1)).notifyQuickStepStarted();
+ }
+
+ @Test
+ public void testLongPressPreventDetection() throws Exception {
+ NavigationGestureAction action = mockAction(true);
+ mController.setGestureActions(action, null /* swipeDownAction */,
+ null /* swipeLeftAction */, null /* swipeRightAction */);
+
+ // Start the drag up
+ assertFalse(touch(MotionEvent.ACTION_DOWN, 100, 1));
+ assertNull(mController.getCurrentAction());
+
+ // Long press something on the navigation bar such as Home button
+ mNavigationBarView.onNavigationButtonLongPress(mock(View.class));
+
+ // Swipe right will not start any gestures
+ MotionEvent motionMoveEvent = event(MotionEvent.ACTION_MOVE, 1, 1);
+ assertFalse(touch(motionMoveEvent));
+ assertNull(mController.getCurrentAction());
+ verify(action, never()).startGesture(motionMoveEvent);
+
+ // Touch up
+ assertFalse(touch(MotionEvent.ACTION_UP, 1, 1));
+ verify(action, never()).endGesture();
+ }
+
+ @Test
+ public void testHitTargetDragged() throws Exception {
+ final int navbarWidth = 1000;
+ final int navbarHeight = 1000;
+ ButtonDispatcher button = mock(ButtonDispatcher.class);
+ FakeLocationView buttonView = spy(new FakeLocationView(mContext, navbarWidth / 2,
+ navbarHeight / 2));
+ doReturn(buttonView).when(button).getCurrentView();
+
+ NavigationGestureAction action = mockAction(true);
+ mController.setGestureActions(action, action, action, action);
+
+ // Setup getting the hit target
+ doReturn(HIT_TARGET_HOME).when(action).requiresTouchDownHitTarget();
+ doReturn(true).when(action).requiresDragWithHitTarget();
+ doReturn(HIT_TARGET_HOME).when(mNavigationBarView).getDownHitTarget();
+ doReturn(button).when(mNavigationBarView).getHomeButton();
+ doReturn(navbarWidth).when(mNavigationBarView).getWidth();
+ doReturn(navbarHeight).when(mNavigationBarView).getHeight();
+
+ // Portrait
+ assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_BOTTOM);
+
+ // Portrait RTL
+ assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_BOTTOM);
+
+ // Landscape
+ assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_RIGHT);
+
+ // Landscape RTL
+ assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_RIGHT);
+
+ // Seascape
+ assertGestureDragsHitTargetAllDirections(buttonView, false /* isRTL */, NAV_BAR_LEFT);
+
+ // Seascape RTL
+ assertGestureDragsHitTargetAllDirections(buttonView, true /* isRTL */, NAV_BAR_LEFT);
+ }
+
+ private void assertGestureDragsHitTargetAllDirections(View buttonView, boolean isRTL,
+ int navPos) {
+ mController.setBarState(isRTL, navPos);
+
+ // Swipe up
+ assertGestureDragsHitTarget(buttonView, 10 /* x1 */, 200 /* y1 */, 0 /* x2 */, 0 /* y2 */,
+ 0 /* dx */, -1 /* dy */);
+ // Swipe left
+ assertGestureDragsHitTarget(buttonView, 200 /* x1 */, 10 /* y1 */, 0 /* x2 */, 0 /* y2 */,
+ -1 /* dx */, 0 /* dy */);
+ // Swipe right
+ assertGestureDragsHitTarget(buttonView, 0 /* x1 */, 0 /* y1 */, 200 /* x2 */, 10 /* y2 */,
+ 1 /* dx */, 0 /* dy */);
+ // Swipe down
+ assertGestureDragsHitTarget(buttonView, 0 /* x1 */, 0 /* y1 */, 10 /* x2 */, 200 /* y2 */,
+ 0 /* dx */, 1 /* dy */);
+ }
+
+ /**
+ * Asserts the gesture actually moves the hit target
+ * @param buttonView button to check if moved, use Mockito.spy on a real object
+ * @param x1 start x
+ * @param x2 start y
+ * @param y1 end x
+ * @param y2 end y
+ * @param dx diff in x, if not 0, its sign determines direction, value does not matter
+ * @param dy diff in y, if not 0, its sign determines direction, value does not matter
+ */
+ private void assertGestureDragsHitTarget(View buttonView, int x1, int y1, int x2, int y2,
+ int dx, int dy) {
+ ArgumentCaptor<Float> captor = ArgumentCaptor.forClass(Float.class);
+ assertFalse(touch(MotionEvent.ACTION_DOWN, x1, y1));
+ assertTrue(touch(MotionEvent.ACTION_MOVE, x2, y2));
+
+ // Verify positions of the button drag
+ if (dx == 0) {
+ verify(buttonView, never()).setTranslationX(anyFloat());
+ } else {
+ verify(buttonView).setTranslationX(captor.capture());
+ if (dx < 0) {
+ assertTrue("Button should have moved left", (float) captor.getValue() < 0);
+ } else {
+ assertTrue("Button should have moved right", (float) captor.getValue() > 0);
+ }
+ }
+ if (dy == 0) {
+ verify(buttonView, never()).setTranslationY(anyFloat());
+ } else {
+ verify(buttonView).setTranslationY(captor.capture());
+ if (dy < 0) {
+ assertTrue("Button should have moved up", (float) captor.getValue() < 0);
+ } else {
+ assertTrue("Button should have moved down", (float) captor.getValue() > 0);
+ }
+ }
+
+ // Touch up
+ assertFalse(touch(MotionEvent.ACTION_UP, x2, y2));
+ verify(buttonView, times(1)).animate();
+
+ // Reset button state
+ reset(buttonView);
+ }
+
+
+ private MotionEvent event(int action, float x, float y) {
+ final MotionEvent event = mock(MotionEvent.class);
+ doReturn(x).when(event).getX();
+ doReturn(y).when(event).getY();
+ doReturn(action & MotionEvent.ACTION_MASK).when(event).getActionMasked();
+ doReturn(action).when(event).getAction();
+ return event;
+ }
+
+ private boolean touch(int action, float x, float y) {
+ return touch(event(action, x, y));
+ }
+
+ private boolean touch(MotionEvent event) {
+ return mController.onInterceptTouchEvent(event);
+ }
+
+ private NavigationGestureAction mockAction(boolean enabled) {
+ final NavigationGestureAction action = mock(NavigationGestureAction.class);
+ doReturn(enabled).when(action).isEnabled();
+ doReturn(HIT_TARGET_NONE).when(action).requiresTouchDownHitTarget();
+ doReturn(true).when(action).canPerformAction();
+ return action;
+ }
+
+ private void assertGestureTriggersAction(NavigationGestureAction action, int x1, int y1,
+ int x2, int y2) {
+ // Start the drag
+ assertFalse(touch(MotionEvent.ACTION_DOWN, x1, y1));
+ assertNull(mController.getCurrentAction());
+
+ // Swipe
+ MotionEvent motionMoveEvent = event(MotionEvent.ACTION_MOVE, x2, y2);
+ assertTrue(touch(motionMoveEvent));
+ assertEquals(action, mController.getCurrentAction());
+ verify(action, times(1)).startGesture(motionMoveEvent);
+
+ // Move again
+ assertTrue(touch(MotionEvent.ACTION_MOVE, x2, y2));
+ verify(action, times(1)).onGestureMove(x2, y2);
+
+ // Touch up
+ assertFalse(touch(MotionEvent.ACTION_UP, x2, y2));
+ assertNull(mController.getCurrentAction());
+ verify(action, times(1)).endGesture();
+ }
+
+ static class FakeLocationView extends View {
+ private final int mX;
+ private final int mY;
+
+ public FakeLocationView(Context context, int x, int y) {
+ super(context);
+ mX = x;
+ mY = y;
+ }
+
+ @Override
+ public void getLocationInWindow(int[] outLocation) {
+ outLocation[0] = mX;
+ outLocation[1] = mY;
+ }
+ }
+}
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-as/strings.xml
new file mode 100644
index 0000000..2e4d729
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ওপঙি থকা নেভিগে’শ্বন বাৰ সম্পৰীক্ষা"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..dc4994f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ফ্লোটিং নেভিগেশন বার সম্পর্কিত পরীক্ষা"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..10ca61d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ફ્લોટિંગ નૅવિગેશન બારનો પ્રયોગ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..b3949d2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ಫ್ಲೋಟಿಂಗ್ ನ್ಯಾವಿಗೇಷನ್ ಬಾರ್ ಪ್ರಯೋಗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ky/strings.xml
index bfd96da..51613ee 100644
--- a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ky/strings.xml
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ky/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"Калкыма чабыттоо тилкесин колдонуу"</string>
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"Калкыма чабыттоо тилкесин сыноо"</string>
</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..f3bfaa2
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ഫ്ലോട്ടിംഗ് നാവിഗേഷൻ ബാർ പരീക്ഷണം"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..e9a5654
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"उत्रिएको नेभिगेसन पट्टीको परीक्षण"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-or/strings.xml
new file mode 100644
index 0000000..1de802b
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ଭାସମାନ ନାଭିଗେସନ୍ ବାର୍ର ପ୍ରୟୋଗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..6d0970a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"ਫਲੋਟਿੰਗ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-si/strings.xml
new file mode 100644
index 0000000..48eedd1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"පාවෙන සංචාලන තීරු අත්දැකීම"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..5c870cd
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"மிதக்கும் வழிசெலுத்துதல் பட்டி சோதனை"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-te/strings.xml
new file mode 100644
index 0000000..3478e10
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="7290469683147348228">"కదిలే నావిగేషన్ పట్టీ ప్రయోగం"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-as/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-as/strings.xml
new file mode 100644
index 0000000..8cce570
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-as/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"লাহী নেভিগে’শ্বন বাৰ সম্পৰীক্ষা"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-bn/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-bn/strings.xml
new file mode 100644
index 0000000..c0ab3b1
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-bn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"স্লিম নেভিগেশন বার সম্পর্কিত পরীক্ষা"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-gu/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-gu/strings.xml
new file mode 100644
index 0000000..96418ae
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-gu/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"સ્લિમ નૅવિગેશન બારનો પ્રયોગ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-kn/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-kn/strings.xml
new file mode 100644
index 0000000..ccdddea
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-kn/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"ಸ್ಲಿಮ್ ನ್ಯಾವಿಗೇಷನ್ ಬಾರ್ ಪ್ರಯೋಗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ky/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ky/strings.xml
index 6b15d51..449de4f 100644
--- a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ky/strings.xml
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ky/strings.xml
@@ -19,5 +19,5 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"Жука чабыттоо тилкесин колдонуу"</string>
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"Чакан чабыттоо тилкесин сыноо"</string>
</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ml/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ml/strings.xml
new file mode 100644
index 0000000..b65afe3
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ml/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"സ്ലിം നാവിഗേഷൻ ബാർ പരീക്ഷണം"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ne/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ne/strings.xml
new file mode 100644
index 0000000..6022b7f
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ne/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"पातलो नेभिगेसन पट्टीको परीक्षण"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-or/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-or/strings.xml
new file mode 100644
index 0000000..1db9783
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-or/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"ସ୍ଲିମ୍ ନାଭିଗେସନ୍ ବାର୍ର ପ୍ରୟୋଗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-pa/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-pa/strings.xml
new file mode 100644
index 0000000..a782f46
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-pa/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"ਸਲਿਮ ਦਿਸ਼ਾ-ਨਿਰਦੇਸ਼ ਪੱਟੀ ਪ੍ਰਯੋਗ"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-si/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-si/strings.xml
new file mode 100644
index 0000000..a1abb64
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-si/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"සිහින් සංචාලන තීරු අත්දැකීම"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ta/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ta/strings.xml
new file mode 100644
index 0000000..9e95c38
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-ta/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"மெலிதான வழிசெலுத்துதல் பட்டி சோதனை"</string>
+</resources>
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-te/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-te/strings.xml
new file mode 100644
index 0000000..d273ab7
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values-te/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="experiment_navigationbar_overlay" msgid="6953777362606036161">"సన్నని నావిగేషన్ పట్టీ ప్రయోగం"</string>
+</resources>
diff --git a/proto/src/task_snapshot.proto b/proto/src/task_snapshot.proto
index 65d6256..a1bbe52 100644
--- a/proto/src/task_snapshot.proto
+++ b/proto/src/task_snapshot.proto
@@ -31,4 +31,5 @@
int32 windowing_mode = 7;
int32 system_ui_visibility = 8;
bool is_translucent = 9;
+ string top_activity_component = 10;
}
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 09f915e..1ff1acd 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -281,18 +281,6 @@
return;
}
- // Sanitize structure before it's sent to service.
- final ComponentName componentNameFromApp = structure.getActivityComponent();
- if (componentNameFromApp == null || !mComponentName.getPackageName()
- .equals(componentNameFromApp.getPackageName())) {
- Slog.w(TAG, "Activity " + mComponentName + " forged different component on "
- + "AssistStructure: " + componentNameFromApp);
- structure.setActivityComponent(mComponentName);
- mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
- componentNameFromApp == null ? "null"
- : componentNameFromApp.flattenToShortString()));
- }
// Flags used to start the session.
int flags = structure.getFlags();
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 32667b8..5814064 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
@@ -36,8 +37,11 @@
import android.app.AppOpsManager.HistoricalPackageOps;
import android.app.AppOpsManagerInternal;
import android.app.AppOpsManagerInternal.CheckOpsDelegate;
+import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -645,6 +649,26 @@
}
}
+ final IntentFilter packageSuspendFilter = new IntentFilter();
+ packageSuspendFilter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
+ packageSuspendFilter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final int[] changedUids = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST);
+ final String[] changedPkgs = intent.getStringArrayExtra(
+ Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(OP_PLAY_AUDIO);
+ for (int i = 0; i < changedUids.length; i++) {
+ final int changedUid = changedUids[i];
+ final String changedPkg = changedPkgs[i];
+ // We trust packagemanager to insert matching uid and packageNames in the extras
+ mHandler.sendMessage(PooledLambda.obtainMessage(AppOpsService::notifyOpChanged,
+ AppOpsService.this, callbacks, OP_PLAY_AUDIO, changedUid, changedPkg));
+ }
+ }
+ }, packageSuspendFilter);
+
PackageManagerInternal packageManagerInternal = LocalServices.getService(
PackageManagerInternal.class);
packageManagerInternal.setExternalSourcesPolicy(
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 54c7d17..5b3ab85 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -38,6 +38,7 @@
import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.KeyguardManager;
@@ -450,6 +451,7 @@
private PackageManagerInternal mPmInternal;
private UserManagerInternal mUmInternal;
+ private ActivityManagerInternal mAmInternal;
private final Callbacks mCallbacks;
private final LockPatternUtils mLockPatternUtils;
@@ -1439,6 +1441,7 @@
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
mUmInternal = LocalServices.getService(UserManagerInternal.class);
+ mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
HandlerThread hthread = new HandlerThread(TAG);
hthread.start();
@@ -2097,6 +2100,26 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ if ((mask & StorageManager.DEBUG_ISOLATED_STORAGE) != 0) {
+ final boolean enabled = (flags & StorageManager.DEBUG_ISOLATED_STORAGE) != 0;
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ SystemProperties.set(StorageManager.PROP_ISOLATED_STORAGE,
+ Boolean.toString(enabled));
+
+ // Some of the storage related permissions get fiddled with during
+ // package scanning. So, delete the package cache to force PackageManagerService
+ // to do package scanning.
+ FileUtils.deleteContents(Environment.getPackageCacheDirectory());
+
+ // Perform hard reboot to kick policy into place
+ mContext.getSystemService(PowerManager.class).reboot(null);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
}
@Override
@@ -3040,25 +3063,25 @@
"(?i)^(/storage/[^/]+/(?:[0-9]+/)?)(.*)");
@Override
- public String translateAppToSystem(String path, String packageName, int userId) {
- return translateInternal(path, packageName, userId, true);
+ public String translateAppToSystem(String path, int pid, int uid) {
+ return translateInternal(path, pid, uid, true);
}
@Override
- public String translateSystemToApp(String path, String packageName, int userId) {
- return translateInternal(path, packageName, userId, false);
+ public String translateSystemToApp(String path, int pid, int uid) {
+ return translateInternal(path, pid, uid, false);
}
- private String translateInternal(String path, String packageName, int userId,
- boolean toSystem) {
+ private String translateInternal(String path, int pid, int uid, boolean toSystem) {
if (!ENABLE_ISOLATED_STORAGE) return path;
if (path.contains("/../")) {
throw new SecurityException("Shady looking path " + path);
}
- final String sharedUserId = mPmInternal.getSharedUserIdForPackage(packageName);
- final String sandboxId = getSandboxId(packageName, sharedUserId);
+ if (!mAmInternal.isAppStorageSandboxed(pid, uid)) {
+ return path;
+ }
final Matcher m = PATTERN_TRANSLATE.matcher(path);
if (m.matches()) {
@@ -3067,9 +3090,7 @@
// Does path belong to any packages belonging to this UID? If so,
// they get to go straight through to legacy paths.
- final String[] pkgs = (sharedUserId == null)
- ? new String[] {packageName}
- : mPmInternal.getPackagesForSharedUserId(sharedUserId, userId);
+ final String[] pkgs = mContext.getPackageManager().getPackagesForUid(uid);
for (String pkg : pkgs) {
if (devicePath.startsWith("Android/data/" + pkg + "/") ||
devicePath.startsWith("Android/media/" + pkg + "/") ||
@@ -3078,6 +3099,9 @@
}
}
+ final String sharedUserId = mPmInternal.getSharedUserIdForPackage(pkgs[0]);
+ final String sandboxId = getSandboxId(pkgs[0], sharedUserId);
+
if (toSystem) {
// Everything else goes into sandbox.
return device + "Android/sandbox/" + sandboxId + "/" + devicePath;
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 65f3c03..f0b472b 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -47,7 +47,6 @@
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
-import android.telephony.VoLteServiceState;
import android.util.LocalLog;
import android.util.StatsLog;
@@ -196,7 +195,7 @@
private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs;
- private VoLteServiceState mVoLteServiceState = new VoLteServiceState();
+ private int[] mSrvccState;
private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -230,8 +229,7 @@
static final int ENFORCE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR |
- PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR |
- PhoneStateListener.LISTEN_VOLTE_STATE;
+ PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR;
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
@@ -356,6 +354,7 @@
mCallForwarding = new boolean[numPhones];
mCellLocation = new Bundle[numPhones];
mCellInfo = new ArrayList<List<CellInfo>>();
+ mSrvccState = new int[numPhones];
mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>();
for (int i = 0; i < numPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
@@ -371,6 +370,7 @@
mCallForwarding[i] = false;
mCellLocation[i] = new Bundle();
mCellInfo.add(i, null);
+ mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
mPhysicalChannelConfigs.add(i, new ArrayList<PhysicalChannelConfig>());
}
@@ -772,6 +772,13 @@
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
+ try {
+ r.callback.onSrvccStateChanged(mSrvccState[phoneId]);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
}
}
} else {
@@ -1522,19 +1529,30 @@
TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause);
}
- public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) {
- if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) {
+ @Override
+ public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) {
+ if (!checkNotifyPermission("notifySrvccStateChanged()")) {
return;
}
+ if (VDBG) {
+ log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state);
+ }
+ int phoneId = SubscriptionManager.getPhoneId(subId);
synchronized (mRecords) {
- mVoLteServiceState = lteState;
- for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) {
- try {
- r.callback.onVoLteServiceStateChanged(
- new VoLteServiceState(mVoLteServiceState));
- } catch (RemoteException ex) {
- mRemoveList.add(r.binder);
+ if (validatePhoneId(phoneId)) {
+ mSrvccState[phoneId] = state;
+ for (Record r : mRecords) {
+ if (r.matchPhoneStateListenerEvent(
+ PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) &&
+ idMatch(r.subId, subId, phoneId)) {
+ try {
+ if (DBG_LOC) {
+ log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r);
+ }
+ r.callback.onSrvccStateChanged(state);
+ } catch (RemoteException ex) {
+ mRemoveList.add(r.binder);
+ }
}
}
}
@@ -1679,7 +1697,7 @@
pw.println("mRingingCallState=" + mRingingCallState);
pw.println("mForegroundCallState=" + mForegroundCallState);
pw.println("mBackgroundCallState=" + mBackgroundCallState);
- pw.println("mVoLteServiceState=" + mVoLteServiceState);
+ pw.println("mSrvccState=" + mSrvccState);
pw.println("mPhoneCapability=" + mPhoneCapability);
pw.println("mPreferredDataSubId=" + mPreferredDataSubId);
pw.println("mRadioPowerState=" + mRadioPowerState);
@@ -1930,6 +1948,12 @@
android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
}
+ if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
+ }
+
+
return true;
}
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 5538e72..cb9d4c6 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -300,11 +300,10 @@
@Override
public void setNightMode(int mode) {
- if (isNightModeLocked() && (getContext().checkCallingOrSelfPermission(
+ if (isNightModeLocked() && (getContext().checkCallingOrSelfPermission(
android.Manifest.permission.MODIFY_DAY_NIGHT_MODE)
!= PackageManager.PERMISSION_GRANTED)) {
- Slog.e(TAG,
- "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
+ Slog.e(TAG, "Night mode locked, requires MODIFY_DAY_NIGHT_MODE permission");
return;
}
switch (mode) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c52df2d..2e01983 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -68,9 +68,7 @@
import static android.os.Process.THREAD_GROUP_RESTRICTED;
import static android.os.Process.THREAD_GROUP_TOP_APP;
import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
-import static android.os.Process.getPidsForCommands;
import static android.os.Process.getTotalMemory;
-import static android.os.Process.getUidForPid;
import static android.os.Process.isThreadInProcess;
import static android.os.Process.killProcess;
import static android.os.Process.killProcessQuiet;
@@ -127,11 +125,8 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
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.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
-import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
@@ -318,6 +313,7 @@
import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
+import com.android.internal.os.Zygote;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
@@ -1336,7 +1332,7 @@
IApplicationThread thread) {
if (DEBUG_ALL) Slog.v(
TAG, "New death recipient " + this
- + " for thread " + thread.asBinder());
+ + " for thread " + thread.asBinder());
mApp = app;
mPid = pid;
mAppThread = thread;
@@ -2059,8 +2055,7 @@
private String mExemptionsStr;
private List<String> mExemptions = Collections.emptyList();
private int mLogSampleRate = -1;
- @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
- @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
+ @HiddenApiEnforcementPolicy private int mPolicy = HIDDEN_API_ENFORCEMENT_DEFAULT;
public HiddenApiSettings(Handler handler, Context context) {
super(handler);
@@ -2077,11 +2072,7 @@
false,
this);
mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
- false,
- this);
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
+ Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY),
false,
this);
update();
@@ -2116,8 +2107,7 @@
mLogSampleRate = logSampleRate;
zygoteProcess.setHiddenApiAccessLogSampleRate(mLogSampleRate);
}
- mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
- mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
+ mPolicy = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY);
}
private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
@@ -2134,12 +2124,8 @@
return mBlacklistDisabled;
}
- @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
- return mPolicyPreP;
- }
-
- @HiddenApiEnforcementPolicy int getPolicyForPApps() {
- return mPolicyP;
+ @HiddenApiEnforcementPolicy int getPolicy() {
+ return mPolicy;
}
public void onChange(boolean selfChange) {
@@ -3046,35 +3032,18 @@
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
- synchronized (this) {
- /**
- * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
- * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
- * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
- * later to modify process settings due to the flags.
- * TODO(b/80414790): Investigate a better way of untangling this.
- */
+
return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
bOptions, userId);
- }
}
WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
- synchronized (this) {
- /**
- * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
- * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
- * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
- * later to modify process settings due to the flags.
- * TODO(b/80414790): Investigate a better way of untangling this.
- */
return mActivityTaskManager.startActivityAndWait(caller, callingPackage, intent,
resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
bOptions, userId);
- }
}
@Override
@@ -17178,6 +17147,179 @@
}
@GuardedBy("this")
+ final boolean updateLowMemStateLocked(int numCached, int numEmpty, int numTrimming) {
+ final int N = mProcessList.getLruSizeLocked();
+ final long now = SystemClock.uptimeMillis();
+ // Now determine the memory trimming level of background processes.
+ // Unfortunately we need to start at the back of the list to do this
+ // properly. We only do this if the number of background apps we
+ // are managing to keep around is less than half the maximum we desire;
+ // if we are keeping a good number around, we'll let them use whatever
+ // memory they want.
+ final int numCachedAndEmpty = numCached + numEmpty;
+ int memFactor;
+ if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
+ && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
+ if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
+ } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
+ } else {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
+ }
+ } else {
+ memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
+ }
+ // We always allow the memory level to go up (better). We only allow it to go
+ // down if we are in a state where that is allowed, *and* the total number of processes
+ // has gone down since last time.
+ if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
+ + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
+ + " numProcs=" + mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses);
+ if (memFactor > mLastMemoryLevel) {
+ if (!mAllowLowerMemLevel || mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
+ memFactor = mLastMemoryLevel;
+ if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
+ }
+ }
+ if (memFactor != mLastMemoryLevel) {
+ EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
+ StatsLog.write(StatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor);
+ }
+ mLastMemoryLevel = memFactor;
+ mLastNumProcesses = mProcessList.getLruSizeLocked();
+ boolean allChanged = mProcessStats.setMemFactorLocked(
+ memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
+ final int trackerMemFactor = mProcessStats.getMemFactorLocked();
+ if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
+ if (mLowRamStartTime == 0) {
+ mLowRamStartTime = now;
+ }
+ int step = 0;
+ int fgTrimLevel;
+ switch (memFactor) {
+ case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
+ break;
+ case ProcessStats.ADJ_MEM_FACTOR_LOW:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
+ break;
+ default:
+ fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
+ break;
+ }
+ int factor = numTrimming/3;
+ int minFactor = 2;
+ if (mAtmInternal.getHomeProcess() != null) minFactor++;
+ if (mAtmInternal.getPreviousProcess() != null) minFactor++;
+ if (factor < minFactor) factor = minFactor;
+ int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
+ for (int i=N-1; i>=0; i--) {
+ ProcessRecord app = mProcessList.mLruProcesses.get(i);
+ if (allChanged || app.procStateChanged) {
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
+ app.procStateChanged = false;
+ }
+ if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
+ && !app.killedByAm) {
+ if (app.trimMemoryLevel < curLevel && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of " + app.processName + " to " + curLevel);
+ app.thread.scheduleTrimMemory(curLevel);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = curLevel;
+ step++;
+ if (step >= factor) {
+ step = 0;
+ switch (curLevel) {
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+ break;
+ }
+ }
+ } else if (app.getCurProcState() == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+ && !app.killedByAm) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
+ && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of heavy-weight " + app.processName
+ + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+ } else {
+ if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+ || app.systemNoUi) && app.hasPendingUiClean()) {
+ // If this application is now in the background and it
+ // had done UI, then give it the special trim level to
+ // have it free UI resources.
+ final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
+ if (app.trimMemoryLevel < level && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of bg-ui " + app.processName
+ + " to " + level);
+ app.thread.scheduleTrimMemory(level);
+ } catch (RemoteException e) {
+ }
+ }
+ app.setPendingUiClean(false);
+ }
+ if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of fg " + app.processName
+ + " to " + fgTrimLevel);
+ app.thread.scheduleTrimMemory(fgTrimLevel);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = fgTrimLevel;
+ }
+ }
+ } else {
+ if (mLowRamStartTime != 0) {
+ mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
+ mLowRamStartTime = 0;
+ }
+ for (int i=N-1; i>=0; i--) {
+ ProcessRecord app = mProcessList.mLruProcesses.get(i);
+ if (allChanged || app.procStateChanged) {
+ setProcessTrackerStateLocked(app, trackerMemFactor, now);
+ app.procStateChanged = false;
+ }
+ if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+ || app.systemNoUi) && app.hasPendingUiClean()) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
+ && app.thread != null) {
+ try {
+ if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
+ "Trimming memory of ui hidden " + app.processName
+ + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ } catch (RemoteException e) {
+ }
+ }
+ app.setPendingUiClean(false);
+ }
+ app.trimMemoryLevel = 0;
+ }
+ }
+ return allChanged;
+ }
+
+ @GuardedBy("this")
final void updateOomAdjLocked() {
mOomAdjProfiler.oomAdjStarted();
final ProcessRecord TOP_APP = getTopAppLocked();
@@ -17409,172 +17551,7 @@
mNumServiceProcs = mNewNumServiceProcs;
- // Now determine the memory trimming level of background processes.
- // Unfortunately we need to start at the back of the list to do this
- // properly. We only do this if the number of background apps we
- // are managing to keep around is less than half the maximum we desire;
- // if we are keeping a good number around, we'll let them use whatever
- // memory they want.
- final int numCachedAndEmpty = numCached + numEmpty;
- int memFactor;
- if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
- && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
- if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
- } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
- } else {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
- }
- } else {
- memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
- }
- // We always allow the memory level to go up (better). We only allow it to go
- // down if we are in a state where that is allowed, *and* the total number of processes
- // has gone down since last time.
- if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
- + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
- + " numProcs=" + mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses);
- if (memFactor > mLastMemoryLevel) {
- if (!mAllowLowerMemLevel || mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
- memFactor = mLastMemoryLevel;
- if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
- }
- }
- if (memFactor != mLastMemoryLevel) {
- EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
- StatsLog.write(StatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor);
- }
- mLastMemoryLevel = memFactor;
- mLastNumProcesses = mProcessList.getLruSizeLocked();
- boolean allChanged = mProcessStats.setMemFactorLocked(
- memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
- final int trackerMemFactor = mProcessStats.getMemFactorLocked();
- if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
- if (mLowRamStartTime == 0) {
- mLowRamStartTime = now;
- }
- int step = 0;
- int fgTrimLevel;
- switch (memFactor) {
- case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
- break;
- case ProcessStats.ADJ_MEM_FACTOR_LOW:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
- break;
- default:
- fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
- break;
- }
- int factor = numTrimming/3;
- int minFactor = 2;
- if (mAtmInternal.getHomeProcess() != null) minFactor++;
- if (mAtmInternal.getPreviousProcess() != null) minFactor++;
- if (factor < minFactor) factor = minFactor;
- int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
- for (int i=N-1; i>=0; i--) {
- ProcessRecord app = mProcessList.mLruProcesses.get(i);
- if (allChanged || app.procStateChanged) {
- setProcessTrackerStateLocked(app, trackerMemFactor, now);
- app.procStateChanged = false;
- }
- if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
- && !app.killedByAm) {
- if (app.trimMemoryLevel < curLevel && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of " + app.processName + " to " + curLevel);
- app.thread.scheduleTrimMemory(curLevel);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = curLevel;
- step++;
- if (step >= factor) {
- step = 0;
- switch (curLevel) {
- case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
- curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
- break;
- case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
- curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
- break;
- }
- }
- } else if (app.getCurProcState() == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
- && !app.killedByAm) {
- if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
- && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of heavy-weight " + app.processName
- + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
- app.thread.scheduleTrimMemory(
- ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
- } else {
- if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
- || app.systemNoUi) && app.hasPendingUiClean()) {
- // If this application is now in the background and it
- // had done UI, then give it the special trim level to
- // have it free UI resources.
- final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
- if (app.trimMemoryLevel < level && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of bg-ui " + app.processName
- + " to " + level);
- app.thread.scheduleTrimMemory(level);
- } catch (RemoteException e) {
- }
- }
- app.setPendingUiClean(false);
- }
- if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of fg " + app.processName
- + " to " + fgTrimLevel);
- app.thread.scheduleTrimMemory(fgTrimLevel);
- } catch (RemoteException e) {
- }
- }
- app.trimMemoryLevel = fgTrimLevel;
- }
- }
- } else {
- if (mLowRamStartTime != 0) {
- mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
- mLowRamStartTime = 0;
- }
- for (int i=N-1; i>=0; i--) {
- ProcessRecord app = mProcessList.mLruProcesses.get(i);
- if (allChanged || app.procStateChanged) {
- setProcessTrackerStateLocked(app, trackerMemFactor, now);
- app.procStateChanged = false;
- }
- if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
- || app.systemNoUi) && app.hasPendingUiClean()) {
- if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
- && app.thread != null) {
- try {
- if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
- "Trimming memory of ui hidden " + app.processName
- + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- app.thread.scheduleTrimMemory(
- ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
- } catch (RemoteException e) {
- }
- }
- app.setPendingUiClean(false);
- }
- app.trimMemoryLevel = 0;
- }
- }
+ boolean allChanged = updateLowMemStateLocked(numCached, numEmpty, numTrimming);
if (mAlwaysFinishActivities) {
// Need to do this on its own message because the stack may not
@@ -18775,28 +18752,6 @@
}
@Override
- public List<ProcessMemoryState> getMemoryStateForNativeProcesses() {
- List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
- int[] pids = getPidsForCommands(MEMORY_STAT_INTERESTING_NATIVE_PROCESSES);
- for (int i = 0; i < pids.length; i++) {
- int pid = pids[i];
- MemoryStat memoryStat = readMemoryStatFromProcfs(pid);
- if (memoryStat == null) {
- continue;
- }
- int uid = getUidForPid(pid);
- String processName = readCmdlineFromProcfs(pid);
- int oomScore = -1; // Unused, not included in the NativeProcessMemoryState atom.
- ProcessMemoryState processMemoryState = new ProcessMemoryState(uid, processName,
- oomScore, memoryStat.pgfault, memoryStat.pgmajfault,
- memoryStat.rssInBytes, memoryStat.cacheInBytes, memoryStat.swapInBytes,
- memoryStat.rssHighWatermarkInBytes, memoryStat.startTimeNanos);
- processMemoryStates.add(processMemoryState);
- }
- return processMemoryStates;
- }
-
- @Override
public int handleIncomingUser(int callingPid, int callingUid, int userId,
boolean allowAll, int allowMode, String name, String callerPackage) {
return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
@@ -19166,25 +19121,44 @@
@Override
public void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
- ProfilerInfo profilerInfo) {
+ ProfilerInfo profilerInfo, Object wmLock) {
synchronized (ActivityManagerService.this) {
- if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
- setDebugApp(aInfo.processName, true, false);
- }
+ /**
+ * This function is called from the window manager context and needs to be executed
+ * synchronously. To avoid deadlock, we pass a message to AMS to execute the
+ * function and notify the passed in lock when it has been completed.
+ */
+ synchronized (wmLock) {
+ if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
+ setDebugApp(aInfo.processName, true, false);
+ }
- if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
- setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
- }
+ if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
+ setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
+ }
- if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
- setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
- }
+ if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
+ setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
+ }
- if (profilerInfo != null) {
- setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+ if (profilerInfo != null) {
+ setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+ }
+ wmLock.notify();
}
}
}
+
+ @Override
+ public boolean isAppStorageSandboxed(int pid, int uid) {
+ if (!SystemProperties.getBoolean(StorageManager.PROP_ISOLATED_STORAGE, false)) {
+ return false;
+ }
+ synchronized (mPidsSelfLocked) {
+ final ProcessRecord pr = mPidsSelfLocked.get(pid);
+ return pr == null || pr.mountMode != Zygote.MOUNT_EXTERNAL_FULL;
+ }
+ }
}
long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
@@ -19473,7 +19447,8 @@
}
@Override
- public void startDelegateShellPermissionIdentity(int delegateUid) {
+ public void startDelegateShellPermissionIdentity(int delegateUid,
+ @Nullable String[] permissions) {
if (UserHandle.getCallingAppId() != Process.SHELL_UID
&& UserHandle.getCallingAppId() != Process.ROOT_UID) {
throw new SecurityException("Only the shell can delegate its permissions");
@@ -19492,11 +19467,13 @@
if (!(mAppOpsService.getAppOpsServiceDelegate() instanceof ShellDelegate)) {
throw new IllegalStateException("Bad shell delegate state");
}
- if (((ShellDelegate) mAppOpsService.getAppOpsServiceDelegate())
- .getDelegateUid() != delegateUid) {
+ final ShellDelegate delegate = (ShellDelegate) mAppOpsService
+ .getAppOpsServiceDelegate();
+ if (delegate.getDelegateUid() != delegateUid) {
throw new SecurityException("Shell can delegate permissions only "
+ "to one instrumentation at a time");
}
+ delegate.setPermissions(permissions);
return;
}
@@ -19514,7 +19491,7 @@
// Hook them up...
final ShellDelegate shellDelegate = new ShellDelegate(
- instr.mTargetInfo.packageName, delegateUid);
+ instr.mTargetInfo.packageName, delegateUid, permissions);
mAppOpsService.setAppOpsServiceDelegate(shellDelegate);
getPackageManagerInternalLocked().setCheckPermissionDelegate(shellDelegate);
return;
@@ -19537,20 +19514,26 @@
private class ShellDelegate implements CheckOpsDelegate, CheckPermissionDelegate {
private final String mTargetPackageName;
private final int mTargetUid;
+ private @Nullable String[] mPermissions;
- ShellDelegate(String targetPacakgeName, int targetUid) {
+ ShellDelegate(String targetPacakgeName, int targetUid, @Nullable String[] permissions) {
mTargetPackageName = targetPacakgeName;
mTargetUid = targetUid;
+ mPermissions = permissions;
}
int getDelegateUid() {
return mTargetUid;
}
+ void setPermissions(@Nullable String[] permissions) {
+ mPermissions = permissions;
+ }
+
@Override
public int checkOperation(int code, int uid, String packageName,
TriFunction<Integer, Integer, String, Integer> superImpl) {
- if (uid == mTargetUid) {
+ if (uid == mTargetUid && isTargetOp(code)) {
final long identity = Binder.clearCallingIdentity();
try {
return superImpl.apply(code, Process.SHELL_UID,
@@ -19565,7 +19548,7 @@
@Override
public int checkAudioOperation(int code, int usage, int uid, String packageName,
QuadFunction<Integer, Integer, Integer, String, Integer> superImpl) {
- if (uid == mTargetUid) {
+ if (uid == mTargetUid && isTargetOp(code)) {
final long identity = Binder.clearCallingIdentity();
try {
return superImpl.apply(code, usage, Process.SHELL_UID,
@@ -19580,7 +19563,7 @@
@Override
public int noteOperation(int code, int uid, String packageName,
TriFunction<Integer, Integer, String, Integer> superImpl) {
- if (uid == mTargetUid) {
+ if (uid == mTargetUid && isTargetOp(code)) {
final long identity = Binder.clearCallingIdentity();
try {
return mAppOpsService.noteProxyOperation(code, Process.SHELL_UID,
@@ -19595,7 +19578,7 @@
@Override
public int checkPermission(String permName, String pkgName, int userId,
TriFunction<String, String, Integer, Integer> superImpl) {
- if (mTargetPackageName.equals(pkgName)) {
+ if (mTargetPackageName.equals(pkgName) && isTargetPermission(permName)) {
return superImpl.apply(permName, "com.android.shell", userId);
}
return superImpl.apply(permName, pkgName, userId);
@@ -19604,11 +19587,29 @@
@Override
public int checkUidPermission(String permName, int uid,
BiFunction<String, Integer, Integer> superImpl) {
- if (uid == mTargetUid) {
+ if (uid == mTargetUid && isTargetPermission(permName)) {
return superImpl.apply(permName, Process.SHELL_UID);
}
return superImpl.apply(permName, uid);
}
+
+ private boolean isTargetOp(int code) {
+ // null permissions means all ops are targeted
+ if (mPermissions == null) {
+ return true;
+ }
+ // no permission for the op means the op is targeted
+ final String permission = AppOpsManager.opToPermission(code);
+ if (permission == null) {
+ return true;
+ }
+ return isTargetPermission(permission);
+ }
+
+ private boolean isTargetPermission(@NonNull String permission) {
+ // null permissions means all permissions are targeted
+ return (mPermissions == null || ArrayUtils.contains(mPermissions, permission));
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index fe402ea..9018006 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2105,8 +2105,13 @@
}
FeatureInfo[] features = pm.getSystemAvailableFeatures();
- Arrays.sort(features, (o1, o2) ->
- (o1.name == o2.name ? 0 : (o1.name == null ? -1 : o1.name.compareTo(o2.name))));
+ Arrays.sort(features, (o1, o2) -> {
+ if (o1.name == o2.name) return 0;
+ if (o1.name == null) return -1;
+ if (o2.name == null) return 1;
+ return o1.name.compareTo(o2.name);
+ });
+
for (int i = 0; i < features.length; i++) {
if (features[i].name != null) {
if (protoOutputStream != null) {
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 8ac19d5..9cfd39c 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -62,6 +62,8 @@
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS_GLES, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, int.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.UPDATED_GFX_DRIVER_DEV_OPT_IN_APP,
+ String.class);
// add other global settings here...
}
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index c978c13..80b4f77 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -16,9 +16,9 @@
package com.android.server.am;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
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.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
import android.annotation.Nullable;
import android.os.FileUtils;
@@ -45,7 +45,7 @@
* <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns
* /system/bin/statsd for the stats daemon.
*/
- static final String[] MEMORY_STAT_INTERESTING_NATIVE_PROCESSES = new String[]{
+ public static final String[] MEMORY_STAT_INTERESTING_NATIVE_PROCESSES = new String[]{
"/system/bin/statsd", // Stats daemon.
"/system/bin/surfaceflinger",
"/system/bin/apexd", // APEX daemon.
@@ -146,7 +146,7 @@
* Returns null if file is not found in procfs or if file has unrecognized contents.
*/
@Nullable
- static MemoryStat readMemoryStatFromProcfs(int pid) {
+ public static MemoryStat readMemoryStatFromProcfs(int pid) {
final String statPath = String.format(Locale.US, PROC_STAT_FILE_FMT, pid);
MemoryStat stat = parseMemoryStatFromProcfs(readFileContents(statPath));
if (stat == null) {
@@ -163,7 +163,7 @@
* Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string
* if the file is not available.
*/
- static String readCmdlineFromProcfs(int pid) {
+ public static String readCmdlineFromProcfs(int pid) {
String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid);
String cmdline = readFileContents(path);
return cmdline != null ? cmdline : "";
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 93c8391..84b364b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -97,18 +97,18 @@
import dalvik.system.VMRuntime;
+import libcore.io.IoUtils;
+
import java.io.File;
import java.io.IOException;
-import java.io.OutputStream;
import java.io.InputStream;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import libcore.io.IoUtils;
-
/**
* Activity manager code dealing with processes.
*
@@ -1311,6 +1311,7 @@
if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
}
+ app.mountMode = mountExternal;
checkSlow(startTime, "startProcess: building args");
if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
uid = 0;
@@ -1362,8 +1363,7 @@
if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
app.info.maybeUpdateHiddenApiEnforcementPolicy(
- mService.mHiddenApiBlacklist.getPolicyForPrePApps(),
- mService.mHiddenApiBlacklist.getPolicyForPApps());
+ mService.mHiddenApiBlacklist.getPolicy());
@ApplicationInfo.HiddenApiEnforcementPolicy int policy =
app.info.getHiddenApiEnforcementPolicy();
int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 8a3f139..745c1263 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -28,7 +28,6 @@
import android.app.ApplicationErrorReport;
import android.app.Dialog;
import android.app.IApplicationThread;
-import android.app.ProfilerInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -57,11 +56,11 @@
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.Zygote;
import com.android.server.wm.WindowProcessController;
import com.android.server.wm.WindowProcessListener;
import java.io.File;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -263,6 +262,7 @@
boolean pendingStart; // Process start is pending.
long startSeq; // Seq no. indicating the latest process start associated with
// this process record.
+ int mountMode; // Indicates how the external storage was mounted for this process.
// These reports are generated & stored when an app gets into an error condition.
// They will be "null" when all is OK.
@@ -443,6 +443,8 @@
pw.print(prefix); pw.print("pendingStart="); pw.println(pendingStart);
}
pw.print(prefix); pw.print("startSeq="); pw.println(startSeq);
+ pw.print(prefix); pw.print("mountMode="); pw.println(
+ DebugUtils.valueToString(Zygote.class, "MOUNT_EXTERNAL_", mountMode));
if (setProcState > ActivityManager.PROCESS_STATE_SERVICE) {
pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
if (lastCpuTime > 0) {
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 0ee55ed..527539d 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -21,6 +21,7 @@
import android.content.IntentFilter;
import android.hardware.ICameraService;
import android.hardware.ICameraServiceProxy;
+import android.media.AudioManager;
import android.metrics.LogMaker;
import android.nfc.INfcAdapter;
import android.os.Binder;
@@ -393,6 +394,19 @@
boolean wasEmpty = mActiveCameraUsage.isEmpty();
switch (newCameraState) {
case ICameraServiceProxy.CAMERA_STATE_OPEN:
+ // Notify the audio subsystem about the facing of the most-recently opened
+ // camera This can be used to select the best audio tuning in case video
+ // recording with that camera will happen. Since only open events are used, if
+ // multiple cameras are opened at once, the one opened last will be used to
+ // select audio tuning.
+ AudioManager audioManager = getContext().getSystemService(AudioManager.class);
+ if (audioManager != null) {
+ // Map external to front for audio tuning purposes
+ String facingStr = (facing == ICameraServiceProxy.CAMERA_FACING_BACK) ?
+ "back" : "front";
+ String facingParameter = "cameraFacing=" + facingStr;
+ audioManager.setParameters(facingParameter);
+ }
break;
case ICameraServiceProxy.CAMERA_STATE_ACTIVE:
CameraUsageEvent newEvent = new CameraUsageEvent(facing, clientName, apiLevel);
diff --git a/services/core/java/com/android/server/connectivity/LingerMonitor.java b/services/core/java/com/android/server/connectivity/LingerMonitor.java
index 635db19..0e727c5 100644
--- a/services/core/java/com/android/server/connectivity/LingerMonitor.java
+++ b/services/core/java/com/android/server/connectivity/LingerMonitor.java
@@ -90,6 +90,8 @@
mNotifier = notifier;
mDailyLimit = dailyLimit;
mRateLimitMillis = rateLimitMillis;
+ // Ensure that (now - mFirstNotificationMillis) >= rateLimitMillis at first
+ mFirstNotificationMillis = -rateLimitMillis;
}
private static HashMap<String, Integer> makeTransportToNameMap() {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index de4f2d8..c3e3842 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -313,6 +313,7 @@
private int mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
private int mEvaluateAttempts = 0;
+ private volatile int mProbeToken = 0;
public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo,
NetworkRequest defaultRequest) {
@@ -838,7 +839,8 @@
@Override
public void enter() {
- mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE,
+ final int token = ++mProbeToken;
+ mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
isCaptivePortal())));
mThread.start();
}
@@ -847,16 +849,13 @@
public boolean processMessage(Message message) {
switch (message.what) {
case CMD_PROBE_COMPLETE:
- // Currently, it's not possible to exit this state without mThread having
- // terminated. Therefore, this state can never get CMD_PROBE_COMPLETE from a
- // stale thread that is not mThread.
- // TODO: As soon as it's possible to exit this state without mThread having
- // terminated, ensure that CMD_PROBE_COMPLETE from stale threads are ignored.
- // This could be done via a sequence number, or by changing mThread to a class
- // that has a stopped volatile boolean or AtomicBoolean.
+ // Ensure that CMD_PROBE_COMPLETE from stale threads are ignored.
+ if (message.arg1 != mProbeToken) {
+ return HANDLED;
+ }
+
final CaptivePortalProbeResult probeResult =
(CaptivePortalProbeResult) message.obj;
-
if (probeResult.isSuccessful()) {
// Transit EvaluatingPrivateDnsState to get to Validated
// state (even if no Private DNS validation required).
@@ -883,6 +882,7 @@
case CMD_REEVALUATE:
// Leave the event to EvaluatingState. Defer this message will result in reset
// of mReevaluateDelayMs and mEvaluateAttempts.
+ case CMD_NETWORK_DISCONNECTED:
return NOT_HANDLED;
default:
// TODO: Some events may able to handle in this state, instead of deferring to
@@ -894,11 +894,9 @@
@Override
public void exit() {
- // If StateMachine get here, the probe started in enter() is guaranteed to have
- // completed, because in this state, all messages except CMD_PROBE_COMPLETE and
- // CMD_REEVALUATE are deferred. CMD_REEVALUATE cannot be in the queue, because it is
- // only ever sent in EvaluatingState#enter, and the StateMachine reach this state by
- // processing it. Therefore, there is no need to stop the thread.
+ if (mThread.isAlive()) {
+ mThread.interrupt();
+ }
mThread = null;
}
}
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index deaa334..94c94a5 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -165,7 +165,7 @@
}
@VisibleForTesting
- int getDeviceFirstSdkInt() {
+ protected int getDeviceFirstSdkInt() {
return Build.VERSION.FIRST_SDK_INT;
}
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index c51dc52..ab64f61 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -95,12 +95,14 @@
/**
* Flag: This display can show its content when non-secure keyguard is shown.
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9;
/**
* Flag: This display will destroy its content on removal.
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
/**
@@ -114,6 +116,7 @@
* status bar, navigation bar, home activity or IME.
* @hide
*/
+ // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12;
/**
diff --git a/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
new file mode 100644
index 0000000..2b67fe7
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java
@@ -0,0 +1,1630 @@
+/*
+ * Copyright (C) 2018 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.inputmethod;
+
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.AnyThread;
+import android.annotation.BinderThread;
+import android.annotation.IntDef;
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.annotation.WorkerThread;
+import android.app.AppOpsManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.inputmethodservice.MultiClientInputMethodServiceDelegate;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.text.style.SuggestionSpan;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.InputChannel;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.IMultiClientInputMethod;
+import com.android.internal.inputmethod.IMultiClientInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.IMultiClientInputMethodSession;
+import com.android.internal.inputmethod.StartInputFlags;
+import com.android.internal.inputmethod.StartInputReason;
+import com.android.internal.inputmethod.UnbindReason;
+import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
+import com.android.internal.view.IInputMethodManager;
+import com.android.internal.view.IInputMethodSession;
+import com.android.internal.view.InputBindResult;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.wm.WindowManagerInternal;
+
+import java.io.FileDescriptor;
+import java.lang.annotation.Retention;
+import java.util.Collections;
+import java.util.List;
+import java.util.WeakHashMap;
+
+/**
+ * Actual implementation of multi-client InputMethodManagerService.
+ *
+ * <p>This system service is intentionally compatible with {@link InputMethodManagerService} so that
+ * we can switch the implementation at the boot time.</p>
+ */
+public final class MultiClientInputMethodManagerService {
+ static final String TAG = "MultiClientInputMethodManagerService";
+ static final boolean DEBUG = false;
+
+ /**
+ * System property key for the production use. The value must be either empty or a valid
+ * (flattened) component name of the multi-client IME.
+ */
+ private static final String PROP_PROD_MULTI_CLIENT_IME = "ro.sys.multi_client_ime";
+
+ /**
+ * System property key for debugging purpose. The value must be either empty or a valid
+ * (flattened) component name of the multi-client IME.
+ *
+ * <p>This value will be ignored when {@link Build#IS_DEBUGGABLE} returns {@code false}</p>
+ */
+ private static final String PROP_DEBUG_MULTI_CLIENT_IME = "persist.debug.multi_client_ime";
+
+ private static final long RECONNECT_DELAY_MSEC = 1000;
+
+ /**
+ * Unlike {@link InputMethodManagerService}, {@link MultiClientInputMethodManagerService}
+ * always binds to the IME with {@link Context#BIND_FOREGROUND_SERVICE} for now for simplicity.
+ */
+ private static final int IME_CONNECTION_UNIFIED_BIND_FLAGS =
+ Context.BIND_AUTO_CREATE
+ | Context.BIND_NOT_VISIBLE
+ | Context.BIND_NOT_FOREGROUND
+ | Context.BIND_FOREGROUND_SERVICE;
+
+ /**
+ * Inner class to read system property on demand, not when
+ * {@link MultiClientInputMethodManagerService} class is accessed.
+ */
+ private static final class ImeComponentName {
+ private static ComponentName evaluate() {
+ if (Build.IS_DEBUGGABLE) {
+ // If debuggable, allow developers to override the multi-client IME component name
+ // with a different (writable) key.
+ final ComponentName debugIme = ComponentName.unflattenFromString(
+ SystemProperties.get(PROP_DEBUG_MULTI_CLIENT_IME, ""));
+ if (debugIme != null) {
+ return debugIme;
+ }
+ }
+ return ComponentName.unflattenFromString(
+ SystemProperties.get(PROP_PROD_MULTI_CLIENT_IME, ""));
+ }
+
+ /**
+ * {@link ComponentName} of the multi-client IME. {@code null} when the system is not
+ * configured to use multi-client IME.
+ */
+ @Nullable
+ static final ComponentName sValue = evaluate();
+ }
+
+ public static boolean isConfiguredToUse() {
+ return ImeComponentName.sValue != null;
+ }
+
+ private static void reportNotSupported() {
+ if (DEBUG) {
+ Slog.d(TAG, "non-supported operation. callers=" + Debug.getCallers(3));
+ }
+ }
+
+ /**
+ * {@link MultiClientInputMethodManagerService} is not intended to be instantiated.
+ */
+ private MultiClientInputMethodManagerService() {
+ }
+
+ /**
+ * The implementation of {@link SystemService} for multi-client IME.
+ */
+ public static final class Lifecycle extends SystemService {
+ private final ApiCallbacks mApiCallbacks;
+ private final OnWorkerThreadCallback mOnWorkerThreadCallback;
+
+ @MainThread
+ public Lifecycle(Context context) {
+ super(context);
+
+ final UserToInputMethodInfoMap userIdToInputMethodInfoMapper =
+ new UserToInputMethodInfoMap();
+ final UserDataMap userDataMap = new UserDataMap();
+ final HandlerThread workerThread = new HandlerThread(TAG);
+ workerThread.start();
+ mApiCallbacks = new ApiCallbacks(context, userDataMap, userIdToInputMethodInfoMapper);
+ mOnWorkerThreadCallback = new OnWorkerThreadCallback(
+ context, userDataMap, userIdToInputMethodInfoMapper,
+ new Handler(workerThread.getLooper(), msg -> false, true));
+
+ LocalServices.addService(InputMethodManagerInternal.class,
+ new InputMethodManagerInternal() {
+ @Override
+ public void setInteractive(boolean interactive) {
+ reportNotSupported();
+ }
+
+ @Override
+ public void hideCurrentInputMethod() {
+ reportNotSupported();
+ }
+
+ @Override
+ public void startVrInputMethodNoCheck(ComponentName componentName) {
+ reportNotSupported();
+ }
+ });
+ }
+
+ @MainThread
+ @Override
+ public void onBootPhase(int phase) {
+ mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
+ OnWorkerThreadCallback::onBootPhase, mOnWorkerThreadCallback, phase));
+ }
+
+ @MainThread
+ @Override
+ public void onStart() {
+ publishBinderService(Context.INPUT_METHOD_SERVICE, mApiCallbacks);
+ }
+
+ @MainThread
+ @Override
+ public void onStartUser(@UserIdInt int userId) {
+ mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
+ OnWorkerThreadCallback::onStartUser, mOnWorkerThreadCallback, userId));
+ }
+
+ @MainThread
+ @Override
+ public void onUnlockUser(@UserIdInt int userId) {
+ mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
+ OnWorkerThreadCallback::onUnlockUser, mOnWorkerThreadCallback, userId));
+ }
+
+ @MainThread
+ @Override
+ public void onStopUser(@UserIdInt int userId) {
+ mOnWorkerThreadCallback.getHandler().sendMessage(PooledLambda.obtainMessage(
+ OnWorkerThreadCallback::onStopUser, mOnWorkerThreadCallback, userId));
+ }
+ }
+
+ private static final class OnWorkerThreadCallback {
+ private final Context mContext;
+ private final UserDataMap mUserDataMap;
+ private final UserToInputMethodInfoMap mInputMethodInfoMap;
+ private final Handler mHandler;
+
+ OnWorkerThreadCallback(Context context, UserDataMap userDataMap,
+ UserToInputMethodInfoMap inputMethodInfoMap, Handler handler) {
+ mContext = context;
+ mUserDataMap = userDataMap;
+ mInputMethodInfoMap = inputMethodInfoMap;
+ mHandler = handler;
+ }
+
+ @AnyThread
+ Handler getHandler() {
+ return mHandler;
+ }
+
+ @WorkerThread
+ private void tryBindInputMethodService(@UserIdInt int userId) {
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.i(TAG, "tryBindInputMethodService is called for an unknown user=" + userId);
+ return;
+ }
+
+ final InputMethodInfo imi = queryInputMethod(mContext, userId, ImeComponentName.sValue);
+ if (imi == null) {
+ Slog.w(TAG, "Multi-client InputMethod is not found. component="
+ + ImeComponentName.sValue);
+ synchronized (data.mLock) {
+ switch (data.mState) {
+ case PerUserState.USER_LOCKED:
+ case PerUserState.SERVICE_NOT_QUERIED:
+ case PerUserState.SERVICE_RECOGNIZED:
+ case PerUserState.UNBIND_CALLED:
+ // Safe to clean up.
+ mInputMethodInfoMap.remove(userId);
+ break;
+ }
+ }
+ return;
+ }
+
+ synchronized (data.mLock) {
+ switch (data.mState) {
+ case PerUserState.USER_LOCKED:
+ // If the user is still locked, we currently do not try to start IME.
+ return;
+ case PerUserState.SERVICE_NOT_QUERIED:
+ case PerUserState.SERVICE_RECOGNIZED:
+ case PerUserState.UNBIND_CALLED:
+ break;
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ case PerUserState.SERVICE_CONNECTED:
+ // OK, nothing to do.
+ return;
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ return;
+ }
+ data.mState = PerUserState.SERVICE_RECOGNIZED;
+ data.mCurrentInputMethodInfo = imi;
+ mInputMethodInfoMap.put(userId, imi);
+ final boolean bindResult = data.bindServiceLocked(mContext, userId);
+ if (!bindResult) {
+ Slog.e(TAG, "Failed to bind Multi-client InputMethod.");
+ return;
+ }
+ data.mState = PerUserState.WAITING_SERVICE_CONNECTED;
+ }
+ }
+
+ @WorkerThread
+ void onStartUser(@UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.v(TAG, "onStartUser userId=" + userId);
+ }
+ final PerUserData data = new PerUserData(userId, null, PerUserState.USER_LOCKED, this);
+ mUserDataMap.put(userId, data);
+ }
+
+ @WorkerThread
+ void onUnlockUser(@UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.v(TAG, "onUnlockUser() userId=" + userId);
+ }
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.i(TAG, "onUnlockUser is called for an unknown user=" + userId);
+ return;
+ }
+ synchronized (data.mLock) {
+ switch (data.mState) {
+ case PerUserState.USER_LOCKED:
+ data.mState = PerUserState.SERVICE_NOT_QUERIED;
+ tryBindInputMethodService(userId);
+ break;
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ break;
+ }
+ }
+ }
+
+ @WorkerThread
+ void onStopUser(@UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.v(TAG, "onStopUser() userId=" + userId);
+ }
+ mInputMethodInfoMap.remove(userId);
+ final PerUserData data = mUserDataMap.removeReturnOld(userId);
+ if (data == null) {
+ Slog.i(TAG, "onStopUser is called for an unknown user=" + userId);
+ return;
+ }
+ synchronized (data.mLock) {
+ switch (data.mState) {
+ case PerUserState.USER_LOCKED:
+ case PerUserState.SERVICE_RECOGNIZED:
+ case PerUserState.UNBIND_CALLED:
+ // OK, nothing to do.
+ return;
+ case PerUserState.SERVICE_CONNECTED:
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ break;
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ break;
+ }
+ data.unbindServiceLocked(mContext);
+ data.mState = PerUserState.UNBIND_CALLED;
+ data.mCurrentInputMethod = null;
+
+ // When a Service is explicitly unbound with Context.unbindService(),
+ // onServiceDisconnected() will not be triggered. Hence here we explicitly call
+ // onInputMethodDisconnectedLocked() as if the Service is already gone.
+ data.onInputMethodDisconnectedLocked();
+ }
+ }
+
+ @WorkerThread
+ void onServiceConnected(PerUserData data, IMultiClientInputMethod service) {
+ if (DEBUG) {
+ Slog.v(TAG, "onServiceConnected() data.mUserId=" + data.mUserId);
+ }
+ synchronized (data.mLock) {
+ switch (data.mState) {
+ case PerUserState.UNBIND_CALLED:
+ // We should ignore this callback.
+ return;
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ // OK.
+ data.mState = PerUserState.SERVICE_CONNECTED;
+ data.mCurrentInputMethod = service;
+ try {
+ data.mCurrentInputMethod.initialize(new ImeCallbacks(data));
+ } catch (RemoteException e) {
+ }
+ data.onInputMethodConnectedLocked();
+ break;
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ return;
+ }
+ }
+ }
+
+ @WorkerThread
+ void onServiceDisconnected(PerUserData data) {
+ if (DEBUG) {
+ Slog.v(TAG, "onServiceDisconnected() data.mUserId=" + data.mUserId);
+ }
+ final WindowManagerInternal windowManagerInternal =
+ LocalServices.getService(WindowManagerInternal.class);
+ synchronized (data.mLock) {
+ // We assume the number of tokens would not be that large (up to 10 or so) hence
+ // linear search should be acceptable.
+ final int numTokens = data.mDisplayIdToImeWindowTokenMap.size();
+ for (int i = 0; i < numTokens; ++i) {
+ final TokenInfo info = data.mDisplayIdToImeWindowTokenMap.valueAt(i);
+ windowManagerInternal.removeWindowToken(info.mToken, false, info.mDisplayId);
+ }
+ data.mDisplayIdToImeWindowTokenMap.clear();
+ switch (data.mState) {
+ case PerUserState.UNBIND_CALLED:
+ // We should ignore this callback.
+ return;
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ case PerUserState.SERVICE_CONNECTED:
+ // onServiceDisconnected() means the biding is still alive.
+ data.mState = PerUserState.WAITING_SERVICE_CONNECTED;
+ data.mCurrentInputMethod = null;
+ data.onInputMethodDisconnectedLocked();
+ break;
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ return;
+ }
+ }
+ }
+
+ @WorkerThread
+ void onBindingDied(PerUserData data) {
+ if (DEBUG) {
+ Slog.v(TAG, "onBindingDied() data.mUserId=" + data.mUserId);
+ }
+ final WindowManagerInternal windowManagerInternal =
+ LocalServices.getService(WindowManagerInternal.class);
+ synchronized (data.mLock) {
+ // We assume the number of tokens would not be that large (up to 10 or so) hence
+ // linear search should be acceptable.
+ final int numTokens = data.mDisplayIdToImeWindowTokenMap.size();
+ for (int i = 0; i < numTokens; ++i) {
+ final TokenInfo info = data.mDisplayIdToImeWindowTokenMap.valueAt(i);
+ windowManagerInternal.removeWindowToken(info.mToken, false, info.mDisplayId);
+ }
+ data.mDisplayIdToImeWindowTokenMap.clear();
+ switch (data.mState) {
+ case PerUserState.UNBIND_CALLED:
+ // We should ignore this callback.
+ return;
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ case PerUserState.SERVICE_CONNECTED: {
+ // onBindingDied() means the biding is dead.
+ data.mState = PerUserState.UNBIND_CALLED;
+ data.mCurrentInputMethod = null;
+ data.onInputMethodDisconnectedLocked();
+ // Schedule a retry
+ mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
+ OnWorkerThreadCallback::tryBindInputMethodService,
+ this, data.mUserId), RECONNECT_DELAY_MSEC);
+ break;
+ }
+ default:
+ Slog.wtf(TAG, "Unknown state=" + data.mState);
+ return;
+ }
+ }
+ }
+
+ @WorkerThread
+ void onBootPhase(int phase) {
+ if (DEBUG) {
+ Slog.v(TAG, "onBootPhase() phase=" + phase);
+ }
+ switch (phase) {
+ case SystemService.PHASE_ACTIVITY_MANAGER_READY: {
+ final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onPackageAdded(intent);
+ }
+ }, filter, null, mHandler);
+ }
+ break;
+ }
+ }
+
+ @WorkerThread
+ void onPackageAdded(Intent intent) {
+ if (DEBUG) {
+ Slog.v(TAG, "onPackageAdded() intent=" + intent);
+ }
+ final Uri uri = intent.getData();
+ if (uri == null) {
+ return;
+ }
+ if (!intent.hasExtra(Intent.EXTRA_UID)) {
+ return;
+ }
+ final String packageName = uri.getSchemeSpecificPart();
+ if (ImeComponentName.sValue == null
+ || packageName == null
+ || !TextUtils.equals(ImeComponentName.sValue.getPackageName(), packageName)) {
+ return;
+ }
+ final int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, 0));
+ tryBindInputMethodService(userId);
+ }
+ }
+
+ private static final class WindowInfo {
+ final IBinder mWindowToken;
+ final int mWindowHandle;
+
+ WindowInfo(IBinder windowToken, int windowCookie) {
+ mWindowToken = windowToken;
+ mWindowHandle = windowCookie;
+ }
+ }
+
+ /**
+ * Describes the state of each IME client.
+ */
+ @Retention(SOURCE)
+ @IntDef({InputMethodClientState.REGISTERED,
+ InputMethodClientState.WAITING_FOR_IME_SESSION,
+ InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT,
+ InputMethodClientState.ALREADY_SENT_BIND_RESULT,
+ InputMethodClientState.UNREGISTERED})
+ private @interface InputMethodClientState {
+ /**
+ * {@link IInputMethodManager#addClient(IInputMethodClient, IInputContext, int)} is called
+ * and this client is now recognized by the system. When the system lost the connection to
+ * the current IME, all the clients need to be re-initialized from this state.
+ */
+ int REGISTERED = 1;
+ /**
+ * This client is notified to the current IME with {@link
+ * IMultiClientInputMethod#addClient(int, int, int, int)} but the IME is not yet responded
+ * with {@link IMultiClientInputMethodPrivilegedOperations#acceptClient(int,
+ * IInputMethodSession, IMultiClientInputMethodSession, InputChannel)}.
+ */
+ int WAITING_FOR_IME_SESSION = 2;
+ /**
+ * This client is already accepted by the IME but a valid {@link InputBindResult} has not
+ * been returned to the client yet.
+ */
+ int READY_TO_SEND_FIRST_BIND_RESULT = 3;
+ /**
+ * This client has already received a valid {@link InputBindResult} at least once. This
+ * means that the client can directly call {@link IInputMethodSession} IPCs and key events
+ * via {@link InputChannel}. When the current IME is unbound, these client end points also
+ * need to be cleared.
+ */
+ int ALREADY_SENT_BIND_RESULT = 4;
+ /**
+ * The client process is dying.
+ */
+ int UNREGISTERED = 5;
+ }
+
+ private static final class InputMethodClientIdSource {
+ @GuardedBy("InputMethodClientIdSource.class")
+ private static int sNextValue = 0;
+
+ private InputMethodClientIdSource() {
+ }
+
+ static synchronized int getNext() {
+ final int result = sNextValue;
+ sNextValue++;
+ if (sNextValue < 0) {
+ sNextValue = 0;
+ }
+ return result;
+ }
+ }
+
+ private static final class WindowHandleSource {
+ @GuardedBy("WindowHandleSource.class")
+ private static int sNextValue = 0;
+
+ private WindowHandleSource() {
+ }
+
+ static synchronized int getNext() {
+ final int result = sNextValue;
+ sNextValue++;
+ if (sNextValue < 0) {
+ sNextValue = 0;
+ }
+ return result;
+ }
+ }
+
+ private static final class InputMethodClientInfo {
+ final IInputMethodClient mClient;
+ final int mUid;
+ final int mPid;
+ final int mSelfReportedDisplayId;
+ final int mClientId;
+
+ @GuardedBy("PerUserData.mLock")
+ @InputMethodClientState
+ int mState;
+ @GuardedBy("PerUserData.mLock")
+ int mBindingSequence;
+ @GuardedBy("PerUserData.mLock")
+ InputChannel mWriteChannel;
+ @GuardedBy("PerUserData.mLock")
+ IInputMethodSession mInputMethodSession;
+ @GuardedBy("PerUserData.mLock")
+ IMultiClientInputMethodSession mMSInputMethodSession;
+ @GuardedBy("PerUserData.mLock")
+ final WeakHashMap<IBinder, WindowInfo> mWindowMap = new WeakHashMap<>();
+
+ InputMethodClientInfo(IInputMethodClient client, int uid, int pid,
+ int selfReportedDisplayId) {
+ mClient = client;
+ mUid = uid;
+ mPid = pid;
+ mSelfReportedDisplayId = selfReportedDisplayId;
+ mClientId = InputMethodClientIdSource.getNext();
+ }
+ }
+
+ private static final class UserDataMap {
+ @GuardedBy("mMap")
+ private final SparseArray<PerUserData> mMap = new SparseArray<>();
+
+ @AnyThread
+ @Nullable
+ PerUserData get(@UserIdInt int userId) {
+ synchronized (mMap) {
+ return mMap.get(userId);
+ }
+ }
+
+ @AnyThread
+ void put(@UserIdInt int userId, PerUserData data) {
+ synchronized (mMap) {
+ mMap.put(userId, data);
+ }
+ }
+
+ @AnyThread
+ @Nullable
+ PerUserData removeReturnOld(@UserIdInt int userId) {
+ synchronized (mMap) {
+ return mMap.removeReturnOld(userId);
+ }
+ }
+ }
+
+ private static final class TokenInfo {
+ final Binder mToken;
+ final int mDisplayId;
+ TokenInfo(Binder token, int displayId) {
+ mToken = token;
+ mDisplayId = displayId;
+ }
+ }
+
+ @Retention(SOURCE)
+ @IntDef({
+ PerUserState.USER_LOCKED,
+ PerUserState.SERVICE_NOT_QUERIED,
+ PerUserState.SERVICE_RECOGNIZED,
+ PerUserState.WAITING_SERVICE_CONNECTED,
+ PerUserState.SERVICE_CONNECTED,
+ PerUserState.UNBIND_CALLED})
+ private @interface PerUserState {
+ /**
+ * The user is still locked.
+ */
+ int USER_LOCKED = 1;
+ /**
+ * The system has not queried whether there is a multi-client IME or not.
+ */
+ int SERVICE_NOT_QUERIED = 2;
+ /**
+ * A multi-client IME specified in {@link #PROP_DEBUG_MULTI_CLIENT_IME} is found in the
+ * system, but not bound yet.
+ */
+ int SERVICE_RECOGNIZED = 3;
+ /**
+ * {@link Context#bindServiceAsUser(Intent, ServiceConnection, int, Handler, UserHandle)} is
+ * already called for the IME but
+ * {@link ServiceConnection#onServiceConnected(ComponentName, IBinder)} is not yet called
+ * back. This includes once the IME is bound but temporarily disconnected as notified with
+ * {@link ServiceConnection#onServiceDisconnected(ComponentName)}.
+ */
+ int WAITING_SERVICE_CONNECTED = 4;
+ /**
+ * {@link ServiceConnection#onServiceConnected(ComponentName, IBinder)} is already called
+ * back. The IME is ready to be used.
+ */
+ int SERVICE_CONNECTED = 5;
+ /**
+ * The binding is gone. Either {@link Context#unbindService(ServiceConnection)} is
+ * explicitly called or the system decided to destroy the binding as notified with
+ * {@link ServiceConnection#onBindingDied(ComponentName)}.
+ */
+ int UNBIND_CALLED = 6;
+ }
+
+ /**
+ * Takes care of per-user state separation.
+ */
+ private static final class PerUserData {
+ final Object mLock = new Object();
+
+ /**
+ * User ID (not UID) that is associated with this data.
+ */
+ @UserIdInt
+ private final int mUserId;
+
+ /**
+ * {@link IMultiClientInputMethod} of the currently connected multi-client IME. This
+ * must be non-{@code null} only while {@link #mState} is
+ * {@link PerUserState#SERVICE_CONNECTED}.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ IMultiClientInputMethod mCurrentInputMethod;
+
+ /**
+ * {@link InputMethodInfo} of the currently selected multi-client IME. This must be
+ * non-{@code null} unless {@link #mState} is {@link PerUserState#SERVICE_NOT_QUERIED}.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ InputMethodInfo mCurrentInputMethodInfo;
+
+ /**
+ * Describes the current service state.
+ */
+ @GuardedBy("mLock")
+ @PerUserState
+ int mState;
+
+ /**
+ * A {@link SparseArray} that maps display ID to IME Window token that is already issued to
+ * the IME.
+ */
+ @GuardedBy("mLock")
+ final ArraySet<TokenInfo> mDisplayIdToImeWindowTokenMap = new ArraySet<>();
+
+ @GuardedBy("mLock")
+ private final ArrayMap<IBinder, InputMethodClientInfo> mClientMap = new ArrayMap<>();
+
+ @GuardedBy("mLock")
+ private SparseArray<InputMethodClientInfo> mClientIdToClientMap = new SparseArray<>();
+
+ private final OnWorkerThreadServiceConnection mOnWorkerThreadServiceConnection;
+
+ /**
+ * A {@link ServiceConnection} that is designed to run on a certain worker thread with
+ * which {@link OnWorkerThreadCallback} is associated.
+ *
+ * @see Context#bindServiceAsUser(Intent, ServiceConnection, int, Handler, UserHandle).
+ */
+ private static final class OnWorkerThreadServiceConnection implements ServiceConnection {
+ private final PerUserData mData;
+ private final OnWorkerThreadCallback mCallback;
+
+ OnWorkerThreadServiceConnection(PerUserData data, OnWorkerThreadCallback callback) {
+ mData = data;
+ mCallback = callback;
+ }
+
+ @WorkerThread
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mCallback.onServiceConnected(mData,
+ IMultiClientInputMethod.Stub.asInterface(service));
+ }
+
+ @WorkerThread
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mCallback.onServiceDisconnected(mData);
+ }
+
+ @WorkerThread
+ @Override
+ public void onBindingDied(ComponentName name) {
+ mCallback.onBindingDied(mData);
+ }
+
+ Handler getHandler() {
+ return mCallback.getHandler();
+ }
+ }
+
+ PerUserData(@UserIdInt int userId, @Nullable InputMethodInfo inputMethodInfo,
+ @PerUserState int initialState, OnWorkerThreadCallback callback) {
+ mUserId = userId;
+ mCurrentInputMethodInfo = inputMethodInfo;
+ mState = initialState;
+ mOnWorkerThreadServiceConnection =
+ new OnWorkerThreadServiceConnection(this, callback);
+ }
+
+ @GuardedBy("mLock")
+ boolean bindServiceLocked(Context context, @UserIdInt int userId) {
+ final Intent intent =
+ new Intent(MultiClientInputMethodServiceDelegate.SERVICE_INTERFACE)
+ .setComponent(mCurrentInputMethodInfo.getComponent())
+ .putExtra(Intent.EXTRA_CLIENT_LABEL,
+ com.android.internal.R.string.input_method_binding_label)
+ .putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
+ context, 0,
+ new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
+
+ // Note: Instead of re-dispatching callback from the main thread to the worker thread
+ // where OnWorkerThreadCallback is running, we pass the Handler object here so that
+ // the callbacks will be directly dispatched to the worker thread.
+ return context.bindServiceAsUser(intent, mOnWorkerThreadServiceConnection,
+ IME_CONNECTION_UNIFIED_BIND_FLAGS,
+ mOnWorkerThreadServiceConnection.getHandler(), UserHandle.of(userId));
+ }
+
+ @GuardedBy("mLock")
+ void unbindServiceLocked(Context context) {
+ context.unbindService(mOnWorkerThreadServiceConnection);
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ InputMethodClientInfo getClientLocked(IInputMethodClient client) {
+ return mClientMap.get(client.asBinder());
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ InputMethodClientInfo getClientFromIdLocked(int clientId) {
+ return mClientIdToClientMap.get(clientId);
+ }
+
+ @GuardedBy("mLock")
+ @Nullable
+ InputMethodClientInfo removeClientLocked(IInputMethodClient client) {
+ final InputMethodClientInfo info = mClientMap.remove(client.asBinder());
+ if (info != null) {
+ mClientIdToClientMap.remove(info.mClientId);
+ }
+ return info;
+ }
+
+ @GuardedBy("mLock")
+ void addClientLocked(int uid, int pid, IInputMethodClient client,
+ int selfReportedDisplayId) {
+ if (getClientLocked(client) != null) {
+ Slog.wtf(TAG, "The same client is added multiple times");
+ return;
+ }
+ final ClientDeathRecipient deathRecipient = new ClientDeathRecipient(this, client);
+ try {
+ client.asBinder().linkToDeath(deathRecipient, 0);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(e);
+ }
+ final InputMethodClientInfo clientInfo =
+ new InputMethodClientInfo(client, uid, pid, selfReportedDisplayId);
+ clientInfo.mState = InputMethodClientState.REGISTERED;
+ mClientMap.put(client.asBinder(), clientInfo);
+ mClientIdToClientMap.put(clientInfo.mClientId, clientInfo);
+ switch (mState) {
+ case PerUserState.SERVICE_CONNECTED:
+ try {
+ mCurrentInputMethod.addClient(
+ clientInfo.mClientId, clientInfo.mPid, clientInfo.mUid,
+ clientInfo.mSelfReportedDisplayId);
+ clientInfo.mState = InputMethodClientState.WAITING_FOR_IME_SESSION;
+ } catch (RemoteException e) {
+ // TODO(yukawa): Need logging and expected behavior
+ }
+ break;
+ }
+ }
+
+ @GuardedBy("mLock")
+ void onInputMethodConnectedLocked() {
+ final int numClients = mClientMap.size();
+ for (int i = 0; i < numClients; ++i) {
+ final InputMethodClientInfo clientInfo = mClientMap.valueAt(i);
+ switch (clientInfo.mState) {
+ case InputMethodClientState.REGISTERED:
+ // OK
+ break;
+ default:
+ Slog.e(TAG, "Unexpected state=" + clientInfo.mState);
+ return;
+ }
+ try {
+ mCurrentInputMethod.addClient(
+ clientInfo.mClientId, clientInfo.mUid, clientInfo.mPid,
+ clientInfo.mSelfReportedDisplayId);
+ clientInfo.mState = InputMethodClientState.WAITING_FOR_IME_SESSION;
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ @GuardedBy("mLock")
+ void onInputMethodDisconnectedLocked() {
+ final int numClients = mClientMap.size();
+ for (int i = 0; i < numClients; ++i) {
+ final InputMethodClientInfo clientInfo = mClientMap.valueAt(i);
+ switch (clientInfo.mState) {
+ case InputMethodClientState.REGISTERED:
+ // Disconnected before onInputMethodConnectedLocked().
+ break;
+ case InputMethodClientState.WAITING_FOR_IME_SESSION:
+ // Disconnected between addClient() and acceptClient().
+ clientInfo.mState = InputMethodClientState.REGISTERED;
+ break;
+ case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
+ clientInfo.mState = InputMethodClientState.REGISTERED;
+ clientInfo.mInputMethodSession = null;
+ clientInfo.mMSInputMethodSession = null;
+ if (clientInfo.mWriteChannel != null) {
+ clientInfo.mWriteChannel.dispose();
+ clientInfo.mWriteChannel = null;
+ }
+ break;
+ case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
+ try {
+ clientInfo.mClient.onUnbindMethod(clientInfo.mBindingSequence,
+ UnbindReason.DISCONNECT_IME);
+ } catch (RemoteException e) {
+ }
+ clientInfo.mState = InputMethodClientState.REGISTERED;
+ clientInfo.mInputMethodSession = null;
+ clientInfo.mMSInputMethodSession = null;
+ if (clientInfo.mWriteChannel != null) {
+ clientInfo.mWriteChannel.dispose();
+ clientInfo.mWriteChannel = null;
+ }
+ break;
+ }
+ }
+ }
+
+ private static final class ClientDeathRecipient implements IBinder.DeathRecipient {
+ private final PerUserData mPerUserData;
+ private final IInputMethodClient mClient;
+
+ ClientDeathRecipient(PerUserData perUserData, IInputMethodClient client) {
+ mPerUserData = perUserData;
+ mClient = client;
+ }
+
+ @BinderThread
+ @Override
+ public void binderDied() {
+ synchronized (mPerUserData.mLock) {
+ mClient.asBinder().unlinkToDeath(this, 0);
+
+ final InputMethodClientInfo clientInfo =
+ mPerUserData.removeClientLocked(mClient);
+ if (clientInfo == null) {
+ return;
+ }
+
+ if (clientInfo.mWriteChannel != null) {
+ clientInfo.mWriteChannel.dispose();
+ clientInfo.mWriteChannel = null;
+ }
+ if (clientInfo.mInputMethodSession != null) {
+ try {
+ clientInfo.mInputMethodSession.finishSession();
+ } catch (RemoteException e) {
+ }
+ clientInfo.mInputMethodSession = null;
+ }
+ clientInfo.mMSInputMethodSession = null;
+ clientInfo.mState = InputMethodClientState.UNREGISTERED;
+ switch (mPerUserData.mState) {
+ case PerUserState.SERVICE_CONNECTED:
+ try {
+ mPerUserData.mCurrentInputMethod.removeClient(clientInfo.mClientId);
+ } catch (RemoteException e) {
+ // TODO(yukawa): Need logging and expected behavior
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Queries for multi-client IME specified with {@code componentName}.
+ *
+ * @param context {@link Context} to be used to query component.
+ * @param userId User ID for which the multi-client IME is queried.
+ * @param componentName {@link ComponentName} to be queried.
+ * @return {@link InputMethodInfo} when multi-client IME is found. Otherwise {@code null}.
+ */
+ @Nullable
+ private static InputMethodInfo queryInputMethod(Context context, @UserIdInt int userId,
+ @Nullable ComponentName componentName) {
+ if (componentName == null) {
+ return null;
+ }
+
+ // Use for queryIntentServicesAsUser
+ final PackageManager pm = context.getPackageManager();
+ final List<ResolveInfo> services = pm.queryIntentServicesAsUser(
+ new Intent(MultiClientInputMethodServiceDelegate.SERVICE_INTERFACE)
+ .setComponent(componentName),
+ PackageManager.GET_META_DATA, userId);
+
+ if (services.isEmpty()) {
+ Slog.e(TAG, "No IME found");
+ return null;
+ }
+
+ if (services.size() > 1) {
+ Slog.e(TAG, "Only one IME service is supported.");
+ return null;
+ }
+
+ final ResolveInfo ri = services.get(0);
+ ServiceInfo si = ri.serviceInfo;
+ final String imeId = InputMethodInfo.computeId(ri);
+ if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(si.permission)) {
+ Slog.e(TAG, imeId + " must have required"
+ + android.Manifest.permission.BIND_INPUT_METHOD);
+ return null;
+ }
+
+ if (!Build.IS_DEBUGGABLE && (si.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ Slog.e(TAG, imeId + " must be pre-installed when Build.IS_DEBUGGABLE is false");
+ return null;
+ }
+
+ try {
+ return new InputMethodInfo(context, ri);
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Unable to load input method " + imeId, e);
+ }
+ return null;
+ }
+
+ /**
+ * Manages the mapping rule from user ID to {@link InputMethodInfo}.
+ */
+ private static final class UserToInputMethodInfoMap {
+ @GuardedBy("mArray")
+ private final SparseArray<InputMethodInfo> mArray = new SparseArray<>();
+
+ @AnyThread
+ void put(@UserIdInt int userId, InputMethodInfo imi) {
+ synchronized (mArray) {
+ mArray.put(userId, imi);
+ }
+ }
+
+ @AnyThread
+ void remove(@UserIdInt int userId) {
+ synchronized (mArray) {
+ mArray.remove(userId);
+ }
+ }
+
+ @AnyThread
+ @Nullable
+ InputMethodInfo get(@UserIdInt int userId) {
+ synchronized (mArray) {
+ return mArray.get(userId);
+ }
+ }
+
+ @AnyThread
+ List<InputMethodInfo> getAsList(@UserIdInt int userId) {
+ final InputMethodInfo info = get(userId);
+ if (info == null) {
+ return Collections.emptyList();
+ }
+ return Collections.singletonList(info);
+ }
+ }
+
+ /**
+ * Takes care of IPCs exposed to the multi-client IME.
+ */
+ private static final class ImeCallbacks
+ extends IMultiClientInputMethodPrivilegedOperations.Stub {
+ private final PerUserData mPerUserData;
+ private final WindowManagerInternal mIWindowManagerInternal;
+
+ ImeCallbacks(PerUserData perUserData) {
+ mPerUserData = perUserData;
+ mIWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ }
+
+ @BinderThread
+ @Override
+ public IBinder createInputMethodWindowToken(int displayId) {
+ synchronized (mPerUserData.mLock) {
+ // We assume the number of tokens would not be that large (up to 10 or so) hence
+ // linear search should be acceptable.
+ final int numTokens = mPerUserData.mDisplayIdToImeWindowTokenMap.size();
+ for (int i = 0; i < numTokens; ++i) {
+ final TokenInfo tokenInfo =
+ mPerUserData.mDisplayIdToImeWindowTokenMap.valueAt(i);
+ // Currently we issue up to one window token per display.
+ if (tokenInfo.mDisplayId == displayId) {
+ return tokenInfo.mToken;
+ }
+ }
+
+ final Binder token = new Binder();
+ Binder.withCleanCallingIdentity(
+ PooledLambda.obtainRunnable(WindowManagerInternal::addWindowToken,
+ mIWindowManagerInternal, token, TYPE_INPUT_METHOD, displayId));
+ mPerUserData.mDisplayIdToImeWindowTokenMap.add(new TokenInfo(token, displayId));
+ return token;
+ }
+ }
+
+ @BinderThread
+ @Override
+ public void deleteInputMethodWindowToken(IBinder token) {
+ synchronized (mPerUserData.mLock) {
+ // We assume the number of tokens would not be that large (up to 10 or so) hence
+ // linear search should be acceptable.
+ final int numTokens = mPerUserData.mDisplayIdToImeWindowTokenMap.size();
+ for (int i = 0; i < numTokens; ++i) {
+ final TokenInfo tokenInfo =
+ mPerUserData.mDisplayIdToImeWindowTokenMap.valueAt(i);
+ if (tokenInfo.mToken == token) {
+ mPerUserData.mDisplayIdToImeWindowTokenMap.remove(tokenInfo);
+ break;
+ }
+ }
+ }
+ }
+
+ @BinderThread
+ @Override
+ public void acceptClient(int clientId, IInputMethodSession inputMethodSession,
+ IMultiClientInputMethodSession multiSessionInputMethodSession,
+ InputChannel writeChannel) {
+ synchronized (mPerUserData.mLock) {
+ final InputMethodClientInfo clientInfo =
+ mPerUserData.getClientFromIdLocked(clientId);
+ if (clientInfo == null) {
+ Slog.e(TAG, "Unknown clientId=" + clientId);
+ return;
+ }
+ switch (clientInfo.mState) {
+ case InputMethodClientState.WAITING_FOR_IME_SESSION:
+ try {
+ clientInfo.mClient.setActive(true, false);
+ } catch (RemoteException e) {
+ // TODO(yukawa): Remove this client.
+ return;
+ }
+ clientInfo.mState = InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT;
+ clientInfo.mWriteChannel = writeChannel;
+ clientInfo.mInputMethodSession = inputMethodSession;
+ clientInfo.mMSInputMethodSession = multiSessionInputMethodSession;
+ break;
+ default:
+ Slog.e(TAG, "Unexpected state=" + clientInfo.mState);
+ break;
+ }
+ }
+ }
+
+ @BinderThread
+ @Override
+ public void reportImeWindowTarget(int clientId, int targetWindowHandle,
+ IBinder imeWindowToken) {
+ synchronized (mPerUserData.mLock) {
+ final InputMethodClientInfo clientInfo =
+ mPerUserData.getClientFromIdLocked(clientId);
+ if (clientInfo == null) {
+ Slog.e(TAG, "Unknown clientId=" + clientId);
+ return;
+ }
+ for (WindowInfo windowInfo : clientInfo.mWindowMap.values()) {
+ if (windowInfo.mWindowHandle == targetWindowHandle) {
+ final IBinder targetWindowToken = windowInfo.mWindowToken;
+ // TODO(yukawa): Report targetWindowToken and targetWindowToken to WMS.
+ if (DEBUG) {
+ Slog.v(TAG, "reportImeWindowTarget"
+ + " clientId=" + clientId
+ + " imeWindowToken=" + imeWindowToken
+ + " targetWindowToken=" + targetWindowToken);
+ }
+ }
+ }
+ // not found.
+ }
+ }
+
+ @BinderThread
+ @Override
+ public boolean isUidAllowedOnDisplay(int displayId, int uid) {
+ return mIWindowManagerInternal.isUidAllowedOnDisplay(displayId, uid);
+ }
+ }
+
+ /**
+ * Takes care of IPCs exposed to the IME client.
+ */
+ private static final class ApiCallbacks extends IInputMethodManager.Stub {
+ private final UserDataMap mUserDataMap;
+ private final UserToInputMethodInfoMap mInputMethodInfoMap;
+ private final AppOpsManager mAppOpsManager;
+ private final WindowManagerInternal mWindowManagerInternal;
+
+ ApiCallbacks(Context context, UserDataMap userDataMap,
+ UserToInputMethodInfoMap inputMethodInfoMap) {
+ mUserDataMap = userDataMap;
+ mInputMethodInfoMap = inputMethodInfoMap;
+ mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+ }
+
+ @AnyThread
+ private boolean checkFocus(int uid, int pid, int displayId) {
+ return mWindowManagerInternal.isInputMethodClientFocus(uid, pid, displayId);
+ }
+
+ @BinderThread
+ @Override
+ public void addClient(IInputMethodClient client, IInputContext inputContext,
+ int selfReportedDisplayId) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(callingUid);
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.e(TAG, "addClient() from unknown userId=" + userId
+ + " uid=" + callingUid + " pid=" + callingPid);
+ return;
+ }
+ synchronized (data.mLock) {
+ data.addClientLocked(callingUid, callingPid, client, selfReportedDisplayId);
+ }
+ }
+
+ @BinderThread
+ @Override
+ public List<InputMethodInfo> getInputMethodList() {
+ return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid()));
+ }
+
+ @BinderThread
+ @Override
+ public List<InputMethodInfo> getVrInputMethodList() {
+ reportNotSupported();
+ return Collections.emptyList();
+ }
+
+ @BinderThread
+ @Override
+ public List<InputMethodInfo> getEnabledInputMethodList() {
+ return mInputMethodInfoMap.getAsList(UserHandle.getUserId(Binder.getCallingUid()));
+ }
+
+ @BinderThread
+ @Override
+ public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
+ boolean allowsImplicitlySelectedSubtypes) {
+ reportNotSupported();
+ return Collections.emptyList();
+ }
+
+ @BinderThread
+ @Override
+ public InputMethodSubtype getLastInputMethodSubtype() {
+ reportNotSupported();
+ return null;
+ }
+
+ @BinderThread
+ @Override
+ public List getShortcutInputMethodsAndSubtypes() {
+ reportNotSupported();
+ return null;
+ }
+
+ @BinderThread
+ @Override
+ public boolean showSoftInput(
+ IInputMethodClient client, int flags, ResultReceiver resultReceiver) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(callingUid);
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.e(TAG, "showSoftInput() from unknown userId=" + userId
+ + " uid=" + callingUid + " pid=" + callingPid);
+ return false;
+ }
+ synchronized (data.mLock) {
+ final InputMethodClientInfo clientInfo = data.getClientLocked(client);
+ if (clientInfo == null) {
+ Slog.e(TAG, "showSoftInput. client not found. ignoring.");
+ return false;
+ }
+ if (clientInfo.mUid != callingUid) {
+ Slog.e(TAG, "Expected calling UID=" + clientInfo.mUid
+ + " actual=" + callingUid);
+ return false;
+ }
+ switch (clientInfo.mState) {
+ case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
+ case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
+ try {
+ clientInfo.mMSInputMethodSession.showSoftInput(flags, resultReceiver);
+ } catch (RemoteException e) {
+ }
+ break;
+ default:
+ if (DEBUG) {
+ Slog.e(TAG, "Ignoring showSoftInput(). clientState="
+ + clientInfo.mState);
+ }
+ break;
+ }
+ return true;
+ }
+ }
+
+ @BinderThread
+ @Override
+ public boolean hideSoftInput(
+ IInputMethodClient client, int flags, ResultReceiver resultReceiver) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(callingUid);
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.e(TAG, "hideSoftInput() from unknown userId=" + userId
+ + " uid=" + callingUid + " pid=" + callingPid);
+ return false;
+ }
+ synchronized (data.mLock) {
+ final InputMethodClientInfo clientInfo = data.getClientLocked(client);
+ if (clientInfo == null) {
+ return false;
+ }
+ if (clientInfo.mUid != callingUid) {
+ Slog.e(TAG, "Expected calling UID=" + clientInfo.mUid
+ + " actual=" + callingUid);
+ return false;
+ }
+ switch (clientInfo.mState) {
+ case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
+ case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
+ try {
+ clientInfo.mMSInputMethodSession.hideSoftInput(flags, resultReceiver);
+ } catch (RemoteException e) {
+ }
+ break;
+ default:
+ if (DEBUG) {
+ Slog.e(TAG, "Ignoring hideSoftInput(). clientState="
+ + clientInfo.mState);
+ }
+ break;
+ }
+ return true;
+ }
+ }
+
+ @BinderThread
+ @Override
+ public InputBindResult startInputOrWindowGainedFocus(
+ @StartInputReason int startInputReason,
+ @Nullable IInputMethodClient client,
+ @Nullable IBinder windowToken,
+ @StartInputFlags int startInputFlags,
+ @SoftInputModeFlags int softInputMode,
+ int windowFlags,
+ @Nullable EditorInfo editorInfo,
+ @Nullable IInputContext inputContext,
+ @MissingMethodFlags int missingMethods,
+ int unverifiedTargetSdkVersion) {
+ final int callingUid = Binder.getCallingUid();
+ final int callingPid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(callingUid);
+
+ if (client == null) {
+ return InputBindResult.INVALID_CLIENT;
+ }
+
+ final boolean packageNameVerified =
+ editorInfo != null && InputMethodUtils.checkIfPackageBelongsToUid(
+ mAppOpsManager, callingUid, editorInfo.packageName);
+ if (editorInfo != null && !packageNameVerified) {
+ Slog.e(TAG, "Rejecting this client as it reported an invalid package name."
+ + " uid=" + callingUid + " package=" + editorInfo.packageName);
+ return InputBindResult.INVALID_PACKAGE_NAME;
+ }
+
+ final PerUserData data = mUserDataMap.get(userId);
+ if (data == null) {
+ Slog.e(TAG, "startInputOrWindowGainedFocus() from unknown userId=" + userId
+ + " uid=" + callingUid + " pid=" + callingPid);
+ return InputBindResult.INVALID_USER;
+ }
+
+ synchronized (data.mLock) {
+ final InputMethodClientInfo clientInfo = data.getClientLocked(client);
+ if (clientInfo == null) {
+ return InputBindResult.INVALID_CLIENT;
+ }
+ if (clientInfo.mUid != callingUid) {
+ Slog.e(TAG, "Expected calling UID=" + clientInfo.mUid
+ + " actual=" + callingUid);
+ return InputBindResult.INVALID_CLIENT;
+ }
+
+ switch (data.mState) {
+ case PerUserState.USER_LOCKED:
+ case PerUserState.SERVICE_NOT_QUERIED:
+ case PerUserState.SERVICE_RECOGNIZED:
+ case PerUserState.WAITING_SERVICE_CONNECTED:
+ case PerUserState.UNBIND_CALLED:
+ return InputBindResult.IME_NOT_CONNECTED;
+ case PerUserState.SERVICE_CONNECTED:
+ // OK
+ break;
+ default:
+ Slog.wtf(TAG, "Unexpected state=" + data.mState);
+ return InputBindResult.IME_NOT_CONNECTED;
+ }
+
+ WindowInfo windowInfo = null;
+ if (windowToken != null) {
+ windowInfo = clientInfo.mWindowMap.get(windowToken);
+ if (windowInfo == null) {
+ windowInfo = new WindowInfo(windowToken, WindowHandleSource.getNext());
+ clientInfo.mWindowMap.put(windowToken, windowInfo);
+ }
+ }
+
+ if (!checkFocus(clientInfo.mUid, clientInfo.mPid,
+ clientInfo.mSelfReportedDisplayId)) {
+ return InputBindResult.NOT_IME_TARGET_WINDOW;
+ }
+
+ if (editorInfo == null) {
+ // So-called dummy InputConnection scenario. For app compatibility, we still
+ // notify this to the IME.
+ switch (clientInfo.mState) {
+ case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
+ case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
+ final int windowHandle = windowInfo != null
+ ? windowInfo.mWindowHandle
+ : MultiClientInputMethodServiceDelegate.INVALID_WINDOW_HANDLE;
+ try {
+ clientInfo.mMSInputMethodSession.startInputOrWindowGainedFocus(
+ inputContext, missingMethods, editorInfo, startInputFlags,
+ softInputMode, windowHandle);
+ } catch (RemoteException e) {
+ }
+ break;
+ }
+ return InputBindResult.NULL_EDITOR_INFO;
+ }
+
+ switch (clientInfo.mState) {
+ case InputMethodClientState.REGISTERED:
+ case InputMethodClientState.WAITING_FOR_IME_SESSION:
+ clientInfo.mBindingSequence++;
+ if (clientInfo.mBindingSequence < 0) {
+ clientInfo.mBindingSequence = 0;
+ }
+ return new InputBindResult(
+ InputBindResult.ResultCode.SUCCESS_WAITING_IME_SESSION,
+ null, null, data.mCurrentInputMethodInfo.getId(),
+ clientInfo.mBindingSequence);
+ case InputMethodClientState.READY_TO_SEND_FIRST_BIND_RESULT:
+ case InputMethodClientState.ALREADY_SENT_BIND_RESULT:
+ clientInfo.mBindingSequence++;
+ if (clientInfo.mBindingSequence < 0) {
+ clientInfo.mBindingSequence = 0;
+ }
+ // Successful start input.
+ final int windowHandle = windowInfo != null
+ ? windowInfo.mWindowHandle
+ : MultiClientInputMethodServiceDelegate.INVALID_WINDOW_HANDLE;
+ try {
+ clientInfo.mMSInputMethodSession.startInputOrWindowGainedFocus(
+ inputContext, missingMethods, editorInfo, startInputFlags,
+ softInputMode, windowHandle);
+ } catch (RemoteException e) {
+ }
+ clientInfo.mState = InputMethodClientState.ALREADY_SENT_BIND_RESULT;
+ return new InputBindResult(
+ InputBindResult.ResultCode.SUCCESS_WITH_IME_SESSION,
+ clientInfo.mInputMethodSession,
+ clientInfo.mWriteChannel.dup(),
+ data.mCurrentInputMethodInfo.getId(),
+ clientInfo.mBindingSequence);
+ case InputMethodClientState.UNREGISTERED:
+ Slog.e(TAG, "The client is already unregistered.");
+ return InputBindResult.INVALID_CLIENT;
+ }
+ }
+ return null;
+ }
+
+ @BinderThread
+ @Override
+ public void showInputMethodPickerFromClient(
+ IInputMethodClient client, int auxiliarySubtypeMode) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public void showInputMethodAndSubtypeEnablerFromClient(
+ IInputMethodClient client, String inputMethodId) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public boolean isInputMethodPickerShownForTest() {
+ reportNotSupported();
+ return false;
+ }
+
+ @BinderThread
+ @Override
+ public void setInputMethod(IBinder token, String id) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public void registerSuggestionSpansForNotification(SuggestionSpan[] suggestionSpans) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public boolean notifySuggestionPicked(
+ SuggestionSpan span, String originalString, int index) {
+ reportNotSupported();
+ return false;
+ }
+
+ @BinderThread
+ @Override
+ public InputMethodSubtype getCurrentInputMethodSubtype() {
+ reportNotSupported();
+ return null;
+ }
+
+ @BinderThread
+ @Override
+ public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
+ reportNotSupported();
+ return false;
+ }
+
+ @BinderThread
+ @Override
+ public boolean switchToPreviousInputMethod(IBinder token) {
+ reportNotSupported();
+ return false;
+ }
+
+ @BinderThread
+ @Override
+ public boolean switchToNextInputMethod(IBinder token, boolean onlyCurrentIme) {
+ reportNotSupported();
+ return false;
+ }
+
+ @BinderThread
+ @Override
+ public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) {
+ reportNotSupported();
+ }
+
+ @BinderThread
+ @Override
+ public int getInputMethodWindowVisibleHeight() {
+ reportNotSupported();
+ return 0;
+ }
+
+ @BinderThread
+ @Override
+ public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback,
+ ResultReceiver resultReceiver) {
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/inputmethod/multi-client-ime.md b/services/core/java/com/android/server/inputmethod/multi-client-ime.md
new file mode 100644
index 0000000..3021d2f
--- /dev/null
+++ b/services/core/java/com/android/server/inputmethod/multi-client-ime.md
@@ -0,0 +1,192 @@
+<!-- Copyright (C) 2018 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.
+-->
+
+# Multi Client Input Method Editors
+
+## History of Multi Client Input Method Editors (Multi Client IMEs)
+
+An advanced multi-display support is requested for certain Android form-factors so that user(s) can type text on each display at the same time without losing software keyboard focus in other displays (hereafter called "multi-client scenario"). This is not possible in Android IMEs built on top of `InputMethodService` class. The assumption that a single IME client can be focused at the same time was made before Android IME APIs were introduced in Android 1.5 and many public APIs in `InputMethodService` have already relied heavily on that assumption (hereafter called "single-client scenario"). Updating `InputMethodService` class to support multi-client scenario is, however, quite challenging because:
+
+ 1. doing so would introduce an unacceptable amount of complexity into `InputMethodService`, which is already hard to maintain,
+ 2. IME developers still need to update their implementation to be able to support parallel requests from multiple focused IME client, which may require non-trivial redesign in their side (e.g. input decoder, typing history database, ...), and
+ 3. actual use cases for multi IME clients are expected to be evolved rapidly hence the new protocol is not yet stable and not yet ready to be exposed as public APIs.
+
+Thus the first decision we made was that to support such special multi-display environments a new type of IME (hereafter called "multi-client IME") needs to be designed and implemented rather than reusing `InputMethodService` public class. On top of this decision, following decisions were also made:
+
+ * Multi-client IME V1 will be built on top of private APIs. This means:
+ * Multi-client IME must be pre-installed into the system. They cannot be distributed via application store since protocol compatibility is not guaranteed across devices and releases.
+ * The system should trust multi-client IME to some extent. System integrators are responsible for making sure that the pre-installed multi-client IME works as expected.
+ * Unlike `InputMethodService`, multiple multi-client IMEs cannot be enabled. The system pre-installs only one multi-client IME.
+ * Punt some special features of Android IMEs (e.g. fullscreen mode, InputMethodSubtype, ...) from V1 goal unless someone actually requests those features for multi-client IME scenario.
+ * Introduce `MultiClientInputMethodManagerService` (MCIMMS) for multi-client IME scenario and use it instead of `InputMethodManagerService` (IMMS) when a certain runtime flag is enabled at the device boot time. This means:
+ * basically no risk for single-client scenario,
+ * the feature can be easily deprecated, and
+ * it forces us to rewrite IME system server, which is expected to be a good chance to reconsider what Android IME protocol should look like.
+ * Most of form-factors such as Phones and TVs continue to use IMMS and support at most one focused IME client even under multi-display environment.
+
+
+## How to test
+
+On AOSP-based development devices (e.g. phones) where `android.os.Build.IS_DEBUGGABLE` returns `true` and you can have root access, you can enable multi-client IME feature by setting a valid component name that supports multi-client IME protocol to the system property `persist.debug.multi_client_ime`. Reboot is required for this to take effect.
+
+```shell
+# Build and install a sample multi-client IME
+make -j MultiClientInputMethod
+adb install -r $OUT/system/priv-app/MultiClientInputMethod/MultiClientInputMethod.apk
+
+# Enable multi-client IME for the side-loaded sample multi-client IME
+adb root
+adb shell setprop persist.debug.multi_client_ime com.example.android.multiclientinputmethod/.MultiClientInputMethod
+adb reboot
+```
+
+To disable multi-client IME on non-supported devices again, just clear `persist.debug.multi_client_ime` as follows. Reboot is still required for this to take effect.
+
+```shell
+# Disable multi-client IME again
+adb root
+adb shell "setprop persist.debug.multi_client_ime ''"
+adb reboot
+```
+
+## How to develop multi-client IMEs
+
+There is a sample multi-client IME in `development/samples/MultiClientInputMethod/`.
+
+## Versioning
+
+Neither forward nor backward compatibility is guaranteed in multi-client IME APIs. The system integrator is responsible for making sure that both the system and pre-installed multi-client IME are compatible with each other every time the system image is updated.
+
+## Implementation note
+
+### Unsupported features
+
+ * VR IME
+ * `VrManager#setVrInputMethod()` system API is not supported.
+ * InputMethodSubtype
+ * Following APIs are not supported
+ * `InputMethodManager#getEnabledInputMethodSubtypeList()`
+ * `InputMethodManager#getCurrentInputMethodSubtype()`
+ * `InputMethodManager#setCurrentInputMethodSubtype()`
+ * `InputMethodManager#getShortcutInputMethodsAndSubtypes()`
+ * `InputMethodManager#setAdditionalInputMethodSubtypes()`
+ * `InputMethodManager#getLastInputMethodSubtype()`
+ * `Settings.Secure#SELECTED_INPUT_METHOD_SUBTYPE`
+ * IME switching
+ * Following APIs are not supported
+ * `InputMethodManager#showInputMethodPicker()`
+ * `InputMethodManager#showInputMethodAndSubtypeEnabler()`
+ * `InputMethodManager#setInputMethod()`
+ * `InputMethodManager#setInputMethodAndSubtype()`
+ * `InputMethodManager#switchToLastInputMethod()`
+ * `InputMethodManager#switchToNextInputMethod()`
+ * `InputMethodManager#shouldOfferSwitchingToNextInputMethod()`
+ * `Settings.Secure#DEFAULT_INPUT_METHOD`
+ * `Settings.Secure#ENABLED_INPUT_METHODS`
+ * Direct-boot aware multi-client IME
+ * Device manufacturer can work around this by integrating in-app keyboard into the initial unlock screen.
+ * Full-screen mode
+ * Following API always returns `false`.
+ * `InputMethodManager#isFullscreenMode()`
+ * Custom inset
+ * For instance, floating IME cannot be implemented right now.
+ * Custom touchable region (`InputMethodService.Insets#touchableRegion`)
+ * Image Insertion API
+ * `InputConnection#commitContent()` API is silently ignored.
+ * `adb shell dumpsys` does not include any log from MCIMMS yet.
+
+### Security
+
+#### Root permission is required to enable MCIMMS on non-supported devices
+
+In order to override `persist.debug.multi_client_ime` device property, an explicit root permission is needed.
+
+#### Multi-client IME must be pre-installed
+
+Multi-client IME must be pre-installed since it is considered as part of the system component. This is verified by checking `ApplicationInfo.FLAG_SYSTEM` bit. This security check can be bypassed when `Build.IS_DEBUGGABLE` is `true` so that IME developers can easily side-load their APKs during development phase.
+
+```java
+public final class MultiClientInputMethodManagerService {
+ ...
+ @Nullable
+ private static InputMethodInfo queryInputMethod(Context context, @UserIdInt int userId,
+ @Nullable ComponentName componentName) {
+
+ ...
+
+ if (! && (si.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ Slog.e(TAG, imeId + " must be pre-installed when Build.IS_DEBUGGABLE is false");
+ return null;
+ }
+```
+[services/core/java/com/android/server/inputmethod/MultiClientInputMethodManagerService.java](MultiClientInputMethodManagerService.java)
+
+
+#### Integer handle vs IBinder token
+
+Sometimes MCIMMS needs to issue certain types of identifiers to the multi-client IME so that the IME can later specify to which entity or resource it intends to access. A good example is the IME client identifier. Multi-client IME definitely need to be able to specify which IME client to be interacted with for certain operations. The problem is that MCIMMS cannot simply pass `IInputMethodClient` to the multi-client IME as an ID because it would allow the IME to make IPC calls to the IME client. For this kind of situations, we usually use `Binder` object just as a non-spoofable token. For instance, IMMS creates another 'Binder' token then pass it to the IME, instead of directly passing 'IWindow' Binder token.
+
+```java
+public class InputMethodManagerService extends IInputMethodManager.Stub
+ implements ServiceConnection, Handler.Callback {
+ ...
+ @GuardedBy("mMethodMap")
+ private final WeakHashMap<IBinder, IBinder> mImeTargetWindowMap = new WeakHashMap<>();
+
+ ...
+
+ @GuardedBy("mMethodMap")
+ @NonNull
+ InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
+ ...
+ final Binder startInputToken = new Binder();
+ final StartInputInfo info = new StartInputInfo(mCurToken, mCurId, startInputReason,
+ !initial, mCurFocusedWindow, mCurAttribute, mCurFocusedWindowSoftInputMode,
+ mCurSeq);
+ mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow);
+ ...
+ }
+
+ ...
+
+ @BinderThread
+ private void reportStartInput(IBinder token, IBinder startInputToken) {
+ if (!calledWithValidToken(token)) {
+ return;
+ }
+
+ synchronized (mMethodMap) {
+ final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken);
+ if (targetWindow != null && mLastImeTargetWindow != targetWindow) {
+ mWindowManagerInternal.updateInputMethodTargetWindow(token, targetWindow);
+ }
+ mLastImeTargetWindow = targetWindow;
+ }
+ }
+```
+[services/core/java/com/android/server/inputmethod/InputMethodManagerService.java](InputMethodManagerService.java)
+
+However, in MCIMMS, for certain cases we decided to use a simple integer token, which can be spoofable and can be messed up if integer overflow happens. This is because:
+
+ * It does not make much sense to worry about malicious multi-client IMEs, because it is guaranteed to be a pre-installed system component.
+ * Integer token is expected to be a more lightweight that `Binder` token.
+ * For that use case, integer overflow is unrealistic.
+ * Strict user separation is still enforced. Multi-client IMEs are still not allowed to interact with other users' resources by any means.
+
+Currently the following IDs are implemented as integer tokens:
+
+ * Client ID
+ * Window Handle
+ * Note that each IME client has its own Window Handle mapping table. Window Handle is valid only within the associated IME client.
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index dd993b8..b3f0629 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -1740,11 +1740,6 @@
/**
* The state of at least one job has changed. Here is where we could enforce various
* policies on when we want to execute jobs.
- * Right now the policy is such:
- * If >1 of the ready jobs is idle mode we send all of them off
- * if more than 2 network connectivity jobs are ready we send them all off.
- * If more than 4 jobs total are ready we send them all off.
- * TODO: It would be nice to consolidate these sort of high-level policies somewhere.
*/
final class MaybeReadyJobQueueFunctor implements Consumer<JobStatus> {
int chargingCount;
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 4ece538d..35fc29e 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -68,10 +68,10 @@
public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE;
public static final long NO_EARLIEST_RUNTIME = 0L;
- static final int CONSTRAINT_CHARGING = JobInfo.CONSTRAINT_FLAG_CHARGING;
- static final int CONSTRAINT_IDLE = JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE;
- static final int CONSTRAINT_BATTERY_NOT_LOW = JobInfo.CONSTRAINT_FLAG_BATTERY_NOT_LOW;
- static final int CONSTRAINT_STORAGE_NOT_LOW = JobInfo.CONSTRAINT_FLAG_STORAGE_NOT_LOW;
+ static final int CONSTRAINT_CHARGING = JobInfo.CONSTRAINT_FLAG_CHARGING; // 1 < 0
+ static final int CONSTRAINT_IDLE = JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE; // 1 << 2
+ static final int CONSTRAINT_BATTERY_NOT_LOW = JobInfo.CONSTRAINT_FLAG_BATTERY_NOT_LOW; // 1 << 1
+ static final int CONSTRAINT_STORAGE_NOT_LOW = JobInfo.CONSTRAINT_FLAG_STORAGE_NOT_LOW; // 1 << 3
static final int CONSTRAINT_TIMING_DELAY = 1<<31;
static final int CONSTRAINT_DEADLINE = 1<<30;
static final int CONSTRAINT_CONNECTIVITY = 1<<28;
@@ -975,8 +975,7 @@
}
/**
- * @return Whether or not this job is ready to run, based on its requirements. This is true if
- * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
+ * @return Whether or not this job is ready to run, based on its requirements.
*/
public boolean isReady() {
// Deadline constraint trumps other constraints (except for periodic jobs where deadline
@@ -1234,16 +1233,18 @@
proto.end(token);
}
- // normalized bucket indices, not the AppStandby constants
- private String bucketName(int bucket) {
- switch (bucket) {
+ /**
+ * Returns a bucket name based on the normalized bucket indices, not the AppStandby constants.
+ */
+ String getBucketName() {
+ switch (standbyBucket) {
case 0: return "ACTIVE";
case 1: return "WORKING_SET";
case 2: return "FREQUENT";
case 3: return "RARE";
case 4: return "NEVER";
default:
- return "Unknown: " + bucket;
+ return "Unknown: " + standbyBucket;
}
}
@@ -1385,6 +1386,17 @@
if ((trackingControllers&TRACKING_TIME) != 0) pw.print(" TIME");
pw.println();
}
+
+ pw.print(prefix); pw.println("Implicit constraints:");
+ pw.print(prefix); pw.print(" readyNotDozing: ");
+ pw.println(mReadyNotDozing);
+ pw.print(prefix); pw.print(" readyNotRestrictedInBg: ");
+ pw.println(mReadyNotRestrictedInBg);
+ if (!job.isPeriodic() && hasDeadlineConstraint()) {
+ pw.print(prefix); pw.print(" readyDeadlineSatisfied: ");
+ pw.println(mReadyDeadlineSatisfied);
+ }
+
if (changedAuthorities != null) {
pw.print(prefix); pw.println("Changed authorities:");
for (int i=0; i<changedAuthorities.size(); i++) {
@@ -1413,7 +1425,7 @@
}
}
pw.print(prefix); pw.print("Standby bucket: ");
- pw.println(bucketName(standbyBucket));
+ pw.println(getBucketName());
if (standbyBucket > 0) {
pw.print(prefix); pw.print("Base heartbeat: ");
pw.println(baseHeartbeat);
@@ -1564,6 +1576,13 @@
JobStatusDumpProto.TRACKING_TIME);
}
+ // Implicit constraints
+ final long icToken = proto.start(JobStatusDumpProto.IMPLICIT_CONSTRAINTS);
+ proto.write(JobStatusDumpProto.ImplicitConstraints.IS_NOT_DOZING, mReadyNotDozing);
+ proto.write(JobStatusDumpProto.ImplicitConstraints.IS_NOT_RESTRICTED_IN_BG,
+ mReadyNotRestrictedInBg);
+ proto.end(icToken);
+
if (changedAuthorities != null) {
for (int k = 0; k < changedAuthorities.size(); k++) {
proto.write(JobStatusDumpProto.CHANGED_AUTHORITIES, changedAuthorities.valueAt(k));
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 53d54ba..f074573 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -24,7 +24,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.database.Cursor;
import android.hardware.location.GeofenceHardware;
import android.hardware.location.GeofenceHardwareImpl;
import android.location.Criteria;
@@ -42,12 +41,6 @@
import android.location.LocationManager;
import android.location.LocationProvider;
import android.location.LocationRequest;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.net.Uri;
import android.os.AsyncTask;
import android.os.BatteryStats;
import android.os.Binder;
@@ -67,7 +60,6 @@
import android.os.WorkSource;
import android.os.WorkSource.WorkChain;
import android.provider.Settings;
-import android.provider.Telephony.Carriers;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -92,8 +84,6 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
@@ -135,14 +125,6 @@
private static final int GPS_STATUS_ENGINE_ON = 3;
private static final int GPS_STATUS_ENGINE_OFF = 4;
- // these need to match AGnssStatusValue enum in IAGnssCallback.hal
- /** AGPS status event values. */
- private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
- private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
- private static final int GPS_AGPS_DATA_CONNECTED = 3;
- private static final int GPS_AGPS_DATA_CONN_DONE = 4;
- private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
-
// these need to match GnssLocationFlags enum in types.hal
private static final int LOCATION_INVALID = 0;
private static final int LOCATION_HAS_LAT_LONG = 1;
@@ -188,17 +170,6 @@
private static final int AGPS_TYPE_SUPL = 1;
private static final int AGPS_TYPE_C2K = 2;
- // these must match the ApnIpType enum in IAGnss.hal
- private static final int APN_INVALID = 0;
- private static final int APN_IPV4 = 1;
- private static final int APN_IPV6 = 2;
- private static final int APN_IPV4V6 = 3;
-
- // for mAGpsDataConnectionState
- private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
- private static final int AGPS_DATA_CONNECTION_OPENING = 1;
- private static final int AGPS_DATA_CONNECTION_OPEN = 2;
-
// Handler messages
private static final int CHECK_LOCATION = 1;
private static final int ENABLE = 2;
@@ -254,9 +225,6 @@
private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
// Default update duration in milliseconds for REQUEST_LOCATION.
private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
- // Default time limit in milliseconds for the ConnectivityManager to find a suitable
- // network with SUPL connectivity or report an error.
- private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000;
/** simpler wrapper for ProviderRequest + Worksource */
private static class GpsRequest {
@@ -427,12 +395,7 @@
// Handler for processing events
private Handler mHandler;
- /** It must be accessed only inside {@link #mHandler}. */
- private int mAGpsDataConnectionState;
- /** It must be accessed only inside {@link #mHandler}. */
- private InetAddress mAGpsDataConnectionIpAddr;
-
- private final ConnectivityManager mConnMgr;
+ private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
private final GpsNetInitiatedHandler mNIHandler;
// Wakelocks
@@ -507,60 +470,6 @@
public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
return mGnssNavigationMessageProvider;
}
-
- /**
- * Callback used to listen for data connectivity changes.
- */
- private final ConnectivityManager.NetworkCallback mNetworkConnectivityCallback =
- new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- mNtpTimeHelper.onNetworkAvailable();
- if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
- if (mSupportsXtra) {
- // Download only if supported, (prevents an unneccesary on-boot
- // download)
- xtraDownloadRequest();
- }
- }
- // Always on, notify HAL so it can get data it needs
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
-
- @Override
- public void onLost(Network network) {
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
- };
-
- /**
- * Callback used to listen for availability of a requested SUPL connection.
- * It is kept as a separate instance from {@link #mNetworkConnectivityCallback} to be able to
- * manage the registration/un-registration lifetimes separate.
- */
- private final ConnectivityManager.NetworkCallback mSuplConnectivityCallback =
- new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- if (DEBUG) Log.d(TAG, "SUPL network connection available.");
- // Specific to a change to a SUPL enabled network becoming ready
- sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
- }
-
- @Override
- public void onLost(Network network) {
- Log.i(TAG, "SUPL network connection lost.");
- releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
- }
-
- @Override
- public void onUnavailable() {
- Log.i(TAG, "SUPL network connection request timed out.");
- // Could not setup the connection to the network in the specified time duration.
- releaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
- }
- };
-
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -793,7 +702,10 @@
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
- mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(
+ context,
+ GnssLocationProvider.this::onNetworkAvailable,
+ looper);
// App ops service to keep track of who is accessing the GPS
mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -843,8 +755,8 @@
return isEnabled();
}
};
- mGnssMetrics = new GnssMetrics(mBatteryStats);
+ mGnssMetrics = new GnssMetrics(mBatteryStats);
mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
looper, this);
@@ -866,7 +778,6 @@
return PROPERTIES;
}
-
/**
* Implements {@link InjectNtpTimeCallback#injectTime}
*/
@@ -875,124 +786,17 @@
native_inject_time(time, timeReference, uncertainty);
}
- private void handleUpdateNetworkState(Network network) {
- // retrieve NetworkInfo for this UID
- NetworkInfo info = mConnMgr.getNetworkInfo(network);
-
- boolean networkAvailable = false;
- boolean isConnected = false;
- int type = ConnectivityManager.TYPE_NONE;
- boolean isRoaming = false;
- String apnName = null;
-
- if (info != null) {
- networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
- isConnected = info.isConnected();
- type = info.getType();
- isRoaming = info.isRoaming();
- apnName = info.getExtraInfo();
- }
-
- if (DEBUG) {
- String message = String.format(
- "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
- agpsDataConnStateAsString(),
- isConnected,
- info,
- mConnMgr.getNetworkCapabilities(network));
- Log.d(TAG, message);
- }
-
- if (native_is_agps_ril_supported()) {
- String defaultApn = getSelectedApn();
- if (defaultApn == null) {
- defaultApn = "dummy-apn";
+ /**
+ * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
+ */
+ private void onNetworkAvailable() {
+ mNtpTimeHelper.onNetworkAvailable();
+ if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
+ if (mSupportsXtra) {
+ // Download only if supported, (prevents an unneccesary on-boot
+ // download)
+ xtraDownloadRequest();
}
-
- native_update_network_state(
- isConnected,
- type,
- isRoaming,
- networkAvailable,
- apnName,
- defaultApn);
- } else if (DEBUG) {
- Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
- }
-
- if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
- if (isConnected) {
- if (apnName == null) {
- // assign a dummy value in the case of C2K as otherwise we will have a runtime
- // exception in the following call to native_agps_data_conn_open
- apnName = "dummy-apn";
- }
- int apnIpType = getApnIpType(apnName);
- setRouting();
- if (DEBUG) {
- String message = String.format(
- "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
- apnName,
- apnIpType);
- Log.d(TAG, message);
- }
- native_agps_data_conn_open(apnName, apnIpType);
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
- } else {
- handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
- }
- }
- }
-
- private void handleRequestSuplConnection(InetAddress address) {
- if (DEBUG) {
- String message = String.format(
- "requestSuplConnection, state=%s, address=%s",
- agpsDataConnStateAsString(),
- address);
- Log.d(TAG, message);
- }
-
- if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
- return;
- }
- mAGpsDataConnectionIpAddr = address;
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
-
- NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
- requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
- NetworkRequest request = requestBuilder.build();
- mConnMgr.requestNetwork(
- request,
- mSuplConnectivityCallback,
- SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS);
- }
-
- private void handleReleaseSuplConnection(int agpsDataConnStatus) {
- if (DEBUG) {
- String message = String.format(
- "releaseSuplConnection, state=%s, status=%s",
- agpsDataConnStateAsString(),
- agpsDataConnStatusAsString(agpsDataConnStatus));
- Log.d(TAG, message);
- }
-
- if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
- return;
- }
- mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
-
- mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
- switch (agpsDataConnStatus) {
- case GPS_AGPS_DATA_CONN_FAILED:
- native_agps_data_conn_failed();
- break;
- case GPS_RELEASE_AGPS_DATA_CONN:
- native_agps_data_conn_closed();
- break;
- default:
- Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
}
}
@@ -1091,7 +895,7 @@
// already downloading data
return;
}
- if (!isDataNetworkConnected()) {
+ if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
// try again when network is up
mDownloadXtraDataPending = STATE_PENDING_NETWORK;
return;
@@ -1822,41 +1626,7 @@
* called from native code to update AGPS status
*/
private void reportAGpsStatus(int type, int status, byte[] ipaddr) {
- switch (status) {
- case GPS_REQUEST_AGPS_DATA_CONN:
- if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
- Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
- InetAddress connectionIpAddress = null;
- if (ipaddr != null) {
- try {
- connectionIpAddress = InetAddress.getByAddress(ipaddr);
- if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
- } catch (UnknownHostException e) {
- Log.e(TAG, "Bad IP Address: " + ipaddr, e);
- }
- }
- sendMessage(REQUEST_SUPL_CONNECTION, 0 /*arg*/, connectionIpAddress);
- break;
- case GPS_RELEASE_AGPS_DATA_CONN:
- if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
- releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
- break;
- case GPS_AGPS_DATA_CONNECTED:
- if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
- break;
- case GPS_AGPS_DATA_CONN_DONE:
- if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
- break;
- case GPS_AGPS_DATA_CONN_FAILED:
- if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
- break;
- default:
- if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
- }
- }
-
- private void releaseSuplConnection(int connStatus) {
- sendMessage(RELEASE_SUPL_CONNECTION, connStatus, null /*obj*/);
+ mNetworkConnectivityHandler.onReportAGpsStatus(type, status, ipaddr);
}
/**
@@ -2332,15 +2102,6 @@
GpsRequest gpsRequest = (GpsRequest) msg.obj;
handleSetRequest(gpsRequest.request, gpsRequest.source);
break;
- case UPDATE_NETWORK_STATE:
- handleUpdateNetworkState((Network) msg.obj);
- break;
- case REQUEST_SUPL_CONNECTION:
- handleRequestSuplConnection((InetAddress) msg.obj);
- break;
- case RELEASE_SUPL_CONNECTION:
- handleReleaseSuplConnection(msg.arg1);
- break;
case INJECT_NTP_TIME:
mNtpTimeHelper.retrieveAndInjectNtpTime();
break;
@@ -2426,14 +2187,7 @@
intentFilter.addAction(SIM_STATE_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
- // register for connectivity change events, this is equivalent to the deprecated way of
- // registering for CONNECTIVITY_ACTION broadcasts
- NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
- networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
- networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
- networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
- NetworkRequest networkRequest = networkRequestBuilder.build();
- mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
+ mNetworkConnectivityHandler.registerNetworkCallbacks();
// listen for PASSIVE_PROVIDER updates
LocationManager locManager =
@@ -2491,160 +2245,6 @@
}
}
- private String getSelectedApn() {
- Uri uri = Uri.parse("content://telephony/carriers/preferapn");
- Cursor cursor = null;
- try {
- cursor = mContext.getContentResolver().query(
- uri,
- new String[]{"apn"},
- null /* selection */,
- null /* selectionArgs */,
- Carriers.DEFAULT_SORT_ORDER);
- if (cursor != null && cursor.moveToFirst()) {
- return cursor.getString(0);
- } else {
- Log.e(TAG, "No APN found to select.");
- }
- } catch (Exception e) {
- Log.e(TAG, "Error encountered on selecting the APN.", e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- return null;
- }
-
- private int getApnIpType(String apn) {
- ensureInHandlerThread();
- if (apn == null) {
- return APN_INVALID;
- }
- TelephonyManager phone = (TelephonyManager)
- mContext.getSystemService(Context.TELEPHONY_SERVICE);
- // Carrier configuration may override framework roaming state, we need to use the actual
- // modem roaming state instead of the framework roaming state.
- boolean isDataRoamingFromRegistration = phone.getServiceState().
- getDataRoamingFromRegistration();
- String projection = isDataRoamingFromRegistration ? Carriers.ROAMING_PROTOCOL :
- Carriers.PROTOCOL;
- String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
- Cursor cursor = null;
- try {
- cursor = mContext.getContentResolver().query(
- Carriers.CONTENT_URI,
- new String[]{projection},
- selection,
- null,
- Carriers.DEFAULT_SORT_ORDER);
-
- if (null != cursor && cursor.moveToFirst()) {
- return translateToApnIpType(cursor.getString(0), apn);
- } else {
- Log.e(TAG, "No entry found in query for APN: " + apn);
- }
- } catch (Exception e) {
- Log.e(TAG, "Error encountered on APN query for: " + apn, e);
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- return APN_INVALID;
- }
-
- private int translateToApnIpType(String ipProtocol, String apn) {
- if ("IP".equals(ipProtocol)) {
- return APN_IPV4;
- }
- if ("IPV6".equals(ipProtocol)) {
- return APN_IPV6;
- }
- if ("IPV4V6".equals(ipProtocol)) {
- return APN_IPV4V6;
- }
-
- // we hit the default case so the ipProtocol is not recognized
- String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
- Log.e(TAG, message);
- return APN_INVALID;
- }
-
- private void setRouting() {
- if (mAGpsDataConnectionIpAddr == null) {
- return;
- }
-
- // TODO: replace the use of this deprecated API
- boolean result = mConnMgr.requestRouteToHostAddress(
- ConnectivityManager.TYPE_MOBILE_SUPL,
- mAGpsDataConnectionIpAddr);
-
- if (!result) {
- Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
- } else if (DEBUG) {
- Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
- }
- }
-
- /**
- * @return {@code true} if there is a data network available for outgoing connections,
- * {@code false} otherwise.
- */
- private boolean isDataNetworkConnected() {
- NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
- return activeNetworkInfo != null && activeNetworkInfo.isConnected();
- }
-
- /**
- * Ensures the calling function is running in the thread associated with {@link #mHandler}.
- */
- private void ensureInHandlerThread() {
- if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
- return;
- }
- throw new RuntimeException("This method must run on the Handler thread.");
- }
-
- /**
- * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
- */
- private String agpsDataConnStateAsString() {
- switch (mAGpsDataConnectionState) {
- case AGPS_DATA_CONNECTION_CLOSED:
- return "CLOSED";
- case AGPS_DATA_CONNECTION_OPEN:
- return "OPEN";
- case AGPS_DATA_CONNECTION_OPENING:
- return "OPENING";
- default:
- return "<Unknown>";
- }
- }
-
- /**
- * @return A string representing the given GPS_AGPS_DATA status.
- */
- private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
- switch (agpsDataConnStatus) {
- case GPS_AGPS_DATA_CONNECTED:
- return "CONNECTED";
- case GPS_AGPS_DATA_CONN_DONE:
- return "DONE";
- case GPS_AGPS_DATA_CONN_FAILED:
- return "FAILED";
- case GPS_RELEASE_AGPS_DATA_CONN:
- return "RELEASE";
- case GPS_REQUEST_AGPS_DATA_CONN:
- return "REQUEST";
- default:
- return "<Unknown>";
- }
- }
-
/**
* @return A string representing the given message ID.
*/
@@ -2654,12 +2254,6 @@
return "ENABLE";
case SET_REQUEST:
return "SET_REQUEST";
- case UPDATE_NETWORK_STATE:
- return "UPDATE_NETWORK_STATE";
- case REQUEST_SUPL_CONNECTION:
- return "REQUEST_SUPL_CONNECTION";
- case RELEASE_SUPL_CONNECTION:
- return "RELEASE_SUPL_CONNECTION";
case INJECT_NTP_TIME:
return "INJECT_NTP_TIME";
case REQUEST_LOCATION:
@@ -2683,7 +2277,6 @@
}
}
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
StringBuilder s = new StringBuilder();
@@ -2723,8 +2316,6 @@
private static native boolean native_is_supported();
- private static native boolean native_is_agps_ril_supported();
-
private static native boolean native_is_gnss_configuration_supported();
private static native void native_init_once();
@@ -2770,12 +2361,6 @@
private native String native_get_internal_state();
// AGPS Support
- private native void native_agps_data_conn_open(String apn, int apnIpType);
-
- private native void native_agps_data_conn_closed();
-
- private native void native_agps_data_conn_failed();
-
private native void native_agps_ni_message(byte[] msg, int length);
private native void native_set_agps_server(int type, String hostname, int port);
@@ -2783,15 +2368,12 @@
// Network-initiated (NI) Support
private native void native_send_ni_response(int notificationId, int userResponse);
- // AGPS ril suport
+ // AGPS ril support
private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
int lac, int cid);
private native void native_agps_set_id(int type, String setid);
- private native void native_update_network_state(boolean connected, int type,
- boolean roaming, boolean available, String extraInfo, String defaultAPN);
-
// GNSS Configuration
private static native boolean native_set_supl_version(int version);
diff --git a/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
new file mode 100644
index 0000000..b211948
--- /dev/null
+++ b/services/core/java/com/android/server/location/GnssNetworkConnectivityHandler.java
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2018 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.location;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.provider.Telephony.Carriers;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Handles network connection requests and network state change updates for AGPS data download.
+ */
+class GnssNetworkConnectivityHandler {
+ static final String TAG = "GnssNetworkConnectivityHandler";
+
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+ // for mAGpsDataConnectionState
+ private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
+ private static final int AGPS_DATA_CONNECTION_OPENING = 1;
+ private static final int AGPS_DATA_CONNECTION_OPEN = 2;
+
+ // these need to match AGnssStatusValue enum in IAGnssCallback.hal
+ /** AGPS status event values. */
+ private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
+ private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
+ private static final int GPS_AGPS_DATA_CONNECTED = 3;
+ private static final int GPS_AGPS_DATA_CONN_DONE = 4;
+ private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
+
+ // these must match the ApnIpType enum in IAGnss.hal
+ private static final int APN_INVALID = 0;
+ private static final int APN_IPV4 = 1;
+ private static final int APN_IPV6 = 2;
+ private static final int APN_IPV4V6 = 3;
+
+ // Default time limit in milliseconds for the ConnectivityManager to find a suitable
+ // network with SUPL connectivity or report an error.
+ private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000;
+
+ private static final int HASH_MAP_INITIAL_CAPACITY_TO_TRACK_CONNECTED_NETWORKS = 5;
+
+ // keeps track of networks and their state as notified by the network request callbacks.
+ // Limit initial capacity to 5 as the number of connected networks will likely be small.
+ private ConcurrentHashMap<Network, NetworkAttributes> mAvailableNetworkAttributes =
+ new ConcurrentHashMap<>(HASH_MAP_INITIAL_CAPACITY_TO_TRACK_CONNECTED_NETWORKS);
+
+ private final ConnectivityManager mConnMgr;
+
+ private final Handler mHandler;
+ private final GnssNetworkListener mGnssNetworkListener;
+
+ private int mAGpsDataConnectionState;
+ private InetAddress mAGpsDataConnectionIpAddr;
+
+ private final Context mContext;
+
+ // Wakelocks
+ private static final String WAKELOCK_KEY = "GnssNetworkConnectivityHandler";
+ private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000;
+ private final PowerManager.WakeLock mWakeLock;
+
+ /**
+ * Network attributes needed when updating HAL about network connectivity status changes.
+ */
+ private static class NetworkAttributes {
+ NetworkCapabilities mCapabilities;
+ String mApn;
+ int mType = ConnectivityManager.TYPE_NONE;
+
+ /**
+ * Returns true if the capabilities that we pass on to HAL change between {@curCapabilities}
+ * and {@code newCapabilities}.
+ */
+ static boolean hasCapabilitiesChanged(NetworkCapabilities curCapabilities,
+ NetworkCapabilities newCapabilities) {
+ if (curCapabilities == null || newCapabilities == null) {
+ return true;
+ }
+
+ return curCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)
+ != newCapabilities.hasCapability(
+ NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+ }
+ }
+
+ /**
+ * Callback used to listen for data connectivity changes.
+ */
+ private ConnectivityManager.NetworkCallback mNetworkConnectivityCallback;
+
+ /**
+ * Callback used to listen for availability of a requested SUPL connection.
+ * It is kept as a separate instance from {@link #mNetworkConnectivityCallback} to be able to
+ * manage the registration/un-registration lifetimes separately.
+ */
+ private ConnectivityManager.NetworkCallback mSuplConnectivityCallback;
+
+ /**
+ * Interface to listen for network availability changes.
+ */
+ public interface GnssNetworkListener {
+ void onNetworkAvailable();
+ }
+
+ GnssNetworkConnectivityHandler(Context context,
+ GnssNetworkListener gnssNetworkListener,
+ Looper looper) {
+ mContext = context;
+ mGnssNetworkListener = gnssNetworkListener;
+
+ PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+
+ mHandler = new Handler(looper);
+ mConnMgr = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ mSuplConnectivityCallback = createSuplConnectivityCallback();
+ }
+
+ public void registerNetworkCallbacks() {
+ mAvailableNetworkAttributes.clear();
+ if (mNetworkConnectivityCallback != null) {
+ mConnMgr.unregisterNetworkCallback(mNetworkConnectivityCallback);
+ }
+
+ // register for connectivity change events.
+ NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
+ networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
+ networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
+ NetworkRequest networkRequest = networkRequestBuilder.build();
+ mNetworkConnectivityCallback = createNetworkConnectivityCallback();
+ mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
+ }
+
+ /**
+ * @return {@code true} if there is a data network available for outgoing connections,
+ * {@code false} otherwise.
+ */
+ public boolean isDataNetworkConnected() {
+ NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
+ return activeNetworkInfo != null && activeNetworkInfo.isConnected();
+ }
+
+ /**
+ * called from native code to update AGPS status
+ */
+ public void onReportAGpsStatus(int type, int status, byte[] ipaddr) {
+ switch (status) {
+ case GPS_REQUEST_AGPS_DATA_CONN:
+ if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
+ Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
+ InetAddress connectionIpAddress = null;
+ if (ipaddr != null) {
+ try {
+ connectionIpAddress = InetAddress.getByAddress(ipaddr);
+ if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
+ } catch (UnknownHostException e) {
+ Log.e(TAG, "Bad IP Address: " + ipaddr, e);
+ }
+ }
+ requestSuplConnection(connectionIpAddress);
+ break;
+ case GPS_RELEASE_AGPS_DATA_CONN:
+ if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
+ releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
+ break;
+ case GPS_AGPS_DATA_CONNECTED:
+ if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
+ break;
+ case GPS_AGPS_DATA_CONN_DONE:
+ if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
+ break;
+ case GPS_AGPS_DATA_CONN_FAILED:
+ if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
+ break;
+ default:
+ if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
+ }
+ }
+
+ private ConnectivityManager.NetworkCallback createNetworkConnectivityCallback() {
+ return new ConnectivityManager.NetworkCallback() {
+ // Used to filter out network capabilities changes that we are not interested in.
+ // NOTE: Not using a ConcurrentHashMap and also not using locking around updates
+ // and access to the map object because it is all done inside the same
+ // handler thread invoking the callback methods.
+ private HashMap<Network, NetworkCapabilities>
+ mAvailableNetworkCapabilities = new HashMap<>(
+ HASH_MAP_INITIAL_CAPACITY_TO_TRACK_CONNECTED_NETWORKS);
+
+ @Override
+ public void onCapabilitiesChanged(Network network,
+ NetworkCapabilities capabilities) {
+ // This callback is invoked for any change in the network capabilities including
+ // initial availability, and changes while still available. Only process if the
+ // capabilities that we pass on to HAL change.
+ if (!NetworkAttributes.hasCapabilitiesChanged(
+ mAvailableNetworkCapabilities.get(network), capabilities)) {
+ if (VERBOSE) {
+ Log.v(TAG, "Relevant network capabilities unchanged. Capabilities: "
+ + capabilities);
+ }
+ return;
+ }
+
+ mAvailableNetworkCapabilities.put(network, capabilities);
+ if (DEBUG) {
+ Log.d(TAG, "Network connected/capabilities updated. Available networks count: "
+ + mAvailableNetworkCapabilities.size());
+ }
+
+ mGnssNetworkListener.onNetworkAvailable();
+
+ // Always on, notify HAL so it can get data it needs
+ updateNetworkState(network, true, capabilities);
+ }
+
+ @Override
+ public void onLost(Network network) {
+ if (mAvailableNetworkCapabilities.remove(network) == null) {
+ Log.w(TAG, "Incorrectly received network callback onLost() before"
+ + " onCapabilitiesChanged() for network: " + network);
+ return;
+ }
+
+ Log.i(TAG, "Network connection lost. Available networks count: "
+ + mAvailableNetworkCapabilities.size());
+ updateNetworkState(network, false, null);
+ }
+ };
+ }
+
+ private ConnectivityManager.NetworkCallback createSuplConnectivityCallback() {
+ return new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ if (DEBUG) Log.d(TAG, "SUPL network connection available.");
+ // Specific to a change to a SUPL enabled network becoming ready
+ suplConnectionAvailable(network);
+ }
+
+ @Override
+ public void onLost(Network network) {
+ Log.i(TAG, "SUPL network connection lost.");
+ releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
+ }
+
+ @Override
+ public void onUnavailable() {
+ Log.i(TAG, "SUPL network connection request timed out.");
+ // Could not setup the connection to the network in the specified time duration.
+ releaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
+ }
+ };
+ }
+
+ private void requestSuplConnection(InetAddress inetAddress) {
+ postEvent(() -> handleRequestSuplConnection(inetAddress));
+ }
+
+ private void suplConnectionAvailable(Network network) {
+ postEvent(() -> handleSuplConnectionAvailable(network));
+ }
+
+ private void releaseSuplConnection(int connStatus) {
+ postEvent(() -> handleReleaseSuplConnection(connStatus));
+ }
+
+ private void updateNetworkState(Network network, boolean isConnected,
+ NetworkCapabilities capabilities) {
+ postEvent(() -> handleUpdateNetworkState(network, isConnected, capabilities));
+ }
+
+ private void postEvent(Runnable event) {
+ // hold a wake lock until this message is delivered
+ // note that this assumes the message will not be removed from the queue before
+ // it is handled (otherwise the wake lock would be leaked).
+ mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
+ if (!mHandler.post(runEventAndReleaseWakeLock(event))) {
+ mWakeLock.release();
+ }
+ }
+
+ private Runnable runEventAndReleaseWakeLock(Runnable event) {
+ return () -> {
+ try {
+ event.run();
+ } finally {
+ mWakeLock.release();
+ }
+ };
+ }
+
+ private void handleUpdateNetworkState(Network network, boolean isConnected,
+ NetworkCapabilities capabilities) {
+ boolean networkAvailable = isConnected && TelephonyManager.getDefault().getDataEnabled();
+ NetworkAttributes networkAttributes = updateTrackedNetworksState(isConnected, network,
+ capabilities);
+ String apnName = networkAttributes.mApn;
+ int type = networkAttributes.mType;
+ // When isConnected is false, capabilities argument is null. So, use last received
+ // capabilities.
+ capabilities = networkAttributes.mCapabilities;
+ boolean isRoaming = !capabilities.hasTransport(
+ NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+
+ Log.i(TAG, String.format(
+ "updateNetworkState, state=%s, connected=%s, network=%s, capabilities=%s"
+ + ", availableNetworkCount: %d",
+ agpsDataConnStateAsString(),
+ isConnected,
+ network,
+ capabilities,
+ mAvailableNetworkAttributes.size()));
+
+ if (native_is_agps_ril_supported()) {
+ String defaultApn = getSelectedApn();
+ if (defaultApn == null) {
+ defaultApn = "dummy-apn";
+ }
+
+ native_update_network_state(
+ isConnected,
+ type,
+ isRoaming,
+ networkAvailable,
+ apnName,
+ defaultApn);
+ } else if (DEBUG) {
+ Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
+ }
+ }
+
+ private NetworkAttributes updateTrackedNetworksState(boolean isConnected, Network network,
+ NetworkCapabilities capabilities) {
+ if (!isConnected) {
+ // Connection lost event. So, remove it from tracked networks.
+ return mAvailableNetworkAttributes.remove(network);
+ }
+
+ NetworkAttributes networkAttributes = mAvailableNetworkAttributes.get(network);
+ if (networkAttributes != null) {
+ // Capabilities updated event for the connected network.
+ networkAttributes.mCapabilities = capabilities;
+ return networkAttributes;
+ }
+
+ // Initial capabilities event (equivalent to connection available event).
+ networkAttributes = new NetworkAttributes();
+ networkAttributes.mCapabilities = capabilities;
+
+ // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
+ // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+ NetworkInfo info = mConnMgr.getNetworkInfo(network);
+ if (info != null) {
+ networkAttributes.mApn = info.getExtraInfo();
+ networkAttributes.mType = info.getType();
+ }
+
+ // Start tracking this network for connection status updates.
+ mAvailableNetworkAttributes.put(network, networkAttributes);
+ return networkAttributes;
+ }
+
+ private void handleSuplConnectionAvailable(Network network) {
+ // TODO(b/119278134): The synchronous method ConnectivityManager.getNetworkInfo() must
+ // not be called inside the asynchronous ConnectivityManager.NetworkCallback methods.
+ NetworkInfo info = mConnMgr.getNetworkInfo(network);
+ String apnName = null;
+ if (info != null) {
+ apnName = info.getExtraInfo();
+ }
+
+ if (DEBUG) {
+ String message = String.format(
+ "handleSuplConnectionAvailable: state=%s, suplNetwork=%s, info=%s",
+ agpsDataConnStateAsString(),
+ network,
+ info);
+ Log.d(TAG, message);
+ }
+
+ if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
+ if (apnName == null) {
+ // assign a dummy value in the case of C2K as otherwise we will have a runtime
+ // exception in the following call to native_agps_data_conn_open
+ apnName = "dummy-apn";
+ }
+ int apnIpType = getApnIpType(apnName);
+ setRouting();
+ if (DEBUG) {
+ String message = String.format(
+ "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
+ apnName,
+ apnIpType);
+ Log.d(TAG, message);
+ }
+ native_agps_data_conn_open(apnName, apnIpType);
+ mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
+ }
+ }
+
+ private void handleRequestSuplConnection(InetAddress address) {
+ if (DEBUG) {
+ String message = String.format(
+ "requestSuplConnection, state=%s, address=%s",
+ agpsDataConnStateAsString(),
+ address);
+ Log.d(TAG, message);
+ }
+
+ if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
+ return;
+ }
+ mAGpsDataConnectionIpAddr = address;
+ mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
+
+ NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
+ requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
+ NetworkRequest request = requestBuilder.build();
+ mConnMgr.requestNetwork(
+ request,
+ mSuplConnectivityCallback,
+ SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS);
+ }
+
+ private void handleReleaseSuplConnection(int agpsDataConnStatus) {
+ if (DEBUG) {
+ String message = String.format(
+ "releaseSuplConnection, state=%s, status=%s",
+ agpsDataConnStateAsString(),
+ agpsDataConnStatusAsString(agpsDataConnStatus));
+ Log.d(TAG, message);
+ }
+
+ if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
+ return;
+ }
+ mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
+
+ mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
+ switch (agpsDataConnStatus) {
+ case GPS_AGPS_DATA_CONN_FAILED:
+ native_agps_data_conn_failed();
+ break;
+ case GPS_RELEASE_AGPS_DATA_CONN:
+ native_agps_data_conn_closed();
+ break;
+ default:
+ Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
+ }
+ }
+
+ private void setRouting() {
+ if (mAGpsDataConnectionIpAddr == null) {
+ return;
+ }
+
+ // TODO(25876485): replace the use of this deprecated API
+ boolean result = mConnMgr.requestRouteToHostAddress(
+ ConnectivityManager.TYPE_MOBILE_SUPL,
+ mAGpsDataConnectionIpAddr);
+
+ if (!result) {
+ Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
+ } else if (DEBUG) {
+ Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
+ }
+ }
+
+ /**
+ * Ensures the calling function is running in the thread associated with {@link #mHandler}.
+ */
+ private void ensureInHandlerThread() {
+ if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
+ return;
+ }
+ throw new IllegalStateException("This method must run on the Handler thread.");
+ }
+
+ /**
+ * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
+ */
+ private String agpsDataConnStateAsString() {
+ switch (mAGpsDataConnectionState) {
+ case AGPS_DATA_CONNECTION_CLOSED:
+ return "CLOSED";
+ case AGPS_DATA_CONNECTION_OPEN:
+ return "OPEN";
+ case AGPS_DATA_CONNECTION_OPENING:
+ return "OPENING";
+ default:
+ return "<Unknown>";
+ }
+ }
+
+ /**
+ * @return A string representing the given GPS_AGPS_DATA status.
+ */
+ private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
+ switch (agpsDataConnStatus) {
+ case GPS_AGPS_DATA_CONNECTED:
+ return "CONNECTED";
+ case GPS_AGPS_DATA_CONN_DONE:
+ return "DONE";
+ case GPS_AGPS_DATA_CONN_FAILED:
+ return "FAILED";
+ case GPS_RELEASE_AGPS_DATA_CONN:
+ return "RELEASE";
+ case GPS_REQUEST_AGPS_DATA_CONN:
+ return "REQUEST";
+ default:
+ return "<Unknown>";
+ }
+ }
+
+ private int getApnIpType(String apn) {
+ ensureInHandlerThread();
+ if (apn == null) {
+ return APN_INVALID;
+ }
+ TelephonyManager phone = (TelephonyManager)
+ mContext.getSystemService(Context.TELEPHONY_SERVICE);
+ // Carrier configuration may override framework roaming state, we need to use the actual
+ // modem roaming state instead of the framework roaming state.
+ boolean isDataRoamingFromRegistration = phone.getServiceState()
+ .getDataRoamingFromRegistration();
+ String projection = isDataRoamingFromRegistration ? Carriers.ROAMING_PROTOCOL :
+ Carriers.PROTOCOL;
+ String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
+ try (Cursor cursor = mContext.getContentResolver().query(
+ Carriers.CONTENT_URI,
+ new String[]{projection},
+ selection,
+ null,
+ Carriers.DEFAULT_SORT_ORDER)) {
+ if (null != cursor && cursor.moveToFirst()) {
+ return translateToApnIpType(cursor.getString(0), apn);
+ } else {
+ Log.e(TAG, "No entry found in query for APN: " + apn);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error encountered on APN query for: " + apn, e);
+ }
+
+ return APN_INVALID;
+ }
+
+ private int translateToApnIpType(String ipProtocol, String apn) {
+ if ("IP".equals(ipProtocol)) {
+ return APN_IPV4;
+ }
+ if ("IPV6".equals(ipProtocol)) {
+ return APN_IPV6;
+ }
+ if ("IPV4V6".equals(ipProtocol)) {
+ return APN_IPV4V6;
+ }
+
+ // we hit the default case so the ipProtocol is not recognized
+ String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
+ Log.e(TAG, message);
+ return APN_INVALID;
+ }
+
+ private String getSelectedApn() {
+ Uri uri = Uri.parse("content://telephony/carriers/preferapn");
+ try (Cursor cursor = mContext.getContentResolver().query(
+ uri,
+ new String[]{"apn"},
+ null /* selection */,
+ null /* selectionArgs */,
+ Carriers.DEFAULT_SORT_ORDER)) {
+ if (cursor != null && cursor.moveToFirst()) {
+ return cursor.getString(0);
+ } else {
+ Log.e(TAG, "No APN found to select.");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error encountered on selecting the APN.", e);
+ }
+
+ return null;
+ }
+
+ // AGPS support
+ private native void native_agps_data_conn_open(String apn, int apnIpType);
+
+ private native void native_agps_data_conn_closed();
+
+ private native void native_agps_data_conn_failed();
+
+ // AGPS ril support
+ private static native boolean native_is_agps_ril_supported();
+
+ private native void native_update_network_state(boolean connected, int type,
+ boolean roaming, boolean available, String extraInfo, String defaultAPN);
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f87a5f7..b404c41 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -6564,6 +6564,7 @@
Bundle smartActions = new Bundle();
Bundle smartReplies = new Bundle();
Bundle audiblyAlerted = new Bundle();
+ Bundle noisy = new Bundle();
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
if (!isVisibleToListener(record.sbn, info)) {
@@ -6594,6 +6595,7 @@
smartActions.putParcelableArrayList(key, record.getSmartActions());
smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
audiblyAlerted.putBoolean(key, record.getAudiblyAlerted());
+ noisy.putBoolean(key, record.getSound() != null || record.getVibration() != null);
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
@@ -6605,7 +6607,7 @@
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
- smartActions, smartReplies, audiblyAlerted);
+ smartActions, smartReplies, audiblyAlerted, noisy);
}
boolean hasCompanionDevice(ManagedServiceInfo info) {
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 95c70d5..95d2154 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -49,7 +49,7 @@
import dalvik.system.DexFile;
-import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_NONE;
+import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED;
import static com.android.server.pm.Installer.DEXOPT_BOOTCOMPLETE;
import static com.android.server.pm.Installer.DEXOPT_DEBUGGABLE;
@@ -548,7 +548,7 @@
// Some apps are executed with restrictions on hidden API usage. If this app is one
// of them, pass a flag to dexopt to enable the same restrictions during compilation.
// TODO we should pass the actual flag value to dexopt, rather than assuming blacklist
- int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_NONE
+ int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_DISABLED
? 0
: DEXOPT_ENABLE_HIDDEN_API_CHECKS;
// Avoid generating CompactDex for modes that are latency critical.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ed5b33b6..77045fb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3203,9 +3203,8 @@
}
// The base directory for the package parser cache lives under /data/system/.
- final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
- "package_cache");
- if (cacheBaseDir == null) {
+ final File cacheBaseDir = Environment.getPackageCacheDirectory();
+ if (!FileUtils.createDir(cacheBaseDir)) {
return null;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 13bb817..4c93441 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -2777,13 +2777,13 @@
// dataPath - path to package's data path
// seinfo - seinfo label for the app (assigned at install time)
// gids - supplementary gids this app launches with
- // profileableFromShellFlag - 0 or 1 if the package is profileable from shell.
//
// NOTE: We prefer not to expose all ApplicationInfo flags for now.
//
// DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
- // system/core/libpackagelistparser
+ // frameworks/base/libs/packagelistparser
+ // system/core/run-as/run-as.c
//
sb.setLength(0);
sb.append(ai.packageName);
@@ -2803,8 +2803,6 @@
} else {
sb.append("none");
}
- sb.append(" ");
- sb.append(ai.isProfileableByShell() ? "1" : "0");
sb.append("\n");
writer.append(sb);
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 753c283..580e4f4 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -35,6 +35,7 @@
import android.util.jar.StrictJarFile;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.Installer;
import com.android.server.pm.Installer.InstallerException;
@@ -153,7 +154,7 @@
* @param classPaths the class paths corresponding to the class loaders names from
* {@param classLoadersNames}. The the first element corresponds to the first class loader
* and so on. A classpath is represented as a list of dex files separated by
- * {@code File.pathSeparator}.
+ * {@code File.pathSeparator}, or null if the class loader's classpath is not known.
* The dex files found in the first class path will be recorded in the usage file.
* @param loaderIsa the ISA of the app loading the dex files
* @param loaderUserId the user id which runs the code loading the dex files
@@ -169,7 +170,8 @@
}
}
- private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
+ @VisibleForTesting
+ /*package*/ void notifyDexLoadInternal(ApplicationInfo loadingAppInfo,
List<String> classLoaderNames, List<String> classPaths, String loaderIsa,
int loaderUserId) {
if (classLoaderNames.size() != classPaths.size()) {
@@ -186,8 +188,14 @@
return;
}
+ // The first classpath should never be null because the first classloader
+ // should always be an instance of BaseDexClassLoader.
+ String firstClassPath = classPaths.get(0);
+ if (firstClassPath == null) {
+ return;
+ }
// The classpath is represented as a list of dex files separated by File.pathSeparator.
- String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator);
+ String[] dexPathsToRegister = firstClassPath.split(File.pathSeparator);
// Encode the class loader contexts for the dexPathsToRegister.
String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index e1310a2..d2600b5 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -318,7 +318,8 @@
// is fine (they come over binder). Even if something changes we expect the sizes to be
// very small and it shouldn't matter much.
for (int i = 1; i < classLoadersNames.size(); i++) {
- if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) {
+ if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))
+ || classPaths.get(i) == null) {
return null;
}
String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator));
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 2be55c0..cef484f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -15,7 +15,13 @@
*/
package com.android.server.stats;
+import static android.os.Process.getPidsForCommands;
+import static android.os.Process.getUidForPid;
+
import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
+import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
@@ -96,6 +102,7 @@
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
+import com.android.server.am.MemoryStatUtil.MemoryStat;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -1012,17 +1019,23 @@
private void pullNativeProcessMemoryState(
int tagId, long elapsedNanos, long wallClockNanos,
List<StatsLogEventWrapper> pulledData) {
- List<ProcessMemoryState> processMemoryStates = LocalServices.getService(
- ActivityManagerInternal.class).getMemoryStateForNativeProcesses();
- for (ProcessMemoryState processMemoryState : processMemoryStates) {
+ int[] pids = getPidsForCommands(MEMORY_STAT_INTERESTING_NATIVE_PROCESSES);
+ for (int i = 0; i < pids.length; i++) {
+ int pid = pids[i];
+ MemoryStat memoryStat = readMemoryStatFromProcfs(pid);
+ if (memoryStat == null) {
+ continue;
+ }
+ int uid = getUidForPid(pid);
+ String processName = readCmdlineFromProcfs(pid);
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
- e.writeInt(processMemoryState.uid);
- e.writeString(processMemoryState.processName);
- e.writeLong(processMemoryState.pgfault);
- e.writeLong(processMemoryState.pgmajfault);
- e.writeLong(processMemoryState.rssInBytes);
- e.writeLong(processMemoryState.rssHighWatermarkInBytes);
- e.writeLong(processMemoryState.startTimeNanos);
+ e.writeInt(uid);
+ e.writeString(processName);
+ e.writeLong(memoryStat.pgfault);
+ e.writeLong(memoryStat.pgmajfault);
+ e.writeLong(memoryStat.rssInBytes);
+ e.writeLong(memoryStat.rssHighWatermarkInBytes);
+ e.writeLong(memoryStat.startTimeNanos);
pulledData.add(e);
}
}
@@ -1856,7 +1869,10 @@
public void notifyThrottling(Temperature temp) {
boolean isThrottling = temp.getStatus() >= Temperature.THROTTLING_SEVERE;
StatsLog.write(StatsLog.THERMAL_THROTTLING, temp.getType(),
- isThrottling ? 1 : 0, temp.getValue());
+ isThrottling ?
+ StatsLog.THERMAL_THROTTLING_STATE_CHANGED__STATE__START :
+ StatsLog.THERMAL_THROTTLING_STATE_CHANGED__STATE__STOP,
+ temp.getValue());
}
}
}
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 79eab6b..ec78560 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -140,13 +140,14 @@
switch (which) {
case 1:
what1 = what;
- return;
+ break;
case 2:
what2 = what;
- return;
+ break;
default:
Slog.w(TAG, "Can't set unsupported disable flag " + which
+ ": 0x" + Integer.toHexString(what));
+ break;
}
this.pkg = pkg;
}
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 478a11a..751ae0d 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -1103,13 +1103,12 @@
}
/**
+ * Checks if system decorations should be shown on this display.
+ *
* @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
*/
boolean supportsSystemDecorations() {
- return mDisplay.supportsSystemDecorations()
- // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
- // (b/114338689) whenever vr 2d display id is set.
- || mDisplayId == mSupervisor.mService.mVr2dDisplayId;
+ return mWindowContainerController.supportsSystemDecorations();
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 9b01dfd..61e1414 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -72,12 +72,12 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
import static com.android.server.am.MemoryStatUtil.MemoryStat;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
import android.app.WindowConfiguration.WindowingMode;
@@ -495,7 +495,9 @@
foundInfo = info;
}
if (allWindowsDrawn()) {
- reset(false /* abort */, foundInfo, "notifyTransitionStarting - all windows drawn");
+ // abort metrics collection if we cannot find a matching transition.
+ final boolean abortMetrics = foundInfo == null;
+ reset(abortMetrics, foundInfo, "notifyTransitionStarting - all windows drawn");
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 8223693..23f8125 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1009,8 +1009,8 @@
updateOverrideConfiguration();
mWindowContainerController = new AppWindowContainerController(taskController, appToken,
- this, Integer.MAX_VALUE /* add on top */, info.screenOrientation, fullscreen,
- (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
+ realActivity, this, Integer.MAX_VALUE /* add on top */, info.screenOrientation,
+ fullscreen, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
appInfo.targetSdkVersion, mRotationAnimationHint,
ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 1944184..7fcee3db 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -5184,12 +5184,14 @@
/**
* Removes the input task from this stack.
+ *
* @param task to remove.
* @param reason for removal.
* @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING},
* {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
*/
void removeTask(TaskRecord task, String reason, int mode) {
+ // TODO(b/119259346): Move some logic below to TaskRecord. See bug for more context.
for (ActivityRecord record : task.mActivities) {
onActivityRemovedFromStack(record);
}
@@ -5204,6 +5206,9 @@
updateTaskMovement(task, true);
if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) {
+ // This task is going away, so save the last state if necessary.
+ task.saveLaunchingStateIfNeeded();
+
// TODO: VI what about activity?
final boolean isVoiceSession = task.voiceSession != null;
if (isVoiceSession) {
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 6034f81..97eaafc 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -174,6 +174,7 @@
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import android.view.DisplayInfo;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -327,6 +328,9 @@
WindowManagerService mWindowManager;
DisplayManager mDisplayManager;
+ /** Common synchronization logic used to save things to disks. */
+ PersisterQueue mPersisterQueue;
+ LaunchParamsPersister mLaunchParamsPersister;
private LaunchParamsController mLaunchParamsController;
/**
@@ -631,10 +635,16 @@
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper());
mKeyguardController = new KeyguardController(mService, this);
- mLaunchParamsController = new LaunchParamsController(mService);
+ mPersisterQueue = new PersisterQueue();
+ mLaunchParamsPersister = new LaunchParamsPersister(mPersisterQueue, this);
+ mLaunchParamsController = new LaunchParamsController(mService, mLaunchParamsPersister);
mLaunchParamsController.registerDefaultModifiers(this);
}
+ void onSystemReady() {
+ mPersisterQueue.startPersisting();
+ mLaunchParamsPersister.onSystemReady();
+ }
public ActivityMetricsLogger getActivityMetricsLogger() {
return mActivityMetricsLogger;
@@ -1280,15 +1290,24 @@
if (!aInfo.processName.equals("system")) {
if ((startFlags & (START_FLAG_DEBUG | START_FLAG_NATIVE_DEBUGGING
| START_FLAG_TRACK_ALLOCATION)) != 0 || profilerInfo != null) {
- /**
- * Assume safe to call into AMS synchronously because the call that set these
- * flags should have originated from AMS which will already have its lock held.
- * @see ActivityManagerService#startActivityAndWait(IApplicationThread, String,
- * Intent, String, IBinder, String, int, int, ProfilerInfo, Bundle, int)
- * TODO(b/80414790): Investigate a better way of untangling this.
- */
- mService.mAmInternal.setDebugFlagsForStartingActivity(
- aInfo, startFlags, profilerInfo);
+
+ // Mimic an AMS synchronous call by passing a message to AMS and wait for AMS
+ // to notify us that the task has completed.
+ // TODO(b/80414790) look into further untangling for the situation where the
+ // caller is on the same thread as the handler we are posting to.
+ synchronized (mService.mGlobalLock) {
+ // Post message to AMS.
+ final Message msg = PooledLambda.obtainMessage(
+ ActivityManagerInternal::setDebugFlagsForStartingActivity,
+ mService.mAmInternal, aInfo, startFlags, profilerInfo,
+ mService.mGlobalLock);
+ mService.mH.sendMessage(msg);
+ try {
+ mService.mGlobalLock.wait();
+ } catch (InterruptedException ignore) {
+
+ }
+ }
}
}
final String intentLaunchToken = intent.getLaunchToken();
@@ -1637,6 +1656,13 @@
// restart the application.
}
+ // Suppress transition until the new activity becomes ready, otherwise the keyguard can
+ // appear for a short amount of time before the new process with the new activity had the
+ // ability to set its showWhenLocked flags.
+ if (getKeyguardController().isKeyguardLocked()) {
+ r.notifyUnknownVisibilityLaunched();
+ }
+
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
final Message msg = PooledLambda.obtainMessage(
@@ -4233,6 +4259,25 @@
return activityDisplay;
}
+ /**
+ * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
+ * defined in {@link DisplayInfo#uniqueId}.
+ *
+ * @param uniqueId the unique ID of the display
+ * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
+ */
+ ActivityDisplay getActivityDisplay(String uniqueId) {
+ for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
+ final ActivityDisplay display = mActivityDisplays.get(i);
+ final boolean isValid = display.mDisplay.isValid();
+ if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
+ return display;
+ }
+ }
+
+ return null;
+ }
+
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 433c05a..1d00075 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -56,13 +56,13 @@
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
import static android.provider.Settings.System.FONT_SCALE;
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.TRANSIT_NONE;
@@ -279,6 +279,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -396,6 +397,30 @@
// How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
private static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
+ // Permission tokens are used to temporarily granted a trusted app the ability to call
+ // #startActivityAsCaller. A client is expected to dump its token after this time has elapsed,
+ // showing any appropriate error messages to the user.
+ private static final long START_AS_CALLER_TOKEN_TIMEOUT =
+ 10 * MINUTE_IN_MILLIS;
+
+ // How long before the service actually expires a token. This is slightly longer than
+ // START_AS_CALLER_TOKEN_TIMEOUT, to provide a buffer so clients will rarely encounter the
+ // expiration exception.
+ private static final long START_AS_CALLER_TOKEN_TIMEOUT_IMPL =
+ START_AS_CALLER_TOKEN_TIMEOUT + 2 * 1000;
+
+ // How long the service will remember expired tokens, for the purpose of providing error
+ // messaging when a client uses an expired token.
+ private static final long START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT =
+ START_AS_CALLER_TOKEN_TIMEOUT_IMPL + 20 * MINUTE_IN_MILLIS;
+
+ // Activity tokens of system activities that are delegating their call to
+ // #startActivityByCaller, keyed by the permissionToken granted to the delegate.
+ final HashMap<IBinder, IBinder> mStartActivitySources = new HashMap<>();
+
+ // Permission tokens that have expired, but we remember for error reporting.
+ final ArrayList<IBinder> mExpiredStartAsCallerTokens = new ArrayList<>();
+
private final ArrayList<PendingAssistExtras> mPendingAssistExtras = new ArrayList<>();
// Keeps track of the active voice interaction service component, notified from
@@ -628,6 +653,7 @@
mAssistUtils = new AssistUtils(mContext);
mVrController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
+ mStackSupervisor.onSystemReady();
}
}
@@ -658,8 +684,6 @@
ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
final boolean supportsMultiDisplay = mContext.getPackageManager()
.hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
- final boolean alwaysFinishActivities =
- Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
final boolean forceResizable = Settings.Global.getInt(
resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
@@ -887,6 +911,20 @@
mService.start();
}
+ @Override
+ public void onUnlockUser(int userId) {
+ synchronized (mService.getGlobalLock()) {
+ mService.mStackSupervisor.mLaunchParamsPersister.onUnlockUser(userId);
+ }
+ }
+
+ @Override
+ public void onCleanupUser(int userId) {
+ synchronized (mService.getGlobalLock()) {
+ mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
+ }
+ }
+
public ActivityTaskManagerService getService() {
return mService;
}
@@ -1146,16 +1184,43 @@
}
}
+
+ @Override
+ public IBinder requestStartActivityPermissionToken(IBinder delegatorToken) {
+ int callingUid = Binder.getCallingUid();
+ if (UserHandle.getAppId(callingUid) != SYSTEM_UID) {
+ throw new SecurityException("Only the system process can request a permission token, "
+ + "received request from uid: " + callingUid);
+ }
+ IBinder permissionToken = new Binder();
+ synchronized (mGlobalLock) {
+ mStartActivitySources.put(permissionToken, delegatorToken);
+ }
+
+ Message expireMsg = PooledLambda.obtainMessage(
+ ActivityTaskManagerService::expireStartAsCallerTokenMsg, this, permissionToken);
+ mUiHandler.sendMessageDelayed(expireMsg, START_AS_CALLER_TOKEN_TIMEOUT_IMPL);
+
+ Message forgetMsg = PooledLambda.obtainMessage(
+ ActivityTaskManagerService::forgetStartAsCallerTokenMsg, this, permissionToken);
+ mUiHandler.sendMessageDelayed(forgetMsg, START_AS_CALLER_TOKEN_EXPIRED_TIMEOUT);
+
+ return permissionToken;
+ }
+
@Override
public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
- int userId) {
-
+ int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
+ boolean ignoreTargetSecurity, int userId) {
// This is very dangerous -- it allows you to perform a start activity (including
- // permission grants) as any app that may launch one of your own activities. So
- // we will only allow this to be done from activities that are part of the core framework,
- // and then only when they are running as the system.
+ // permission grants) as any app that may launch one of your own activities. So we only
+ // allow this in two cases:
+ // 1) The caller is an activity that is part of the core framework, and then only when it
+ // is running as the system.
+ // 2) The caller provides a valid permissionToken. Permission tokens are one-time use and
+ // can only be requested by a system activity, which may then delegate this call to
+ // another app.
final ActivityRecord sourceRecord;
final int targetUid;
final String targetPackage;
@@ -1164,17 +1229,46 @@
if (resultTo == null) {
throw new SecurityException("Must be called from an activity");
}
- sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
- if (sourceRecord == null) {
- throw new SecurityException("Called with bad activity token: " + resultTo);
+ final IBinder sourceToken;
+ if (permissionToken != null) {
+ // To even attempt to use a permissionToken, an app must also have this signature
+ // permission.
+ mAmInternal.enforceCallingPermission(
+ android.Manifest.permission.START_ACTIVITY_AS_CALLER,
+ "startActivityAsCaller");
+ // If called with a permissionToken, we want the sourceRecord from the delegator
+ // activity that requested this token.
+ sourceToken = mStartActivitySources.remove(permissionToken);
+ if (sourceToken == null) {
+ // Invalid permissionToken, check if it recently expired.
+ if (mExpiredStartAsCallerTokens.contains(permissionToken)) {
+ throw new SecurityException("Called with expired permission token: "
+ + permissionToken);
+ } else {
+ throw new SecurityException("Called with invalid permission token: "
+ + permissionToken);
+ }
+ }
+ } else {
+ // This method was called directly by the source.
+ sourceToken = resultTo;
}
- if (!sourceRecord.info.packageName.equals("android")) {
- throw new SecurityException(
- "Must be called from an activity that is declared in the android package");
+
+ sourceRecord = mStackSupervisor.isInAnyStackLocked(sourceToken);
+ if (sourceRecord == null) {
+ throw new SecurityException("Called with bad activity token: " + sourceToken);
}
if (sourceRecord.app == null) {
throw new SecurityException("Called without a process attached to activity");
}
+
+ // Whether called directly or from a delegate, the source activity must be from the
+ // android package.
+ if (!sourceRecord.info.packageName.equals("android")) {
+ throw new SecurityException("Must be called from an activity that is "
+ + "declared in the android package");
+ }
+
if (UserHandle.getAppId(sourceRecord.app.mUid) != SYSTEM_UID) {
// This is still okay, as long as this activity is running under the
// uid of the original calling activity.
@@ -2666,6 +2760,9 @@
pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
}
if (structure != null) {
+ // Pre-fill the task/activity component for all assist data receivers
+ structure.setTaskId(pae.activity.getTask().taskId);
+ structure.setActivityComponent(pae.activity.realActivity);
structure.setHomeActivity(pae.isHome);
}
pae.haveResult = true;
@@ -4904,6 +5001,15 @@
}
}
+ private void expireStartAsCallerTokenMsg(IBinder permissionToken) {
+ mStartActivitySources.remove(permissionToken);
+ mExpiredStartAsCallerTokens.add(permissionToken);
+ }
+
+ private void forgetStartAsCallerTokenMsg(IBinder permissionToken) {
+ mExpiredStartAsCallerTokens.remove(permissionToken);
+ }
+
boolean isActivityStartsLoggingEnabled() {
return mAmInternal.isActivityStartsLoggingEnabled();
}
@@ -5455,6 +5561,8 @@
final class H extends Handler {
static final int REPORT_TIME_TRACKER_MSG = 1;
+
+
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_SUPERVISOR_STACK_MSG = 200;
@@ -5628,8 +5736,12 @@
// We might change the visibilities here, so prepare an empty app transition which
// might be overridden later if we actually change visibilities.
- final DisplayWindowController dwc = mStackSupervisor.getActivityDisplay(displayId)
- .getWindowContainerController();
+ final ActivityDisplay activityDisplay =
+ mStackSupervisor.getActivityDisplay(displayId);
+ if (activityDisplay == null) {
+ return;
+ }
+ final DisplayWindowController dwc = activityDisplay.getWindowContainerController();
final boolean wasTransitionSet = dwc.getPendingAppTransition() != TRANSIT_NONE;
if (!wasTransitionSet) {
dwc.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */);
@@ -6758,4 +6870,4 @@
}
}
}
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 830c2e6..3cbb2577 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -42,6 +42,7 @@
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityOptions;
import android.content.Intent;
+import android.content.ComponentName;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.GraphicBuffer;
@@ -200,20 +201,21 @@
};
public AppWindowContainerController(TaskWindowContainerController taskController,
- IApplicationToken token, AppWindowContainerListener listener, int index,
- int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
+ IApplicationToken token, ComponentName activityComponent,
+ AppWindowContainerListener listener, int index, int requestedOrientation,
+ boolean fullscreen, boolean showForAllUsers, int configChanges,
boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos) {
- this(taskController, token, listener, index, requestedOrientation, fullscreen,
- showForAllUsers,
- configChanges, voiceInteraction, launchTaskBehind, alwaysFocusable,
- targetSdkVersion, rotationAnimationHint, inputDispatchingTimeoutNanos,
- WindowManagerService.getInstance());
+ this(taskController, token, activityComponent, listener, index, requestedOrientation,
+ fullscreen, showForAllUsers, configChanges, voiceInteraction, launchTaskBehind,
+ alwaysFocusable, targetSdkVersion, rotationAnimationHint,
+ inputDispatchingTimeoutNanos, WindowManagerService.getInstance());
}
public AppWindowContainerController(TaskWindowContainerController taskController,
- IApplicationToken token, AppWindowContainerListener listener, int index,
- int requestedOrientation, boolean fullscreen, boolean showForAllUsers, int configChanges,
+ IApplicationToken token, ComponentName activityComponent,
+ AppWindowContainerListener listener, int index, int requestedOrientation,
+ boolean fullscreen, boolean showForAllUsers, int configChanges,
boolean voiceInteraction, boolean launchTaskBehind, boolean alwaysFocusable,
int targetSdkVersion, int rotationAnimationHint, long inputDispatchingTimeoutNanos,
WindowManagerService service) {
@@ -234,10 +236,10 @@
+ " controller=" + taskController);
}
- atoken = createAppWindow(mService, token, voiceInteraction, task.getDisplayContent(),
- inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdkVersion,
- requestedOrientation, rotationAnimationHint, configChanges, launchTaskBehind,
- alwaysFocusable, this);
+ atoken = createAppWindow(mService, token, activityComponent, voiceInteraction,
+ task.getDisplayContent(), inputDispatchingTimeoutNanos, fullscreen,
+ showForAllUsers, targetSdkVersion, requestedOrientation, rotationAnimationHint,
+ configChanges, launchTaskBehind, alwaysFocusable, this);
if (DEBUG_TOKEN_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "addAppToken: " + atoken
+ " controller=" + taskController + " at " + index);
task.addChild(atoken, index);
@@ -246,11 +248,12 @@
@VisibleForTesting
AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
- boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
- boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
- int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
- boolean alwaysFocusable, AppWindowContainerController controller) {
- return new AppWindowToken(service, token, voiceInteraction, dc,
+ ComponentName component, boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
+ int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
+ boolean launchTaskBehind, boolean alwaysFocusable,
+ AppWindowContainerController controller) {
+ return new AppWindowToken(service, token, component, voiceInteraction, dc,
inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk, orientation,
rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
controller);
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 9baafcb..d30cd19 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -81,6 +81,7 @@
import android.annotation.CallSuper;
import android.app.Activity;
+import android.content.ComponentName;
import android.content.res.Configuration;
import android.graphics.GraphicBuffer;
import android.graphics.Point;
@@ -130,7 +131,7 @@
// Non-null only for application tokens.
final IApplicationToken appToken;
-
+ final ComponentName mActivityComponent;
final boolean mVoiceInteraction;
/** @see WindowContainer#fillsParent() */
@@ -272,12 +273,13 @@
/** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
boolean mNeedsAnimationBoundsLayer;
- AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
- DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
- boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
- int configChanges, boolean launchTaskBehind, boolean alwaysFocusable,
+ AppWindowToken(WindowManagerService service, IApplicationToken token,
+ ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
+ int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
+ boolean launchTaskBehind, boolean alwaysFocusable,
AppWindowContainerController controller) {
- this(service, token, voiceInteraction, dc, fullscreen);
+ this(service, token, activityComponent, voiceInteraction, dc, fullscreen);
setController(controller);
mInputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos;
mShowForAllUsers = showForAllUsers;
@@ -293,11 +295,13 @@
hiddenRequested = true;
}
- AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
- DisplayContent dc, boolean fillsParent) {
+ AppWindowToken(WindowManagerService service, IApplicationToken token,
+ ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
+ boolean fillsParent) {
super(service, token != null ? token.asBinder() : null, TYPE_APPLICATION, true, dc,
false /* ownerCanManageAppTokens */);
appToken = token;
+ mActivityComponent = activityComponent;
mVoiceInteraction = voiceInteraction;
mFillsParent = fillsParent;
mInputApplicationHandle = new InputApplicationHandle(this);
@@ -2155,6 +2159,7 @@
if (appToken != null) {
pw.println(prefix + "app=true mVoiceInteraction=" + mVoiceInteraction);
}
+ pw.println(prefix + "component=" + mActivityComponent.flattenToShortString());
pw.print(prefix); pw.print("task="); pw.println(getTask());
pw.print(prefix); pw.print(" mFillsParent="); pw.print(mFillsParent);
pw.print(" mOrientation="); pw.println(mOrientation);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index fece980..767a6ef 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2011,9 +2011,7 @@
mDisplay.getDisplayInfo(mDisplayInfo);
mDisplay.getMetrics(mDisplayMetrics);
- for (int i = mTaskStackContainers.getChildCount() - 1; i >= 0; --i) {
- mTaskStackContainers.getChildAt(i).updateDisplayInfo(null);
- }
+ onDisplayChanged(this);
}
void initializeDisplayBaseInfo() {
@@ -2132,7 +2130,7 @@
if (density == mInitialDisplayDensity) {
density = 0;
}
- mService.mDisplaySettings.setForcedDensity(this, density, userId);
+ mService.mDisplayWindowSettings.setForcedDensity(this, density, userId);
}
/** @param mode {@link #FORCE_SCALING_MODE_AUTO} or {@link #FORCE_SCALING_MODE_DISABLED}. */
@@ -2145,7 +2143,7 @@
Slog.i(TAG_WM, "Using display scaling mode: " + (mDisplayScalingDisabled ? "off" : "auto"));
mService.reconfigureDisplayLocked(this);
- mService.mDisplaySettings.setForcedScalingMode(this, mode);
+ mService.mDisplayWindowSettings.setForcedScalingMode(this, mode);
}
/** If the given width and height equal to initial size, the setting will be cleared. */
@@ -2167,7 +2165,7 @@
if (clear) {
width = height = 0;
}
- mService.mDisplaySettings.setForcedSize(this, width, height);
+ mService.mDisplayWindowSettings.setForcedSize(this, width, height);
}
void getStableRect(Rect out) {
@@ -4666,4 +4664,16 @@
pendingLayoutChanges |= changes;
}
+
+ /**
+ * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ boolean supportsSystemDecorations() {
+ // TODO(b/114338689): Read the setting from DisplaySettings.
+ return mDisplay.supportsSystemDecorations()
+ // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
+ // (b/114338689) whenever vr 2d display id is set.
+ || mDisplayId == mService.mVr2dDisplayId
+ || mService.mForceDesktopModeOnExternalDisplays;
+ }
}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 9f98dc5..6ab7090 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -265,7 +265,8 @@
mUserRotation = userRotation;
changed = true;
}
- mService.mDisplaySettings.setUserRotation(mDisplayContent, userRotationMode, userRotation);
+ mService.mDisplayWindowSettings.setUserRotation(mDisplayContent, userRotationMode,
+ userRotation);
if (changed) {
mService.updateRotation(true /* alwaysSendConfiguration */,
false /* forceRelayout */);
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index 632494b..864f7e1 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -339,6 +339,17 @@
|| transit == TRANSIT_TASK_TO_FRONT;
}
+ /**
+ * Checks if system decorations should be shown on this display.
+ *
+ * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+ */
+ public boolean supportsSystemDecorations() {
+ synchronized (mGlobalLock) {
+ return mContainer.supportsSystemDecorations();
+ }
+ }
+
@Override
public String toString() {
return "{DisplayWindowController displayId=" + mDisplayId + "}";
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
similarity index 69%
rename from services/core/java/com/android/server/wm/DisplaySettings.java
rename to services/core/java/com/android/server/wm/DisplayWindowSettings.java
index 44956ab..f7dfd3f 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -16,6 +16,10 @@
package com.android.server.wm;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
+
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_AUTO;
import static com.android.server.wm.DisplayContent.FORCE_SCALING_MODE_DISABLED;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -52,8 +56,8 @@
/**
* Current persistent settings about a display
*/
-class DisplaySettings {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplaySettings" : TAG_WM;
+class DisplayWindowSettings {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM;
private final WindowManagerService mService;
private final AtomicFile mFile;
@@ -72,9 +76,13 @@
private int mForcedHeight;
private int mForcedDensity;
private int mForcedScalingMode = FORCE_SCALING_MODE_AUTO;
+ private int mRemoveContentMode = REMOVE_CONTENT_MODE_UNDEFINED;
+ private boolean mShouldShowWithInsecureKeyguard = false;
+ private boolean mShouldShowSystemDecors = false;
+ private boolean mShouldShowIme = false;
- private Entry(String _name) {
- mName = _name;
+ private Entry(String name) {
+ mName = name;
}
/** @return {@code true} if all values are default. */
@@ -85,16 +93,20 @@
&& mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
&& mUserRotation == Surface.ROTATION_0
&& mForcedWidth == 0 && mForcedHeight == 0 && mForcedDensity == 0
- && mForcedScalingMode == FORCE_SCALING_MODE_AUTO;
+ && mForcedScalingMode == FORCE_SCALING_MODE_AUTO
+ && mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED
+ && !mShouldShowWithInsecureKeyguard
+ && !mShouldShowSystemDecors
+ && !mShouldShowIme;
}
}
- DisplaySettings(WindowManagerService service) {
+ DisplayWindowSettings(WindowManagerService service) {
this(service, new File(Environment.getDataDirectory(), "system"));
}
@VisibleForTesting
- DisplaySettings(WindowManagerService service, File folder) {
+ DisplayWindowSettings(WindowManagerService service, File folder) {
mService = service;
mFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays");
readSettings();
@@ -185,19 +197,124 @@
}
// No record is present so use default windowing mode policy.
if (windowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
- if (displayId == Display.DEFAULT_DISPLAY) {
- windowingMode = (mService.mIsPc && mService.mSupportsFreeformWindowManagement)
- ? WindowConfiguration.WINDOWING_MODE_FREEFORM
- : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
- } else {
- windowingMode = mService.mSupportsFreeformWindowManagement
- ? WindowConfiguration.WINDOWING_MODE_FREEFORM
- : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
- }
+ final boolean forceDesktopMode = mService.mForceDesktopModeOnExternalDisplays
+ && displayId != Display.DEFAULT_DISPLAY;
+ windowingMode = mService.mSupportsFreeformWindowManagement
+ && (mService.mIsPc || forceDesktopMode)
+ ? WindowConfiguration.WINDOWING_MODE_FREEFORM
+ : WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
}
return windowingMode;
}
+ int getWindowingModeLocked(DisplayContent dc) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getEntry(displayInfo);
+ return getWindowingModeLocked(entry, dc.getDisplayId());
+ }
+
+ void setWindowingModeLocked(DisplayContent dc, int mode) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ entry.mWindowingMode = mode;
+ dc.setWindowingMode(mode);
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
+ int getRemoveContentModeLocked(DisplayContent dc) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getEntry(displayInfo);
+ if (entry == null || entry.mRemoveContentMode == REMOVE_CONTENT_MODE_UNDEFINED) {
+ if (dc.isPrivate()) {
+ // For private displays by default content is destroyed on removal.
+ return REMOVE_CONTENT_MODE_DESTROY;
+ }
+ // For other displays by default content is moved to primary on removal.
+ return REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
+ }
+ return entry.mRemoveContentMode;
+ }
+
+ void setRemoveContentModeLocked(DisplayContent dc, int mode) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ entry.mRemoveContentMode = mode;
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
+ boolean shouldShowWithInsecureKeyguardLocked(DisplayContent dc) {
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getEntry(displayInfo);
+ if (entry == null) {
+ return false;
+ }
+ return entry.mShouldShowWithInsecureKeyguard;
+ }
+
+ void setShouldShowWithInsecureKeyguardLocked(DisplayContent dc, boolean shouldShow) {
+ if (!dc.isPrivate() && shouldShow) {
+ Slog.e(TAG, "Public display can't be allowed to show content when locked");
+ return;
+ }
+
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ entry.mShouldShowWithInsecureKeyguard = shouldShow;
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
+ boolean shouldShowSystemDecorsLocked(DisplayContent dc) {
+ if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
+ // For default display should show system decors.
+ return true;
+ }
+
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getEntry(displayInfo);
+ if (entry == null) {
+ return false;
+ }
+ return entry.mShouldShowSystemDecors;
+ }
+
+ void setShouldShowSystemDecorsLocked(DisplayContent dc, boolean shouldShow) {
+ if (dc.getDisplayId() == Display.DEFAULT_DISPLAY && !shouldShow) {
+ Slog.e(TAG, "Default display should show system decors");
+ return;
+ }
+
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ entry.mShouldShowSystemDecors = shouldShow;
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
+ boolean shouldShowImeLocked(DisplayContent dc) {
+ if (dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
+ // For default display should shows IME.
+ return true;
+ }
+
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getEntry(displayInfo);
+ if (entry == null) {
+ return false;
+ }
+ return entry.mShouldShowIme;
+ }
+
+ void setShouldShowImeLocked(DisplayContent dc, boolean shouldShow) {
+ if (dc.getDisplayId() == Display.DEFAULT_DISPLAY && !shouldShow) {
+ Slog.e(TAG, "Default display should show IME");
+ return;
+ }
+
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
+ final Entry entry = getOrCreateEntry(displayInfo);
+ entry.mShouldShowIme = shouldShow;
+ writeSettingsIfNeeded(entry, displayInfo);
+ }
+
void applySettingsToDisplayLocked(DisplayContent dc) {
final DisplayInfo displayInfo = dc.getDisplayInfo();
final Entry entry = getEntry(displayInfo);
@@ -295,13 +412,26 @@
private int getIntAttribute(XmlPullParser parser, String name, int defaultValue) {
try {
- String str = parser.getAttributeValue(null, name);
+ final String str = parser.getAttributeValue(null, name);
return str != null ? Integer.parseInt(str) : defaultValue;
} catch (NumberFormatException e) {
return defaultValue;
}
}
+ private boolean getBooleanAttribute(XmlPullParser parser, String name) {
+ return getBooleanAttribute(parser, name, false /* defaultValue */);
+ }
+
+ private boolean getBooleanAttribute(XmlPullParser parser, String name, boolean defaultValue) {
+ try {
+ final String str = parser.getAttributeValue(null, name);
+ return str != null ? Boolean.parseBoolean(str) : defaultValue;
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+
private void readDisplay(XmlPullParser parser) throws NumberFormatException,
XmlPullParserException, IOException {
String name = parser.getAttributeValue(null, "name");
@@ -322,6 +452,12 @@
entry.mForcedDensity = getIntAttribute(parser, "forcedDensity");
entry.mForcedScalingMode = getIntAttribute(parser, "forcedScalingMode",
FORCE_SCALING_MODE_AUTO);
+ entry.mRemoveContentMode = getIntAttribute(parser, "removeContentMode",
+ REMOVE_CONTENT_MODE_UNDEFINED);
+ entry.mShouldShowWithInsecureKeyguard = getBooleanAttribute(parser,
+ "shouldShowWithInsecureKeyguard");
+ entry.mShouldShowSystemDecors = getBooleanAttribute(parser, "shouldShowSystemDecors");
+ entry.mShouldShowIme = getBooleanAttribute(parser, "shouldShowIme");
mEntries.put(name, entry);
}
XmlUtils.skipCurrentTag(parser);
@@ -390,6 +526,21 @@
out.attribute(null, "forcedScalingMode",
Integer.toString(entry.mForcedScalingMode));
}
+ if (entry.mRemoveContentMode != REMOVE_CONTENT_MODE_UNDEFINED) {
+ out.attribute(null, "removeContentMode",
+ Integer.toString(entry.mRemoveContentMode));
+ }
+ if (entry.mShouldShowWithInsecureKeyguard) {
+ out.attribute(null, "shouldShowWithInsecureKeyguard",
+ Boolean.toString(entry.mShouldShowWithInsecureKeyguard));
+ }
+ if (entry.mShouldShowSystemDecors) {
+ out.attribute(null, "shouldShowSystemDecors",
+ Boolean.toString(entry.mShouldShowSystemDecors));
+ }
+ if (entry.mShouldShowIme) {
+ out.attribute(null, "shouldShowIme", Boolean.toString(entry.mShouldShowIme));
+ }
out.endTag(null, "display");
}
diff --git a/services/core/java/com/android/server/wm/LaunchParamsController.java b/services/core/java/com/android/server/wm/LaunchParamsController.java
index 252f47c..0947577 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsController.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsController.java
@@ -40,6 +40,7 @@
*/
class LaunchParamsController {
private final ActivityTaskManagerService mService;
+ private final LaunchParamsPersister mPersister;
private final List<LaunchParamsModifier> mModifiers = new ArrayList<>();
// Temporary {@link LaunchParams} for internal calculations. This is kept separate from
@@ -49,8 +50,9 @@
private final LaunchParams mTmpCurrent = new LaunchParams();
private final LaunchParams mTmpResult = new LaunchParams();
- LaunchParamsController(ActivityTaskManagerService service) {
- mService = service;
+ LaunchParamsController(ActivityTaskManagerService service, LaunchParamsPersister persister) {
+ mService = service;
+ mPersister = persister;
}
/**
@@ -75,6 +77,10 @@
ActivityRecord source, ActivityOptions options, LaunchParams result) {
result.reset();
+ if (task != null || activity != null) {
+ mPersister.getLaunchParams(task, activity, result);
+ }
+
// We start at the last registered {@link LaunchParamsModifier} as this represents
// The modifier closest to the product level. Moving back through the list moves closer to
// the platform logic.
@@ -139,12 +145,20 @@
task.getStack().setWindowingMode(mTmpParams.mWindowingMode);
}
- if (!mTmpParams.mBounds.isEmpty()) {
- task.updateOverrideConfiguration(mTmpParams.mBounds);
- return true;
- } else {
+ if (mTmpParams.mBounds.isEmpty()) {
return false;
}
+
+ if (task.getStack().inFreeformWindowingMode()) {
+ // Only set bounds if it's in freeform mode.
+ task.updateOverrideConfiguration(mTmpParams.mBounds);
+ return true;
+ }
+
+ // Setting last non-fullscreen bounds to the bounds so next time the task enters
+ // freeform windowing mode it can be in this bounds.
+ task.setLastNonFullscreenBounds(mTmpParams.mBounds);
+ return false;
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
new file mode 100644
index 0000000..72d5143
--- /dev/null
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2018 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.wm;
+
+import android.content.ComponentName;
+import android.content.pm.PackageList;
+import android.content.pm.PackageManagerInternal;
+import android.graphics.Rect;
+import android.os.Environment;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.Xml;
+import android.view.DisplayInfo;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.FastXmlSerializer;
+import com.android.server.LocalServices;
+import com.android.server.wm.LaunchParamsController.LaunchParams;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.IntFunction;
+
+/**
+ * Persister that saves launch parameters in memory and in storage. It saves the last seen state of
+ * tasks key-ed on task's user ID and the activity used to launch the task ({@link
+ * TaskRecord#realActivity}) and that's used to determine the launch params when the activity is
+ * being launched again in {@link LaunchParamsController}.
+ *
+ * Need to hold {@link ActivityTaskManagerService#getGlobalLock()} to access this class.
+ */
+class LaunchParamsPersister {
+ private static final String TAG = "LaunchParamsPersister";
+ private static final String LAUNCH_PARAMS_DIRNAME = "launch_params";
+ private static final String LAUNCH_PARAMS_FILE_SUFFIX = ".xml";
+
+ // Chars below are used to escape the backslash in component name to underscore.
+ private static final char ORIGINAL_COMPONENT_SEPARATOR = '/';
+ private static final char ESCAPED_COMPONENT_SEPARATOR = '_';
+
+ private static final String TAG_LAUNCH_PARAMS = "launch_params";
+
+ private final PersisterQueue mPersisterQueue;
+ private final ActivityStackSupervisor mSupervisor;
+
+ /**
+ * A function that takes in user ID and returns a folder to store information of that user. Used
+ * to differentiate storage location in test environment and production environment.
+ */
+ private final IntFunction<File> mUserFolderGetter;
+
+ private PackageList mPackageList;
+
+ /**
+ * A dual layer map that first maps user ID to a secondary map, which maps component name (the
+ * launching activity of tasks) to {@link PersistableLaunchParams} that stores launch metadata
+ * that are stable across reboots.
+ */
+ private final SparseArray<ArrayMap<ComponentName, PersistableLaunchParams>> mMap =
+ new SparseArray<>();
+
+ LaunchParamsPersister(PersisterQueue persisterQueue, ActivityStackSupervisor supervisor) {
+ this(persisterQueue, supervisor, Environment::getDataSystemCeDirectory);
+ }
+
+ @VisibleForTesting
+ LaunchParamsPersister(PersisterQueue persisterQueue, ActivityStackSupervisor supervisor,
+ IntFunction<File> userFolderGetter) {
+ mPersisterQueue = persisterQueue;
+ mSupervisor = supervisor;
+ mUserFolderGetter = userFolderGetter;
+ }
+
+ void onSystemReady() {
+ PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
+ mPackageList = pmi.getPackageList(new PackageListObserver());
+ }
+
+ void onUnlockUser(int userId) {
+ loadLaunchParams(userId);
+ }
+
+ void onCleanupUser(int userId) {
+ mMap.remove(userId);
+ }
+
+ private void loadLaunchParams(int userId) {
+ final List<File> filesToDelete = new ArrayList<>();
+ final File launchParamsFolder = getLaunchParamFolder(userId);
+ if (!launchParamsFolder.isDirectory()) {
+ Slog.i(TAG, "Didn't find launch param folder for user " + userId);
+ return;
+ }
+
+ final Set<String> packages = new ArraySet<>(mPackageList.getPackageNames());
+
+ final File[] paramsFiles = launchParamsFolder.listFiles();
+ final ArrayMap<ComponentName, PersistableLaunchParams> map =
+ new ArrayMap<>(paramsFiles.length);
+ mMap.put(userId, map);
+
+ for (File paramsFile : paramsFiles) {
+ if (!paramsFile.isFile()) {
+ Slog.w(TAG, paramsFile.getAbsolutePath() + " is not a file.");
+ continue;
+ }
+ if (!paramsFile.getName().endsWith(LAUNCH_PARAMS_FILE_SUFFIX)) {
+ Slog.w(TAG, "Unexpected params file name: " + paramsFile.getName());
+ filesToDelete.add(paramsFile);
+ continue;
+ }
+ final String paramsFileName = paramsFile.getName();
+ final String componentNameString = paramsFileName.substring(
+ 0 /* beginIndex */,
+ paramsFileName.length() - LAUNCH_PARAMS_FILE_SUFFIX.length())
+ .replace(ESCAPED_COMPONENT_SEPARATOR, ORIGINAL_COMPONENT_SEPARATOR);
+ final ComponentName name = ComponentName.unflattenFromString(
+ componentNameString);
+ if (name == null) {
+ Slog.w(TAG, "Unexpected file name: " + paramsFileName);
+ filesToDelete.add(paramsFile);
+ continue;
+ }
+
+ if (!packages.contains(name.getPackageName())) {
+ // Rare case. PersisterQueue doesn't have a chance to remove files for removed
+ // packages last time.
+ filesToDelete.add(paramsFile);
+ continue;
+ }
+
+ BufferedReader reader = null;
+ try {
+ reader = new BufferedReader(new FileReader(paramsFile));
+ final PersistableLaunchParams params = new PersistableLaunchParams();
+ final XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(reader);
+ int event;
+ while ((event = parser.next()) != XmlPullParser.END_DOCUMENT
+ && event != XmlPullParser.END_TAG) {
+ if (event != XmlPullParser.START_TAG) {
+ continue;
+ }
+
+ final String tagName = parser.getName();
+ if (!TAG_LAUNCH_PARAMS.equals(tagName)) {
+ Slog.w(TAG, "Unexpected tag name: " + tagName);
+ continue;
+ }
+
+ params.restoreFromXml(parser);
+ }
+
+ map.put(name, params);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to restore launch params for " + name, e);
+ filesToDelete.add(paramsFile);
+ } finally {
+ IoUtils.closeQuietly(reader);
+ }
+ }
+
+ if (!filesToDelete.isEmpty()) {
+ mPersisterQueue.addItem(new CleanUpComponentQueueItem(filesToDelete), true);
+ }
+ }
+
+ void saveTask(TaskRecord task) {
+ final ComponentName name = task.realActivity;
+ final int userId = task.userId;
+ PersistableLaunchParams params;
+ ArrayMap<ComponentName, PersistableLaunchParams> map = mMap.get(userId);
+ if (map == null) {
+ map = new ArrayMap<>();
+ mMap.put(userId, map);
+ }
+
+ params = map.get(name);
+ if (params == null) {
+ params = new PersistableLaunchParams();
+ map.put(name, params);
+ }
+ final boolean changed = saveTaskToLaunchParam(task, params);
+
+ if (changed) {
+ mPersisterQueue.updateLastOrAddItem(
+ new LaunchParamsWriteQueueItem(userId, name, params),
+ /* flush */ false);
+ }
+ }
+
+ private boolean saveTaskToLaunchParam(TaskRecord task, PersistableLaunchParams params) {
+ final ActivityStack<?> stack = task.getStack();
+ final int displayId = stack.mDisplayId;
+ final ActivityDisplay display = mSupervisor.getActivityDisplay(displayId);
+ final DisplayInfo info = new DisplayInfo();
+ display.mDisplay.getDisplayInfo(info);
+
+ boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId);
+ params.mDisplayUniqueId = info.uniqueId;
+
+ changed |= params.mWindowingMode != stack.getWindowingMode();
+ params.mWindowingMode = stack.getWindowingMode();
+
+ if (task.mLastNonFullscreenBounds != null) {
+ changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds);
+ params.mBounds.set(task.mLastNonFullscreenBounds);
+ } else {
+ changed |= !params.mBounds.isEmpty();
+ params.mBounds.setEmpty();
+ }
+
+ return changed;
+ }
+
+ void getLaunchParams(TaskRecord task, ActivityRecord activity, LaunchParams outParams) {
+ final ComponentName name = task != null ? task.realActivity : activity.realActivity;
+ final int userId = task != null ? task.userId : activity.userId;
+
+ outParams.reset();
+ Map<ComponentName, PersistableLaunchParams> map = mMap.get(userId);
+ if (map == null) {
+ return;
+ }
+ final PersistableLaunchParams persistableParams = map.get(name);
+
+ if (persistableParams == null) {
+ return;
+ }
+
+ final ActivityDisplay display = mSupervisor.getActivityDisplay(
+ persistableParams.mDisplayUniqueId);
+ if (display != null) {
+ outParams.mPreferredDisplayId = display.mDisplayId;
+ }
+ outParams.mWindowingMode = persistableParams.mWindowingMode;
+ outParams.mBounds.set(persistableParams.mBounds);
+ }
+
+ private void onPackageRemoved(String packageName) {
+ final List<File> fileToDelete = new ArrayList<>();
+ for (int i = 0; i < mMap.size(); ++i) {
+ int userId = mMap.keyAt(i);
+ final File launchParamsFolder = getLaunchParamFolder(userId);
+ ArrayMap<ComponentName, PersistableLaunchParams> map = mMap.valueAt(i);
+ for (int j = map.size() - 1; j >= 0; --j) {
+ final ComponentName name = map.keyAt(j);
+ if (name.getPackageName().equals(packageName)) {
+ map.removeAt(j);
+ fileToDelete.add(getParamFile(launchParamsFolder, name));
+ }
+ }
+ }
+
+ synchronized (mPersisterQueue) {
+ mPersisterQueue.removeItems(
+ item -> item.mComponentName.getPackageName().equals(packageName),
+ LaunchParamsWriteQueueItem.class);
+
+ mPersisterQueue.addItem(new CleanUpComponentQueueItem(fileToDelete), true);
+ }
+ }
+
+ private File getParamFile(File launchParamFolder, ComponentName name) {
+ final String componentNameString = name.flattenToShortString()
+ .replace(ORIGINAL_COMPONENT_SEPARATOR, ESCAPED_COMPONENT_SEPARATOR);
+ return new File(launchParamFolder, componentNameString + LAUNCH_PARAMS_FILE_SUFFIX);
+ }
+
+ private File getLaunchParamFolder(int userId) {
+ final File userFolder = mUserFolderGetter.apply(userId);
+ return new File(userFolder, LAUNCH_PARAMS_DIRNAME);
+ }
+
+ private class PackageListObserver implements PackageManagerInternal.PackageListObserver {
+ @Override
+ public void onPackageAdded(String packageName) { }
+
+ @Override
+ public void onPackageRemoved(String packageName) {
+ LaunchParamsPersister.this.onPackageRemoved(packageName);
+ }
+ }
+
+ private class LaunchParamsWriteQueueItem
+ implements PersisterQueue.WriteQueueItem<LaunchParamsWriteQueueItem> {
+ private final int mUserId;
+ private final ComponentName mComponentName;
+
+ private PersistableLaunchParams mLaunchParams;
+
+ private LaunchParamsWriteQueueItem(int userId, ComponentName componentName,
+ PersistableLaunchParams launchParams) {
+ mUserId = userId;
+ mComponentName = componentName;
+ mLaunchParams = launchParams;
+ }
+
+ private StringWriter saveParamsToXml() {
+ final StringWriter writer = new StringWriter();
+ final XmlSerializer serializer = new FastXmlSerializer();
+
+ try {
+ serializer.setOutput(writer);
+ serializer.startDocument(/* encoding */ null, /* standalone */ true);
+ serializer.startTag(null, TAG_LAUNCH_PARAMS);
+
+ mLaunchParams.saveToXml(serializer);
+
+ serializer.endTag(null, TAG_LAUNCH_PARAMS);
+ serializer.endDocument();
+ serializer.flush();
+
+ return writer;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public void process() {
+ final StringWriter writer = saveParamsToXml();
+
+ final File launchParamFolder = getLaunchParamFolder(mUserId);
+ if (!launchParamFolder.isDirectory() && !launchParamFolder.mkdirs()) {
+ Slog.w(TAG, "Failed to create folder for " + mUserId);
+ return;
+ }
+
+ final File launchParamFile = getParamFile(launchParamFolder, mComponentName);
+ final AtomicFile atomicFile = new AtomicFile(launchParamFile);
+
+ FileOutputStream stream = null;
+ try {
+ stream = atomicFile.startWrite();
+ stream.write(writer.toString().getBytes());
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to write param file for " + mComponentName, e);
+ if (stream != null) {
+ atomicFile.failWrite(stream);
+ }
+ return;
+ }
+ atomicFile.finishWrite(stream);
+ }
+
+ @Override
+ public boolean matches(LaunchParamsWriteQueueItem item) {
+ return mUserId == item.mUserId && mComponentName.equals(item.mComponentName);
+ }
+
+ @Override
+ public void updateFrom(LaunchParamsWriteQueueItem item) {
+ mLaunchParams = item.mLaunchParams;
+ }
+ }
+
+ private class CleanUpComponentQueueItem implements PersisterQueue.WriteQueueItem {
+ private final List<File> mComponentFiles;
+
+ private CleanUpComponentQueueItem(List<File> componentFiles) {
+ mComponentFiles = componentFiles;
+ }
+
+ @Override
+ public void process() {
+ for (File file : mComponentFiles) {
+ if (!file.delete()) {
+ Slog.w(TAG, "Failed to delete " + file.getAbsolutePath());
+ }
+ }
+ }
+ }
+
+ private class PersistableLaunchParams {
+ private static final String ATTR_WINDOWING_MODE = "windowing_mode";
+ private static final String ATTR_DISPLAY_UNIQUE_ID = "display_unique_id";
+ private static final String ATTR_BOUNDS = "bounds";
+
+ /** The bounds within the parent container. */
+ final Rect mBounds = new Rect();
+
+ /** The unique id of the display the {@link TaskRecord} would prefer to be on. */
+ String mDisplayUniqueId;
+
+ /** The windowing mode to be in. */
+ int mWindowingMode;
+
+ void saveToXml(XmlSerializer serializer) throws IOException {
+ serializer.attribute(null, ATTR_DISPLAY_UNIQUE_ID, mDisplayUniqueId);
+ serializer.attribute(null, ATTR_WINDOWING_MODE,
+ Integer.toString(mWindowingMode));
+ serializer.attribute(null, ATTR_BOUNDS, mBounds.flattenToString());
+ }
+
+ void restoreFromXml(XmlPullParser parser) {
+ for (int i = 0; i < parser.getAttributeCount(); ++i) {
+ final String attrValue = parser.getAttributeValue(i);
+ switch (parser.getAttributeName(i)) {
+ case ATTR_DISPLAY_UNIQUE_ID:
+ mDisplayUniqueId = attrValue;
+ break;
+ case ATTR_WINDOWING_MODE:
+ mWindowingMode = Integer.parseInt(attrValue);
+ break;
+ case ATTR_BOUNDS: {
+ final Rect bounds = Rect.unflattenFromString(attrValue);
+ if (bounds != null) {
+ mBounds.set(bounds);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder("PersistableLaunchParams{");
+ builder.append("windowingMode=" + mWindowingMode);
+ builder.append(" displayUniqueId=" + mDisplayUniqueId);
+ builder.append(" bounds=" + mBounds);
+ builder.append(" }");
+ return builder.toString();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/PersisterQueue.java b/services/core/java/com/android/server/wm/PersisterQueue.java
index 1cfc7ac..a17ee65 100644
--- a/services/core/java/com/android/server/wm/PersisterQueue.java
+++ b/services/core/java/com/android/server/wm/PersisterQueue.java
@@ -130,6 +130,30 @@
return null;
}
+ /**
+ *
+ * @param item
+ * @param flush
+ * @param <T>
+ */
+ synchronized <T extends WriteQueueItem> void updateLastOrAddItem(T item, boolean flush) {
+ final T itemToUpdate = findLastItem(item::matches, (Class<T>) item.getClass());
+ if (itemToUpdate == null) {
+ addItem(item, flush);
+ } else {
+ itemToUpdate.updateFrom(item);
+ }
+
+ yieldIfQueueTooDeep();
+ }
+
+ /**
+ * Removes all items with which given predicate returns {@code true}.
+ *
+ * @param predicate the predicate
+ * @param clazz
+ * @param <T>
+ */
synchronized <T extends WriteQueueItem> void removeItems(Predicate<T> predicate,
Class<T> clazz) {
for (int i = mWriteQueue.size() - 1; i >= 0; --i) {
@@ -230,8 +254,14 @@
item.process();
}
- interface WriteQueueItem {
+ interface WriteQueueItem<T extends WriteQueueItem<T>> {
void process();
+
+ default void updateFrom(T item) {}
+
+ default boolean matches(T item) {
+ return false;
+ }
}
interface Listener {
diff --git a/services/core/java/com/android/server/wm/PinnedActivityStack.java b/services/core/java/com/android/server/wm/PinnedActivityStack.java
index af18077..3ef42e7 100644
--- a/services/core/java/com/android/server/wm/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/wm/PinnedActivityStack.java
@@ -97,7 +97,10 @@
// It is guaranteed that the activities requiring the update will be in the pinned stack at
// this point (either reparented before the animation into PiP, or before reparenting after
// the animation out of PiP)
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
+ if (!isAttached()) {
+ return;
+ }
ArrayList<TaskRecord> tasks = getAllTasks();
for (int i = 0; i < tasks.size(); i++ ) {
mStackSupervisor.updatePictureInPictureMode(tasks.get(i), targetStackBounds,
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index c995d3f..15478b4 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -19,6 +19,7 @@
import static android.app.ActivityManager.FLAG_AND_UNLOCKED;
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
import static android.app.ActivityManager.RECENT_WITH_EXCLUDED;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
@@ -33,6 +34,7 @@
import static android.os.Process.SYSTEM_UID;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
@@ -40,8 +42,6 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
@@ -196,7 +196,8 @@
final Resources res = service.mContext.getResources();
mService = service;
mSupervisor = mService.mStackSupervisor;
- mTaskPersister = new TaskPersister(systemDir, stackSupervisor, service, this);
+ mTaskPersister = new TaskPersister(systemDir, stackSupervisor, service, this,
+ stackSupervisor.mPersisterQueue);
mGlobalMaxNumTasks = ActivityTaskManager.getMaxRecentTasksStatic();
mHasVisibleRecentTasks = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
loadParametersFromResources(res);
@@ -432,7 +433,6 @@
void onSystemReadyLocked() {
loadRecentsComponent(mService.mContext.getResources());
mTasks.clear();
- mTaskPersister.onSystemReady();
}
Bitmap getTaskDescriptionIcon(String path) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 8c0c073..01b05c3 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -217,7 +217,7 @@
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
- mService.mDisplaySettings.applySettingsToDisplayLocked(dc);
+ mService.mDisplayWindowSettings.applySettingsToDisplayLocked(dc);
if (mService.mDisplayManagerInternal != null) {
mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 30eca89..c9800f8 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -237,7 +237,7 @@
super.onParentSet();
// Update task bounds if needed.
- updateDisplayInfo(getDisplayContent());
+ adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
if (getWindowConfiguration().windowsAreScaleable()) {
// We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
@@ -303,6 +303,7 @@
@Override
void onDisplayChanged(DisplayContent dc) {
updateSurfaceSize(dc);
+ adjustBoundsForDisplayChangeIfNeeded(dc);
super.onDisplayChanged(dc);
}
@@ -501,7 +502,7 @@
return mDragResizeMode;
}
- void updateDisplayInfo(final DisplayContent displayContent) {
+ private void adjustBoundsForDisplayChangeIfNeeded(final DisplayContent displayContent) {
if (displayContent == null) {
return;
}
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index b7804e8..117984a 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -48,6 +48,7 @@
import android.os.Build;
import android.util.Slog;
import android.view.Gravity;
+import android.view.View;
import com.android.server.wm.LaunchParamsController.LaunchParams;
import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
@@ -198,13 +199,13 @@
|| displayId == currentParams.mPreferredDisplayId)) {
if (currentParams.hasWindowingMode()) {
launchMode = currentParams.mWindowingMode;
- fullyResolvedCurrentParam = (launchMode != WINDOWING_MODE_FREEFORM);
+ fullyResolvedCurrentParam = launchMode != WINDOWING_MODE_FREEFORM;
if (DEBUG) {
appendLog("inherit-" + WindowConfiguration.windowingModeToString(launchMode));
}
}
- if (!currentParams.mBounds.isEmpty()) {
+ if (launchMode == WINDOWING_MODE_FREEFORM && !currentParams.mBounds.isEmpty()) {
outParams.mBounds.set(currentParams.mBounds);
fullyResolvedCurrentParam = true;
if (DEBUG) appendLog("inherit-bounds=" + outParams.mBounds);
@@ -250,11 +251,20 @@
// for all other windowing modes that's not freeform mode. One can read comments in
// relevant methods to further understand this step.
//
- // We skip making adjustments if the params are fully resolved from previous results and
- // trust that they are valid.
- if (!fullyResolvedCurrentParam) {
- final int resolvedMode = (launchMode != WINDOWING_MODE_UNDEFINED) ? launchMode
- : display.getWindowingMode();
+ // We skip making adjustments if the params are fully resolved from previous results.
+ final int resolvedMode = (launchMode != WINDOWING_MODE_UNDEFINED) ? launchMode
+ : display.getWindowingMode();
+ if (fullyResolvedCurrentParam) {
+ if (resolvedMode == WINDOWING_MODE_FREEFORM) {
+ // Make sure bounds are in the display if it's possibly in a different display.
+ if (currentParams.mPreferredDisplayId != displayId) {
+ adjustBoundsToFitInDisplay(display, outParams.mBounds);
+ }
+ // Even though we want to keep original bounds, we still don't want it to stomp on
+ // an existing task.
+ adjustBoundsToAvoidConflict(display, outParams.mBounds);
+ }
+ } else {
if (source != null && source.inFreeformWindowingMode()
&& resolvedMode == WINDOWING_MODE_FREEFORM
&& outParams.mBounds.isEmpty()
@@ -291,13 +301,12 @@
}
if (displayId != INVALID_DISPLAY && mSupervisor.getActivityDisplay(displayId) == null) {
- displayId = INVALID_DISPLAY;
+ displayId = currentParams.mPreferredDisplayId;
}
displayId = (displayId == INVALID_DISPLAY) ? currentParams.mPreferredDisplayId : displayId;
- displayId = (displayId == INVALID_DISPLAY) ? DEFAULT_DISPLAY : displayId;
-
- return displayId;
+ return (displayId != INVALID_DISPLAY && mSupervisor.getActivityDisplay(displayId) != null)
+ ? displayId : DEFAULT_DISPLAY;
}
private boolean canApplyFreeformWindowPolicy(@NonNull ActivityDisplay display, int launchMode) {
@@ -596,7 +605,12 @@
if (displayBounds.width() < inOutBounds.width()
|| displayBounds.height() < inOutBounds.height()) {
// There is no way for us to fit the bounds in the display without changing width
- // or height. Don't even try it.
+ // or height. Just move the start to align with the display.
+ final int layoutDirection = mSupervisor.getConfiguration().getLayoutDirection();
+ final int left = layoutDirection == View.LAYOUT_DIRECTION_RTL
+ ? displayBounds.width() - inOutBounds.width()
+ : 0;
+ inOutBounds.offsetTo(left, 0 /* newTop */);
return;
}
diff --git a/services/core/java/com/android/server/wm/TaskPersister.java b/services/core/java/com/android/server/wm/TaskPersister.java
index 9705d42..8120dec 100644
--- a/services/core/java/com/android/server/wm/TaskPersister.java
+++ b/services/core/java/com/android/server/wm/TaskPersister.java
@@ -83,7 +83,8 @@
private final ArraySet<Integer> mTmpTaskIds = new ArraySet<>();
TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor,
- ActivityTaskManagerService service, RecentTasks recentTasks) {
+ ActivityTaskManagerService service, RecentTasks recentTasks,
+ PersisterQueue persisterQueue) {
final File legacyImagesDir = new File(systemDir, IMAGES_DIRNAME);
if (legacyImagesDir.exists()) {
@@ -103,7 +104,7 @@
mStackSupervisor = stackSupervisor;
mService = service;
mRecentTasks = recentTasks;
- mPersisterQueue = new PersisterQueue();
+ mPersisterQueue = persisterQueue;
mPersisterQueue.addListener(this);
}
@@ -117,10 +118,6 @@
mPersisterQueue.addListener(this);
}
- void onSystemReady() {
- mPersisterQueue.startPersisting();
- }
-
private void removeThumbnails(TaskRecord task) {
mPersisterQueue.removeItems(
item -> {
@@ -219,21 +216,12 @@
}
void saveImage(Bitmap image, String filePath) {
- synchronized (mPersisterQueue) {
- final ImageWriteQueueItem item = mPersisterQueue.findLastItem(
- queueItem -> queueItem.mFilePath.equals(filePath), ImageWriteQueueItem.class);
- if (item != null) {
- // replace the Bitmap with the new one.
- item.mImage = image;
- } else {
- mPersisterQueue.addItem(new ImageWriteQueueItem(filePath, image),
- /* flush */ false);
- }
- if (DEBUG) Slog.d(TAG, "saveImage: filePath=" + filePath + " now=" +
- SystemClock.uptimeMillis() + " Callers=" + Debug.getCallers(4));
+ mPersisterQueue.updateLastOrAddItem(new ImageWriteQueueItem(filePath, image),
+ /* flush */ false);
+ if (DEBUG) {
+ Slog.d(TAG, "saveImage: filePath=" + filePath + " now="
+ + SystemClock.uptimeMillis() + " Callers=" + Debug.getCallers(4));
}
-
- mPersisterQueue.yieldIfQueueTooDeep();
}
Bitmap getTaskDescriptionIcon(String filePath) {
@@ -603,7 +591,8 @@
}
}
- private static class ImageWriteQueueItem implements PersisterQueue.WriteQueueItem {
+ private static class ImageWriteQueueItem implements
+ PersisterQueue.WriteQueueItem<ImageWriteQueueItem> {
final String mFilePath;
Bitmap mImage;
@@ -633,6 +622,16 @@
}
@Override
+ public boolean matches(ImageWriteQueueItem item) {
+ return mFilePath.equals(item.mFilePath);
+ }
+
+ @Override
+ public void updateFrom(ImageWriteQueueItem item) {
+ mImage = item.mImage;
+ }
+
+ @Override
public String toString() {
return "ImageWriteQueueItem{path=" + mFilePath
+ ", image=(" + mImage.getWidth() + "x" + mImage.getHeight() + ")}";
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index d4acb18..bd6689f 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -46,22 +46,7 @@
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
-import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+
import static com.android.server.am.TaskRecordProto.ACTIVITIES;
import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static com.android.server.am.TaskRecordProto.BOUNDS;
@@ -75,6 +60,23 @@
import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
import static com.android.server.am.TaskRecordProto.STACK_ID;
+import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
+import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
+import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
+import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
+import static com.android.server.wm.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
import static java.lang.Integer.MAX_VALUE;
import android.annotation.IntDef;
@@ -87,6 +89,7 @@
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
import android.app.TaskInfo;
+import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -550,6 +553,8 @@
}
mWindowContainerController.resize(kept, forced);
+ saveLaunchingStateIfNeeded();
+
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
return kept;
} finally {
@@ -1820,6 +1825,29 @@
mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
}
// TODO: Should also take care of Pip mode changes here.
+
+ saveLaunchingStateIfNeeded();
+ }
+
+ /**
+ * Saves launching state if necessary so that we can launch the activity to its latest state.
+ * It only saves state if this task has been shown to user and it's in fullscreen or freeform
+ * mode.
+ */
+ void saveLaunchingStateIfNeeded() {
+ if (!hasBeenVisible) {
+ // Not ever visible to user.
+ return;
+ }
+
+ final int windowingMode = getWindowingMode();
+ if (windowingMode != WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+ && windowingMode != WindowConfiguration.WINDOWING_MODE_FREEFORM) {
+ return;
+ }
+
+ // Saves the new state so that we can launch the activity at the same location.
+ mService.mStackSupervisor.mLaunchParamsPersister.saveTask(this);
}
/** Clears passed config and fills it with new override values. */
@@ -1965,7 +1993,7 @@
? reuseActivitiesReport.base.intent.getComponent()
: null;
info.topActivity = reuseActivitiesReport.top != null
- ? reuseActivitiesReport.top.intent.getComponent()
+ ? reuseActivitiesReport.top.realActivity
: null;
info.origActivity = origActivity;
info.realActivity = realActivity;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index b84d20d..7ab4d08 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -290,9 +290,10 @@
return null;
}
final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
- return new TaskSnapshot(buffer, appWindowToken.getConfiguration().orientation,
- getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
- true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
+ return new TaskSnapshot(appWindowToken.mActivityComponent, buffer,
+ appWindowToken.getConfiguration().orientation, getInsets(mainWindow),
+ isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */,
+ task.getWindowingMode(), getSystemUiVisibility(task),
!appWindowToken.fillsParent() || isWindowTranslucent);
}
@@ -382,7 +383,7 @@
}
// Note, the app theme snapshot is never translucent because we enforce a non-translucent
// color above
- return new TaskSnapshot(hwBitmap.createGraphicBufferHandle(),
+ return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
topChild.getConfiguration().orientation, mainWindow.getStableInsets(),
ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */,
false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
index 1410c21..0e1570b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotLoader.java
@@ -21,6 +21,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.app.ActivityManager.TaskSnapshot;
+import android.content.ComponentName;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
@@ -87,7 +88,9 @@
+ bitmapFile.getPath());
return null;
}
- return new TaskSnapshot(buffer, proto.orientation,
+ ComponentName topActivityComponent = ComponentName.unflattenFromString(
+ proto.topActivityComponent);
+ return new TaskSnapshot(topActivityComponent, buffer, proto.orientation,
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
reducedResolution, reducedResolution ? REDUCED_SCALE : 1f,
proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 6fd17955..24b5b61 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -16,7 +16,7 @@
package com.android.server.wm;
-import static android.graphics.Bitmap.CompressFormat.*;
+import static android.graphics.Bitmap.CompressFormat.JPEG;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -321,6 +321,7 @@
proto.windowingMode = mSnapshot.getWindowingMode();
proto.systemUiVisibility = mSnapshot.getSystemUiVisibility();
proto.isTranslucent = mSnapshot.isTranslucent();
+ proto.topActivityComponent = mSnapshot.getTopActivityComponent().flattenToString();
final byte[] bytes = TaskSnapshotProto.toByteArray(proto);
final File file = getProtoFile(mTaskId, mUserId);
final AtomicFile atomicFile = new AtomicFile(file);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 4dc2b8e..3493111 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -418,32 +418,6 @@
getBounds(out);
}
- void updateDisplayInfo(Rect bounds) {
- if (mDisplayContent == null) {
- return;
- }
-
- for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
- mChildren.get(taskNdx).updateDisplayInfo(mDisplayContent);
- }
- if (bounds != null) {
- setBounds(bounds);
- return;
- } else if (matchParentBounds()) {
- setBounds(null);
- return;
- }
-
- mTmpRect2.set(getRawBounds());
- final int newRotation = mDisplayContent.getDisplayInfo().rotation;
- final int newDensity = mDisplayContent.getDisplayInfo().logicalDensityDpi;
- if (mRotation == newRotation && mDensity == newDensity) {
- setBounds(mTmpRect2);
- }
-
- // If the rotation or density didn't match, we'll update it in onConfigurationChanged.
- }
-
/**
* Updates the passed-in {@code inOutBounds} based on how it would change when this container's
* override configuration is applied to the specified {@code parentConfig} and
@@ -820,16 +794,24 @@
@Override
void onDisplayChanged(DisplayContent dc) {
- if (mDisplayContent != null) {
+ if (mDisplayContent != null && mDisplayContent != dc) {
throw new IllegalStateException("onDisplayChanged: Already attached");
}
+ final boolean movedToNewDisplay = mDisplayContent == null;
mDisplayContent = dc;
- updateBoundsForWindowModeChange();
- mAnimationBackgroundSurface = makeChildSurface(null).setColorLayer(true)
- .setName("animation background stackId=" + mStackId)
- .build();
+ if (movedToNewDisplay) {
+ updateBoundsForWindowModeChange();
+ } else {
+ updateBoundsForDisplayChanges();
+ }
+
+ if (mAnimationBackgroundSurface != null) {
+ mAnimationBackgroundSurface = makeChildSurface(null).setColorLayer(true)
+ .setName("animation background stackId=" + mStackId)
+ .build();
+ }
super.onDisplayChanged(dc);
}
@@ -845,10 +827,41 @@
}, true);
}
- updateDisplayInfo(bounds);
+ setBoundsForWindowModeChange(bounds);
updateSurfaceBounds();
}
+ private void setBoundsForWindowModeChange(Rect bounds) {
+ if (mDisplayContent == null) {
+ return;
+ }
+
+ if (bounds != null) {
+ setBounds(bounds);
+ return;
+ }
+
+ updateBoundsForDisplayChanges();
+ }
+
+ private void updateBoundsForDisplayChanges() {
+ // Avoid setting override bounds to bounds inherited from parent if there was no override
+ // bounds set.
+ if (matchParentBounds()) {
+ setBounds(null);
+ return;
+ }
+
+ mTmpRect2.set(getRawBounds());
+ final int newRotation = mDisplayContent.getDisplayInfo().rotation;
+ final int newDensity = mDisplayContent.getDisplayInfo().logicalDensityDpi;
+ if (mRotation == newRotation && mDensity == newDensity) {
+ setBounds(mTmpRect2);
+ }
+
+ // If the rotation or density didn't match, we'll update it in onConfigurationChanged.
+ }
+
private Rect calculateBoundsForWindowModeChange() {
final boolean inSplitScreenPrimary = inSplitScreenPrimaryWindowingMode();
final TaskStack splitScreenStack =
@@ -1765,6 +1778,11 @@
@Override
public boolean shouldDeferStartOnMoveToFullscreen() {
synchronized (mService.mGlobalLock) {
+ if (!isAttached()) {
+ // Unnecessary to pause the animation because the stack is detached.
+ return false;
+ }
+
// Workaround for the recents animation -- normally we need to wait for the new activity
// to show before starting the PiP animation, but because we start and show the home
// activity early for the recents animation prior to the PiP animation starting, there
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index abc3826..266006d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -42,8 +42,10 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Builder;
import android.view.SurfaceSession;
+
import com.android.internal.util.ToBooleanFunction;
import com.android.server.wm.SurfaceAnimator.Animatable;
+
import java.io.PrintWriter;
import java.util.Comparator;
import java.util.LinkedList;
@@ -501,8 +503,10 @@
}
/**
- * Notify that the display this container is on has changed.
- * @param dc The new display this container is on.
+ * Notify that the display this container is on has changed. This could be either this container
+ * is moved to a new display, or some configurations on the display it is on changes.
+ *
+ * @param dc The display this container is on after changes.
*/
void onDisplayChanged(DisplayContent dc) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ec68f76..02904d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
@@ -29,6 +30,7 @@
import static android.os.Process.SYSTEM_UID;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.DOCKED_INVALID;
@@ -61,6 +63,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
@@ -117,6 +120,7 @@
import android.app.IActivityManager;
import android.app.IActivityTaskManager;
import android.app.IAssistDataReceiver;
+import android.app.WindowConfiguration;
import android.app.admin.DevicePolicyCache;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -214,6 +218,7 @@
import android.view.WindowContentFrameStats;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
+import android.view.WindowManager.RemoveContentMode;
import android.view.WindowManager.TransitionType;
import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
@@ -427,7 +432,7 @@
final AppOpsManager mAppOps;
final PackageManagerInternal mPmInternal;
- final DisplaySettings mDisplaySettings;
+ final DisplayWindowSettings mDisplayWindowSettings;
/** If the system should display notifications for apps displaying an alert window. */
boolean mShowAlertWindowNotifications = true;
@@ -538,12 +543,21 @@
int mDockedStackCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
Rect mDockedStackCreateBounds;
- boolean mForceResizableTasks = false;
- boolean mSupportsPictureInPicture = false;
- boolean mSupportsFreeformWindowManagement = false;
- boolean mIsPc = false;
+ boolean mForceResizableTasks;
+ boolean mSupportsPictureInPicture;
+ boolean mSupportsFreeformWindowManagement;
+ boolean mIsPc;
+ /**
+ * Flag that indicates that desktop mode is forced for public secondary screens.
+ *
+ * This includes several settings:
+ * - Set freeform windowing mode on external screen if it's supported and enabled.
+ * - Enable system decorations and IME on external screen.
+ * - TODO: Show mouse pointer on external screen.
+ */
+ boolean mForceDesktopModeOnExternalDisplays;
- boolean mDisableTransitionAnimation = false;
+ boolean mDisableTransitionAnimation;
int getDragLayerLocked() {
return mPolicy.getWindowLayerFromTypeLw(TYPE_DRAG) * TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
@@ -904,7 +918,7 @@
com.android.internal.R.bool.config_disableTransitionAnimation);
mInputManager = inputManager; // Must be before createDisplayContentLocked.
mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class);
- mDisplaySettings = new DisplaySettings(this);
+ mDisplayWindowSettings = new DisplayWindowSettings(this);
mPolicy = policy;
mAnimator = new WindowAnimator(this);
@@ -980,17 +994,21 @@
}
}, UserHandle.ALL, suspendPackagesFilter, null, null);
+ final ContentResolver resolver = context.getContentResolver();
// Get persisted window scale setting
- mWindowAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+ mWindowAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
- mTransitionAnimationScaleSetting = Settings.Global.getFloat(context.getContentResolver(),
+ mTransitionAnimationScaleSetting = Settings.Global.getFloat(resolver,
Settings.Global.TRANSITION_ANIMATION_SCALE,
context.getResources().getFloat(
R.dimen.config_appTransitionAnimationDurationScaleDefault));
- setAnimatorDurationScale(Settings.Global.getFloat(context.getContentResolver(),
+ setAnimatorDurationScale(Settings.Global.getFloat(resolver,
Settings.Global.ANIMATOR_DURATION_SCALE, mAnimatorDurationScaleSetting));
+ mForceDesktopModeOnExternalDisplays = Settings.Global.getInt(resolver,
+ DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS, 0) != 0;
+
IntentFilter filter = new IntentFilter();
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -5077,7 +5095,7 @@
displayInfo.overscanRight = right;
displayInfo.overscanBottom = bottom;
- mDisplaySettings.setOverscanLocked(displayInfo, left, top, right, bottom);
+ mDisplayWindowSettings.setOverscanLocked(displayInfo, left, top, right, bottom);
reconfigureDisplayLocked(displayContent);
}
@@ -6398,6 +6416,12 @@
}
}
+ void setForceDesktopModeOnExternalDisplays(boolean forceDesktopModeOnExternalDisplays) {
+ synchronized (mWindowMap) {
+ mForceDesktopModeOnExternalDisplays = forceDesktopModeOnExternalDisplays;
+ }
+ }
+
public void setIsPc(boolean isPc) {
synchronized (mGlobalLock) {
mIsPc = isPc;
@@ -6576,10 +6600,10 @@
final long token = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- final DisplayContent dc = getDisplayContentOrCreate(displayId, null);
+ final DisplayContent dc = getDisplayContentOrCreate(displayId, null /* token */);
if (dc == null) {
throw new IllegalArgumentException(
- "Trying to register a non existent display.");
+ "Trying to configure a non existent display.");
}
// We usually set the override info in DisplayManager so that we get consistent
// values when displays are changing. However, we don't do this for displays that
@@ -6595,6 +6619,193 @@
}
@Override
+ public int getWindowingMode(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getWindowingMode()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to get windowing mode of a display that does not exist: "
+ + displayId);
+ return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+ }
+ return mDisplayWindowSettings.getWindowingModeLocked(displayContent);
+ }
+ }
+
+ @Override
+ public void setWindowingMode(int displayId, int mode) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setWindowingMode()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to set windowing mode to a display that does not exist: "
+ + displayId);
+ return;
+ }
+
+ mDisplayWindowSettings.setWindowingModeLocked(displayContent, mode);
+
+ reconfigureDisplayLocked(displayContent);
+ }
+ }
+
+ @Override
+ public @RemoveContentMode int getRemoveContentMode(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "getRemoveContentMode()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to get remove mode of a display that does not exist: "
+ + displayId);
+ return REMOVE_CONTENT_MODE_UNDEFINED;
+ }
+ return mDisplayWindowSettings.getRemoveContentModeLocked(displayContent);
+ }
+ }
+
+ @Override
+ public void setRemoveContentMode(int displayId, @RemoveContentMode int mode) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setRemoveContentMode()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to set remove mode to a display that does not exist: "
+ + displayId);
+ return;
+ }
+
+ mDisplayWindowSettings.setRemoveContentModeLocked(displayContent, mode);
+
+ reconfigureDisplayLocked(displayContent);
+ }
+ }
+
+ @Override
+ public boolean shouldShowWithInsecureKeyguard(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowWithInsecureKeyguard()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to get flag of a display that does not exist: "
+ + displayId);
+ return false;
+ }
+ return mDisplayWindowSettings.shouldShowWithInsecureKeyguardLocked(displayContent);
+ }
+ }
+
+ @Override
+ public void setShouldShowWithInsecureKeyguard(int displayId, boolean shouldShow) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW,
+ "setShouldShowWithInsecureKeyguard()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to set flag to a display that does not exist: "
+ + displayId);
+ return;
+ }
+
+ mDisplayWindowSettings.setShouldShowWithInsecureKeyguardLocked(displayContent,
+ shouldShow);
+
+ reconfigureDisplayLocked(displayContent);
+ }
+ }
+
+ @Override
+ public boolean shouldShowSystemDecors(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowSystemDecors()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to get system decors flag of a display that does "
+ + "not exist: " + displayId);
+ return false;
+ }
+ return mDisplayWindowSettings.shouldShowSystemDecorsLocked(displayContent);
+ }
+ }
+
+ @Override
+ public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to set system decors flag to a display that does "
+ + "not exist: " + displayId);
+ return;
+ }
+
+ mDisplayWindowSettings.setShouldShowSystemDecorsLocked(displayContent, shouldShow);
+
+ reconfigureDisplayLocked(displayContent);
+ }
+ }
+
+ @Override
+ public boolean shouldShowIme(int displayId) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "shouldShowIme()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to get IME flag of a display that does not exist: "
+ + displayId);
+ return false;
+ }
+ return mDisplayWindowSettings.shouldShowImeLocked(displayContent);
+ }
+ }
+
+ @Override
+ public void setShouldShowIme(int displayId, boolean shouldShow) {
+ if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowIme()")) {
+ throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+ }
+
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = getDisplayContentOrCreate(displayId, null);
+ if (displayContent == null) {
+ Slog.w(TAG_WM, "Attempted to set IME flag to a display that does not exist: "
+ + displayId);
+ return;
+ }
+
+ mDisplayWindowSettings.setShouldShowImeLocked(displayContent, shouldShow);
+
+ reconfigureDisplayLocked(displayContent);
+ }
+ }
+
+ @Override
public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
throws RemoteException {
if (!checkCallingPermission(REGISTER_WINDOW_MANAGER_LISTENERS, "registerShortcutKey")) {
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 15a3a1a..04a526f 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -98,7 +98,7 @@
"libhwbinder",
"libutils",
"libhwui",
- "libbpf",
+ "libbpf_android",
"libnetdbpf",
"libnetdutils",
"android.hardware.audio.common@2.0",
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index a4983a9..9216005 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1299,7 +1299,7 @@
return (gnssHal != nullptr) ? JNI_TRUE : JNI_FALSE;
}
-static jboolean android_location_GnssLocationProvider_is_agps_ril_supported(
+static jboolean android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported(
JNIEnv* /* env */, jclass /* clazz */) {
return (agnssRilIface != nullptr) ? JNI_TRUE : JNI_FALSE;
}
@@ -1571,7 +1571,7 @@
env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
}
-static void android_location_GnssLocationProvider_agps_data_conn_open(
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
JNIEnv* env, jobject /* obj */, jstring apn, jint apnIpType) {
if (agnssIface == nullptr) {
ALOGE("no AGPS interface in agps_data_conn_open");
@@ -1591,7 +1591,7 @@
env->ReleaseStringUTFChars(apn, apnStr);
}
-static void android_location_GnssLocationProvider_agps_data_conn_closed(JNIEnv* /* env */,
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed(JNIEnv* /* env */,
jobject /* obj */) {
if (agnssIface == nullptr) {
ALOGE("%s: AGPS interface not supported", __func__);
@@ -1604,7 +1604,7 @@
}
}
-static void android_location_GnssLocationProvider_agps_data_conn_failed(JNIEnv* /* env */,
+static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed(JNIEnv* /* env */,
jobject /* obj */) {
if (agnssIface == nullptr) {
ALOGE("%s: AGPS interface not supported", __func__);
@@ -1718,7 +1718,7 @@
return result;
}
-static void android_location_GnssLocationProvider_update_network_state(JNIEnv* env,
+static void android_location_GnssNetworkConnectivityHandler_update_network_state(JNIEnv* env,
jobject /* obj */,
jboolean connected,
jint type,
@@ -2118,8 +2118,6 @@
android_location_GnssLocationProvider_class_init_native)},
{"native_is_supported", "()Z", reinterpret_cast<void *>(
android_location_GnssLocationProvider_is_supported)},
- {"native_is_agps_ril_supported", "()Z",
- reinterpret_cast<void *>(android_location_GnssLocationProvider_is_agps_ril_supported)},
{"native_is_gnss_configuration_supported", "()Z",
reinterpret_cast<void *>(
android_location_gpsLocationProvider_is_gnss_configuration_supported)},
@@ -2151,15 +2149,6 @@
{"native_inject_xtra_data",
"([BI)V",
reinterpret_cast<void *>(android_location_GnssLocationProvider_inject_xtra_data)},
- {"native_agps_data_conn_open",
- "(Ljava/lang/String;I)V",
- reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_open)},
- {"native_agps_data_conn_closed",
- "()V",
- reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_closed)},
- {"native_agps_data_conn_failed",
- "()V",
- reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_data_conn_failed)},
{"native_agps_set_id",
"(ILjava/lang/String;)V",
reinterpret_cast<void *>(android_location_GnssLocationProvider_agps_set_id)},
@@ -2176,9 +2165,6 @@
{"native_get_internal_state",
"()Ljava/lang/String;",
reinterpret_cast<void *>(android_location_GnssLocationProvider_get_internal_state)},
- {"native_update_network_state",
- "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
- reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
{"native_set_supl_es",
"(I)Z",
reinterpret_cast<void *>(android_location_GnssLocationProvider_set_supl_es)},
@@ -2278,6 +2264,24 @@
android_location_GnssNavigationMessageProvider_stop_navigation_message_collection)},
};
+static const JNINativeMethod sNetworkConnectivityMethods[] = {
+ /* name, signature, funcPtr */
+ {"native_is_agps_ril_supported", "()Z",
+ reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_is_agps_ril_supported)},
+ {"native_update_network_state",
+ "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
+ reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_update_network_state)},
+ {"native_agps_data_conn_open",
+ "(Ljava/lang/String;I)V",
+ reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_open)},
+ {"native_agps_data_conn_closed",
+ "()V",
+ reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_closed)},
+ {"native_agps_data_conn_failed",
+ "()V",
+ reinterpret_cast<void *>(android_location_GnssNetworkConnectivityHandler_agps_data_conn_failed)},
+};
+
int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
jniRegisterNativeMethods(
env,
@@ -2299,6 +2303,11 @@
"com/android/server/location/GnssNavigationMessageProvider",
sNavigationMessageMethods,
NELEM(sNavigationMessageMethods));
+ jniRegisterNativeMethods(
+ env,
+ "com/android/server/location/GnssNetworkConnectivityHandler",
+ sNetworkConnectivityMethods,
+ NELEM(sNetworkConnectivityMethods));
return jniRegisterNativeMethods(
env,
"com/android/server/location/GnssLocationProvider",
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 933eac6..86eb6f3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -89,6 +89,7 @@
import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
import com.android.server.inputmethod.InputMethodManagerService;
+import com.android.server.inputmethod.MultiClientInputMethodManagerService;
import com.android.server.job.JobSchedulerService;
import com.android.server.lights.LightsService;
import com.android.server.media.MediaResourceMonitorService;
@@ -819,6 +820,9 @@
boolean isWatch = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WATCH);
+ boolean isArc = context.getPackageManager().hasSystemFeature(
+ "org.chromium.arc");
+
boolean enableVrService = context.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
@@ -1013,7 +1017,12 @@
// Bring up services needed for UI.
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
traceBeginAndSlog("StartInputMethodManagerLifecycle");
- mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
+ if (MultiClientInputMethodManagerService.isConfiguredToUse()) {
+ mSystemServiceManager.startService(
+ MultiClientInputMethodManagerService.Lifecycle.class);
+ } else {
+ mSystemServiceManager.startService(InputMethodManagerService.Lifecycle.class);
+ }
traceEnd();
traceBeginAndSlog("StartAccessibilityManagerService");
@@ -1341,7 +1350,17 @@
}
traceBeginAndSlog("StartAudioService");
- mSystemServiceManager.startService(AudioService.Lifecycle.class);
+ if (!isArc) {
+ mSystemServiceManager.startService(AudioService.Lifecycle.class);
+ } else {
+ String className = context.getResources()
+ .getString(R.string.config_deviceSpecificAudioService);
+ try {
+ mSystemServiceManager.startService(className + "$Lifecycle");
+ } catch (Throwable e) {
+ reportWtf("starting " + className, e);
+ }
+ }
traceEnd();
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_BROADCAST_RADIO)) {
diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
index 69d8e25..ee42ce8 100644
--- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
@@ -21,11 +21,11 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
+import android.app.ActivityManagerInternal;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.os.storage.StorageManagerInternal;
@@ -48,6 +48,7 @@
@Mock private PackageManager mPm;
@Mock private PackageManagerInternal mPmi;
@Mock private UserManagerInternal mUmi;
+ @Mock private ActivityManagerInternal mAmi;
private static final String PKG_GREY = "com.grey";
private static final String PKG_RED = "com.red";
@@ -56,6 +57,10 @@
private static final int UID_GREY = 10000;
private static final int UID_COLORS = 10001;
+ private static final int PID_GREY = 1111;
+ private static final int PID_RED = 2222;
+ private static final int PID_BLUE = 3333;
+
private static final String NAME_COLORS = "colors";
private static ApplicationInfo buildApplicationInfo(String packageName, int uid) {
@@ -75,6 +80,8 @@
LocalServices.addService(PackageManagerInternal.class, mPmi);
LocalServices.removeServiceForTest(UserManagerInternal.class);
LocalServices.addService(UserManagerInternal.class, mUmi);
+ LocalServices.removeServiceForTest(ActivityManagerInternal.class);
+ LocalServices.addService(ActivityManagerInternal.class, mAmi);
when(mContext.getPackageManager()).thenReturn(mPm);
@@ -87,37 +94,52 @@
when(mPmi.getPackagesForSharedUserId(eq(NAME_COLORS), anyInt()))
.thenReturn(new String[] { PKG_RED, PKG_BLUE });
+ when(mPm.getPackagesForUid(eq(UID_GREY))).thenReturn(new String[] { PKG_GREY });
+ when(mPm.getPackagesForUid(eq(UID_COLORS))).thenReturn(new String[] { PKG_RED, PKG_BLUE });
+
+ setIsAppStorageSandboxed(PID_BLUE, UID_COLORS, true);
+ setIsAppStorageSandboxed(PID_GREY, UID_GREY, true);
+ setIsAppStorageSandboxed(PID_RED, UID_COLORS, true);
+
mService = new StorageManagerService(mContext);
}
+ private void setIsAppStorageSandboxed(int pid, int uid, boolean sandboxed) {
+ when(mAmi.isAppStorageSandboxed(pid, uid)).thenReturn(sandboxed);
+ }
+
@Test
public void testNone() throws Exception {
assertTranslation(
"/dev/null",
- "/dev/null", PKG_GREY);
+ "/dev/null", PID_GREY, UID_GREY);
assertTranslation(
"/dev/null",
- "/dev/null", PKG_RED);
+ "/dev/null", PID_RED, UID_COLORS);
}
@Test
public void testPrimary() throws Exception {
assertTranslation(
"/storage/emulated/0/Android/sandbox/com.grey/foo.jpg",
- "/storage/emulated/0/foo.jpg", PKG_GREY);
+ "/storage/emulated/0/foo.jpg",
+ PID_GREY, UID_GREY);
assertTranslation(
"/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
- "/storage/emulated/0/foo.jpg", PKG_RED);
+ "/storage/emulated/0/foo.jpg",
+ PID_RED, UID_COLORS);
}
@Test
public void testSecondary() throws Exception {
assertTranslation(
"/storage/0000-0000/Android/sandbox/com.grey/foo/bar.jpg",
- "/storage/0000-0000/foo/bar.jpg", PKG_GREY);
+ "/storage/0000-0000/foo/bar.jpg",
+ PID_GREY, UID_GREY);
assertTranslation(
"/storage/0000-0000/Android/sandbox/shared:colors/foo/bar.jpg",
- "/storage/0000-0000/foo/bar.jpg", PKG_RED);
+ "/storage/0000-0000/foo/bar.jpg",
+ PID_RED, UID_COLORS);
}
@Test
@@ -125,13 +147,15 @@
// Accessing their own paths goes straight through
assertTranslation(
"/storage/emulated/0/Android/data/com.grey/foo.jpg",
- "/storage/emulated/0/Android/data/com.grey/foo.jpg", PKG_GREY);
+ "/storage/emulated/0/Android/data/com.grey/foo.jpg",
+ PID_GREY, UID_GREY);
// Accessing other package paths goes into sandbox
assertTranslation(
"/storage/emulated/0/Android/sandbox/shared:colors/"
+ "Android/data/com.grey/foo.jpg",
- "/storage/emulated/0/Android/data/com.grey/foo.jpg", PKG_RED);
+ "/storage/emulated/0/Android/data/com.grey/foo.jpg",
+ PID_RED, UID_COLORS);
}
@Test
@@ -139,16 +163,19 @@
// Accessing their own paths goes straight through
assertTranslation(
"/storage/emulated/0/Android/data/com.red/foo.jpg",
- "/storage/emulated/0/Android/data/com.red/foo.jpg", PKG_RED);
+ "/storage/emulated/0/Android/data/com.red/foo.jpg",
+ PID_RED, UID_COLORS);
assertTranslation(
"/storage/emulated/0/Android/data/com.red/foo.jpg",
- "/storage/emulated/0/Android/data/com.red/foo.jpg", PKG_BLUE);
+ "/storage/emulated/0/Android/data/com.red/foo.jpg",
+ PID_BLUE, UID_COLORS);
// Accessing other package paths goes into sandbox
assertTranslation(
"/storage/emulated/0/Android/sandbox/com.grey/"
+ "Android/data/com.red/foo.jpg",
- "/storage/emulated/0/Android/data/com.red/foo.jpg", PKG_GREY);
+ "/storage/emulated/0/Android/data/com.red/foo.jpg",
+ PID_GREY, UID_GREY);
}
@Test
@@ -157,7 +184,7 @@
try {
mService.translateAppToSystem(
"/storage/emulated/0/../foo.jpg",
- PKG_GREY, UserHandle.USER_SYSTEM);
+ PID_GREY, UID_GREY);
fail();
} catch (SecurityException expected) {
}
@@ -166,7 +193,7 @@
try {
mService.translateSystemToApp(
"/storage/emulated/0/foo.jpg",
- PKG_GREY, UserHandle.USER_SYSTEM);
+ PID_GREY, UID_GREY);
fail();
} catch (SecurityException expected) {
}
@@ -175,17 +202,33 @@
try {
mService.translateSystemToApp(
"/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
- PKG_GREY, UserHandle.USER_SYSTEM);
+ PID_GREY, UID_GREY);
fail();
} catch (SecurityException expected) {
}
}
- private void assertTranslation(String system, String sandbox, String packageName)
- throws Exception {
+ @Test
+ public void testPackageNotSandboxed() throws Exception {
+ setIsAppStorageSandboxed(PID_RED, UID_COLORS, false);
+
+ // Both app and system have the same view
+ assertTranslation(
+ "/storage/emulated/0/Android/data/com.red/foo.jpg",
+ "/storage/emulated/0/Android/data/com.red/foo.jpg",
+ PID_RED, UID_COLORS);
+
+ assertTranslation(
+ "/storage/emulated/0/Android/sandbox/com.grey/bar.jpg",
+ "/storage/emulated/0/Android/sandbox/com.grey/bar.jpg",
+ PID_RED, UID_COLORS);
+ }
+
+ private void assertTranslation(String system, String sandbox,
+ int pid, int uid) throws Exception {
assertEquals(system,
- mService.translateAppToSystem(sandbox, packageName, UserHandle.USER_SYSTEM));
+ mService.translateAppToSystem(sandbox, pid, uid));
assertEquals(sandbox,
- mService.translateSystemToApp(system, packageName, UserHandle.USER_SYSTEM));
+ mService.translateSystemToApp(system, pid, uid));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/job/JobSetTest.java b/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
index e62e07d..6b7634d 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobSetTest.java
@@ -29,6 +29,7 @@
import android.content.pm.PackageManagerInternal;
import android.os.Build;
import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
@@ -47,6 +48,7 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
+@Presubmit
public class JobSetTest {
private static final String TAG = JobSetTest.class.getSimpleName();
private static final int SECONDARY_USER_ID_1 = 12;
@@ -64,6 +66,7 @@
final PackageManagerInternal pm = mock(PackageManagerInternal.class);
when(pm.getPackageTargetSdkVersion(anyString()))
.thenReturn(Build.VERSION_CODES.CUR_DEVELOPMENT);
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, pm);
assumeFalse("Test cannot run in user " + mContext.getUserId(),
mContext.getUserId() == SECONDARY_USER_ID_1
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index 553d234a..c6be1c0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -16,6 +16,10 @@
package com.android.server.pm;
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_PLAY_AUDIO;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -35,12 +39,14 @@
import android.content.pm.PackageManager;
import android.content.pm.SuspendDialogInfo;
import android.content.res.Resources;
+import android.media.AudioAttributes;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
@@ -54,6 +60,8 @@
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.app.IAppOpsCallback;
+import com.android.internal.app.IAppOpsService;
import com.android.servicestests.apps.suspendtestapp.SuspendTestActivity;
import com.android.servicestests.apps.suspendtestapp.SuspendTestReceiver;
@@ -550,6 +558,32 @@
assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
}
+ @Test
+ public void testAudioOpBlockedOnSuspend() throws Exception {
+ final IAppOpsService iAppOps = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ final CountDownLatch latch = new CountDownLatch(1);
+ final IAppOpsCallback watcher = new IAppOpsCallback.Stub() {
+ @Override
+ public void opChanged(int op, int uid, String packageName) {
+ if (op == OP_PLAY_AUDIO && packageName.equals(TEST_APP_PACKAGE_NAME)) {
+ latch.countDown();
+ }
+ }
+ };
+ iAppOps.startWatchingMode(OP_PLAY_AUDIO, TEST_APP_PACKAGE_NAME, watcher);
+ final int testPackageUid = mPackageManager.getPackageUid(TEST_APP_PACKAGE_NAME, 0);
+ int audioOpMode = iAppOps.checkAudioOperation(OP_PLAY_AUDIO,
+ AudioAttributes.USAGE_UNKNOWN, testPackageUid, TEST_APP_PACKAGE_NAME);
+ assertEquals("Audio muted for unsuspended package", MODE_ALLOWED, audioOpMode);
+ suspendTestPackage(null, null, null);
+ assertTrue("AppOpsWatcher did not callback", latch.await(5, TimeUnit.SECONDS));
+ audioOpMode = iAppOps.checkAudioOperation(OP_PLAY_AUDIO,
+ AudioAttributes.USAGE_UNKNOWN, testPackageUid, TEST_APP_PACKAGE_NAME);
+ assertEquals("Audio not muted for suspended package", MODE_IGNORED, audioOpMode);
+ iAppOps.stopWatchingMode(watcher);
+ }
+
@After
public void tearDown() throws IOException {
mAppCommsReceiver.unregister();
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index bd42b73..dad7b93 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -68,6 +68,7 @@
private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName();
private static final String DELEGATE_LAST_CLASS_LOADER_NAME =
DelegateLastClassLoader.class.getName();
+ private static final String UNSUPPORTED_CLASS_LOADER_NAME = "unsupported.class_loader";
@Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Mock Installer mInstaller;
@@ -105,7 +106,7 @@
mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1);
mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0,
- "unsupported.class_loader");
+ UNSUPPORTED_CLASS_LOADER_NAME);
mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0,
DELEGATE_LAST_CLASS_LOADER_NAME);
@@ -405,6 +406,24 @@
}
@Test
+ public void testNotifySupportedAndUnsupportedClassLoader() {
+ String classPath = String.join(File.pathSeparator, mBarUser0.getSecondaryDexPaths());
+ List<String> classLoaders =
+ Arrays.asList(PATH_CLASS_LOADER_NAME, UNSUPPORTED_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(classPath, classPath);
+ notifyDexLoad(mBarUser0, classLoaders, classPaths, mUser0);
+
+ assertNoUseInfo(mBarUser0);
+ }
+
+ @Test
+ public void testNotifyNullClassPath() {
+ notifyDexLoad(mBarUser0, null, mUser0);
+
+ assertNoUseInfo(mBarUser0);
+ }
+
+ @Test
public void testNotifyVariableClassLoader() {
// Record bar secondaries with the default PathClassLoader.
List<String> secondaries = mBarUser0.getSecondaryDexPaths();
@@ -499,14 +518,17 @@
// By default, assume a single class loader in the chain.
// This makes writing tests much easier.
List<String> classLoaders = Arrays.asList(testData.mClassLoader);
- List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths));
+ List<String> classPaths = (dexPaths == null)
+ ? Arrays.asList((String) null)
+ : Arrays.asList(String.join(File.pathSeparator, dexPaths));
notifyDexLoad(testData, classLoaders, classPaths, loaderUserId);
}
- private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths,
- int loaderUserId) {
- mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths,
- testData.mLoaderIsa, loaderUserId);
+ private void notifyDexLoad(TestData testData, List<String> classLoaders,
+ List<String> classPaths, int loaderUserId) {
+ // We call the internal function so any exceptions thrown cause test failures.
+ mDexManager.notifyDexLoadInternal(testData.mPackageInfo.applicationInfo, classLoaders,
+ classPaths, testData.mLoaderIsa, loaderUserId);
}
private PackageUseInfo getPackageUseInfo(TestData testData) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 77f517b..cd15a57 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -353,6 +353,18 @@
}
@Test
+ public void testProcessContextForDexLoadNoClassPath() {
+ List<String> classLoaders = Arrays.asList(
+ DELEGATE_LAST_CLASS_LOADER_NAME,
+ PATH_CLASS_LOADER_NAME);
+ List<String> classPaths = Arrays.asList(
+ String.join(File.pathSeparator, "foo.dex", "bar.dex"),
+ null);
+ String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths);
+ assertNull(context);
+ }
+
+ @Test
public void testProcessContextForDexLoadIllegalCallEmptyList() {
boolean gotException = false;
try {
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
index 793d6b0..8496a96 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
@@ -19,12 +19,13 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.app.PendingIntent;
import android.os.HandlerThread;
import android.os.Looper;
-import androidx.test.filters.MediumTest;
+import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
@@ -32,11 +33,13 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
-@MediumTest
+@LargeTest
public class AppTimeLimitControllerTests {
private static final String PKG_SOC1 = "package.soc1";
@@ -159,7 +162,6 @@
assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
addUsageSessionObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_1_MIN);
assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID2));
- assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
}
/** Verify app usage observer is removed */
@@ -180,6 +182,42 @@
assertFalse("Observer wasn't removed", hasUsageSessionObserver(UID, OBS_ID1));
}
+ /** Verify nothing happens when a nonexistent app usage observer is removed */
+ @Test
+ public void testAppUsageObserver_RemoveMissingObserver() {
+ assertFalse("Observer should not exist", hasAppUsageObserver(UID, OBS_ID1));
+ try {
+ mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID);
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+ sw.write("Hit exception trying to remove nonexistent observer:\n");
+ sw.write(e.toString());
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ sw.write("\nTest Failed!");
+ fail(sw.toString());
+ }
+ assertFalse("Observer should not exist", hasAppUsageObserver(UID, OBS_ID1));
+ }
+
+ /** Verify nothing happens when a nonexistent usage session observer is removed */
+ @Test
+ public void testUsageSessionObserver_RemoveMissingObserver() {
+ assertFalse("Observer should not exist", hasUsageSessionObserver(UID, OBS_ID1));
+ try {
+ mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID);
+ } catch (Exception e) {
+ StringWriter sw = new StringWriter();
+ sw.write("Hit exception trying to remove nonexistent observer:");
+ sw.write(e.toString());
+ PrintWriter pw = new PrintWriter(sw);
+ e.printStackTrace(pw);
+ sw.write("\nTest Failed!");
+ fail(sw.toString());
+ }
+ assertFalse("Observer should not exist", hasUsageSessionObserver(UID, OBS_ID1));
+ }
+
/** Re-adding an observer should result in only one copy */
@Test
public void testAppUsageObserver_ObserverReAdd() {
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayWindowSettingsTests.java
similarity index 70%
rename from services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
rename to services/tests/servicestests/src/com/android/server/wm/DisplayWindowSettingsTests.java
index f0c49c8..b823e70 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayWindowSettingsTests.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_DESTROY;
+import static android.view.WindowManager.REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
@@ -43,20 +46,23 @@
import java.io.File;
/**
- * Tests for the {@link DisplaySettings} class.
+ * Tests for the {@link DisplayWindowSettings} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:DisplaySettingsTests
+ * atest FrameworksServicesTests:DisplayWindowSettingsTests
*/
@SmallTest
@Presubmit
-public class DisplaySettingsTests extends WindowTestsBase {
+public class DisplayWindowSettingsTests extends WindowTestsBase {
private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
- private DisplaySettings mTarget;
+ private DisplayWindowSettings mTarget;
+
+ DisplayInfo mPrivateDisplayInfo;
private DisplayContent mPrimaryDisplay;
private DisplayContent mSecondaryDisplay;
+ private DisplayContent mPrivateDisplay;
@Before
public void setUp() throws Exception {
@@ -64,12 +70,19 @@
mWm.setSupportsFreeformWindowManagement(false);
mWm.setIsPc(false);
+ mWm.setForceDesktopModeOnExternalDisplays(false);
- mTarget = new DisplaySettings(mWm, TEST_FOLDER);
+ mTarget = new DisplayWindowSettings(mWm, TEST_FOLDER);
mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
mSecondaryDisplay = mDisplayContent;
assertNotEquals(Display.DEFAULT_DISPLAY, mSecondaryDisplay.getDisplayId());
+
+ mPrivateDisplayInfo = new DisplayInfo(mDisplayInfo);
+ mPrivateDisplayInfo.flags |= Display.FLAG_PRIVATE;
+ mPrivateDisplay = createNewDisplay(mPrivateDisplayInfo);
+ assertNotEquals(Display.DEFAULT_DISPLAY, mPrivateDisplay.getDisplayId());
+ assertNotEquals(mSecondaryDisplay.getDisplayId(), mPrivateDisplay.getDisplayId());
}
@After
@@ -78,7 +91,7 @@
}
@Test
- public void testPrimaryDisplayDefaultToFullscreenWithoutFreeformSupport() {
+ public void testPrimaryDisplayDefaultToFullscreen_NoFreeformSupport() {
mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
@@ -86,7 +99,7 @@
}
@Test
- public void testPrimaryDisplayDefaultToFullscreenWithFreeformSupportNonPc() {
+ public void testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_NoDesktopMode() {
mWm.setSupportsFreeformWindowManagement(true);
mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
@@ -96,7 +109,18 @@
}
@Test
- public void testPrimaryDisplayDefaultToFreeformWithFreeformIsPc() {
+ public void testPrimaryDisplayDefaultToFullscreen_HasFreeformSupport_NonPc_HasDesktopMode() {
+ mWm.setSupportsFreeformWindowManagement(true);
+ mWm.setForceDesktopModeOnExternalDisplays(true);
+
+ mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
+
+ assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
+ mPrimaryDisplay.getWindowingMode());
+ }
+
+ @Test
+ public void testPrimaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc() {
mWm.setSupportsFreeformWindowManagement(true);
mWm.setIsPc(true);
@@ -107,7 +131,7 @@
}
@Test
- public void testSecondaryDisplayDefaultToFullscreenWithoutFreeformSupport() {
+ public void testSecondaryDisplayDefaultToFullscreen_NoFreeformSupport() {
mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
@@ -115,17 +139,28 @@
}
@Test
- public void testSecondaryDisplayDefaultToFreeformWithFreeformSupportNonPc() {
+ public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_NoDesktopMode() {
mWm.setSupportsFreeformWindowManagement(true);
mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+ assertEquals(WindowConfiguration.WINDOWING_MODE_FULLSCREEN,
+ mSecondaryDisplay.getWindowingMode());
+ }
+
+ @Test
+ public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_NonPc_HasDesktopMode() {
+ mWm.setSupportsFreeformWindowManagement(true);
+ mWm.setForceDesktopModeOnExternalDisplays(true);
+
+ mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
assertEquals(WindowConfiguration.WINDOWING_MODE_FREEFORM,
mSecondaryDisplay.getWindowingMode());
}
@Test
- public void testSecondaryDisplayDefaultToFreeformWithFreeformSupportIsPc() {
+ public void testSecondaryDisplayDefaultToFreeform_HasFreeformSupport_IsPc() {
mWm.setSupportsFreeformWindowManagement(true);
mWm.setIsPc(true);
@@ -238,6 +273,67 @@
}
@Test
+ public void testPrivateDisplayDefaultToDestroyContent() {
+ assertEquals(REMOVE_CONTENT_MODE_DESTROY,
+ mTarget.getRemoveContentModeLocked(mPrivateDisplay));
+ }
+
+ @Test
+ public void testPublicDisplayDefaultToMoveToPrimary() {
+ assertEquals(REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY,
+ mTarget.getRemoveContentModeLocked(mSecondaryDisplay));
+ }
+
+ @Test
+ public void testDefaultToNotShowWithInsecureKeyguard() {
+ assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
+ assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
+ }
+
+ @Test
+ public void testPublicDisplayNotAllowSetShouldShowWithInsecureKeyguard() {
+ mTarget.setShouldShowWithInsecureKeyguardLocked(mSecondaryDisplay, true);
+
+ assertFalse(mTarget.shouldShowWithInsecureKeyguardLocked(mSecondaryDisplay));
+ }
+
+ @Test
+ public void testPrivateDisplayAllowSetShouldShowWithInsecureKeyguard() {
+ mTarget.setShouldShowWithInsecureKeyguardLocked(mPrivateDisplay, true);
+
+ assertTrue(mTarget.shouldShowWithInsecureKeyguardLocked(mPrivateDisplay));
+ }
+
+ @Test
+ public void testPrimaryDisplayShouldShowSystemDecors() {
+ assertTrue(mTarget.shouldShowSystemDecorsLocked(mPrimaryDisplay));
+
+ mTarget.setShouldShowSystemDecorsLocked(mPrimaryDisplay, false);
+
+ // Default display should show system decors
+ assertTrue(mTarget.shouldShowSystemDecorsLocked(mPrimaryDisplay));
+ }
+
+ @Test
+ public void testSecondaryDisplayDefaultToNotShowSystemDecors() {
+ assertFalse(mTarget.shouldShowSystemDecorsLocked(mSecondaryDisplay));
+ }
+
+ @Test
+ public void testPrimaryDisplayShouldShowIme() {
+ assertTrue(mTarget.shouldShowImeLocked(mPrimaryDisplay));
+
+ mTarget.setShouldShowImeLocked(mPrimaryDisplay, false);
+
+ assertTrue(mTarget.shouldShowImeLocked(mPrimaryDisplay));
+ }
+
+ @Test
+ public void testSecondaryDisplayDefaultToNotShowIme() {
+ assertFalse(mTarget.shouldShowImeLocked(mSecondaryDisplay));
+ }
+
+ @Test
public void testPersistUserRotationModeInSameInstance() {
mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
Surface.ROTATION_90);
@@ -294,11 +390,11 @@
/**
* This method helps to ensure read and write persistent settings successfully because the
- * constructor of {@link DisplaySettings} should read the persistent file from the given path
- * that also means the previous state must be written correctly.
+ * constructor of {@link DisplayWindowSettings} should read the persistent file from the given
+ * path that also means the previous state must be written correctly.
*/
private void applySettingsToDisplayByNewInstance(DisplayContent display) {
- new DisplaySettings(mWm, TEST_FOLDER).applySettingsToDisplayLocked(display);
+ new DisplayWindowSettings(mWm, TEST_FOLDER).applySettingsToDisplayLocked(display);
}
private static boolean deleteRecursively(File file) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 0f9b825..946ffb60 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -24,6 +24,7 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.app.ActivityManager.TaskSnapshot;
+import android.content.ComponentName;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
@@ -126,9 +127,9 @@
Canvas c = buffer.lockCanvas();
c.drawColor(Color.RED);
buffer.unlockCanvasAndPost(c);
- return new TaskSnapshot(buffer, ORIENTATION_PORTRAIT, TEST_INSETS,
- mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, mWindowingMode,
- mSystemUiVisibility, mIsTranslucent);
+ return new TaskSnapshot(new ComponentName("", ""), buffer, ORIENTATION_PORTRAIT,
+ TEST_INSETS, mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot,
+ mWindowingMode, mSystemUiVisibility, mIsTranslucent);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 7c16191..a569b9e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -30,6 +30,7 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager.TaskSnapshot;
+import android.content.ComponentName;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.GraphicBuffer;
@@ -60,7 +61,7 @@
int windowFlags, Rect taskBounds) {
final GraphicBuffer buffer = GraphicBuffer.create(width, height, PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
- final TaskSnapshot snapshot = new TaskSnapshot(buffer,
+ final TaskSnapshot snapshot = new TaskSnapshot(new ComponentName("", ""), buffer,
ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */,
WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */);
mSurface = new TaskSnapshotSurface(mWm, new Window(), new Surface(), snapshot, "Test",
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index b318b91..80bb936 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -32,6 +32,7 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -144,17 +145,19 @@
private TestAppWindowToken(DisplayContent dc) {
super(dc.mService, new IApplicationToken.Stub() {
public String getName() {return null;}
- }, false, dc, true /* fillsParent */);
+ }, new ComponentName("", ""), false, dc, true /* fillsParent */);
}
TestAppWindowToken(WindowManagerService service, IApplicationToken token,
- boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
- boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
- int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
- boolean alwaysFocusable, AppWindowContainerController controller) {
- super(service, token, voiceInteraction, dc, inputDispatchingTimeoutNanos, fullscreen,
- showForAllUsers, targetSdk, orientation, rotationAnimationHint, configChanges,
- launchTaskBehind, alwaysFocusable, controller);
+ ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos, boolean fullscreen, boolean showForAllUsers,
+ int targetSdk, int orientation, int rotationAnimationHint, int configChanges,
+ boolean launchTaskBehind, boolean alwaysFocusable,
+ AppWindowContainerController controller) {
+ super(service, token, activityComponent, voiceInteraction, dc,
+ inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
+ orientation, rotationAnimationHint, configChanges, launchTaskBehind,
+ alwaysFocusable, controller);
}
int getWindowsCount() {
@@ -318,22 +321,24 @@
TestAppWindowContainerController(TestTaskWindowContainerController taskController,
IApplicationToken token) {
- super(taskController, token, null /* listener */, 0 /* index */,
- SCREEN_ORIENTATION_UNSPECIFIED, true /* fullscreen */,
- true /* showForAllUsers */, 0 /* configChanges */, false /* voiceInteraction */,
- false /* launchTaskBehind */, false /* alwaysFocusable */,
- 0 /* targetSdkVersion */, 0 /* rotationAnimationHint */,
- 0 /* inputDispatchingTimeoutNanos */, taskController.mService);
+ super(taskController, token, new ComponentName("", "") /* activityComponent */,
+ null /* listener */, 0 /* index */, SCREEN_ORIENTATION_UNSPECIFIED,
+ true /* fullscreen */, true /* showForAllUsers */, 0 /* configChanges */,
+ false /* voiceInteraction */, false /* launchTaskBehind */,
+ false /* alwaysFocusable */, 0 /* targetSdkVersion */,
+ 0 /* rotationAnimationHint */, 0 /* inputDispatchingTimeoutNanos */,
+ taskController.mService);
mToken = token;
}
@Override
AppWindowToken createAppWindow(WindowManagerService service, IApplicationToken token,
- boolean voiceInteraction, DisplayContent dc, long inputDispatchingTimeoutNanos,
+ ComponentName activityComponent, boolean voiceInteraction, DisplayContent dc,
+ long inputDispatchingTimeoutNanos,
boolean fullscreen, boolean showForAllUsers, int targetSdk, int orientation,
int rotationAnimationHint, int configChanges, boolean launchTaskBehind,
boolean alwaysFocusable, AppWindowContainerController controller) {
- return new TestAppWindowToken(service, token, voiceInteraction, dc,
+ return new TestAppWindowToken(service, token, activityComponent, voiceInteraction, dc,
inputDispatchingTimeoutNanos, fullscreen, showForAllUsers, targetSdk,
orientation,
rotationAnimationHint, configChanges, launchTaskBehind, alwaysFocusable,
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 945cbb9..2abe64d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -354,9 +354,14 @@
/** Creates a {@link DisplayContent} and adds it to the system. */
DisplayContent createNewDisplay() {
+ return createNewDisplay(mDisplayInfo);
+ }
+
+ /** Creates a {@link DisplayContent} and adds it to the system. */
+ DisplayContent createNewDisplay(DisplayInfo displayInfo) {
final int displayId = sNextDisplayId++;
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
- mDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
+ displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
synchronized (mWm.mGlobalLock) {
return new DisplayContent(display, mWm, mWallpaperController,
mock(DisplayWindowController.class));
diff --git a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
index 32e4e02..3c8ae3c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
@@ -122,7 +122,6 @@
public SurfaceControl build() {
final SurfaceControl sc = super.build();
mTransaction.addParentFor(sc, mPendingParent);
- mTransaction = null;
mPendingParent = null;
return sc;
}
@@ -138,7 +137,6 @@
@Override
public SurfaceControl.Builder make(SurfaceSession s) {
final LayerRecordingTransaction transaction = mTransaction;
- mTransaction = null;
return new HierarchyRecorder(s, transaction);
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 0d7b584..bcba15d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -114,6 +114,7 @@
Bundle smartActions = new Bundle();
Bundle smartReplies = new Bundle();
Bundle audiblyAlerted = new Bundle();
+ Bundle noisy = new Bundle();
for (int i = 0; i < mKeys.length; i++) {
String key = mKeys[i];
@@ -134,12 +135,13 @@
smartActions.putParcelableArrayList(key, getSmartActions(key, i));
smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
audiblyAlerted.putBoolean(key, audiblyAlerted(i));
+ noisy.putBoolean(key, getNoisy(i));
}
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
interceptedKeys.toArray(new String[0]), visibilityOverrides,
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
- smartActions, smartReplies, audiblyAlerted);
+ smartActions, smartReplies, audiblyAlerted, noisy);
return update;
}
@@ -195,6 +197,10 @@
return index < 2;
}
+ private boolean getNoisy(int index) {
+ return index < 1;
+ }
+
private ArrayList<String> getPeople(String key, int index) {
ArrayList<String> people = new ArrayList<>();
for (int i = 0; i < index; i++) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index c35e4d6..26286e2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -144,6 +144,10 @@
return TestActivityDisplay.create(mSupervisor, sNextDisplayId++);
}
+ TestActivityDisplay createNewActivityDisplay(DisplayInfo info) {
+ return TestActivityDisplay.create(mSupervisor, sNextDisplayId++, info);
+ }
+
/** Creates and adds a {@link TestActivityDisplay} to supervisor at the given position. */
TestActivityDisplay addNewActivityDisplayAt(int position) {
final TestActivityDisplay display = createNewActivityDisplay();
@@ -586,12 +590,17 @@
private final ActivityStackSupervisor mSupervisor;
static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId) {
+ return create(supervisor, displayId, new DisplayInfo());
+ }
+
+ static TestActivityDisplay create(ActivityStackSupervisor supervisor, int displayId,
+ DisplayInfo info) {
if (displayId == DEFAULT_DISPLAY) {
return new TestActivityDisplay(supervisor,
supervisor.mDisplayManager.getDisplay(displayId));
}
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
- new DisplayInfo(), DEFAULT_DISPLAY_ADJUSTMENTS);
+ info, DEFAULT_DISPLAY_ADJUSTMENTS);
return new TestActivityDisplay(supervisor, display);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
index 40c20a4..f8d64e9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsControllerTests.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -37,8 +39,12 @@
import static org.mockito.Mockito.verify;
import android.app.ActivityOptions;
+import android.content.ComponentName;
import android.content.pm.ActivityInfo.WindowLayout;
+import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
+import android.util.ArrayMap;
+import android.util.SparseArray;
import androidx.test.filters.MediumTest;
@@ -48,6 +54,8 @@
import org.junit.Before;
import org.junit.Test;
+import java.util.Map;
+
/**
* Tests for exercising {@link LaunchParamsController}.
*
@@ -58,11 +66,13 @@
@Presubmit
public class LaunchParamsControllerTests extends ActivityTestsBase {
private LaunchParamsController mController;
+ private TestLaunchParamsPersister mPersister;
@Before
public void setUp() throws Exception {
mService = createActivityTaskManagerService();
- mController = new LaunchParamsController(mService);
+ mPersister = new TestLaunchParamsPersister();
+ mController = new LaunchParamsController(mService, mPersister);
}
/**
@@ -86,6 +96,31 @@
}
/**
+ * Makes sure controller passes stored params to modifiers.
+ */
+ @Test
+ public void testStoredParamsRecovery() {
+ final LaunchParamsModifier positioner = mock(LaunchParamsModifier.class);
+ mController.registerModifier(positioner);
+
+ final ComponentName name = new ComponentName("com.android.foo", ".BarActivity");
+ final int userId = 0;
+ final ActivityRecord activity = new ActivityBuilder(mService).setComponent(name)
+ .setUid(userId).build();
+ final LaunchParams expected = new LaunchParams();
+ expected.mPreferredDisplayId = 3;
+ expected.mWindowingMode = WINDOWING_MODE_PINNED;
+ expected.mBounds.set(200, 300, 400, 500);
+
+ mPersister.putLaunchParams(userId, name, expected);
+
+ mController.calculate(activity.getTask(), null /*layout*/, activity, null /*source*/,
+ null /*options*/, new LaunchParams());
+ verify(positioner, times(1)).onCalculate(any(), any(), any(), any(), any(), eq(expected),
+ any());
+ }
+
+ /**
* Ensures positioners further down the chain are not called when RESULT_DONE is returned.
*/
@Test
@@ -254,6 +289,53 @@
assertEquals(windowingMode, afterWindowMode);
}
+ /**
+ * Ensures that {@link LaunchParamsModifier} requests specifying bounds during
+ * layout are honored if window is in freeform.
+ */
+ @Test
+ public void testLayoutTaskBoundsChangeFreeformWindow() {
+ final Rect expected = new Rect(10, 20, 30, 40);
+
+ final LaunchParams params = new LaunchParams();
+ params.mWindowingMode = WINDOWING_MODE_FREEFORM;
+ params.mBounds.set(expected);
+ final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
+ final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
+
+ mController.registerModifier(positioner);
+
+ assertNotEquals(expected, task.getBounds());
+
+ mController.layoutTask(task, null /* windowLayout */);
+
+ assertEquals(expected, task.getBounds());
+ }
+
+ /**
+ * Ensures that {@link LaunchParamsModifier} requests specifying bounds during
+ * layout are set to last non-fullscreen bounds.
+ */
+ @Test
+ public void testLayoutTaskBoundsChangeFixedWindow() {
+ final Rect expected = new Rect(10, 20, 30, 40);
+
+ final LaunchParams params = new LaunchParams();
+ params.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+ params.mBounds.set(expected);
+ final InstrumentedPositioner positioner = new InstrumentedPositioner(RESULT_DONE, params);
+ final TaskRecord task = new TaskBuilder(mService.mStackSupervisor).build();
+
+ mController.registerModifier(positioner);
+
+ assertNotEquals(expected, task.getBounds());
+
+ mController.layoutTask(task, null /* windowLayout */);
+
+ assertNotEquals(expected, task.getBounds());
+ assertEquals(expected, task.mLastNonFullscreenBounds);
+ }
+
public static class InstrumentedPositioner implements LaunchParamsModifier {
private final int mReturnVal;
@@ -276,4 +358,73 @@
return mParams;
}
}
+
+ /**
+ * Test double for {@link LaunchParamsPersister}. This class only manages an in-memory storage
+ * of a mapping from user ID and component name to launch params.
+ */
+ static class TestLaunchParamsPersister extends LaunchParamsPersister {
+
+ private final SparseArray<Map<ComponentName, LaunchParams>> mMap =
+ new SparseArray<>();
+ private final LaunchParams mTmpParams = new LaunchParams();
+
+ TestLaunchParamsPersister() {
+ super(null, null, null);
+ }
+
+ void putLaunchParams(int userId, ComponentName name, LaunchParams params) {
+ Map<ComponentName, LaunchParams> map = mMap.get(userId);
+ if (map == null) {
+ map = new ArrayMap<>();
+ mMap.put(userId, map);
+ }
+
+ LaunchParams paramRecord = map.get(name);
+ if (paramRecord == null) {
+ paramRecord = new LaunchParams();
+ map.put(name, params);
+ }
+
+ paramRecord.set(params);
+ }
+
+ @Override
+ void onUnlockUser(int userId) {
+ if (mMap.get(userId) == null) {
+ mMap.put(userId, new ArrayMap<>());
+ }
+ }
+
+ @Override
+ void saveTask(TaskRecord task) {
+ final int userId = task.userId;
+ final ComponentName realActivity = task.realActivity;
+ mTmpParams.mPreferredDisplayId = task.getStack().mDisplayId;
+ mTmpParams.mWindowingMode = task.getWindowingMode();
+ if (task.mLastNonFullscreenBounds != null) {
+ mTmpParams.mBounds.set(task.mLastNonFullscreenBounds);
+ } else {
+ mTmpParams.mBounds.setEmpty();
+ }
+ putLaunchParams(userId, realActivity, mTmpParams);
+ }
+
+ @Override
+ void getLaunchParams(TaskRecord task, ActivityRecord activity, LaunchParams params) {
+ final int userId = task != null ? task.userId : activity.userId;
+ final ComponentName name = task != null ? task.realActivity : activity.realActivity;
+
+ params.reset();
+ final Map<ComponentName, LaunchParams> map = mMap.get(userId);
+ if (map == null) {
+ return;
+ }
+
+ final LaunchParams paramsRecord = map.get(name);
+ if (paramsRecord != null) {
+ params.set(paramsRecord);
+ }
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
new file mode 100644
index 0000000..59e9ce3
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2018 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.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.pm.PackageList;
+import android.content.pm.PackageManagerInternal;
+import android.graphics.Rect;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.view.DisplayInfo;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.MediumTest;
+
+import com.android.server.LocalServices;
+import com.android.server.wm.LaunchParamsController.LaunchParams;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+
+/**
+ * Unit tests for {@link LaunchParamsPersister}.
+ *
+ * Build/Install/Run:
+ * atest WmTests:LaunchParamsPersisterTests
+ */
+@MediumTest
+@Presubmit
+@FlakyTest(detail = "Confirm stable in post-submit before removing")
+public class LaunchParamsPersisterTests extends ActivityTestsBase {
+ private static final int TEST_USER_ID = 3;
+ private static final int ALTERNATIVE_USER_ID = 0;
+ private static final ComponentName TEST_COMPONENT =
+ ComponentName.createRelative("com.android.foo", ".BarActivity");
+ private static final ComponentName ALTERNATIVE_COMPONENT =
+ ComponentName.createRelative("com.android.foo", ".AlternativeBarActivity");
+
+ private static final int TEST_WINDOWING_MODE = WINDOWING_MODE_FREEFORM;
+ private static final Rect TEST_BOUNDS = new Rect(100, 200, 300, 400);
+
+ private static int sNextUniqueId;
+
+ private TestPersisterQueue mPersisterQueue;
+ private File mFolder;
+ private ActivityDisplay mTestDisplay;
+ private String mDisplayUniqueId;
+ private TaskRecord mTestTask;
+ private TaskRecord mTaskWithDifferentUser;
+ private TaskRecord mTaskWithDifferentComponent;
+ private PackageManagerInternal mMockPmi;
+ private PackageManagerInternal.PackageListObserver mObserver;
+
+ private final IntFunction<File> mUserFolderGetter =
+ userId -> new File(mFolder, Integer.toString(userId));
+
+ private LaunchParamsPersister mTarget;
+
+ private LaunchParams mResult;
+
+ @Before
+ public void setUp() throws Exception {
+ mPersisterQueue = new TestPersisterQueue();
+
+ final File cacheFolder = InstrumentationRegistry.getContext().getCacheDir();
+ mFolder = new File(cacheFolder, "launch_params_tests");
+ deleteRecursively(mFolder);
+
+ setupActivityTaskManagerService();
+
+ mDisplayUniqueId = "test:" + Integer.toString(sNextUniqueId++);
+ final DisplayInfo info = new DisplayInfo();
+ info.uniqueId = mDisplayUniqueId;
+ mTestDisplay = createNewActivityDisplay(info);
+ mSupervisor.addChild(mTestDisplay, ActivityDisplay.POSITION_TOP);
+ when(mSupervisor.getActivityDisplay(eq(mDisplayUniqueId))).thenReturn(mTestDisplay);
+
+ ActivityStack stack = mTestDisplay.createStack(TEST_WINDOWING_MODE,
+ ACTIVITY_TYPE_STANDARD, /* onTop */ true);
+ mTestTask = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).setStack(stack)
+ .build();
+ mTestTask.userId = TEST_USER_ID;
+ mTestTask.mLastNonFullscreenBounds = TEST_BOUNDS;
+ mTestTask.hasBeenVisible = true;
+
+ mTaskWithDifferentComponent = new TaskBuilder(mSupervisor)
+ .setComponent(ALTERNATIVE_COMPONENT).build();
+ mTaskWithDifferentComponent.userId = TEST_USER_ID;
+
+ mTaskWithDifferentUser = new TaskBuilder(mSupervisor).setComponent(TEST_COMPONENT).build();
+ mTaskWithDifferentUser.userId = ALTERNATIVE_USER_ID;
+
+ mTarget = new LaunchParamsPersister(mPersisterQueue, mSupervisor, mUserFolderGetter);
+
+ LocalServices.removeServiceForTest(PackageManagerInternal.class);
+ mMockPmi = mock(PackageManagerInternal.class);
+ LocalServices.addService(PackageManagerInternal.class, mMockPmi);
+ when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(
+ Collections.singletonList(TEST_COMPONENT.getPackageName()), /* observer */ null));
+ mTarget.onSystemReady();
+
+ final ArgumentCaptor<PackageManagerInternal.PackageListObserver> observerCaptor =
+ ArgumentCaptor.forClass(PackageManagerInternal.PackageListObserver.class);
+ verify(mMockPmi).getPackageList(observerCaptor.capture());
+ mObserver = observerCaptor.getValue();
+
+ mResult = new LaunchParams();
+ mResult.reset();
+ }
+
+ @Test
+ public void testReturnsEmptyLaunchParamsByDefault() {
+ mResult.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+
+ mTarget.getLaunchParams(mTestTask, null, mResult);
+
+ assertTrue("Default result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testSavesAndRestoresLaunchParamsInSameInstance() {
+ mTarget.saveTask(mTestTask);
+
+ mTarget.getLaunchParams(mTestTask, null, mResult);
+
+ assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId);
+ assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode);
+ assertEquals(TEST_BOUNDS, mResult.mBounds);
+ }
+
+ @Test
+ public void testFetchesSameResultWithActivity() {
+ mTarget.saveTask(mTestTask);
+
+ final ActivityRecord activity = new ActivityBuilder(mService).setComponent(TEST_COMPONENT)
+ .setUid(TEST_USER_ID * UserHandle.PER_USER_RANGE).build();
+
+ mTarget.getLaunchParams(null, activity, mResult);
+
+ assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId);
+ assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode);
+ assertEquals(TEST_BOUNDS, mResult.mBounds);
+ }
+
+ @Test
+ public void testReturnsEmptyDisplayIfDisplayIsNotFound() {
+ mTarget.saveTask(mTestTask);
+
+ when(mSupervisor.getActivityDisplay(eq(mDisplayUniqueId))).thenReturn(null);
+
+ mTarget.getLaunchParams(mTestTask, null, mResult);
+
+ assertEquals(INVALID_DISPLAY, mResult.mPreferredDisplayId);
+ assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode);
+ assertEquals(TEST_BOUNDS, mResult.mBounds);
+ }
+
+ @Test
+ public void testReturnsEmptyLaunchParamsUserIdMismatch() {
+ mTarget.saveTask(mTestTask);
+
+ mResult.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+ mTarget.getLaunchParams(mTaskWithDifferentUser, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testReturnsEmptyLaunchParamsComponentMismatch() {
+ mTarget.saveTask(mTestTask);
+
+ mResult.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+ mTarget.getLaunchParams(mTaskWithDifferentComponent, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testSavesAndRestoresLaunchParamsAcrossInstances() {
+ mTarget.saveTask(mTestTask);
+ mPersisterQueue.flush();
+
+ final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
+ mUserFolderGetter);
+ target.onSystemReady();
+ target.onUnlockUser(TEST_USER_ID);
+
+ target.getLaunchParams(mTestTask, null, mResult);
+
+ assertEquals(mTestDisplay.mDisplayId, mResult.mPreferredDisplayId);
+ assertEquals(TEST_WINDOWING_MODE, mResult.mWindowingMode);
+ assertEquals(TEST_BOUNDS, mResult.mBounds);
+ }
+
+ @Test
+ public void testClearsRecordsOfTheUserOnUserCleanUp() {
+ mTarget.saveTask(mTestTask);
+
+ ActivityStack stack = mTestDisplay.createStack(TEST_WINDOWING_MODE,
+ ACTIVITY_TYPE_STANDARD, /* onTop */ true);
+ final TaskRecord anotherTaskOfTheSameUser = new TaskBuilder(mSupervisor)
+ .setComponent(ALTERNATIVE_COMPONENT)
+ .setUserId(TEST_USER_ID)
+ .setStack(stack)
+ .build();
+ anotherTaskOfTheSameUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ anotherTaskOfTheSameUser.setBounds(200, 300, 400, 500);
+ anotherTaskOfTheSameUser.hasBeenVisible = true;
+ mTarget.saveTask(anotherTaskOfTheSameUser);
+
+ stack = mTestDisplay.createStack(TEST_WINDOWING_MODE,
+ ACTIVITY_TYPE_STANDARD, /* onTop */ true);
+ final TaskRecord anotherTaskOfDifferentUser = new TaskBuilder(mSupervisor)
+ .setComponent(TEST_COMPONENT)
+ .setUserId(ALTERNATIVE_USER_ID)
+ .setStack(stack)
+ .build();
+ anotherTaskOfDifferentUser.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ anotherTaskOfDifferentUser.setBounds(300, 400, 500, 600);
+ anotherTaskOfDifferentUser.hasBeenVisible = true;
+ mTarget.saveTask(anotherTaskOfDifferentUser);
+
+ mTarget.onCleanupUser(TEST_USER_ID);
+
+ mTarget.getLaunchParams(anotherTaskOfDifferentUser, null, mResult);
+ assertFalse("Shouldn't clear record of a different user.", mResult.isEmpty());
+
+ mTarget.getLaunchParams(mTestTask, null, mResult);
+ assertTrue("Should have cleaned record for " + TEST_COMPONENT, mResult.isEmpty());
+
+ mTarget.getLaunchParams(anotherTaskOfTheSameUser, null, mResult);
+ assertTrue("Should have cleaned record for " + ALTERNATIVE_COMPONENT, mResult.isEmpty());
+ }
+
+ @Test
+ public void testClearsRecordInMemoryOnPackageUninstalled() {
+ mTarget.saveTask(mTestTask);
+
+ mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+
+ mTarget.getLaunchParams(mTestTask, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testClearsWriteQueueItemOnPackageUninstalled() {
+ mTarget.saveTask(mTestTask);
+
+ mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+
+ final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
+ mUserFolderGetter);
+ target.onSystemReady();
+ target.onUnlockUser(TEST_USER_ID);
+
+ target.getLaunchParams(mTestTask, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testClearsFileOnPackageUninstalled() {
+ mTarget.saveTask(mTestTask);
+ mPersisterQueue.flush();
+
+ mObserver.onPackageRemoved(TEST_COMPONENT.getPackageName());
+
+ final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
+ mUserFolderGetter);
+ target.onSystemReady();
+ target.onUnlockUser(TEST_USER_ID);
+
+ target.getLaunchParams(mTestTask, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ @Test
+ public void testClearsRemovedPackageFilesOnStartUp() {
+ mTarget.saveTask(mTestTask);
+ mPersisterQueue.flush();
+
+ when(mMockPmi.getPackageList(any())).thenReturn(
+ new PackageList(Collections.emptyList(), /* observer */ null));
+
+ final LaunchParamsPersister target = new LaunchParamsPersister(mPersisterQueue, mSupervisor,
+ mUserFolderGetter);
+ target.onSystemReady();
+ target.onUnlockUser(TEST_USER_ID);
+
+ target.getLaunchParams(mTestTask, null, mResult);
+
+ assertTrue("Result should be empty.", mResult.isEmpty());
+ }
+
+ private static boolean deleteRecursively(File file) {
+ boolean result = true;
+ if (file.isDirectory()) {
+ for (File child : file.listFiles()) {
+ result &= deleteRecursively(child);
+ }
+ }
+
+ result &= file.delete();
+ return result;
+ }
+
+ /**
+ * Test double to {@link PersisterQueue}. This is not thread-safe and caller should always use
+ * {@link #flush()} to execute write items in it.
+ */
+ static class TestPersisterQueue extends PersisterQueue {
+ private List<WriteQueueItem> mWriteQueue = new ArrayList<>();
+ private List<Listener> mListeners = new ArrayList<>();
+
+ @Override
+ void flush() {
+ while (!mWriteQueue.isEmpty()) {
+ final WriteQueueItem item = mWriteQueue.remove(0);
+ final boolean queueEmpty = mWriteQueue.isEmpty();
+ for (Listener listener : mListeners) {
+ listener.onPreProcessItem(queueEmpty);
+ }
+ item.process();
+ }
+ }
+
+ @Override
+ void startPersisting() {
+ // Do nothing. We're not using threading logic.
+ }
+
+ @Override
+ void stopPersisting() {
+ // Do nothing. We're not using threading logic.
+ }
+
+ @Override
+ void addItem(WriteQueueItem item, boolean flush) {
+ mWriteQueue.add(item);
+ if (flush) {
+ flush();
+ }
+ }
+
+ @Override
+ synchronized <T extends WriteQueueItem> T findLastItem(Predicate<T> predicate,
+ Class<T> clazz) {
+ for (int i = mWriteQueue.size() - 1; i >= 0; --i) {
+ WriteQueueItem writeQueueItem = mWriteQueue.get(i);
+ if (clazz.isInstance(writeQueueItem)) {
+ T item = clazz.cast(writeQueueItem);
+ if (predicate.test(item)) {
+ return item;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ synchronized <T extends WriteQueueItem> void removeItems(Predicate<T> predicate,
+ Class<T> clazz) {
+ for (int i = mWriteQueue.size() - 1; i >= 0; --i) {
+ WriteQueueItem writeQueueItem = mWriteQueue.get(i);
+ if (clazz.isInstance(writeQueueItem)) {
+ T item = clazz.cast(writeQueueItem);
+ if (predicate.test(item)) {
+ mWriteQueue.remove(i);
+ }
+ }
+ }
+ }
+
+ @Override
+ void addListener(Listener listener) {
+ mListeners.add(listener);
+ }
+
+ @Override
+ void yieldIfQueueTooDeep() {
+ // Do nothing. We're not using threading logic.
+ }
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 20150b4..434ba93 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -185,7 +185,7 @@
mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
assertEquals("Target didn't process all items.", 2, mItemCount.get());
processDuration = SystemClock.uptimeMillis() - dispatchTime;
- assertTrue("Target didn't wait enough time before processing item."
+ assertTrue("Target didn't wait enough time before processing item. Process time: "
+ processDuration + "ms pre task delay: "
+ PRE_TASK_DELAY_MS + "ms",
processDuration >= PRE_TASK_DELAY_MS);
@@ -246,6 +246,39 @@
}
@Test
+ public void testUpdateLastOrAddItemUpdatesMatchedItem() throws Exception {
+ mLatch = new CountDownLatch(1);
+ final MatchingTestItem scheduledItem = new MatchingTestItem(true);
+ final MatchingTestItem expected = new MatchingTestItem(true);
+ synchronized (mTarget) {
+ mTarget.addItem(scheduledItem, false);
+ mTarget.updateLastOrAddItem(expected, false);
+ }
+
+ assertSame(expected, scheduledItem.mUpdateFromItem);
+ assertTrue("Target didn't call callback enough times.",
+ mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+ assertEquals("Target didn't process item.", 1, mItemCount.get());
+ }
+
+ @Test
+ public void testUpdateLastOrAddItemUpdatesAddItemWhenNoMatch() throws Exception {
+ mLatch = new CountDownLatch(2);
+ final MatchingTestItem scheduledItem = new MatchingTestItem(false);
+ final MatchingTestItem expected = new MatchingTestItem(true);
+ synchronized (mTarget) {
+ mTarget.addItem(scheduledItem, false);
+ mTarget.updateLastOrAddItem(expected, false);
+ }
+
+ assertNull(scheduledItem.mUpdateFromItem);
+ assertTrue("Target didn't call callback enough times.",
+ mLatch.await(PRE_TASK_DELAY_MS + INTER_WRITE_DELAY_MS + TIMEOUT_ALLOWANCE,
+ TimeUnit.MILLISECONDS));
+ assertEquals("Target didn't process item.", 2, mItemCount.get());
+ }
+
+ @Test
public void testRemoveItemsRemoveMatchedItem() throws Exception {
mLatch = new CountDownLatch(1);
synchronized (mTarget) {
@@ -283,18 +316,30 @@
mSetUpLatch.countDown();
}
- private class TestItem implements PersisterQueue.WriteQueueItem {
+ private class TestItem<T extends TestItem<T>> implements PersisterQueue.WriteQueueItem<T> {
@Override
public void process() {
mItemCount.getAndIncrement();
}
}
- private class MatchingTestItem extends TestItem {
+ private class MatchingTestItem extends TestItem<MatchingTestItem> {
private boolean mMatching;
+ private MatchingTestItem mUpdateFromItem;
+
private MatchingTestItem(boolean matching) {
mMatching = matching;
}
+
+ @Override
+ public boolean matches(MatchingTestItem item) {
+ return item.mMatching;
+ }
+
+ @Override
+ public void updateFrom(MatchingTestItem item) {
+ mUpdateFromItem = item;
+ }
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index 95965c8..2168fab 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -41,6 +41,7 @@
import android.graphics.Rect;
import android.os.Build;
import android.platform.test.annotations.Presubmit;
+import android.view.Display;
import android.view.Gravity;
import androidx.test.filters.FlakyTest;
@@ -110,6 +111,16 @@
}
@Test
+ public void testUsesDefaultDisplayIfPreviousDisplayNotExists() {
+ mCurrent.mPreferredDisplayId = 19;
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+ mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+ assertEquals(DEFAULT_DISPLAY, mResult.mPreferredDisplayId);
+ }
+
+ @Test
public void testUsesPreviousDisplayIdIfSet() {
createNewActivityDisplay(WINDOWING_MODE_FREEFORM);
final TestActivityDisplay display = createNewActivityDisplay(WINDOWING_MODE_FULLSCREEN);
@@ -856,30 +867,48 @@
}
@Test
- public void testAdjustBoundsToFitDisplay_LargerThanDisplay() {
+ public void testAdjustBoundsToFitNewDisplay_LargerThanDisplay() {
final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
WINDOWING_MODE_FREEFORM);
- Configuration overrideConfig = new Configuration();
- overrideConfig.setTo(mSupervisor.getOverrideConfiguration());
- overrideConfig.setLayoutDirection(new Locale("ar"));
- mSupervisor.onConfigurationChanged(overrideConfig);
-
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchDisplayId(freeformDisplay.mDisplayId);
- final ActivityRecord source = createSourceActivity(freeformDisplay);
- source.setBounds(1720, 680, 1920, 1080);
+ mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+ mCurrent.mBounds.set(100, 200, 2120, 1380);
mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
- mActivity, source, options, mCurrent, mResult));
+ mActivity, /* source */ null, options, mCurrent, mResult));
- final Rect displayBounds = freeformDisplay.getBounds();
- assertTrue("display bounds doesn't contain result. display bounds: "
- + displayBounds + " result: " + mResult.mBounds,
- displayBounds.contains(mResult.mBounds));
+ assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
+ mResult.mBounds.left == 0 && mResult.mBounds.top == 0);
+ }
+
+ @Test
+ public void testAdjustBoundsToFitNewDisplay_LargerThanDisplay_RTL() {
+ final Configuration overrideConfig = mSupervisor.getOverrideConfiguration();
+ // Egyptian Arabic is a RTL language.
+ overrideConfig.setLayoutDirection(new Locale("ar", "EG"));
+ mSupervisor.onOverrideConfigurationChanged(overrideConfig);
+
+ final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+ WINDOWING_MODE_FREEFORM);
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+ mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+ mCurrent.mBounds.set(100, 200, 2120, 1380);
+
+ mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+ mActivity, /* source */ null, options, mCurrent, mResult));
+
+ assertTrue("Result bounds should start from origin, but it's " + mResult.mBounds,
+ mResult.mBounds.left == -100 && mResult.mBounds.top == 0);
}
@Test
@@ -1021,6 +1050,41 @@
assertEquals(new Rect(0, 0, 1680, 953), mResult.mBounds);
}
+ @Test
+ public void testAdjustsBoundsToFitInDisplayFullyResolvedBounds() {
+ final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+ WINDOWING_MODE_FREEFORM);
+
+ mCurrent.mPreferredDisplayId = Display.INVALID_DISPLAY;
+ mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+ mCurrent.mBounds.set(-100, -200, 200, 100);
+
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+ mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+ assertEquals(new Rect(0, 0, 300, 300), mResult.mBounds);
+ }
+
+ @Test
+ public void testAdjustsBoundsToAvoidConflictFullyResolvedBounds() {
+ final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+ WINDOWING_MODE_FREEFORM);
+
+ addFreeformTaskTo(freeformDisplay, new Rect(0, 0, 200, 100));
+
+ mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+ mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+ mCurrent.mBounds.set(0, 0, 200, 100);
+
+ assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+ mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+ assertEquals(new Rect(120, 0, 320, 100), mResult.mBounds);
+ }
+
private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
display.setWindowingMode(windowingMode);
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index eaaf9b2..8e1ede1 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -118,9 +118,14 @@
void removeUsageGroup(UsageGroup group) {
final int size = group.mObserved.length;
for (int i = 0; i < size; i++) {
- final ArrayList<UsageGroup> list = observedMap.get(group.mObserved[i]);
+ final String observed = group.mObserved[i];
+ final ArrayList<UsageGroup> list = observedMap.get(observed);
if (list != null) {
list.remove(group);
+ if (list.isEmpty()) {
+ // No more observers for this observed entity, remove from map
+ observedMap.remove(observed);
+ }
}
}
}
@@ -137,7 +142,7 @@
}
pw.println();
pw.print(" Observed Entities:");
- final int nEntities = currentlyActive.size();
+ final int nEntities = observedMap.size();
for (int i = 0; i < nEntities; i++) {
pw.print(observedMap.keyAt(i));
pw.print(", ");
@@ -183,7 +188,7 @@
pw.println();
}
pw.println(" Session Usage Groups:");
- final int nSessionUsageGroups = appUsageGroups.size();
+ final int nSessionUsageGroups = sessionUsageGroups.size();
for (int i = 0; i < nSessionUsageGroups; i++) {
sessionUsageGroups.valueAt(i).dump(pw);
pw.println();
@@ -616,7 +621,7 @@
AppUsageGroup group = observerApp.appUsageGroups.get(observerId);
if (group != null) {
// Remove previous app usage group associated with observerId
- observerApp.appUsageGroups.get(observerId).remove();
+ group.remove();
}
final int observerIdCount = observerApp.appUsageGroups.size();
@@ -646,8 +651,12 @@
*/
public void removeAppUsageObserver(int requestingUid, int observerId, @UserIdInt int userId) {
synchronized (mLock) {
- ObserverAppData observerApp = getOrCreateObserverAppDataLocked(requestingUid);
- observerApp.appUsageGroups.get(observerId).remove();
+ final ObserverAppData observerApp = getOrCreateObserverAppDataLocked(requestingUid);
+ final AppUsageGroup group = observerApp.appUsageGroups.get(observerId);
+ if (group != null) {
+ // Remove previous app usage group associated with observerId
+ group.remove();
+ }
}
}
@@ -668,8 +677,8 @@
ObserverAppData observerApp = getOrCreateObserverAppDataLocked(requestingUid);
SessionUsageGroup group = observerApp.sessionUsageGroups.get(observerId);
if (group != null) {
- // Remove previous app usage group associated with observerId
- observerApp.sessionUsageGroups.get(observerId).remove();
+ // Remove previous session usage group associated with observerId
+ group.remove();
}
final int observerIdCount = observerApp.sessionUsageGroups.size();
@@ -696,8 +705,12 @@
public void removeUsageSessionObserver(int requestingUid, int observerId,
@UserIdInt int userId) {
synchronized (mLock) {
- ObserverAppData observerApp = getOrCreateObserverAppDataLocked(requestingUid);
- observerApp.sessionUsageGroups.get(observerId).remove();
+ final ObserverAppData observerApp = getOrCreateObserverAppDataLocked(requestingUid);
+ final SessionUsageGroup group = observerApp.sessionUsageGroups.get(observerId);
+ if (group != null) {
+ // Remove previous app usage group associated with observerId
+ group.remove();
+ }
}
}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 27b8cdf..60cb08f 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -153,6 +153,7 @@
private static final int MSG_SET_FUNCTIONS_TIMEOUT = 15;
private static final int MSG_GET_CURRENT_USB_FUNCTIONS = 16;
private static final int MSG_FUNCTION_SWITCH_TIMEOUT = 17;
+ private static final int MSG_GADGET_HAL_REGISTERED = 18;
private static final int AUDIO_MODE_SOURCE = 1;
@@ -1708,10 +1709,16 @@
protected static final String CTL_STOP = "ctl.stop";
/**
- * Adb natvie daemon
+ * Adb native daemon.
*/
protected static final String ADBD = "adbd";
+ /**
+ * Gadget HAL fully qualified instance name for registering for ServiceNotification.
+ */
+ protected static final String GADGET_HAL_FQ_NAME =
+ "android.hardware.usb.gadget@1.0::IUsbGadget";
+
protected boolean mCurrentUsbFunctionsRequested;
UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager,
@@ -1721,8 +1728,7 @@
ServiceNotification serviceNotification = new ServiceNotification();
boolean ret = IServiceManager.getService()
- .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget",
- "", serviceNotification);
+ .registerForNotifications(GADGET_HAL_FQ_NAME, "", serviceNotification);
if (!ret) {
Slog.e(TAG, "Failed to register usb gadget service start notification");
return;
@@ -1764,20 +1770,12 @@
@Override
public void onRegistration(String fqName, String name, boolean preexisting) {
Slog.i(TAG, "Usb gadget hal service started " + fqName + " " + name);
- synchronized (mGadgetProxyLock) {
- try {
- mGadgetProxy = IUsbGadget.getService();
- mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
- USB_GADGET_HAL_DEATH_COOKIE);
- if (!mCurrentFunctionsApplied && !mCurrentUsbFunctionsRequested) {
- setEnabledFunctions(mCurrentFunctions, false);
- }
- } catch (NoSuchElementException e) {
- Slog.e(TAG, "Usb gadget hal not found", e);
- } catch (RemoteException e) {
- Slog.e(TAG, "Usb Gadget hal not responding", e);
- }
+ if (!fqName.equals(GADGET_HAL_FQ_NAME)) {
+ Slog.e(TAG, "fqName does not match");
+ return;
}
+
+ sendMessage(MSG_GADGET_HAL_REGISTERED, preexisting);
}
}
@@ -1815,6 +1813,23 @@
setEnabledFunctions(UsbManager.FUNCTION_NONE, !isAdbEnabled());
}
break;
+ case MSG_GADGET_HAL_REGISTERED:
+ boolean preexisting = msg.arg1 == 1;
+ synchronized (mGadgetProxyLock) {
+ try {
+ mGadgetProxy = IUsbGadget.getService();
+ mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
+ USB_GADGET_HAL_DEATH_COOKIE);
+ if (!mCurrentFunctionsApplied && !preexisting) {
+ setEnabledFunctions(mCurrentFunctions, false);
+ }
+ } catch (NoSuchElementException e) {
+ Slog.e(TAG, "Usb gadget hal not found", e);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Usb Gadget hal not responding", e);
+ }
+ }
+ break;
default:
super.handleMessage(msg);
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index ad2501d..d6b40ae 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -42,6 +42,7 @@
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Slog;
+
import com.android.internal.logging.MetricsLogger;
import java.io.FileDescriptor;
@@ -566,38 +567,34 @@
}
}
- SoundTrigger.RecognitionEvent getGenericModelState(UUID modelId) {
+ int getGenericModelState(UUID modelId) {
synchronized (mLock) {
MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
if (modelId == null || mModule == null) {
- return null;
+ return STATUS_ERROR;
}
ModelData modelData = mModelDataMap.get(modelId);
if (modelData == null || !modelData.isGenericModel()) {
Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
modelId);
- return null;
+ return STATUS_ERROR;
}
if (!modelData.isModelLoaded()) {
Slog.i(TAG, "GetGenericModelState: Given generic model is not loaded:" + modelId);
- return null;
+ return STATUS_ERROR;
}
if (!modelData.isModelStarted()) {
Slog.i(TAG, "GetGenericModelState: Given generic model is not started:" + modelId);
- return null;
+ return STATUS_ERROR;
}
- SoundTrigger.RecognitionEvent ret = mModule.getModelState(modelData.getHandle());
- if (ret == null) {
- Slog.w(TAG, "GetGenericModelState() call failed");
- }
- return ret;
+ return mModule.getModelState(modelData.getHandle());
}
}
- SoundTrigger.RecognitionEvent getKeyphraseModelState(UUID modelId) {
+ int getKeyphraseModelState(UUID modelId) {
Slog.w(TAG, "GetKeyphraseModelState error: Not implemented");
- return null;
+ return STATUS_ERROR;
}
//---- SoundTrigger.StatusListener methods
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index d57fcb1..8c82cc8 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -436,9 +436,10 @@
}
@Override
- public SoundTrigger.RecognitionEvent getModelState(ParcelUuid soundModelId) {
+ public int getModelState(ParcelUuid soundModelId) {
enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
- if (!isInitialized()) return null;
+ int ret = STATUS_ERROR;
+ if (!isInitialized()) return ret;
if (DEBUG) {
Slog.i(TAG, "getModelState(): id = " + soundModelId);
}
@@ -447,9 +448,8 @@
SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
if (soundModel == null) {
Slog.e(TAG, soundModelId + " is not loaded");
- return null;
+ return ret;
}
- SoundTrigger.RecognitionEvent ret = null;
switch (soundModel.type) {
case SoundModel.TYPE_KEYPHRASE:
ret = mSoundTriggerHelper.getKeyphraseModelState(soundModel.uuid);
@@ -461,9 +461,6 @@
Slog.e(TAG, "Unknown model type");
break;
}
- if (ret == null) {
- Slog.e(TAG, "Failed to get model state");
- }
return ret;
}
@@ -942,7 +939,11 @@
runOrAddOperation(new Operation(
// always execute:
() -> {
- if (!mRecognitionConfig.allowMultipleTriggers) {
+ // Don't remove the callback if multiple triggers are allowed or
+ // if this event was triggered by a getModelState request
+ if (!mRecognitionConfig.allowMultipleTriggers
+ && event.status
+ != SoundTrigger.RECOGNITION_STATUS_GET_STATE_RESPONSE) {
// Unregister this remoteService once op is done
synchronized (mCallbacksLock) {
mCallbacks.remove(mPuuid.getUuid());
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index c39688c..0c40a6b 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -62,3 +62,22 @@
],
test_suites: ["general-tests"],
}
+
+cc_binary_host {
+ name: "dex_testcase_generator",
+ defaults: ["viewcompiler_defaults"],
+ srcs: ["dex_testcase_generator.cc"],
+ static_libs: [
+ "libviewcompiler",
+ ],
+}
+
+genrule {
+ name: "generate_dex_testcases",
+ tools: [":dex_testcase_generator"],
+ cmd: "$(location :dex_testcase_generator) $(genDir)",
+ out: [
+ "simple.dex",
+ "trivial.dex",
+ ],
+}
diff --git a/startop/view_compiler/README.md b/startop/view_compiler/README.md
index 5659501..f8da02b 100644
--- a/startop/view_compiler/README.md
+++ b/startop/view_compiler/README.md
@@ -23,3 +23,31 @@
application.
* This only works for apps that do not use a custom layout inflater.
* Other limitations yet to be discovered.
+
+## DexBuilder Tests
+
+The DexBuilder has several low-level end to end tests to verify generated DEX
+code validates, runs, and has the correct behavior. There are, unfortunately, a
+number of pieces that must be added to generate new tests. Here are the
+components:
+
+* `dex_testcase_generator` - Written in C++ using `DexBuilder`. This runs as a
+ build step produce the DEX files that will be tested on device. See the
+ `genrule` named `generate_dex_testcases` in `Android.bp`. These files are then
+ copied over to the device by TradeFed when running tests.
+* `DexBuilderTest` - This is a Java Language test harness that loads the
+ generated DEX files and exercises methods in the file.
+
+To add a new DEX file test, follow these steps:
+1. Modify `dex_testcase_generator` to produce the DEX file.
+2. Add the filename to the `out` list of the `generate_dex_testcases` rule in
+ `Android.bp`.
+3. Add a new `push` option to `AndroidTest.xml` to copy the DEX file to the
+ device.
+4. Modify `DexBuilderTest.java` to load and exercise the new test.
+
+In each case, you should be able to cargo-cult the existing test cases.
+
+In general, you can probably get by without adding a new generated DEX file, and
+instead add more methods to the files that are already generated. In this case,
+you can skip all of steps 2 and 3 above, and simplify steps 1 and 4.
diff --git a/startop/view_compiler/TEST_MAPPING b/startop/view_compiler/TEST_MAPPING
new file mode 100644
index 0000000..5d675b7
--- /dev/null
+++ b/startop/view_compiler/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "dex-builder-test"
+ }
+ ]
+}
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 13e7f73..33df6f9 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -17,7 +17,6 @@
#include "dex_builder.h"
#include "dex/descriptors_names.h"
-#include "dex/dex_instruction.h"
#include <fstream>
#include <memory>
@@ -56,6 +55,12 @@
case Instruction::Op::kInvokeVirtual:
out << "kInvokeVirtual";
return out;
+ case Instruction::Op::kBindLabel:
+ out << "kBindLabel";
+ return out;
+ case Instruction::Op::kBranchEqz:
+ out << "kBranchEqz";
+ return out;
}
}
@@ -224,6 +229,11 @@
Value MethodBuilder::MakeRegister() { return Value::Local(num_registers_++); }
+Value MethodBuilder::MakeLabel() {
+ labels_.push_back({});
+ return Value::Label(labels_.size() - 1);
+}
+
void MethodBuilder::AddInstruction(Instruction instruction) {
instructions_.push_back(instruction);
}
@@ -254,6 +264,10 @@
return EncodeMove(instruction);
case Instruction::Op::kInvokeVirtual:
return EncodeInvokeVirtual(instruction);
+ case Instruction::Op::kBindLabel:
+ return BindLabel(instruction.args()[0]);
+ case Instruction::Op::kBranchEqz:
+ return EncodeBranch(art::Instruction::IF_EQZ, instruction);
}
}
@@ -307,7 +321,22 @@
}
}
-size_t MethodBuilder::RegisterValue(Value value) const {
+// Encodes a conditional branch that tests a single argument.
+void MethodBuilder::EncodeBranch(art::Instruction::Code op, const Instruction& instruction) {
+ const auto& args = instruction.args();
+ const auto& test_value = args[0];
+ const auto& branch_target = args[1];
+ CHECK_EQ(2, args.size());
+ CHECK(test_value.is_variable());
+ CHECK(branch_target.is_label());
+
+ size_t instruction_offset = buffer_.size();
+ buffer_.push_back(op | (RegisterValue(test_value) << 8));
+ size_t field_offset = buffer_.size();
+ buffer_.push_back(LabelValue(branch_target, instruction_offset, field_offset));
+}
+
+size_t MethodBuilder::RegisterValue(const Value& value) const {
if (value.is_register()) {
return value.value();
} else if (value.is_parameter()) {
@@ -317,6 +346,37 @@
return 0;
}
+void MethodBuilder::BindLabel(const Value& label_id) {
+ CHECK(label_id.is_label());
+
+ LabelData& label = labels_[label_id.value()];
+ CHECK(!label.bound_address.has_value());
+
+ label.bound_address = buffer_.size();
+
+ // patch any forward references to this label.
+ for (const auto& ref : label.references) {
+ buffer_[ref.field_offset] = *label.bound_address - ref.instruction_offset;
+ }
+ // No point keeping these around anymore.
+ label.references.clear();
+}
+
+::dex::u2 MethodBuilder::LabelValue(const Value& label_id, size_t instruction_offset,
+ size_t field_offset) {
+ CHECK(label_id.is_label());
+ LabelData& label = labels_[label_id.value()];
+
+ // Short-circuit if the label is already bound.
+ if (label.bound_address.has_value()) {
+ return *label.bound_address - instruction_offset;
+ }
+
+ // Otherwise, save a reference to where we need to back-patch later.
+ label.references.push_front(LabelReference{instruction_offset, field_offset});
+ return 0;
+}
+
const MethodDeclData& DexBuilder::GetOrDeclareMethod(TypeDescriptor type, const std::string& name,
Prototype prototype) {
MethodDeclData& entry = method_id_map_[{type, name, prototype}];
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index e46655e..0744151 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -16,12 +16,14 @@
#ifndef DEX_BUILDER_H_
#define DEX_BUILDER_H_
+#include <forward_list>
#include <map>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>
+#include "dex/dex_instruction.h"
#include "slicer/dex_ir.h"
#include "slicer/writer.h"
@@ -108,15 +110,18 @@
static constexpr Value Local(size_t id) { return Value{id, Kind::kLocalRegister}; }
static constexpr Value Parameter(size_t id) { return Value{id, Kind::kParameter}; }
static constexpr Value Immediate(size_t value) { return Value{value, Kind::kImmediate}; }
+ static constexpr Value Label(size_t id) { return Value{id, Kind::kLabel}; }
bool is_register() const { return kind_ == Kind::kLocalRegister; }
bool is_parameter() const { return kind_ == Kind::kParameter; }
+ bool is_variable() const { return is_register() || is_parameter(); }
bool is_immediate() const { return kind_ == Kind::kImmediate; }
+ bool is_label() const { return kind_ == Kind::kLabel; }
size_t value() const { return value_; }
private:
- enum class Kind { kLocalRegister, kParameter, kImmediate };
+ enum class Kind { kLocalRegister, kParameter, kImmediate, kLabel };
const size_t value_;
const Kind kind_;
@@ -132,7 +137,7 @@
public:
// The operation performed by this instruction. These are virtual instructions that do not
// correspond exactly to DEX instructions.
- enum class Op { kReturn, kMove, kInvokeVirtual };
+ enum class Op { kReturn, kMove, kInvokeVirtual, kBindLabel, kBranchEqz };
////////////////////////
// Named Constructors //
@@ -195,6 +200,8 @@
// it's up to the caller to reuse registers as appropriate.
Value MakeRegister();
+ Value MakeLabel();
+
/////////////////////////////////
// Instruction builder methods //
/////////////////////////////////
@@ -215,9 +222,18 @@
void EncodeReturn(const Instruction& instruction);
void EncodeMove(const Instruction& instruction);
void EncodeInvokeVirtual(const Instruction& instruction);
+ void EncodeBranch(art::Instruction::Code op, const Instruction& instruction);
// Converts a register or parameter to its DEX register number.
- size_t RegisterValue(Value value) const;
+ size_t RegisterValue(const Value& value) const;
+
+ // Sets a label's address to the current position in the instruction buffer. If there are any
+ // forward references to the label, this function will back-patch them.
+ void BindLabel(const Value& label);
+
+ // Returns the offset of the label relative to the given instruction offset. If the label is not
+ // bound, a reference will be saved and it will automatically be patched when the label is bound.
+ ::dex::u2 LabelValue(const Value& label, size_t instruction_offset, size_t field_offset);
DexBuilder* dex_;
ir::Class* class_;
@@ -231,6 +247,21 @@
// How many registers we've allocated
size_t num_registers_{0};
+
+ // Stores information needed to back-patch a label once it is bound. We need to know the start of
+ // the instruction that refers to the label, and the offset to where the actual label value should
+ // go.
+ struct LabelReference {
+ size_t instruction_offset;
+ size_t field_offset;
+ };
+
+ struct LabelData {
+ std::optional<size_t> bound_address;
+ std::forward_list<LabelReference> references;
+ };
+
+ std::vector<LabelData> labels_;
};
// A helper to build class definitions.
diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp
new file mode 100644
index 0000000..4449ea0
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/Android.bp
@@ -0,0 +1,29 @@
+//
+// Copyright (C) 2018 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.
+//
+
+android_test {
+ name: "dex-builder-test",
+ srcs: ["src/android/startop/test/DexBuilderTest.java"],
+ sdk_version: "current",
+ data: [":generate_dex_testcases"],
+ static_libs: [
+ "android-support-test",
+ "guava",
+ ],
+ manifest: "AndroidManifest.xml",
+ test_config: "AndroidTest.xml",
+ test_suites: ["general-tests"],
+}
diff --git a/startop/view_compiler/dex_builder_test/AndroidManifest.xml b/startop/view_compiler/dex_builder_test/AndroidManifest.xml
new file mode 100644
index 0000000..6ac5fc5
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.startop.test" >
+
+ <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.startop.test"
+ android:label="DexBuilder Tests"/>
+
+</manifest>
diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml
new file mode 100644
index 0000000..6f90cf3
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+<configuration description="Runs DexBuilder Tests.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-instrumentation" />
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="dex-builder-test.apk" />
+ </target_preparer>
+
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+ <option name="cleanup" value="true" />
+ <option name="push" value="trivial.dex->/data/local/tmp/dex-builder-test/trivial.dex" />
+ <option name="push" value="simple.dex->/data/local/tmp/dex-builder-test/simple.dex" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="android.startop.test" />
+ <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+ </test>
+</configuration>
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
new file mode 100644
index 0000000..169c633
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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.startop.test;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import com.google.common.io.ByteStreams;
+import dalvik.system.InMemoryDexClassLoader;
+import dalvik.system.PathClassLoader;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import org.junit.Assert;
+import org.junit.Test;
+
+// Adding tests here requires changes in several other places. See README.md in
+// the view_compiler directory for more information.
+public class DexBuilderTest {
+ static ClassLoader loadDexFile(String filename) throws Exception {
+ return new PathClassLoader("/data/local/tmp/dex-builder-test/" + filename,
+ ClassLoader.getSystemClassLoader());
+ }
+
+ public void hello() {}
+
+ @Test
+ public void loadTrivialDex() throws Exception {
+ ClassLoader loader = loadDexFile("trivial.dex");
+ loader.loadClass("android.startop.test.testcases.Trivial");
+ }
+
+ @Test
+ public void return5() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("return5");
+ Assert.assertEquals(5, method.invoke(null));
+ }
+
+ @Test
+ public void returnParam() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("returnParam", int.class);
+ Assert.assertEquals(5, method.invoke(null, 5));
+ Assert.assertEquals(42, method.invoke(null, 42));
+ }
+
+ @Test
+ public void returnStringLength() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("returnStringLength", String.class);
+ Assert.assertEquals(13, method.invoke(null, "Hello, World!"));
+ }
+
+ @Test
+ public void returnIfZero() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("returnIfZero", int.class);
+ Assert.assertEquals(5, method.invoke(null, 0));
+ Assert.assertEquals(3, method.invoke(null, 17));
+ }
+
+ @Test
+ public void backwardsBranch() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("backwardsBranch");
+ Assert.assertEquals(2, method.invoke(null));
+ }
+}
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
new file mode 100644
index 0000000..c521bf2
--- /dev/null
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2018 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 "android-base/logging.h"
+#include "dex_builder.h"
+
+#include <fstream>
+#include <string>
+
+// Adding tests here requires changes in several other places. See README.md in
+// the view_compiler directory for more information.
+
+using namespace startop::dex;
+using namespace std;
+
+void GenerateTrivialDexFile(const string& outdir) {
+ DexBuilder dex_file;
+
+ ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.Trivial")};
+ cbuilder.set_source_file("dex_testcase_generator.cc#GenerateTrivialDexFile");
+
+ slicer::MemView image{dex_file.CreateImage()};
+ std::ofstream out_file(outdir + "/trivial.dex");
+ out_file.write(image.ptr<const char>(), image.size());
+}
+
+// Generates test cases that test around 1 instruction.
+void GenerateSimpleTestCases(const string& outdir) {
+ DexBuilder dex_file;
+
+ ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.SimpleTests")};
+ cbuilder.set_source_file("dex_testcase_generator.cc#GenerateSimpleTestCases");
+
+ // int return5() { return 5; }
+ auto return5{cbuilder.CreateMethod("return5", Prototype{TypeDescriptor::Int()})};
+ {
+ Value r{return5.MakeRegister()};
+ return5.BuildConst4(r, 5);
+ return5.BuildReturn(r);
+ }
+ return5.Encode();
+
+ // // int returnParam(int x) { return x; }
+ auto returnParam{cbuilder.CreateMethod("returnParam",
+ Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
+ returnParam.BuildReturn(Value::Parameter(0));
+ returnParam.Encode();
+
+ // int returnStringLength(String x) { return x.length(); }
+ auto string_type{TypeDescriptor::FromClassname("java.lang.String")};
+ MethodDeclData string_length{
+ dex_file.GetOrDeclareMethod(string_type, "length", Prototype{TypeDescriptor::Int()})};
+
+ auto returnStringLength{
+ cbuilder.CreateMethod("returnStringLength", Prototype{TypeDescriptor::Int(), string_type})};
+ {
+ Value result = returnStringLength.MakeRegister();
+ returnStringLength.AddInstruction(
+ Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0)));
+ returnStringLength.BuildReturn(result);
+ }
+ returnStringLength.Encode();
+
+ // int returnIfZero(int x) { if (x == 0) { return 5; } else { return 3; } }
+ MethodBuilder returnIfZero{cbuilder.CreateMethod(
+ "returnIfZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
+ {
+ Value resultIfZero{returnIfZero.MakeRegister()};
+ Value else_target{returnIfZero.MakeLabel()};
+ returnIfZero.AddInstruction(Instruction::OpWithArgs(
+ Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target));
+ // else branch
+ returnIfZero.BuildConst4(resultIfZero, 3);
+ returnIfZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero));
+ // then branch
+ returnIfZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target));
+ returnIfZero.BuildConst4(resultIfZero, 5);
+ returnIfZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero));
+ }
+ returnIfZero.Encode();
+
+ // Make sure backwards branches work too.
+ //
+ // Pseudo code for test:
+ // {
+ // zero = 0;
+ // result = 1;
+ // if (zero == 0) goto B;
+ // A:
+ // return result;
+ // B:
+ // result = 2;
+ // if (zero == 0) goto A;
+ // result = 3;
+ // return result;
+ // }
+ // If it runs correctly, this test should return 2.
+ MethodBuilder backwardsBranch{
+ cbuilder.CreateMethod("backwardsBranch", Prototype{TypeDescriptor::Int()})};
+ [](MethodBuilder& method) {
+ Value zero = method.MakeRegister();
+ Value result = method.MakeRegister();
+ Value labelA = method.MakeLabel();
+ Value labelB = method.MakeLabel();
+ method.BuildConst4(zero, 0);
+ method.BuildConst4(result, 1);
+ method.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelB));
+
+ method.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelA));
+ method.BuildReturn(result);
+
+ method.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelB));
+ method.BuildConst4(result, 2);
+ method.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelA));
+
+ method.BuildConst4(result, 3);
+ method.BuildReturn(result);
+ }(backwardsBranch);
+ backwardsBranch.Encode();
+
+ slicer::MemView image{dex_file.CreateImage()};
+ std::ofstream out_file(outdir + "/simple.dex");
+ out_file.write(image.ptr<const char>(), image.size());
+}
+
+int main(int argc, char** argv) {
+ CHECK_EQ(argc, 2);
+
+ string outdir = argv[1];
+
+ GenerateTrivialDexFile(outdir);
+ GenerateSimpleTestCases(outdir);
+}
diff --git a/telecomm/java/android/telecom/Logging/EventManager.java b/telecomm/java/android/telecom/Logging/EventManager.java
index 2bda648..1342038 100644
--- a/telecomm/java/android/telecom/Logging/EventManager.java
+++ b/telecomm/java/android/telecom/Logging/EventManager.java
@@ -180,7 +180,7 @@
}
}
- private final List<Event> mEvents = new LinkedList<>();
+ private final List<Event> mEvents = Collections.synchronizedList(new LinkedList<>());
private final Loggable mRecordEntry;
public EventRecord(Loggable recordEntry) {
@@ -197,7 +197,7 @@
}
public List<Event> getEvents() {
- return mEvents;
+ return new LinkedList<>(mEvents);
}
public List<EventTiming> extractEventTimings() {
@@ -207,21 +207,24 @@
LinkedList<EventTiming> result = new LinkedList<>();
Map<String, PendingResponse> pendingResponses = new HashMap<>();
- for (Event event : mEvents) {
- if (requestResponsePairs.containsKey(event.eventId)) {
- // This event expects a response, so add that expected response to the maps
- // of pending events.
- for (EventManager.TimedEventPair p : requestResponsePairs.get(event.eventId)) {
- pendingResponses.put(p.mResponse, new PendingResponse(event.eventId,
- event.time, p.mTimeoutMillis, p.mName));
+ synchronized (mEvents) {
+ for (Event event : mEvents) {
+ if (requestResponsePairs.containsKey(event.eventId)) {
+ // This event expects a response, so add that expected response to the maps
+ // of pending events.
+ for (EventManager.TimedEventPair p : requestResponsePairs.get(
+ event.eventId)) {
+ pendingResponses.put(p.mResponse, new PendingResponse(event.eventId,
+ event.time, p.mTimeoutMillis, p.mName));
+ }
}
- }
- PendingResponse pendingResponse = pendingResponses.remove(event.eventId);
- if (pendingResponse != null) {
- long elapsedTime = event.time - pendingResponse.requestEventTimeMillis;
- if (elapsedTime < pendingResponse.timeoutMillis) {
- result.add(new EventTiming(pendingResponse.name, elapsedTime));
+ PendingResponse pendingResponse = pendingResponses.remove(event.eventId);
+ if (pendingResponse != null) {
+ long elapsedTime = event.time - pendingResponse.requestEventTimeMillis;
+ if (elapsedTime < pendingResponse.timeoutMillis) {
+ result.add(new EventTiming(pendingResponse.name, elapsedTime));
+ }
}
}
}
@@ -233,7 +236,8 @@
pw.print(mRecordEntry.getDescription());
pw.increaseIndent();
- for (Event event : mEvents) {
+ // Iterate over copy of events so that this doesn't hold the lock for too long.
+ for (Event event : getEvents()) {
pw.print(event.timestampString);
pw.print(" - ");
pw.print(event.eventId);
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 61d60e3..b3e1ffa 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3613,6 +3613,27 @@
}
/**
+ * Generates a content {@link Uri} used to receive updates on precise carrier identity
+ * change on the given subscriptionId
+ * {@link TelephonyManager#ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED}.
+ * <p>
+ * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+ * precise carrier identity {@link TelephonyManager#getSimPreciseCarrierId()}
+ * while your app is running. You can also use a {@link JobService} to ensure your app
+ * is notified of changes to the {@link Uri} even when it is not running.
+ * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+ * updates to the {@link Uri}.
+ *
+ * @param subscriptionId the subscriptionId to receive updates on
+ * @return the Uri used to observe precise carrier identity changes
+ * @hide
+ */
+ public static Uri getPreciseCarrierIdUriForSubscriptionId(int subscriptionId) {
+ return Uri.withAppendedPath(Uri.withAppendedPath(CONTENT_URI, "precise"),
+ String.valueOf(subscriptionId));
+ }
+
+ /**
* A user facing carrier name.
* @see TelephonyManager#getSimCarrierIdName()
* <P>Type: TEXT </P>
@@ -3627,6 +3648,35 @@
public static final String CARRIER_ID = "carrier_id";
/**
+ * A user facing carrier name for precise carrier id.
+ * @see TelephonyManager#getSimPreciseCarrierIdName()
+ * This is not a database column, only used to notify content observers for
+ * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
+ * @hide
+ */
+ public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
+
+ /**
+ * A fine-grained carrier id.
+ * @see TelephonyManager#getSimPreciseCarrierId()
+ * This is not a database column, only used to notify content observers for
+ * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
+ * @hide
+ */
+ public static final String PRECISE_CARRIER_ID = "precise_carrier_id";
+
+ /**
+ * A unique parent carrier id. The parent-child
+ * relationship can be used to further differentiate a single carrier by different networks,
+ * by prepaid v.s. postpaid or even by 4G v.s. 3G plan. It's an optional field.
+ * A carrier id with a valid parent_carrier_id is considered fine-grained carrier id, will
+ * not be returned as {@link #CARRIER_ID} but {@link #PRECISE_CARRIER_ID}.
+ * <P>Type: INTEGER </P>
+ * @hide
+ */
+ public static final String PARENT_CARRIER_ID = "parent_carrier_id";
+
+ /**
* A unique mno carrier id. mno carrier shares the same {@link All#MCCMNC} as carrier id
* and can be solely identified by {@link All#MCCMNC} only. If there is no such mno
* carrier, then mno carrier id equals to {@link #CARRIER_ID carrier id}.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3f9a533..fbc54ae6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1079,24 +1079,44 @@
"wfc_operator_error_codes_string_array";
/**
- * Indexes of SPN format strings in wfcSpnFormats and wfcDataSpnFormats.
+ * Indexes of SPN format strings in wfcSpnFormats.
*
* <p>Available options are:
* <ul>
- * <li> 0: %s</li>
- * <li> 1: %s Wi-Fi Calling</li>
- * <li> 2: WLAN Call</li>
- * <li> 3: %s WLAN Call</li>
- * <li> 4: %s Wi-Fi</li>
- * <li> 5: WiFi Calling | %s</li>
- * <li> 6: %s VoWifi</li>
+ * <li> 0: %s</li>
+ * <li> 1: %s Wi-Fi Calling</li>
+ * <li> 2: WLAN Call</li>
+ * <li> 3: %s WLAN Call</li>
+ * <li> 4: %s Wi-Fi</li>
+ * <li> 5: WiFi Calling | %s</li>
+ * <li> 6: %s VoWifi</li>
+ * <li> 7: Wi-Fi Calling</li>
+ * <li> 8: Wi-Fi</li>
+ * <li> 9: WiFi Calling</li>
+ * <li> 10: VoWifi</li>
* @hide
*/
public static final String KEY_WFC_SPN_FORMAT_IDX_INT = "wfc_spn_format_idx_int";
- /** @hide */
+
+ /**
+ * Indexes of data SPN format strings in wfcSpnFormats.
+ *
+ * @see KEY_WFC_SPN_FORMAT_IDX_INT for available options.
+ * @hide
+ */
public static final String KEY_WFC_DATA_SPN_FORMAT_IDX_INT = "wfc_data_spn_format_idx_int";
/**
+ * Indexes of SPN format strings in wfcSpnFormats used during flight mode.
+ *
+ * Set to -1 to use the value from KEY_WFC_SPN_FORMAT_IDX_INT also in this case.
+ * @see KEY_WFC_SPN_FORMAT_IDX_INT for other available options.
+ * @hide
+ */
+ public static final String KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT =
+ "wfc_flight_mode_spn_format_idx_int";
+
+ /**
* Use root locale when reading wfcSpnFormats.
*
* If true, then the root locale will always be used when reading wfcSpnFormats. This means the
@@ -2456,6 +2476,7 @@
sDefaults.putStringArray(KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY, null);
sDefaults.putInt(KEY_WFC_SPN_FORMAT_IDX_INT, 0);
sDefaults.putInt(KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 0);
+ sDefaults.putInt(KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT, -1);
sDefaults.putBoolean(KEY_WFC_SPN_USE_ROOT_LOCALE, false);
sDefaults.putString(KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING, "");
sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 2ff75e6..d075394 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -30,6 +30,25 @@
private static final String LOG_TAG = "CellSignalStrengthLte";
private static final boolean DBG = false;
+ /**
+ * Indicates the unknown or undetectable RSSI value in ASU.
+ *
+ * Reference: TS 27.007 8.5 - Signal quality +CSQ
+ */
+ private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
+ /**
+ * Indicates the maximum valid RSSI value in ASU.
+ *
+ * Reference: TS 27.007 8.5 - Signal quality +CSQ
+ */
+ private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
+ /**
+ * Indicates the minimum valid RSSI value in ASU.
+ *
+ * Reference: TS 27.007 8.5 - Signal quality +CSQ
+ */
+ private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
+
@UnsupportedAppUsage
private int mSignalStrength;
@UnsupportedAppUsage
@@ -141,6 +160,19 @@
}
/**
+ * Get Received Signal Strength Indication (RSSI) in dBm
+ *
+ * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
+ *
+ * Reference: TS 27.007 8.5 Signal quality +CSQ
+ *
+ * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
+ */
+ public int getRssi() {
+ return convertRssiAsuToDBm(mSignalStrength);
+ }
+
+ /**
* Get reference signal signal-to-noise ratio
*
* @return the RSSNR if available or
@@ -308,4 +340,17 @@
private static void log(String s) {
Rlog.w(LOG_TAG, s);
}
+
+ private static int convertRssiAsuToDBm(int rssiAsu) {
+ if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN
+ && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
+ || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
+ Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
+ return CellInfo.UNAVAILABLE;
+ }
+ if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
+ return CellInfo.UNAVAILABLE;
+ }
+ return -113 + (2 * rssiAsu);
+ }
}
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index c3d8898..68e512e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -237,10 +237,9 @@
}
/**
- * @return {@link ServiceState.RoamingType roaming type}. This could return
- * overridden roaming type based on resource overlay or carrier config.
- * @hide
+ * @return the current network roaming type.
*/
+
public @ServiceState.RoamingType int getRoamingType() {
return mRoamingType;
}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 97b1bdc..f5dff20 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -16,7 +16,9 @@
package android.telephony;
+import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
@@ -201,12 +203,13 @@
public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000;
/**
- * Listen for changes to LTE network state
- *
- * @see #onLteNetworkStateChanged
+ * Listen for changes to the SRVCC state of the active call.
+ * @see #onServiceStateChanged(ServiceState)
* @hide
*/
- public static final int LISTEN_VOLTE_STATE = 0x00004000;
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000;
/**
* Listen for OEM hook raw event
@@ -409,8 +412,8 @@
PhoneStateListener.this.onDataConnectionRealTimeInfoChanged(
(DataConnectionRealTimeInfo)msg.obj);
break;
- case LISTEN_VOLTE_STATE:
- PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj);
+ case LISTEN_SRVCC_STATE_CHANGED:
+ PhoneStateListener.this.onSrvccStateChanged((int) msg.obj);
break;
case LISTEN_VOICE_ACTIVATION_STATE:
PhoneStateListener.this.onVoiceActivationStateChanged((int)msg.obj);
@@ -613,13 +616,13 @@
}
/**
- * Callback invoked when the service state of LTE network
- * related to the VoLTE service has changed.
- * @param stateInfo is the current LTE network information
+ * Callback invoked when there has been a change in the Single Radio Voice Call Continuity
+ * (SRVCC) state for the currently active call.
* @hide
*/
- @UnsupportedAppUsage
- public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) {
+ @SystemApi
+ public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) {
+
}
/**
@@ -803,8 +806,8 @@
send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo);
}
- public void onVoLteServiceStateChanged(VoLteServiceState lteState) {
- send(LISTEN_VOLTE_STATE, 0, 0, lteState);
+ public void onSrvccStateChanged(int state) {
+ send(LISTEN_SRVCC_STATE_CHANGED, 0, 0, state);
}
public void onVoiceActivationStateChanged(int activationState) {
@@ -855,4 +858,4 @@
private void log(String s) {
Rlog.d(LOG_TAG, s);
}
-}
+}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index c407681..0937b10 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -211,29 +211,30 @@
ROAMING_TYPE_INTERNATIONAL
})
public @interface RoamingType {}
+
/**
- * Roaming type
- * HOME : in home network
+ * Not roaming, registered in home network.
* @hide
*/
+ @SystemApi
public static final int ROAMING_TYPE_NOT_ROAMING = 0;
/**
- * Roaming type
- * UNKNOWN : in a roaming network, but we can not tell if it's domestic or international
+ * registered in a roaming network, but can not tell if it's domestic or international.
* @hide
*/
+ @SystemApi
public static final int ROAMING_TYPE_UNKNOWN = 1;
/**
- * Roaming type
- * DOMESTIC : in domestic roaming network
+ * registered in a domestic roaming network
* @hide
*/
+ @SystemApi
public static final int ROAMING_TYPE_DOMESTIC = 2;
/**
- * Roaming type
- * INTERNATIONAL : in international roaming network
+ * registered in an international roaming network
* @hide
*/
+ @SystemApi
public static final int ROAMING_TYPE_INTERNATIONAL = 3;
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8414ed3..a188ef6 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -181,6 +181,57 @@
/** @hide */
static public final int KEY_TYPE_WLAN = 2;
+ /**
+ * No Single Radio Voice Call Continuity (SRVCC) handover is active.
+ * See TS 23.216 for more information.
+ * @hide
+ */
+ @SystemApi
+ public static final int SRVCC_STATE_HANDOVER_NONE = -1;
+
+ /**
+ * Single Radio Voice Call Continuity (SRVCC) handover has been started on the network.
+ * See TS 23.216 for more information.
+ * @hide
+ */
+ @SystemApi
+ public static final int SRVCC_STATE_HANDOVER_STARTED = 0;
+
+ /**
+ * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has successfully completed.
+ * See TS 23.216 for more information.
+ * @hide
+ */
+ @SystemApi
+ public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1;
+
+ /**
+ * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has failed.
+ * See TS 23.216 for more information.
+ * @hide
+ */
+ @SystemApi
+ public static final int SRVCC_STATE_HANDOVER_FAILED = 2;
+
+ /**
+ * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has been canceled.
+ * See TS 23.216 for more information.
+ * @hide
+ */
+ @SystemApi
+ public static final int SRVCC_STATE_HANDOVER_CANCELED = 3;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"SRVCC_STATE_"},
+ value = {
+ SRVCC_STATE_HANDOVER_NONE,
+ SRVCC_STATE_HANDOVER_STARTED,
+ SRVCC_STATE_HANDOVER_COMPLETED,
+ SRVCC_STATE_HANDOVER_FAILED,
+ SRVCC_STATE_HANDOVER_CANCELED})
+ public @interface SrvccState {}
+
private final Context mContext;
private final int mSubId;
@UnsupportedAppUsage
@@ -1161,6 +1212,33 @@
"android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
/**
+ * Broadcast Action: The subscription precise carrier identity has changed.
+ * Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be sent
+ * on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}. However, its possible
+ * that precise carrier identity changes while
+ * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, the same
+ * subscription switches to different IMSI could potentially change its precise carrier id.
+ *
+ * The intent will have the following extra values:
+ * <ul>
+ * <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the
+ * current subscription.
+ * </li>
+ * <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date carrier name of the current
+ * subscription.
+ * </li>
+ * <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier
+ * identity.
+ * </li>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED =
+ "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
+
+ /**
* An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
* the updated carrier id {@link TelephonyManager#getSimCarrierId()} of
* the current subscription.
@@ -1189,6 +1267,28 @@
public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
/**
+ * An int extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
+ * indicates the updated precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()} of
+ * the current subscription. Note, its possible precise carrier id changes while
+ * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, when
+ * subscription switch to different IMSI.
+ * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
+ * the carrier cannot be identified.
+ * @hide
+ */
+ public static final String EXTRA_PRECISE_CARRIER_ID =
+ "android.telephony.extra.PRECISE_CARRIER_ID";
+
+ /**
+ * An string extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
+ * indicates the updated precise carrier name of the current subscription.
+ * {@see TelephonyManager#getSimPreciseCarrierIdName()}
+ * <p>it's a user-facing name of the precise carrier id {@link #EXTRA_PRECISE_CARRIER_ID},
+ * @hide
+ */
+ public static final String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
+
+ /**
* An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the
* subscription which has changed.
*/
@@ -8269,6 +8369,62 @@
}
/**
+ * Returns fine-grained carrier id of the current subscription.
+ *
+ * <p>The precise carrier id can be used to further differentiate a carrier by different
+ * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
+ * carrier id {@link #getSimCarrierId()} but can have multiple precise carrier id. e.g,
+ * {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
+ * {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
+ * current subscription IMSI.
+ *
+ * <p>For carriers without any fine-grained carrier ids, return {@link #getSimCarrierId()}
+ * <p>Precise carrier ids are defined in the same way as carrier id
+ * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * except each with a "parent" id linking to its top-level carrier id.
+ *
+ * @return Returns fine-grained carrier id of the current subscription.
+ * Return {@link #UNKNOWN_CARRIER_ID} if the subscription is unavailable or the carrier cannot
+ * be identified.
+ *
+ * @hide
+ */
+ public int getSimPreciseCarrierId() {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getSubscriptionPreciseCarrierId(getSubId());
+ }
+ } catch (RemoteException ex) {
+ // This could happen if binder process crashes.
+ }
+ return UNKNOWN_CARRIER_ID;
+ }
+
+ /**
+ * Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the
+ * precise carrier id {@link #getSimPreciseCarrierId()}
+ *
+ * <p>The returned name is unlocalized.
+ *
+ * @return user-facing name of the subscription precise carrier id. Return {@code null} if the
+ * subscription is unavailable or the carrier cannot be identified.
+ *
+ * @hide
+ */
+ public CharSequence getSimPreciseCarrierIdName() {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getSubscriptionPreciseCarrierName(getSubId());
+ }
+ } catch (RemoteException ex) {
+ // This could happen if binder process crashes.
+ }
+ return null;
+ }
+
+ /**
* Return a list of certs in hex string from loaded carrier privileges access rules.
*
* @return a list of certificate in hex string. return {@code null} if there is no certs
@@ -9068,7 +9224,7 @@
public static final int NETWORK_TYPE_BITMASK_LTE_CA = (1 << NETWORK_TYPE_LTE_CA);
/**
- * @return Modem supported radio access family bitmask {@link NetworkTypeBitMask}
+ * @return Modem supported radio access family bitmask
*
* <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
* that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java
index 25bb8b4..cf961d0 100644
--- a/telephony/java/android/telephony/VoLteServiceState.java
+++ b/telephony/java/android/telephony/VoLteServiceState.java
@@ -24,9 +24,11 @@
/**
* Contains LTE network state related information.
- *
+ * @deprecated Only contains SRVCC state, which isn't specific to LTE handovers. For SRVCC
+ * indications, use {@link PhoneStateListener#onSrvccStateChanged(int)}.
* @hide
*/
+@Deprecated
public final class VoLteServiceState implements Parcelable {
private static final String LOG_TAG = "VoLteServiceState";
diff --git a/telephony/java/android/telephony/RcsManager.java b/telephony/java/android/telephony/rcs/RcsManager.java
similarity index 86%
rename from telephony/java/android/telephony/RcsManager.java
rename to telephony/java/android/telephony/rcs/RcsManager.java
index 00ce03a..0ef4e15 100644
--- a/telephony/java/android/telephony/RcsManager.java
+++ b/telephony/java/android/telephony/rcs/RcsManager.java
@@ -14,18 +14,22 @@
* limitations under the License.
*/
-package android.telephony;
+package android.telephony.rcs;
+import android.annotation.SystemService;
+import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.telephony.Rlog;
-import com.android.internal.telephony.IRcs;
+import com.android.internal.telephony.rcs.IRcs;
/**
* RcsManager is the application interface to RcsProvider and provides access methods to
* RCS related database tables.
* @hide - TODO make this public
*/
+@SystemService(Context.TELEPHONY_RCS_SERVICE)
public class RcsManager {
private static final String TAG = "RcsManager";
private static final boolean VDBG = false;
diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/telephony/java/android/telephony/rcs/RcsThread.aidl
new file mode 100644
index 0000000..e2e0da5d
--- /dev/null
+++ b/telephony/java/android/telephony/rcs/RcsThread.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2018, 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.telephony;
+
+parcelable RcsThread;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/rcs/RcsThread.java b/telephony/java/android/telephony/rcs/RcsThread.java
new file mode 100644
index 0000000..83eb973
--- /dev/null
+++ b/telephony/java/android/telephony/rcs/RcsThread.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 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.telephony.rcs;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.rcs.IRcs;
+
+/**
+ * RcsThread represents a single RCS conversation thread. It holds messages that were sent and
+ * received and events that occured on that thread.
+ * @hide - TODO(sahinc) make this public
+ */
+public class RcsThread implements Parcelable {
+ public static final Creator<RcsThread> CREATOR = new Creator<RcsThread>() {
+ @Override
+ public RcsThread createFromParcel(Parcel in) {
+ return new RcsThread(in);
+ }
+
+ @Override
+ public RcsThread[] newArray(int size) {
+ return new RcsThread[size];
+ }
+ };
+
+ protected RcsThread(Parcel in) {
+ }
+
+ /**
+ * Returns the number of messages in this RCS thread.
+ *
+ * @hide
+ */
+ public int getMessageCount() {
+ try {
+ IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+ if (iRcs != null) {
+ // TODO(sahinc): substitute to the regular thread id once we have database
+ // TODO(sahinc): connection in place
+ return iRcs.getMessageCount(/* rcsThreadId= */ 123);
+ }
+ } catch (RemoteException re) {
+ // TODO(sahinc): Log something meaningful
+ }
+ return 0;
+ }
+
+ /** Implement the Parcelable interface */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ }
+}
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 9e42f12..79f0635 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -25,7 +25,6 @@
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
-import android.telephony.VoLteServiceState;
oneway interface IPhoneStateListener {
void onServiceStateChanged(in ServiceState serviceState);
@@ -45,7 +44,7 @@
void onPreciseCallStateChanged(in PreciseCallState callState);
void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState);
void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo);
- void onVoLteServiceStateChanged(in VoLteServiceState lteState);
+ void onSrvccStateChanged(in int state);
void onVoiceActivationStateChanged(int activationState);
void onDataActivationStateChanged(int activationState);
void onOemHookRawEvent(in byte[] rawData);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 682141f..3aaa323 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1323,6 +1323,37 @@
int getSubscriptionMNOCarrierId(int subId);
/**
+ * Returns fine-grained carrier id of the current subscription.
+ *
+ * <p>The precise carrier id can be used to further differentiate a carrier by different
+ * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
+ * carrier id {@link #getSimCarrierId()} but can have multiple precise carrier id. e.g,
+ * {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
+ * {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
+ * current underlying network.
+ *
+ * <p>For carriers without any fine-grained carrier ids, return {@link #getSimCarrierId()}
+ *
+ * @return Returns fine-grained carrier id of the current subscription.
+ * Return {@link #UNKNOWN_CARRIER_ID} if the subscription is unavailable or the carrier cannot
+ * be identified.
+ * @hide
+ */
+ int getSubscriptionPreciseCarrierId(int subId);
+
+ /**
+ * Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the
+ * precise carrier id {@link #getSimPreciseCarrierId()}
+ *
+ * <p>The returned name is unlocalized.
+ *
+ * @return user-facing name of the subscription precise carrier id. Return {@code null} if the
+ * subscription is unavailable or the carrier cannot be identified.
+ * @hide
+ */
+ String getSubscriptionPreciseCarrierName(int subId);
+
+ /**
* Action set from carrier signalling broadcast receivers to enable/disable metered apns
* Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
* @param subId the subscription ID that this action applies to.
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 0baf860..923ab06 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -25,7 +25,6 @@
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
-import android.telephony.VoLteServiceState;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -70,7 +69,7 @@
void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn,
String failCause);
void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo);
- void notifyVoLteServiceStateChanged(in VoLteServiceState lteState);
+ void notifySrvccStateChanged(in int subId, in int lteState);
void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId,
int activationState, int activationType);
void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 5ecb43e..2a648bd 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -480,9 +480,9 @@
public static final String EXTRA_PCO_VALUE_KEY = "pcoValue";
public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable";
- /**
+ /**
* Broadcast action to trigger CI OMA-DM Session.
- */
+ */
public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE =
"com.android.omadm.service.CONFIGURATION_UPDATE";
@@ -491,4 +491,14 @@
*/
public static final String ACTION_CARRIER_CERTIFICATE_DOWNLOAD =
"com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD";
+
+ /**
+ * Broadcast action to indicate an error related to Line1Number has been detected.
+ *
+ * Requires the READ_PRIVILEGED_PHONE_STATE permission.
+ *
+ * @hide
+ */
+ public static final String ACTION_LINE1_NUMBER_ERROR_DETECTED =
+ "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED";
}
diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
similarity index 83%
rename from telephony/java/com/android/internal/telephony/IRcs.aidl
rename to telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
index ede8695..4c289ac 100644
--- a/telephony/java/com/android/internal/telephony/IRcs.aidl
+++ b/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
@@ -14,8 +14,12 @@
* limitations under the License.
*/
-package com.android.internal.telephony;
+package com.android.internal.telephony.rcs;
interface IRcs {
+ // RcsManager APIs
void deleteThread(int threadId);
+
+ // RcsThread APIs
+ int getMessageCount(int rcsThreadId);
}
\ No newline at end of file
diff --git a/tests/RcsTests/Android.mk b/tests/RcsTests/Android.mk
new file mode 100644
index 0000000..adc7cab
--- /dev/null
+++ b/tests/RcsTests/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := RcsTests
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+LOCAL_CERTIFICATE := platform
+LOCAL_JAVA_LIBRARIES := android.test.runner android.test.base
+LOCAL_STATIC_JAVA_LIBRARIES := junit android-support-test mockito-target-minus-junit4
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/RcsTests/AndroidManifest.xml b/tests/RcsTests/AndroidManifest.xml
new file mode 100644
index 0000000..a7e7d47
--- /dev/null
+++ b/tests/RcsTests/AndroidManifest.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.tests.rcs">
+ <application android:label="RCS Test">
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.tests.rcs"/>
+</manifest>
diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java b/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java
new file mode 100644
index 0000000..7f5f03e0d
--- /dev/null
+++ b/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 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.tests.rcs;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.telephony.rcs.RcsManager;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RcsManagerTest {
+ //TODO(sahinc): Add meaningful tests once we have more of the implementation in place
+ @Test
+ public void testDeleteThreadDoesntCrash() {
+ RcsManager mRcsManager = new RcsManager();
+ mRcsManager.deleteThread(0);
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index f12756a..af7123b 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -30,7 +30,9 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -63,24 +65,13 @@
@Mock private PackageManager mPackageManager;
private PermissionMonitor mPermissionMonitor;
- private int mMockFirstSdkInt;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(MOCK_PACKAGE_NAMES);
- // Try to use spy() here for stubbing getDeviceFirstSdkInt value but the spies are loaded
- // by a custom class loader that's different from the loader used for loading the real
- // thing. That means those two classes are not in the same package, so a package private
- // method is not accessible. Hence, using override method to control FIRST_SDK_INT value
- // instead of spy function for testing.
- mPermissionMonitor = new PermissionMonitor(mContext, null) {
- @Override
- int getDeviceFirstSdkInt() {
- return mMockFirstSdkInt;
- }
- };
+ mPermissionMonitor = spy(new PermissionMonitor(mContext, null));
}
private boolean hasBgPermission(String partition, int targetSdkVersion, int uid,
@@ -166,13 +157,13 @@
@Test
public void testHasUseBackgroundNetworksPermissionSystemUid() throws Exception {
- mMockFirstSdkInt = VERSION_P;
+ doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CHANGE_WIFI_STATE));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID,
CONNECTIVITY_USE_RESTRICTED_NETWORKS));
- mMockFirstSdkInt = VERSION_Q;
+ doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt();
assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CHANGE_WIFI_STATE));
assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID,
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 1ef34b9..8585ae9 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -435,7 +435,7 @@
fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
fprintf(out, " }\n");
fprintf(out, " if (ret < 0) {\n");
- fprintf(out, " note_log_drop();\n");
+ fprintf(out, " note_log_drop(ret);\n");
fprintf(out, " }\n");
fprintf(out, " return ret;\n");
fprintf(out, "}\n");
@@ -528,7 +528,7 @@
fprintf(out, " std::this_thread::sleep_for(std::chrono::milliseconds(10));\n");
fprintf(out, " }\n");
fprintf(out, " if (ret < 0) {\n");
- fprintf(out, " note_log_drop();\n");
+ fprintf(out, " note_log_drop(ret);\n");
fprintf(out, " }\n");
fprintf(out, " return ret;\n\n");
fprintf(out, "}\n");