Merge "Adding SecureTouchListener to drop suspicious touches" into oc-dev
diff --git a/api/current.txt b/api/current.txt
index 157a72c..899381b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30508,7 +30508,7 @@
field public static final int M = 23; // 0x17
field public static final int N = 24; // 0x18
field public static final int N_MR1 = 25; // 0x19
- field public static final int O = 26; // 0x1a
+ field public static final int O = 10000; // 0x2710
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index 110d1dd..8aa6c36 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -33218,7 +33218,7 @@
field public static final int M = 23; // 0x17
field public static final int N = 24; // 0x18
field public static final int N_MR1 = 25; // 0x19
- field public static final int O = 26; // 0x1a
+ field public static final int O = 10000; // 0x2710
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index ef2fce7..944a350 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -30617,7 +30617,7 @@
field public static final int M = 23; // 0x17
field public static final int N = 24; // 0x18
field public static final int N_MR1 = 25; // 0x19
- field public static final int O = 26; // 0x1a
+ field public static final int O = 10000; // 0x2710
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/cmds/vr/src/com/android/commands/vr/Vr.java b/cmds/vr/src/com/android/commands/vr/Vr.java
index bf97bba..b765866 100644
--- a/cmds/vr/src/com/android/commands/vr/Vr.java
+++ b/cmds/vr/src/com/android/commands/vr/Vr.java
@@ -16,7 +16,7 @@
package com.android.commands.vr;
-import android.app.CompatibilityDisplayProperties;
+import android.app.Vr2dDisplayProperties;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -39,7 +39,7 @@
private static final String COMMAND_SET_PERSISTENT_VR_MODE_ENABLED =
"set-persistent-vr-mode-enabled";
- private static final String COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES =
+ private static final String COMMAND_SET_VR2D_DISPLAY_PROPERTIES =
"set-display-props";
private IVrManager mVrService;
@@ -63,8 +63,8 @@
String command = nextArgRequired();
switch (command) {
- case COMMAND_SET_COMPATIBILITY_DISPLAY_PROPERTIES:
- runSetCompatibilityDisplayProperties();
+ case COMMAND_SET_VR2D_DISPLAY_PROPERTIES:
+ runSetVr2dDisplayProperties();
break;
case COMMAND_SET_PERSISTENT_VR_MODE_ENABLED:
runSetPersistentVrModeEnabled();
@@ -74,7 +74,7 @@
}
}
- private void runSetCompatibilityDisplayProperties() throws RemoteException {
+ private void runSetVr2dDisplayProperties() throws RemoteException {
String widthStr = nextArgRequired();
int width = Integer.parseInt(widthStr);
@@ -84,11 +84,11 @@
String dpiStr = nextArgRequired();
int dpi = Integer.parseInt(dpiStr);
- CompatibilityDisplayProperties compatDisplayProperties =
- new CompatibilityDisplayProperties(width, height, dpi);
+ Vr2dDisplayProperties vr2dDisplayProperties =
+ new Vr2dDisplayProperties(width, height, dpi);
try {
- mVrService.setCompatibilityDisplayProperties(compatDisplayProperties);
+ mVrService.setVr2dDisplayProperties(vr2dDisplayProperties);
} catch (RemoteException re) {
System.err.println("Error: Can't set persistent mode " + re);
}
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 65cb5f4..0dfaf6a 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -244,8 +244,8 @@
/**
* Called after virtual display Id is updated by
- * {@link com.android.server.vr.CompatibilityDisplay} with a specific
- * {@param compatibilityDisplayId}.
+ * {@link com.android.server.vr.Vr2dDisplay} with a specific
+ * {@param vr2dDisplayId}.
*/
- public abstract void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId);
+ public abstract void setVr2dDisplayId(int vr2dDisplayId);
}
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 3221c5d..620e5cf 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -226,11 +226,7 @@
@Override
public void doAlarm(IAlarmCompleteListener alarmManager) {
mCompletion = alarmManager;
- mHandler.post(this);
- }
- @Override
- public void run() {
// Remove this listener from the wrapper cache first; the server side
// already considers it gone
synchronized (AlarmManager.class) {
@@ -239,6 +235,11 @@
}
}
+ mHandler.post(this);
+ }
+
+ @Override
+ public void run() {
// Now deliver it to the app
try {
mListener.onAlarm();
diff --git a/core/java/android/app/AuthenticationRequiredException.java b/core/java/android/app/AuthenticationRequiredException.java
index 8960979..04e5e0a 100644
--- a/core/java/android/app/AuthenticationRequiredException.java
+++ b/core/java/android/app/AuthenticationRequiredException.java
@@ -56,10 +56,7 @@
* {@link Activity#setResult(int)} before finishing to
* communicate the final status of the recovery. For example,
* apps that observe {@link Activity#RESULT_OK} may choose to
- * immediately retry their operation. If this exception was
- * thrown from a {@link ContentProvider}, you should also send
- * any relevant {@link ContentResolver#notifyChange} events to
- * trigger reloading of data.
+ * immediately retry their operation.
*/
public AuthenticationRequiredException(Throwable cause, PendingIntent userAction) {
super(cause.getMessage());
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index f369955..4994fbb 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -39,8 +39,11 @@
* Called whenever IActivityManager.startActivity is called on an activity that is already
* running in the pinned stack and the activity is not actually started, but the task is either
* brought to the front or a new Intent is delivered to it.
+ *
+ * @param clearedTask whether or not the launch activity also cleared the task as a part of
+ * starting
*/
- void onPinnedActivityRestartAttempt();
+ void onPinnedActivityRestartAttempt(boolean clearedTask);
/**
* Called whenever the pinned stack is starting animating a resize.
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c8b8c6c..2e56bcf 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4358,6 +4358,8 @@
mN.mLargeIcon = null;
Bitmap largeIconLegacy = mN.largeIcon;
mN.largeIcon = null;
+ ArrayList<Action> actions = mActions;
+ mActions = new ArrayList<>();
Bundle publicExtras = new Bundle();
publicExtras.putBoolean(EXTRA_SHOW_WHEN,
savedBundle.getBoolean(EXTRA_SHOW_WHEN));
@@ -4373,6 +4375,7 @@
mN.extras = savedBundle;
mN.mLargeIcon = largeIcon;
mN.largeIcon = largeIconLegacy;
+ mActions = actions;
mStyle = style;
return view;
}
diff --git a/core/java/android/app/RecoverableSecurityException.java b/core/java/android/app/RecoverableSecurityException.java
index a503a46..6747004 100644
--- a/core/java/android/app/RecoverableSecurityException.java
+++ b/core/java/android/app/RecoverableSecurityException.java
@@ -76,10 +76,7 @@
* {@link Activity#setResult(int)} before finishing to
* communicate the final status of the recovery. For example,
* apps that observe {@link Activity#RESULT_OK} may choose to
- * immediately retry their operation. If this exception was
- * thrown from a {@link ContentProvider}, you should also send
- * any relevant {@link ContentResolver#notifyChange} events to
- * trigger reloading of data.
+ * immediately retry their operation.
*/
public RecoverableSecurityException(Throwable cause, CharSequence userMessage,
RemoteAction userAction) {
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 0265ea5..10d6a7b 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -671,22 +671,22 @@
}
/**
- * Make this service run in the foreground, supplying the ongoing
+ * If your service is started (running through {@link Context#startService(Intent)}), then
+ * also make this service run in the foreground, supplying the ongoing
* notification to be shown to the user while in this state.
- * By default services are background, meaning that if the system needs to
- * kill them to reclaim more memory (such as to display a large page in a
- * web browser), they can be killed without too much harm. You can set this
- * flag if killing your service would be disruptive to the user, such as
+ * By default started services are background, meaning that their process won't be given
+ * foreground CPU scheduling (unless something else in that process is foreground) and,
+ * if the system needs to kill them to reclaim more memory (such as to display a large page in a
+ * web browser), they can be killed without too much harm. You use
+ * {@link #startForeground} if killing your service would be disruptive to the user, such as
* if your service is performing background music playback, so the user
* would notice if their music stopped playing.
- *
- * <p>If you need your application to run on platform versions prior to API
- * level 5, you can use the following model to call the the older setForeground()
- * or this modern method as appropriate:
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
- * foreground_compatibility}
- *
+ *
+ * <p>Note that calling this method does <em>not</em> put the service in the started state
+ * itself, even though the name sounds like it. You must always call
+ * {@link #startService(Intent)} first to tell the system it should keep the service running,
+ * and then use this method to tell it to keep it running harder.</p>
+ *
* @param id The identifier for this notification as per
* {@link NotificationManager#notify(int, Notification)
* NotificationManager.notify(int, Notification)}; must not be 0.
@@ -716,7 +716,9 @@
/**
* Remove this service from foreground state, allowing it to be killed if
- * more memory is needed.
+ * more memory is needed. This does not stop the service from running (for that
+ * you use {@link #stopSelf()} or related methods), just takes it out of the
+ * foreground state.
*
* @param flags additional behavior options.
* @see #startForeground(int, Notification)
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 307fc91..2df011f 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -39,7 +39,7 @@
}
@Override
- public void onPinnedActivityRestartAttempt() throws RemoteException {
+ public void onPinnedActivityRestartAttempt(boolean clearedTask) throws RemoteException {
}
@Override
diff --git a/core/java/android/app/CompatibilityDisplayProperties.aidl b/core/java/android/app/Vr2dDisplayProperties.aidl
similarity index 93%
rename from core/java/android/app/CompatibilityDisplayProperties.aidl
rename to core/java/android/app/Vr2dDisplayProperties.aidl
index 626a63e..1e04943 100644
--- a/core/java/android/app/CompatibilityDisplayProperties.aidl
+++ b/core/java/android/app/Vr2dDisplayProperties.aidl
@@ -17,4 +17,4 @@
package android.app;
/** @hide */
-parcelable CompatibilityDisplayProperties;
+parcelable Vr2dDisplayProperties;
diff --git a/core/java/android/app/CompatibilityDisplayProperties.java b/core/java/android/app/Vr2dDisplayProperties.java
similarity index 75%
rename from core/java/android/app/CompatibilityDisplayProperties.java
rename to core/java/android/app/Vr2dDisplayProperties.java
index 9a9bc2c..a608bb0 100644
--- a/core/java/android/app/CompatibilityDisplayProperties.java
+++ b/core/java/android/app/Vr2dDisplayProperties.java
@@ -27,7 +27,7 @@
*
* @hide
*/
-public class CompatibilityDisplayProperties implements Parcelable {
+public class Vr2dDisplayProperties implements Parcelable {
/**
* The actual width, height and dpi.
@@ -36,7 +36,7 @@
private final int mHeight;
private final int mDpi;
- public CompatibilityDisplayProperties(int width, int height, int dpi) {
+ public Vr2dDisplayProperties(int width, int height, int dpi) {
mWidth = width;
mHeight = height;
mDpi = dpi;
@@ -52,7 +52,7 @@
@Override
public String toString() {
- return "CompatibilityDisplayProperties{" +
+ return "Vr2dDisplayProperties{" +
"mWidth=" + mWidth +
", mHeight=" + mHeight +
", mDpi=" + mDpi +
@@ -64,7 +64,7 @@
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- CompatibilityDisplayProperties that = (CompatibilityDisplayProperties) o;
+ Vr2dDisplayProperties that = (Vr2dDisplayProperties) o;
if (getWidth() != that.getWidth()) return false;
if (getHeight() != that.getHeight()) return false;
@@ -83,27 +83,27 @@
dest.writeInt(mDpi);
}
- public static final Parcelable.Creator<CompatibilityDisplayProperties> CREATOR
- = new Parcelable.Creator<CompatibilityDisplayProperties>() {
+ public static final Parcelable.Creator<Vr2dDisplayProperties> CREATOR
+ = new Parcelable.Creator<Vr2dDisplayProperties>() {
@Override
- public CompatibilityDisplayProperties createFromParcel(Parcel source) {
- return new CompatibilityDisplayProperties(source);
+ public Vr2dDisplayProperties createFromParcel(Parcel source) {
+ return new Vr2dDisplayProperties(source);
}
@Override
- public CompatibilityDisplayProperties[] newArray(int size) {
- return new CompatibilityDisplayProperties[size];
+ public Vr2dDisplayProperties[] newArray(int size) {
+ return new Vr2dDisplayProperties[size];
}
};
- private CompatibilityDisplayProperties(Parcel source) {
+ private Vr2dDisplayProperties(Parcel source) {
mWidth = source.readInt();
mHeight = source.readInt();
mDpi = source.readInt();
}
public void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "CompatibilityDisplayProperties:");
+ pw.println(prefix + "Vr2dDisplayProperties:");
pw.println(prefix + " width=" + mWidth);
pw.println(prefix + " height=" + mHeight);
pw.println(prefix + " dpi=" + mDpi);
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 878c8c3..040b330 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -45,20 +45,20 @@
}
/**
- * Sets the resolution and DPI of the compatibility virtual display used to display 2D
+ * Sets the resolution and DPI of the vr2d virtual display used to display 2D
* applications in VR mode.
*
* <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
*
- * @param {@link android.app.CompatibilityDisplayProperties} properties to be set to the
- * virtual display for 2D applications in VR mode.
+ * @param vr2dDisplayProp properties to be set to the virtual display for
+ * 2D applications in VR mode.
*
* {@hide}
*/
- public void setCompatibilityDisplayProperties(
- CompatibilityDisplayProperties compatDisplayProp) {
+ public void setVr2dDisplayProperties(
+ Vr2dDisplayProperties vr2dDisplayProp) {
try {
- mService.setCompatibilityDisplayProperties(compatDisplayProp);
+ mService.setVr2dDisplayProperties(vr2dDisplayProp);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 3353530..7261dfa 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -1559,14 +1559,14 @@
@Override
public void setText(CharSequence text) {
ViewNodeText t = getNodeText();
- t.mText = text;
+ t.mText = TextUtils.trimNoCopySpans(text);
t.mTextSelectionStart = t.mTextSelectionEnd = -1;
}
@Override
public void setText(CharSequence text, int selectionStart, int selectionEnd) {
ViewNodeText t = getNodeText();
- t.mText = text;
+ t.mText = TextUtils.trimNoCopySpans(text);
t.mTextSelectionStart = selectionStart;
t.mTextSelectionEnd = selectionEnd;
}
@@ -1737,13 +1737,6 @@
}
@Override
- public void setUrl(String url) {
- if (url == null) return;
-
- setWebDomain(url);
- }
-
- @Override
public void setWebDomain(@Nullable String domain) {
if (domain == null) {
mNode.mWebDomain = null;
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index d1ad8de..c58eaa1 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -136,6 +136,38 @@
*/
public static final int STATE_NOT_PLAYING = 11;
+ /**
+ * We don't have a stored preference for whether or not the given A2DP sink device supports
+ * optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_SUPPORT_UNKNOWN = -1;
+
+ /**
+ * The given A2DP sink device does not support optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0;
+
+ /**
+ * The given A2DP sink device does support optional codecs.
+ * @hide */
+ public static final int OPTIONAL_CODECS_SUPPORTED = 1;
+
+ /**
+ * We don't have a stored preference for whether optional codecs should be enabled or disabled
+ * for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_UNKNOWN = -1;
+
+ /**
+ * Optional codecs should be disabled for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_DISABLED = 0;
+
+ /**
+ * Optional codecs should be enabled for the given A2DP device.
+ * @hide */
+ public static final int OPTIONAL_CODECS_PREF_ENABLED = 1;
+
private Context mContext;
private ServiceListener mServiceListener;
private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
@@ -655,6 +687,88 @@
}
/**
+ * Returns whether this device supports optional codecs.
+ *
+ * @param device The device to check
+ * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
+ * OPTIONAL_CODECS_SUPPORTED.
+ *
+ * @hide
+ */
+ public int supportsOptionalCodecs(BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.supportsOptionalCodecs(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
+ return OPTIONAL_CODECS_SUPPORT_UNKNOWN;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Returns whether this device should have optional codecs enabled.
+ *
+ * @param device The device in question.
+ * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
+ * OPTIONAL_CODECS_PREF_DISABLED.
+ *
+ * @hide
+ */
+ public int getOptionalCodecsEnabled(BluetoothDevice device) {
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled() && isValidDevice(device)) {
+ return mService.getOptionalCodecsEnabled(device);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return OPTIONAL_CODECS_PREF_UNKNOWN;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error talking to BT service in getSupportsOptionalCodecs()", e);
+ return OPTIONAL_CODECS_PREF_UNKNOWN;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
+ * Sets a persistent preference for whether a given device should have optional codecs enabled.
+ *
+ * @param device The device to set this preference for.
+ * @param value Whether the optional codecs should be enabled for this device. This should be
+ * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
+ * OPTIONAL_CODECS_PREF_DISABLED.
+ * @hide
+ */
+ public void setOptionalCodecsEnabled(BluetoothDevice device, int value) {
+ try {
+ if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN &&
+ value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED &&
+ value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
+ Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
+ return;
+ }
+ mServiceLock.readLock().lock();
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ mService.setOptionalCodecsEnabled(device, value);
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return;
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return;
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ }
+
+ /**
* Helper for converting a state to a string.
*
* For debug use only - strings are not internationalized.
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index d60d4db..64c0f31 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1024,28 +1024,6 @@
}
/**
- * enable or disable Bluetooth HCI snoop log.
- *
- * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission
- *
- * @return true to indicate configure HCI log successfully, or false on
- * immediate error
- * @hide
- */
- public boolean configHciSnoopLog(boolean enable) {
- try {
- mServiceLock.readLock().lock();
- if (mService != null) return mService.configHciSnoopLog(enable);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- } finally {
- mServiceLock.readLock().unlock();
- }
- return false;
- }
-
- /**
* Factory reset bluetooth settings.
*
* <p>Requires the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index c427268..e8ad69d 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1703,7 +1703,7 @@
* an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
* if {@code autoConnect} is set to true.
* @param handler The handler to use for the callback. If {@code null}, callbacks will happen
- * on the service's main thread.
+ * on an un-specified background thread.
* @throws NullPointerException if callback is null
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
@@ -1712,9 +1712,6 @@
if (callback == null)
throw new NullPointerException("callback is null");
- if (handler == null)
- handler = new Handler(Looper.getMainLooper());
-
// TODO(Bluetooth) check whether platform support BLE
// Do the check here or in GattServer?
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 0f01d62..5fabbb6 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -156,7 +156,7 @@
}
mClientIf = clientIf;
if (status != GATT_SUCCESS) {
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -191,7 +191,7 @@
return;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -213,7 +213,7 @@
return;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -238,7 +238,7 @@
int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED;
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -300,7 +300,7 @@
}
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -352,7 +352,7 @@
if (status == 0) characteristic.setValue(value);
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -401,7 +401,7 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -430,7 +430,7 @@
characteristic.setValue(value);
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -477,7 +477,7 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -523,7 +523,7 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -549,7 +549,7 @@
mDeviceBusy = false;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -570,7 +570,7 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -592,7 +592,7 @@
return;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -616,7 +616,7 @@
return;
}
- mHandler.post(new Runnable() {
+ runOrQueueCallback(new Runnable() {
@Override
public void run() {
if (mCallback != null) {
@@ -703,6 +703,22 @@
}
/**
+ * Queue the runnable on a {@link Handler} provided by the user, or execute the runnable
+ * immediately if no Handler was provided.
+ */
+ private void runOrQueueCallback(final Runnable cb) {
+ if (mHandler == null) {
+ try {
+ cb.run();
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception in callback", ex);
+ }
+ } else {
+ mHandler.post(cb);
+ }
+ }
+
+ /**
* Register an application callback to start using GATT.
*
* <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index b337817..43c5ae4 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -97,7 +97,6 @@
ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);
ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
- boolean configHciSnoopLog(boolean enable);
boolean factoryReset();
boolean isMultiAdvertisementSupported();
diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl
index a775a1f..1b533cb 100644
--- a/core/java/android/bluetooth/IBluetoothA2dp.aidl
+++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl
@@ -42,4 +42,7 @@
oneway void setCodecConfigPreference(in BluetoothCodecConfig codecConfig);
oneway void enableOptionalCodecs();
oneway void disableOptionalCodecs();
+ int supportsOptionalCodecs(in BluetoothDevice device);
+ int getOptionalCodecsEnabled(in BluetoothDevice device);
+ oneway void setOptionalCodecsEnabled(in BluetoothDevice device, int value);
}
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index e2d4f5b..dc5c7b6 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -43,10 +43,10 @@
interface IBluetoothGatt {
List<BluetoothDevice> getDevicesMatchingConnectionStates(in int[] states);
- void registerScanner(in IScannerCallback callback);
+ void registerScanner(in IScannerCallback callback, in WorkSource workSource);
void unregisterScanner(in int scannerId);
void startScan(in int scannerId, in ScanSettings settings, in List<ScanFilter> filters,
- in WorkSource workSource, in List scanStorages, in String callingPackage);
+ in List scanStorages, in String callingPackage);
void startScanForIntent(in PendingIntent intent, in ScanSettings settings, in List<ScanFilter> filters,
in String callingPackage);
void stopScanForIntent(in PendingIntent intent, in String callingPackage);
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 5246513..f3f0ae5 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -360,7 +360,7 @@
// Scan stopped.
if (mScannerId == -1) return;
try {
- mBluetoothGatt.registerScanner(this);
+ mBluetoothGatt.registerScanner(this, mWorkSource);
wait(REGISTRATION_CALLBACK_TIMEOUT_MILLIS);
} catch (InterruptedException | RemoteException e) {
Log.e(TAG, "application registeration exception", e);
@@ -424,7 +424,7 @@
} else {
mScannerId = scannerId;
mBluetoothGatt.startScan(mScannerId, mSettings, mFilters,
- mWorkSource, mResultStorages,
+ mResultStorages,
ActivityThread.currentOpPackageName());
}
} catch (RemoteException e) {
diff --git a/core/java/android/content/pm/AuxiliaryResolveInfo.java b/core/java/android/content/pm/AuxiliaryResolveInfo.java
index 69bfeca..323733c 100644
--- a/core/java/android/content/pm/AuxiliaryResolveInfo.java
+++ b/core/java/android/content/pm/AuxiliaryResolveInfo.java
@@ -43,13 +43,16 @@
public final String token;
/** The version code of the package */
public final int versionCode;
+ /** An intent to start upon failure to install */
+ public final Intent failureIntent;
/** Create a response for installing an instant application. */
public AuxiliaryResolveInfo(@NonNull InstantAppResolveInfo resolveInfo,
@NonNull IntentFilter orig,
@Nullable String splitName,
@NonNull String token,
- boolean needsPhase2) {
+ boolean needsPhase2,
+ @Nullable Intent failureIntent) {
super(orig);
this.resolveInfo = resolveInfo;
this.packageName = resolveInfo.getPackageName();
@@ -57,12 +60,14 @@
this.token = token;
this.needsPhaseTwo = needsPhase2;
this.versionCode = resolveInfo.getVersionCode();
+ this.failureIntent = failureIntent;
}
/** Create a response for installing a split on demand. */
public AuxiliaryResolveInfo(@NonNull String packageName,
@Nullable String splitName,
- int versionCode) {
+ int versionCode,
+ @Nullable Intent failureIntent) {
super();
this.packageName = packageName;
this.splitName = splitName;
@@ -70,5 +75,6 @@
this.resolveInfo = null;
this.token = null;
this.needsPhaseTwo = false;
+ this.failureIntent = failureIntent;
}
}
\ No newline at end of file
diff --git a/core/java/android/content/pm/InstantAppResolveInfo.java b/core/java/android/content/pm/InstantAppResolveInfo.java
index 603192a..dcaf66e 100644
--- a/core/java/android/content/pm/InstantAppResolveInfo.java
+++ b/core/java/android/content/pm/InstantAppResolveInfo.java
@@ -47,7 +47,7 @@
private final int mVersionCode;
public InstantAppResolveInfo(@NonNull InstantAppDigest digest, @Nullable String packageName,
- @Nullable List<InstantAppIntentFilter> filters, int versionConde) {
+ @Nullable List<InstantAppIntentFilter> filters, int versionCode) {
// validate arguments
if ((packageName == null && (filters != null && filters.size() != 0))
|| (packageName != null && (filters == null || filters.size() == 0))) {
@@ -61,7 +61,7 @@
mFilters = null;
}
mPackageName = packageName;
- mVersionCode = versionConde;
+ mVersionCode = versionCode;
}
public InstantAppResolveInfo(@NonNull String hostName, @Nullable String packageName,
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index aaaff0c..4e11233 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -26,6 +26,7 @@
import android.app.ActivityManager;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.PackageManager.InstallReason;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.FileBridge;
@@ -948,7 +949,7 @@
/** {@hide} */
public int installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
/** {@hide} */
- public int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
+ public @InstallReason int installReason = PackageManager.INSTALL_REASON_UNKNOWN;
/** {@hide} */
public long sizeBytes = -1;
/** {@hide} */
@@ -1146,7 +1147,10 @@
}
}
- public void setInstallReason(int installReason) {
+ /**
+ * Set the reason for installing this package.
+ */
+ public void setInstallReason(@InstallReason int installReason) {
this.installReason = installReason;
}
@@ -1236,7 +1240,7 @@
/** {@hide} */
public int mode;
/** {@hide} */
- public int installReason;
+ public @InstallReason int installReason;
/** {@hide} */
public long sizeBytes;
/** {@hide} */
@@ -1324,9 +1328,9 @@
/**
* Return the reason for installing this package.
*
- * @see PackageManager#INSTALL_REASON_UNKNOWN
+ * @return The install reason.
*/
- public int getInstallReason() {
+ public @InstallReason int getInstallReason() {
return installReason;
}
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index ee56a18..4e53914 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -44,7 +44,6 @@
public boolean notLaunched;
public boolean hidden; // Is the app restricted by owner / admin
public boolean suspended;
- public boolean blockUninstall;
public boolean instantApp;
public int enabled;
public String lastDisableAppCaller;
@@ -75,7 +74,6 @@
notLaunched = o.notLaunched;
hidden = o.hidden;
suspended = o.suspended;
- blockUninstall = o.blockUninstall;
instantApp = o.instantApp;
enabled = o.enabled;
lastDisableAppCaller = o.lastDisableAppCaller;
@@ -193,9 +191,6 @@
if (suspended != oldState.suspended) {
return false;
}
- if (blockUninstall != oldState.blockUninstall) {
- return false;
- }
if (instantApp != oldState.instantApp) {
return false;
}
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 2b76ae2..d0c6397 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -23,7 +23,6 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
@@ -96,6 +95,9 @@
public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9;
/** @hide */
+ public static final int FLAG_RETURNED_BY_SERVICE = 1 << 10;
+
+ /** @hide */
@IntDef(flag = true,
value = {
FLAG_DYNAMIC,
@@ -108,6 +110,7 @@
FLAG_STRINGS_RESOLVED,
FLAG_IMMUTABLE,
FLAG_ADAPTIVE_BITMAP,
+ FLAG_RETURNED_BY_SERVICE
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShortcutFlags {}
@@ -1343,6 +1346,16 @@
return (mFlags & flags) == flags;
}
+ /** @hide */
+ public boolean isReturnedByServer() {
+ return hasFlags(FLAG_RETURNED_BY_SERVICE);
+ }
+
+ /** @hide */
+ public void setReturnedByServer() {
+ addFlags(FLAG_RETURNED_BY_SERVICE);
+ }
+
/** Return whether a shortcut is dynamic. */
public boolean isDynamic() {
return hasFlags(FLAG_DYNAMIC);
@@ -1450,7 +1463,7 @@
/**
* Return whether a shortcut's icon is adaptive bitmap following design guideline
- * defined in {@link AdaptiveIconDrawable}.
+ * defined in {@link android.graphics.drawable.AdaptiveIconDrawable}.
*
* @hide internal/unit tests only
*/
@@ -1776,6 +1789,9 @@
if (hasStringResourcesResolved()) {
sb.append("Sr");
}
+ if (isReturnedByServer()) {
+ sb.append("V");
+ }
sb.append("]");
sb.append(", packageName=");
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index a7c09b5..e3e0cc5 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -618,6 +618,10 @@
/**
* Return all dynamic shortcuts from the caller app.
*
+ * <p>This API is intended to be used for examining what shortcuts are currently published.
+ * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+ * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+ *
* @throws IllegalStateException when the user is locked.
*/
@NonNull
@@ -633,6 +637,10 @@
/**
* Return all static (manifest) shortcuts from the caller app.
*
+ * <p>This API is intended to be used for examining what shortcuts are currently published.
+ * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+ * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+ *
* @throws IllegalStateException when the user is locked.
*/
@NonNull
@@ -697,6 +705,10 @@
/**
* Return all pinned shortcuts from the caller app.
*
+ * <p>This API is intended to be used for examining what shortcuts are currently published.
+ * Re-publishing returned {@link ShortcutInfo}s via APIs such as
+ * {@link #setDynamicShortcuts(List)} may cause loss of information such as icons.
+ *
* @throws IllegalStateException when the user is locked.
*/
@NonNull
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index b21ccf1..042eb87 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -18,6 +18,7 @@
import com.android.internal.R;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
@@ -36,8 +37,6 @@
*/
public class FontResourcesParser {
private static final String TAG = "FontResourcesParser";
- private static final int NORMAL_WEIGHT = 400;
- private static final int ITALIC = 1;
// A class represents single entry of font-family in xml file.
public interface FamilyResourceEntry {}
@@ -78,10 +77,10 @@
public static final class FontFileResourceEntry {
private final @NonNull String mFileName;
private int mWeight;
- private boolean mItalic;
+ private int mItalic;
private int mResourceId;
- public FontFileResourceEntry(@NonNull String fileName, int weight, boolean italic) {
+ public FontFileResourceEntry(@NonNull String fileName, int weight, int italic) {
mFileName = fileName;
mWeight = weight;
mItalic = italic;
@@ -95,7 +94,7 @@
return mWeight;
}
- public boolean isItalic() {
+ public int getItalic() {
return mItalic;
}
}
@@ -200,8 +199,10 @@
throws XmlPullParserException, IOException {
AttributeSet attrs = Xml.asAttributeSet(parser);
TypedArray array = resources.obtainAttributes(attrs, R.styleable.FontFamilyFont);
- int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight, NORMAL_WEIGHT);
- boolean isItalic = ITALIC == array.getInt(R.styleable.FontFamilyFont_fontStyle, 0);
+ int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight,
+ Typeface.RESOLVE_BY_FONT_TABLE);
+ int italic = array.getInt(R.styleable.FontFamilyFont_fontStyle,
+ Typeface.RESOLVE_BY_FONT_TABLE);
String filename = array.getString(R.styleable.FontFamilyFont_font);
array.recycle();
while (parser.next() != XmlPullParser.END_TAG) {
@@ -210,7 +211,7 @@
if (filename == null) {
return null;
}
- return new FontFileResourceEntry(filename, weight, isItalic);
+ return new FontFileResourceEntry(filename, weight, italic);
}
private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 73e52c8..d163a44 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -45,7 +45,7 @@
* Set the active scorer and clear existing scores.
* @param packageName the package name of the new scorer to use.
* @return true if the operation succeeded, or false if the new package is not a valid scorer.
- * @throws SecurityException if the caller is not the system.
+ * @throws SecurityException if the caller is not the system or a network scorer.
*/
boolean setActiveScorer(in String packageName);
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index eeb426a..9f6e45c 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -16,27 +16,20 @@
package android.net;
-import static android.net.NetworkRecommendationProvider.EXTRA_RECOMMENDATION_RESULT;
-
+import android.Manifest.permission;
import android.annotation.IntDef;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.content.Context;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteCallback;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
-import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
-import java.util.concurrent.CompletableFuture;
/**
* Class that manages communication between network subsystems and a network scorer.
@@ -49,9 +42,9 @@
*
* <p>A network scorer is any application which:
* <ul>
- * <li>Declares the {@link android.Manifest.permission#SCORE_NETWORKS} permission.
+ * <li>Declares the {@link permission#SCORE_NETWORKS} permission.
* <li>Include a Service for the {@link #ACTION_RECOMMEND_NETWORKS} action
- * protected by the {@link android.Manifest.permission#BIND_NETWORK_RECOMMENDATION_SERVICE}
+ * protected by the {@link permission#BIND_NETWORK_RECOMMENDATION_SERVICE}
* permission.
* </ul>
*
@@ -319,7 +312,7 @@
*
* @return true if the operation succeeded, or false if the new package is not a valid scorer.
* @throws SecurityException if the caller is not a system process or does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission
+ * {@link permission#SCORE_NETWORKS} permission
* @hide
*/
@SystemApi
@@ -351,7 +344,7 @@
*
* @return true if the broadcast was sent, or false if there is no active scorer.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
+ * {@link permission#REQUEST_NETWORK_SCORES} permission.
* @hide
*/
public boolean requestScores(NetworkKey[] networks) throws SecurityException {
@@ -368,7 +361,7 @@
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
+ * {@link permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @deprecated equivalent to registering for cache updates with CACHE_FILTER_NONE.
* @hide
@@ -385,7 +378,7 @@
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores
* @param filterType the {@link CacheUpdateFilter} to apply
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
+ * {@link permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @hide
*/
@@ -404,7 +397,7 @@
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
+ * {@link permission#REQUEST_NETWORK_SCORES} permission.
* @throws IllegalArgumentException if a score cache is already registered for this type.
* @hide
*/
@@ -417,25 +410,6 @@
}
/**
- * Request a recommendation for which network to connect to.
- *
- * <p>It is not safe to call this method from the main thread.
- *
- * @param request a {@link RecommendationRequest} instance containing additional
- * request details
- * @return a {@link RecommendationResult} instance containing the recommended network
- * to connect to
- * @throws SecurityException if the caller does not hold the
- * {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission.
- * @hide
- * @deprecated to be removed.
- */
- public RecommendationResult requestRecommendation(RecommendationRequest request)
- throws SecurityException {
- return null;
- }
-
- /**
* Determine whether the application with the given UID is the enabled scorer.
*
* @param callingUid the UID to check
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 4bad7ab..86fcfc8 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -758,7 +758,7 @@
/**
* O.
*/
- public static final int O = 26;
+ public static final int O = CUR_DEVELOPMENT; // STOPSHIP Replace with the real version.
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 44addfc..a01b8ed 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -87,16 +87,6 @@
public abstract void setScreenBrightnessOverrideFromWindowManager(int brightness);
/**
- * Used by the window manager to override the button brightness based on the
- * current foreground activity.
- *
- * This method must only be called by the window manager.
- *
- * @param brightness The overridden brightness, or -1 to disable the override.
- */
- public abstract void setButtonBrightnessOverrideFromWindowManager(int brightness);
-
- /**
* Used by the window manager to override the user activity timeout based on the
* current foreground activity. It can only be used to make the timeout shorter
* than usual, not longer.
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 1ef3916..8302ece 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -26,17 +26,12 @@
private static final String LOG_TAG = "VintfObject";
/**
- * Slurps all device information (both manifests)
- * and report it.
+ * Slurps all device information (both manifests and both matrices)
+ * and report them.
* If any error in getting one of the manifests, it is not included in
* the list.
*/
- public static String[] report() {
- ArrayList<String> ret = new ArrayList<>();
- put(ret, getDeviceManifest(), "device manifest");
- put(ret, getFrameworkManifest(), "framework manifest");
- return ret.toArray(new String[0]);
- }
+ public static native String[] report();
/**
* Verify that the given metadata for an OTA package is compatible with
@@ -50,15 +45,4 @@
*/
public static native int verify(String[] packageInfo);
- // return null if any error, otherwise XML string.
- private static native String getDeviceManifest();
- private static native String getFrameworkManifest();
-
- private static void put(ArrayList<String> list, String content, String message) {
- if (content == null || content.length() == 0) {
- Log.e(LOG_TAG, "Cannot get;" + message + "; check native logs for details.");
- return;
- }
- list.add(content);
- }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f215ae7..0840549 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5176,13 +5176,6 @@
public static final String AUTOFILL_SERVICE = "autofill_service";
/**
- * bluetooth HCI snoop log configuration
- * @hide
- */
- public static final String BLUETOOTH_HCI_LOG =
- "bluetooth_hci_log";
-
- /**
* @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead
*/
@Deprecated
@@ -6789,7 +6782,8 @@
* Represented as milliseconds from midnight (e.g. 79200000 == 10pm).
* @hide
*/
- public static final String NIGHT_DISPLAY_CUSTOM_START_TIME = "night_display_custom_start_time";
+ public static final String NIGHT_DISPLAY_CUSTOM_START_TIME =
+ "night_display_custom_start_time";
/**
* Custom time when Night display is scheduled to deactivate.
@@ -6799,6 +6793,14 @@
public static final String NIGHT_DISPLAY_CUSTOM_END_TIME = "night_display_custom_end_time";
/**
+ * Time in milliseconds (since epoch) when Night display was last activated. Use to decide
+ * whether to apply the current activated state after a reboot or user change.
+ * @hide
+ */
+ public static final String NIGHT_DISPLAY_LAST_ACTIVATED_TIME =
+ "night_display_last_activated_time";
+
+ /**
* Names of the service components that the current user has explicitly allowed to
* be a VR mode listener, separated by ':'.
*
@@ -7024,6 +7026,7 @@
NIGHT_DISPLAY_CUSTOM_END_TIME,
NIGHT_DISPLAY_COLOR_TEMPERATURE,
NIGHT_DISPLAY_AUTO_MODE,
+ NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
NIGHT_DISPLAY_ACTIVATED,
SYNC_PARENT_SOUNDS,
CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
@@ -8971,6 +8974,12 @@
public static final String
BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX = "bluetooth_a2dp_src_priority_";
/** {@hide} */
+ public static final String BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX =
+ "bluetooth_a2dp_supports_optional_codecs_";
+ /** {@hide} */
+ public static final String BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX =
+ "bluetooth_a2dp_optional_codecs_enabled_";
+ /** {@hide} */
public static final String
BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX = "bluetooth_input_device_priority_";
/** {@hide} */
@@ -9237,6 +9246,25 @@
}
/**
+ * Get the key that retrieves a bluetooth a2dp device's ability to support optional codecs.
+ * @hide
+ */
+ public static final String getBluetoothA2dpSupportsOptionalCodecsKey(String address) {
+ return BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX +
+ address.toUpperCase(Locale.ROOT);
+ }
+
+ /**
+ * Get the key that retrieves whether a bluetooth a2dp device should have optional codecs
+ * enabled.
+ * @hide
+ */
+ public static final String getBluetoothA2dpOptionalCodecsEnabledKey(String address) {
+ return BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX +
+ address.toUpperCase(Locale.ROOT);
+ }
+
+ /**
* Get the key that retrieves a bluetooth Input Device's priority.
* @hide
*/
@@ -10379,6 +10407,15 @@
public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
/**
+ * Displays toasts when an app posts a notification that does not specify a valid channel.
+ *
+ * The value 1 - enable, 0 - disable
+ * @hide
+ */
+ public static final String SHOW_NOTIFICATION_CHANNEL_WARNINGS =
+ "show_notification_channel_warnings";
+
+ /**
* Whether cell is enabled/disabled
* @hide
*/
diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl
index 8b2d0c6..fc8afe9 100644
--- a/core/java/android/service/vr/IVrManager.aidl
+++ b/core/java/android/service/vr/IVrManager.aidl
@@ -16,7 +16,7 @@
package android.service.vr;
-import android.app.CompatibilityDisplayProperties;
+import android.app.Vr2dDisplayProperties;
import android.service.vr.IVrStateCallbacks;
import android.service.vr.IPersistentVrStateCallbacks;
@@ -68,16 +68,16 @@
void setPersistentVrModeEnabled(in boolean enabled);
/**
- * Sets the resolution and DPI of the compatibility virtual display used to display
+ * Sets the resolution and DPI of the vr2d virtual display used to display
* 2D applications in VR mode.
*
* <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
*
- * @param compatDisplayProperties Compatibitlity display properties to be set for
+ * @param vr2dDisplayProperties Vr2d display properties to be set for
* the VR virtual display
*/
- void setCompatibilityDisplayProperties(
- in CompatibilityDisplayProperties compatDisplayProperties);
+ void setVr2dDisplayProperties(
+ in Vr2dDisplayProperties vr2dDisplayProperties);
/**
* Return current virtual display id.
@@ -85,7 +85,7 @@
* @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
* currently, else return the display id of the virtual display
*/
- int getCompatibilityDisplayId();
+ int getVr2dDisplayId();
/**
* Initiate connection for system controller data.
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 081deeb..91f43d6 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -1921,6 +1921,22 @@
return false;
}
+ /**
+ * If the {@code charSequence} is instance of {@link Spanned}, creates a new copy and
+ * {@link NoCopySpan}'s are removed from the copy. Otherwise the given {@code charSequence} is
+ * returned as it is.
+ *
+ * @hide
+ */
+ @Nullable
+ public static CharSequence trimNoCopySpans(@Nullable CharSequence charSequence) {
+ if (charSequence != null && charSequence instanceof Spanned) {
+ // SpannableStringBuilder copy constructor trims NoCopySpans.
+ return new SpannableStringBuilder(charSequence);
+ }
+ return charSequence;
+ }
+
private static Object sLock = new Object();
private static char[] sTemp = null;
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index f71589c..6bdc9ff 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -374,13 +374,6 @@
public abstract Rect getTempRect();
/**
- * @deprecated - use {@link #setWebDomain(String)} instead.
- * @hide
- */
- @Deprecated
- public abstract void setUrl(String url);
-
- /**
* Sets the Web domain represented by this node.
*
* <p>Typically used when the view is a container for an HTML document.
diff --git a/core/java/android/view/autofill/AutofillValue.java b/core/java/android/view/autofill/AutofillValue.java
index b57dab5..3beae11 100644
--- a/core/java/android/view/autofill/AutofillValue.java
+++ b/core/java/android/view/autofill/AutofillValue.java
@@ -26,6 +26,7 @@
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import android.view.View;
import com.android.internal.util.Preconditions;
@@ -257,7 +258,8 @@
* <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
*/
public static AutofillValue forText(@Nullable CharSequence value) {
- return value == null ? null : new AutofillValue(AUTOFILL_TYPE_TEXT, value);
+ return value == null ? null : new AutofillValue(AUTOFILL_TYPE_TEXT,
+ TextUtils.trimNoCopySpans(value));
}
/**
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index ebf1c01..7362c70 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -102,7 +102,9 @@
string, selectionStartIndex, selectionEndIndex);
final int start = startEnd[0];
final int end = startEnd[1];
- if (start >= 0 && end <= string.length() && start <= end) {
+ if (start <= end
+ && start >= 0 && end <= string.length()
+ && start <= selectionStartIndex && end >= selectionEndIndex) {
final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
final SmartSelection.ClassificationResult[] results =
smartSelection.classifyText(
@@ -144,9 +146,6 @@
final TextClassification classificationResult =
createClassificationResult(
results, string.subSequence(startIndex, endIndex));
- // TODO: Added this log for debug only. Remove before release.
- Log.d(LOG_TAG, String.format(
- "Classification type: %s", classificationResult));
return classificationResult;
}
}
@@ -377,11 +376,6 @@
&& Linkify.sUrlMatchFilter.acceptMatch(text, start, end)) {
flag |= SmartSelection.HINT_FLAG_URL;
}
- // TODO: Added this log for debug only. Remove before release.
- Log.d(LOG_TAG, String.format("Email hint: %b",
- (flag & SmartSelection.HINT_FLAG_EMAIL) != 0));
- Log.d(LOG_TAG, String.format("Url hint: %b",
- (flag & SmartSelection.HINT_FLAG_URL) != 0));
return flag;
}
@@ -607,6 +601,7 @@
@Nullable
public static Intent create(Context context, String type, String text) {
type = type.trim().toLowerCase(Locale.ENGLISH);
+ text = text.trim();
switch (type) {
case TextClassifier.TYPE_EMAIL:
return new Intent(Intent.ACTION_SENDTO)
@@ -618,6 +613,9 @@
return new Intent(Intent.ACTION_VIEW)
.setData(Uri.parse(String.format("geo:0,0?q=%s", text)));
case TextClassifier.TYPE_URL:
+ if (!text.startsWith("https://") && !text.startsWith("http://")) {
+ text = "http://" + text;
+ }
return new Intent(Intent.ACTION_VIEW, Uri.parse(text))
.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
default:
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index ad3a99d..b0d6395 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1404,6 +1404,11 @@
// or double-clicks that could "dismiss" the floating toolbar.
int delay = ViewConfiguration.getDoubleTapTimeout();
mTextView.postDelayed(mShowFloatingToolbar, delay);
+
+ // This classifies the text and most likely returns before the toolbar is actually
+ // shown. If not, it will update the toolbar with the result when classification
+ // returns. We would rather not wait for a long running classification process.
+ invalidateActionModeAsync();
}
}
@@ -1853,7 +1858,7 @@
mInsertionPointCursorController.invalidateHandle();
}
if (mTextActionMode != null) {
- invalidateActionModeAsync();
+ invalidateActionMode();
}
}
@@ -1945,12 +1950,12 @@
if (mRestartActionModeOnNextRefresh) {
// To avoid distraction, newly start action mode only when selection action
// mode is being restarted.
- startSelectionActionMode();
+ startSelectionActionModeAsync(false);
}
} else if (selectionController == null || !selectionController.isActive()) {
// Insertion action mode is active. Avoid dismissing the selection.
stopTextActionModeWithPreservingSelection();
- startSelectionActionMode();
+ startSelectionActionModeAsync(false);
} else {
mTextActionMode.invalidateContentRect();
}
@@ -2004,15 +2009,8 @@
/**
* Asynchronously starts a selection action mode using the TextClassifier.
*/
- void startSelectionActionModeAsync() {
- getSelectionActionModeHelper().startActionModeAsync();
- }
-
- /**
- * Synchronously starts a selection action mode without the TextClassifier.
- */
- void startSelectionActionMode() {
- getSelectionActionModeHelper().startActionMode();
+ void startSelectionActionModeAsync(boolean adjustSelection) {
+ getSelectionActionModeHelper().startActionModeAsync(adjustSelection);
}
/**
@@ -2022,6 +2020,15 @@
getSelectionActionModeHelper().invalidateActionModeAsync();
}
+ /**
+ * Synchronously invalidates an action mode without the TextClassifier.
+ */
+ private void invalidateActionMode() {
+ if (mTextActionMode != null) {
+ mTextActionMode.invalidate();
+ }
+ }
+
private SelectionActionModeHelper getSelectionActionModeHelper() {
if (mSelectionActionModeHelper == null) {
mSelectionActionModeHelper = new SelectionActionModeHelper(this);
@@ -2075,7 +2082,7 @@
}
if (mTextActionMode != null) {
// Text action mode is already started
- invalidateActionModeAsync();
+ invalidateActionMode();
return false;
}
@@ -4703,7 +4710,7 @@
}
positionAtCursorOffset(offset, false);
if (mTextActionMode != null) {
- invalidateActionModeAsync();
+ invalidateActionMode();
}
}
@@ -4787,7 +4794,7 @@
}
updateDrawable();
if (mTextActionMode != null) {
- invalidateActionModeAsync();
+ invalidateActionMode();
}
}
@@ -5414,13 +5421,8 @@
resetDragAcceleratorState();
if (mTextView.hasSelection()) {
- // Do not invoke the text assistant if this was a drag selection.
- if (mHaventMovedEnoughToStartDrag) {
- startSelectionActionModeAsync();
- } else {
- startSelectionActionMode();
- }
-
+ // Drag selection should not be adjusted by the text classifier.
+ startSelectionActionModeAsync(mHaventMovedEnoughToStartDrag);
}
break;
}
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 4507917..16a1087 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -33,6 +33,7 @@
import com.android.internal.util.Preconditions;
+import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -64,7 +65,7 @@
textView.getTextClassifier(), textView.getText(), 0, 1, textView.getTextLocales());
}
- public void startActionModeAsync() {
+ public void startActionModeAsync(boolean adjustSelection) {
cancelAsyncTask();
if (isNoOpTextClassifier() || !hasSelection()) {
// No need to make an async call for a no-op TextClassifier.
@@ -73,16 +74,16 @@
} else {
resetTextClassificationHelper();
mTextClassificationAsyncTask = new TextClassificationAsyncTask(
- mEditor.getTextView(), TIMEOUT_DURATION,
- mTextClassificationHelper::suggestSelection, this::startActionMode)
+ mEditor.getTextView(),
+ TIMEOUT_DURATION,
+ adjustSelection
+ ? mTextClassificationHelper::suggestSelection
+ : mTextClassificationHelper::classifyText,
+ this::startActionMode)
.execute();
}
}
- public void startActionMode() {
- startActionMode(null);
- }
-
public void invalidateActionModeAsync() {
cancelAsyncTask();
if (isNoOpTextClassifier() || !hasSelection()) {
@@ -310,6 +311,13 @@
/** End index relative to mTrimmedText */
private int mRelativeEnd;
+ /** Information about the last classified text to avoid re-running a query. */
+ private CharSequence mLastClassificationText;
+ private int mLastClassificationSelectionStart;
+ private int mLastClassificationSelectionEnd;
+ private LocaleList mLastClassificationLocales;
+ private SelectionResult mLastClassificationResult;
+
TextClassificationHelper(TextClassifier textClassifier,
CharSequence text, int selectionStart, int selectionEnd, LocaleList locales) {
reset(textClassifier, text, selectionStart, selectionEnd, locales);
@@ -328,12 +336,25 @@
@WorkerThread
public SelectionResult classifyText() {
- trimText();
- return new SelectionResult(
- mSelectionStart,
- mSelectionEnd,
- mTextClassifier.classifyText(
- mTrimmedText, mRelativeStart, mRelativeEnd, mLocales));
+ if (!Objects.equals(mText, mLastClassificationText)
+ || mSelectionStart != mLastClassificationSelectionStart
+ || mSelectionEnd != mLastClassificationSelectionEnd
+ || !Objects.equals(mLocales, mLastClassificationLocales)) {
+
+ mLastClassificationText = mText;
+ mLastClassificationSelectionStart = mSelectionStart;
+ mLastClassificationSelectionEnd = mSelectionEnd;
+ mLastClassificationLocales = mLocales;
+
+ trimText();
+ mLastClassificationResult = new SelectionResult(
+ mSelectionStart,
+ mSelectionEnd,
+ mTextClassifier.classifyText(
+ mTrimmedText, mRelativeStart, mRelativeEnd, mLocales));
+
+ }
+ return mLastClassificationResult;
}
@WorkerThread
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 242dcf5..eaf1115 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10579,7 +10579,7 @@
Selection.setSelection((Spannable) text, start, end);
// Make sure selection mode is engaged.
if (mEditor != null) {
- mEditor.startSelectionActionMode();
+ mEditor.startSelectionActionModeAsync(false);
}
return true;
}
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index 7b2efea..58a2b0f 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -708,18 +708,20 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (isInPlaybackState() && mMediaController != null) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN
+ && isInPlaybackState() && mMediaController != null) {
toggleMediaControlsVisiblity();
}
- return false;
+ return super.onTouchEvent(ev);
}
@Override
public boolean onTrackballEvent(MotionEvent ev) {
- if (isInPlaybackState() && mMediaController != null) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN
+ && isInPlaybackState() && mMediaController != null) {
toggleMediaControlsVisiblity();
}
- return false;
+ return super.onTrackballEvent(ev);
}
@Override
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index e8bebb7..ee5f6fd 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -97,7 +97,8 @@
final List<ResolveInfo> infos = mpm.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY
| (shouldGetResolvedFilter ? PackageManager.GET_RESOLVED_FILTER : 0)
- | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0));
+ | (shouldGetActivityMetadata ? PackageManager.GET_META_DATA : 0)
+ | PackageManager.MATCH_INSTANT);
if (infos != null) {
if (resolvedComponents == null) {
resolvedComponents = new ArrayList<>();
diff --git a/core/java/com/android/internal/inputmethod/LocaleUtils.java b/core/java/com/android/internal/inputmethod/LocaleUtils.java
index b18f83c..eeb3854 100644
--- a/core/java/com/android/internal/inputmethod/LocaleUtils.java
+++ b/core/java/com/android/internal/inputmethod/LocaleUtils.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.icu.util.ULocale;
import android.os.LocaleList;
+import android.text.TextUtils;
import java.util.ArrayList;
import java.util.Arrays;
@@ -41,7 +42,7 @@
/**
* Calculates a matching score for the single desired locale.
*
- * @see LocaleUtils#calculateMatchingScore(ULocale, LocaleList, byte[])
+ * @see LocaleUtils#filterByLanguage(List, LocaleExtractor, LocaleList, ArrayList)
*
* @param supported The locale supported by IME subtype.
* @param desired The locale preferred by user.
@@ -72,48 +73,6 @@
return 3;
}
- /**
- * Calculates a matching score for the desired locale list.
- *
- * <p>The supported locale gets a matching score of 3 if all language, script and country of the
- * supported locale matches with the desired locale. The supported locale gets a matching
- * score of 2 if the language and script of the supported locale matches with the desired
- * locale. The supported locale gets a matching score of 1 if only language of the supported
- * locale matches with the desired locale. The supported locale gets a matching score of 0 if
- * the language of the supported locale doesn't match with the desired locale.</p>
- *
- * @param supported The locale supported by IME subtyle.
- * @param desired The locale list preferred by user. Typically system locale list.
- * @param out The output buffer to be stored the individual score for the desired language list.
- * The length of {@code out} must be same as the length of {@code desired} language list.
- * @return {@code false} if supported locale doesn't match with any desired locale list.
- * Otherwise {@code true}.
- */
- private static boolean calculateMatchingScore(@NonNull final ULocale supported,
- @NonNull final LocaleList desired, @NonNull byte[] out) {
- if (desired.isEmpty()) {
- return false;
- }
-
- boolean allZeros = true;
- final int N = desired.size();
- for (int i = 0; i < N; ++i) {
- final Locale locale = desired.get(i);
-
- if (!locale.getLanguage().equals(supported.getLanguage())) {
- // TODO: cache the result of addLikelySubtags if it is slow.
- out[i] = 0;
- } else {
- out[i] = calculateMatchingSubScore(
- supported, ULocale.addLikelySubtags(ULocale.forLocale(locale)));
- if (allZeros && out[i] != 0) {
- allZeros = false;
- }
- }
- }
- return !allZeros;
- }
-
private static final class ScoreEntry implements Comparable<ScoreEntry> {
public int mIndex = -1;
@NonNull public final byte[] mScore; // matching score of the i-th system languages.
@@ -175,17 +134,17 @@
/**
* Filters the given items based on language preferences.
*
- * <p>For each language found in {@code preferredLanguages}, this method tries to copy at most
+ * <p>For each language found in {@code preferredLocales}, this method tries to copy at most
* one best-match item from {@code source} to {@code dest}. For example, if
- * {@code "en-GB", "ja", "en-AU", "fr-CA", "en-IN"} is specified to {@code preferredLanguages},
+ * {@code "en-GB", "ja", "en-AU", "fr-CA", "en-IN"} is specified to {@code preferredLocales},
* this method tries to copy at most one English locale, at most one Japanese, and at most one
* French locale from {@code source} to {@code dest}. Here the best matching English locale
* will be searched from {@code source} based on matching score. For the score design, see
- * {@link LocaleUtils#calculateMatchingScore(ULocale, LocaleList, byte[])}</p>
+ * {@link LocaleUtils#calculateMatchingSubScore(ULocale, ULocale)}</p>
*
* @param sources Source items to be filtered.
* @param extractor Type converter from the source items to {@link Locale} object.
- * @param preferredLanguages Ordered list of locales with which the input items will be
+ * @param preferredLocales Ordered list of locales with which the input items will be
* filtered.
* @param dest Destination into which the filtered items will be added.
* @param <T> Type of the data items.
@@ -194,17 +153,43 @@
public static <T> void filterByLanguage(
@NonNull List<T> sources,
@NonNull LocaleExtractor<T> extractor,
- @NonNull LocaleList preferredLanguages,
+ @NonNull LocaleList preferredLocales,
@NonNull ArrayList<T> dest) {
+ if (preferredLocales.isEmpty()) {
+ return;
+ }
+
+ final int numPreferredLocales = preferredLocales.size();
final HashMap<String, ScoreEntry> scoreboard = new HashMap<>();
- final byte[] score = new byte[preferredLanguages.size()];
+ final byte[] score = new byte[numPreferredLocales];
+ final ULocale[] preferredULocaleCache = new ULocale[numPreferredLocales];
final int sourceSize = sources.size();
for (int i = 0; i < sourceSize; ++i) {
final Locale locale = extractor.get(sources.get(i));
- if (locale == null ||
- !calculateMatchingScore(ULocale.addLikelySubtags(ULocale.forLocale(locale)),
- preferredLanguages, score)) {
+ if (locale == null) {
+ continue;
+ }
+
+ boolean canSkip = true;
+ for (int j = 0; j < numPreferredLocales; ++j) {
+ final Locale preferredLocale = preferredLocales.get(j);
+ if (!TextUtils.equals(locale.getLanguage(), preferredLocale.getLanguage())) {
+ score[j] = 0;
+ continue;
+ }
+ if (preferredULocaleCache[j] == null) {
+ preferredULocaleCache[j] = ULocale.addLikelySubtags(
+ ULocale.forLocale(preferredLocale));
+ }
+ score[j] = calculateMatchingSubScore(
+ preferredULocaleCache[j],
+ ULocale.addLikelySubtags(ULocale.forLocale(locale)));
+ if (canSkip && score[j] != 0) {
+ canSkip = false;
+ }
+ }
+ if (canSkip) {
continue;
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 372607d..369bb7f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -526,7 +526,7 @@
/*
* Reads a "property" into "buffer". If the property is non-empty, it
* is treated as a dex2oat compiler option that should be
- * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=verify-none".
+ * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=assume-verified".
*
* The "compilerArg" is a prefix for the option such as "--compiler-filter=".
*
@@ -774,7 +774,7 @@
"-Xmx", "-Ximage-compiler-option");
if (skip_compilation) {
addOption("-Ximage-compiler-option");
- addOption("--compiler-filter=verify-none");
+ addOption("--compiler-filter=assume-verified");
} else {
parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
"--compiler-filter=", "-Ximage-compiler-option");
@@ -805,7 +805,7 @@
"-Xmx", "-Xcompiler-option");
if (skip_compilation) {
addOption("-Xcompiler-option");
- addOption("--compiler-filter=verify-none");
+ addOption("--compiler-filter=assume-verified");
// We skip compilation when a minimal runtime is brought up for decryption. In that case
// /data is temporarily backed by a tmpfs, which is usually small.
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 9491a1e..033f2df 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 The Android Open Source Project
+ * 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.
@@ -16,6 +16,10 @@
#define LOG_TAG "VintfObject"
//#define LOG_NDEBUG 0
+#include <android-base/logging.h>
+
+#include <vector>
+#include <string>
#include <JNIHelp.h>
#include <vintf/VintfObject.h>
@@ -23,31 +27,48 @@
#include "core_jni_helpers.h"
+static jclass gString;
+
namespace android {
-using vintf::HalManifest;
-using vintf::RuntimeInfo;
using vintf::VintfObject;
using vintf::gHalManifestConverter;
+using vintf::gCompatibilityMatrixConverter;
+using vintf::XmlConverter;
-static jstring android_os_VintfObject_getDeviceManifest(JNIEnv* env, jclass clazz)
-{
- const HalManifest *manifest = VintfObject::GetDeviceHalManifest();
- if (manifest == nullptr) {
- return nullptr;
+static inline jobjectArray toJavaStringArray(JNIEnv* env, const std::vector<std::string>& v) {
+ jobjectArray ret = env->NewObjectArray(v.size(), gString, NULL /* init element */);
+ for (size_t i = 0; i < v.size(); ++i) {
+ env->SetObjectArrayElement(ret, i, env->NewStringUTF(v[i].c_str()));
}
- std::string xml = gHalManifestConverter(*manifest);
- return env->NewStringUTF(xml.c_str());
+ return ret;
}
-static jstring android_os_VintfObject_getFrameworkManifest(JNIEnv* env, jclass clazz)
-{
- const HalManifest *manifest = VintfObject::GetFrameworkHalManifest();
- if (manifest == nullptr) {
- return nullptr;
+template<typename T>
+static void tryAddSchema(const T* object, const XmlConverter<T>& converter,
+ const std::string& description,
+ std::vector<std::string>* cStrings) {
+ if (object == nullptr) {
+ LOG(WARNING) << __FUNCTION__ << "Cannot get " << description;
+ } else {
+ cStrings->push_back(converter(*object));
}
- std::string xml = gHalManifestConverter(*manifest);
- return env->NewStringUTF(xml.c_str());
+}
+
+static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass clazz)
+{
+ std::vector<std::string> cStrings;
+
+ tryAddSchema(VintfObject::GetDeviceHalManifest(), gHalManifestConverter,
+ "device manifest", &cStrings);
+ tryAddSchema(VintfObject::GetFrameworkHalManifest(), gHalManifestConverter,
+ "framework manifest", &cStrings);
+ tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), gCompatibilityMatrixConverter,
+ "device compatibility matrix", &cStrings);
+ tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), gCompatibilityMatrixConverter,
+ "framework compatibility matrix", &cStrings);
+
+ return toJavaStringArray(env, cStrings);
}
static jint android_os_VintfObject_verify(JNIEnv *env, jclass clazz, jobjectArray packageInfo) {
@@ -66,15 +87,18 @@
// ----------------------------------------------------------------------------
static const JNINativeMethod gVintfObjectMethods[] = {
- {"getDeviceManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getDeviceManifest},
- {"getFrameworkManifest", "()Ljava/lang/String;", (void*)android_os_VintfObject_getFrameworkManifest},
- {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
+ {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
+ {"verify", "([Ljava/lang/String;)I", (void*)android_os_VintfObject_verify},
};
+
const char* const kVintfObjectPathName = "android/os/VintfObject";
int register_android_os_VintfObject(JNIEnv* env)
{
+
+ gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
+
return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
NELEM(gVintfObjectMethods));
}
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index ce951de..ea40fd5 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -329,6 +329,8 @@
SettingProto max_notification_enqueue_rate = 284;
SettingProto cell_on = 285;
SettingProto network_recommendations_package = 286;
+ SettingProto bluetooth_a2dp_supports_optional_codecs_prefix = 287;
+ SettingProto bluetooth_a2dp_optional_codecs_enabled_prefix = 288;
}
message SecureSettingsProto {
diff --git a/core/res/res/drawable/sym_def_app_icon.xml b/core/res/res/drawable/sym_def_app_icon.xml
index 0fdb0dd..9c02402 100644
--- a/core/res/res/drawable/sym_def_app_icon.xml
+++ b/core/res/res/drawable/sym_def_app_icon.xml
@@ -2,10 +2,7 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@android:color/white" />
<foreground>
- <inset android:insetLeft="27.7%"
- android:insetTop="27.7%"
- android:insetRight="27.7%"
- android:insetBottom="27.7%">
+ <inset android:inset="27.7%">
<bitmap android:src="@mipmap/sym_def_app_icon"/>
</inset>
</foreground>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 4524b6e..1f649b9 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Opletberigte"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kleinhandeldemonstrasie"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programme wat op die agtergrond loop"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> loop tans op die agtergrond"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> programme loop tans op die agtergrond"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik vir besonderhede oor battery- en datagebruik"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Skakel oor na persoonlik"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index a3ebecb..7c4fee9 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ማንቂያዎች"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"የችርቻሮ ማሳያ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"የዩኤስቢ ግንኙነት"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> በጀርባ ውስጥ እያሄደ ነው"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> መተግበሪያዎች በጀርባ ውስጥ እያሄዱ ነው"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>፣ <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android ስርዓት"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ወደ የግል ቀይር"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index d1b9dcb..2771d40 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -76,7 +76,7 @@
<string name="ClirMmi" msgid="7784673673446833091">"معرف المتصل الصادر"</string>
<string name="ColpMmi" msgid="3065121483740183974">"معرّف الخط المتصل"</string>
<string name="ColrMmi" msgid="4996540314421889589">"تقييد معرّف الخط المتصل"</string>
- <string name="CfMmi" msgid="5123218989141573515">"اعادة توجيه المكالمة"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"إعادة توجيه المكالمة"</string>
<string name="CwMmi" msgid="9129678056795016867">"انتظار المكالمة"</string>
<string name="BaMmi" msgid="455193067926770581">"حظر الاتصال"</string>
<string name="PwdMmi" msgid="7043715687905254199">"تغيير كلمة المرور"</string>
@@ -92,7 +92,7 @@
<string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"الإعداد الافتراضي لمعرف المتصل هو غير مقيّد. الاتصال التالي: مقيّد"</string>
<string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"الإعداد الافتراضي لمعرف المتصل هو غير مقيّد. الاتصال التالي: غير مقيّد"</string>
<string name="serviceNotProvisioned" msgid="8614830180508686666">"الخدمة غير متوفرة."</string>
- <string name="CLIRPermanent" msgid="3377371145926835671">"لا يمكنك تغيير إعداد معرف المتصل."</string>
+ <string name="CLIRPermanent" msgid="3377371145926835671">"لا يمكنك تغيير إعداد معرّف المتصل."</string>
<string name="RestrictedOnDataTitle" msgid="1322504692764166532">"ليست هناك خدمة بيانات"</string>
<string name="RestrictedOnEmergencyTitle" msgid="1236071219598685236">"لا تتوفر خدمة طوارئ"</string>
<string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"لا تتوفر خدمة صوتية"</string>
@@ -104,7 +104,7 @@
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"يتعذر الوصول إلى الشبكة"</string>
<string name="NetworkPreferenceSwitchSummary" msgid="4164230263214915351">"لتحسين الاستقبال، يمكنك تجربة تغيير النوع المحدّد في النظام > الشبكة والإنترنت > شبكات الجوّال > نوع الشبكة المفضّل."</string>
<string name="notification_channel_network_alert" msgid="4427736684338074967">"التنبيهات"</string>
- <string name="notification_channel_call_forward" msgid="2419697808481833249">"اعادة توجيه المكالمة"</string>
+ <string name="notification_channel_call_forward" msgid="2419697808481833249">"إعادة توجيه المكالمة"</string>
<string name="notification_channel_emergency_callback" msgid="6686166232265733921">"وضع معاودة الاتصال بالطوارئ"</string>
<string name="notification_channel_mobile_data_alert" msgid="6130875231721406231">"تنبيهات بيانات الجوّال"</string>
<string name="notification_channel_sms" msgid="3441746047346135073">"الرسائل القصيرة SMS"</string>
@@ -277,16 +277,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"التنبيهات"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"عرض توضيحي لبائع التجزئة"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"اتصال USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"التطبيقات التي تعمل في الخلفية"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"جارٍ تشغيل <xliff:g id="APP_NAME">%1$s</xliff:g> في الخلفية"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"جارٍ تشغيل <xliff:g id="NUMBER">%1$d</xliff:g> تطبيق في الخلفية"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"نظام Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"التبديل إلى الشخصي"</string>
@@ -1380,7 +1375,7 @@
<string name="tethered_notification_message" msgid="2113628520792055377">"انقر للإعداد."</string>
<string name="back_button_label" msgid="2300470004503343439">"رجوع"</string>
<string name="next_button_label" msgid="1080555104677992408">"التالي"</string>
- <string name="skip_button_label" msgid="1275362299471631819">"تخطٍ"</string>
+ <string name="skip_button_label" msgid="1275362299471631819">"تخطي"</string>
<string name="no_matches" msgid="8129421908915840737">"ليس هناك أية مطابقات"</string>
<string name="find_on_page" msgid="1946799233822820384">"بحث في الصفحة"</string>
<plurals name="matches_found" formatted="false" msgid="1210884353962081884">
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 552c4e3..bf87223 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Siqnallar"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Pərakəndə demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB əlaqə"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Arxa fonda işləyən tətbiqlər"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> arxa fonda işləyir"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> tətbiq arxa fonda işləyir"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistemi"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Şəxsi profilə keçirin"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9fc3a28c..cd16bdb 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Obaveštenja"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Režim demonstracije za maloprodajne objekte"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije pokrenute u pozadini"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> je pokrenuta u pozadini"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije (<xliff:g id="NUMBER">%1$d</xliff:g>) su pokrenute u pozadini"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste pregledali detalje o bateriji i potrošnji podataka"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Pređi na Lični profil"</string>
@@ -300,13 +295,13 @@
<string name="permgroupdesc_phone" msgid="6234224354060641055">"upućuje telefonske pozive i upravlja njima"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Senzori za telo"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"pristupa podacima senzora o vitalnim funkcijama"</string>
- <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Preuzima sadržaj prozora"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"da preuzima sadržaj prozora"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Proverava sadržaj prozora sa kojim ostvarujete interakciju."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Uključi Istraživanja dodirom"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"da uključi Istraživanja dodirom"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Stavke koje dodirnete će biti izgovorene naglas, a možete da se krećete po ekranu pokretima."</string>
- <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Prati tekst koji unosite"</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"da prati tekst koji unosite"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Obuhvata lične podatke kao što su brojevi kreditnih kartica i lozinke."</string>
- <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Upravljaj uvećanjem prikaza"</string>
+ <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"da upravlja uvećanjem prikaza"</string>
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Upravlja nivoom zumiranja prikaza i određivanjem položaja."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Obavljanje pokreta"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Može da dodiruje, lista, skuplja prikaz i obavlja druge pokrete."</string>
@@ -1053,7 +1048,7 @@
<string name="noApplications" msgid="2991814273936504689">"Nijedna aplikacija ne može da obavlja ovu radnju."</string>
<string name="aerr_application" msgid="250320989337856518">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> je zaustavljena"</string>
<string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
- <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja"</string>
+ <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se stalno zaustavlja(ju)"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno zaustavlja"</string>
<string name="aerr_restart" msgid="7581308074153624475">"Ponovo otvori aplikaciju"</string>
<string name="aerr_report" msgid="5371800241488400617">"Pošaljite povratne informacije"</string>
@@ -1312,7 +1307,7 @@
<string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite da biste podesili"</string>
<string name="upload_file" msgid="2897957172366730416">"Odaberi datoteku"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Nije izabrana nijedna datoteka"</string>
- <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+ <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
<string name="submit" msgid="1602335572089911941">"Pošalji"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Režim rada u automobilu je omogućen"</string>
<string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite da biste izašli iz režima rada u automobilu."</string>
@@ -1346,7 +1341,7 @@
<string name="sync_really_delete" msgid="2572600103122596243">"Izbriši stavke"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Opozovi brisanja"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"Ne radi ništa za sada"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"Izbor naloga"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Izaberite nalog"</string>
<string name="add_account_label" msgid="2935267344849993553">"Dodaj nalog"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Dodaj nalog"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"Povećavanje"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index fdd15d3..486fa1d 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Абвесткi"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Дэманстрацыйны рэжым для пунктаў продажу"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Падключэнне USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> працуе ў фонавым рэжыме"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Праграмы (<xliff:g id="NUMBER">%1$d</xliff:g>) працуюць у фонавым рэжыме"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Дакраніцеся, каб атрымаць падрабязныя звесткі пра выкарыстанне трафіка і акумулятара"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string>
<string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Пераключыцца на асабісты"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index b03e09e..91ba6b9 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Сигнали"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрационен режим за магазини"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB връзка"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работещи на заден план"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> работи на заден план"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> приложения работят на заден план"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Докоснете за подробности относно използването на батерията и преноса на данни"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Превключване към личния потребителски профил"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b574890..69511b7 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"সতর্কতাগুলি"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"খুচরা বিক্রয়ের ডেমো"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB সংযোগ"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"পটভূমিতে অ্যাপ চালু আছে"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"পটভূমিতে <xliff:g id="APP_NAME">%1$s</xliff:g> অ্যাপ চালু আছে"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"পটভূমিতে <xliff:g id="NUMBER">%1$d</xliff:g>টি অ্যাপ চালু আছে"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android সিস্টেম"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ব্যক্তিগততে পাল্টান"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 37fa55f..4d07253 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Promotivna demonstracija u maloprodaji"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije koje rade u pozadini"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> radi u pozadini"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Broj aplikacija koje rade u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite za detalje o bateriji i prijenosu podataka"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Prebacite se na lični"</string>
@@ -1317,7 +1312,7 @@
<string name="vpn_lockdown_config" msgid="5099330695245008680">"Dodirnite za postavke"</string>
<string name="upload_file" msgid="2897957172366730416">"Odabir fajla"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Nije izabran nijedan fajl"</string>
- <string name="reset" msgid="2448168080964209908">"Vrati na zadano"</string>
+ <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
<string name="submit" msgid="1602335572089911941">"Potvrdi"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Način rada u autu omogućen"</string>
<string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Dodirnite za izlaz iz načina rada u automobilu"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 0b77c82..b18b588 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostració comercial"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Connexió USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacions que s\'estan executant en segon pla"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'està executant en segon pla"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicacions s\'estan executant en segon pla"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca per obtenir informació sobre l\'ús de dades i la bateria"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode segur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Canvia al perfil personal"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 31f0826..b45374e 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornění"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodejní ukázka"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Připojení USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikace běžící na pozadí"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> běží na pozadí"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikace (<xliff:g id="NUMBER">%1$d</xliff:g>) běží na pozadí"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Přepnout na osobní profil"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index a258f08..61590e3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Underretninger"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo til udstilling i butik"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-forbindelse"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps, der kører i baggrunden"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> kører i baggrunden"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps kører i baggrunden"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryk for at se oplysninger om batteri- og dataforbrug"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Skift til Tilpasset"</string>
@@ -1618,7 +1613,7 @@
<string name="package_installed_device_owner" msgid="6875717669960212648">"Installeret af din administrator"</string>
<string name="package_updated_device_owner" msgid="1847154566357862089">"Opdateret af din administrator"</string>
<string name="package_deleted_device_owner" msgid="2307122077550236438">"Slettet af din administrator"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"Batterisparefunktionen hjælper med at forlænge batteriets levetid ved at reducere enhedens ydeevne og begrænse vibration, placeringstjenester og det meste baggrundsdata. E-mail, beskedfunktioner og andre apps, der benytter synkronisering, opdateres muligvis ikke, medmindre du åbner dem.\n\nBatterisparefunktionen slukker automatisk, når enheden oplader."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"Batterisparefunktionen hjælper med at forlænge batteriets levetid ved at reducere enhedens ydeevne og begrænse vibration, placeringstjenester og det meste baggrundsdata. E-mail, beskedfunktioner og andre apps, der benytter synkronisering, opdateres muligvis ikke, medmindre du åbner dem.\n\nBatterisparefunktionen deaktiveres automatisk, når enheden oplader."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Datasparefunktionen forhindrer nogle apps i at sende eller modtage data i baggrunden for at reducere dataforbruget. En app, der er i brug, kan få adgang til data, men gør det måske ikke så ofte. Dette kan f.eks. betyde, at billeder ikke vises, før du trykker på dem."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Vil du slå Datasparefunktion til?"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"Slå til"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5a70d9b..629ede8 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Warnmeldungen"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo für Einzelhandel"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-Verbindung"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps, die im Hintergrund ausgeführt werden"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> wird im Hintergrund ausgeführt"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> Apps werden im Hintergrund ausgeführt"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Für weitere Informationen zur Akku- und Datennutzung tippen"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Zu \"Privat\" wechseln"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 0cc6dc6..56a7b35 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Ειδοποιήσεις"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Επίδειξη λιανικής"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Σύνδεση USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> εκτελείται στο παρασκήνιο"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> εφαρμογές εκτελούνται στο παρασκήνιο"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string>
<string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Μετάβαση σε προσωπικό προφίλ"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 4976b03..d1fd60d 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 4976b03..d1fd60d 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 4976b03..d1fd60d 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alerts"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB connection"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps running in background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> is running in the background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps are running in the background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap for details on battery and data usage"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 5515ae1..84a0b36 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para punto de venta"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps que se ejecutan en segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en segundo plano"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps se están ejecutando en segundo plano"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Cambiar al perfil personal"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 33c0e5c..292a984 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo para tiendas"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Conexión USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicaciones que se están ejecutando en segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> se está ejecutando en segundo plano"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicaciones se están ejecutando en segundo plano"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para ver información detallada sobre el uso de datos y la batería"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Cambiar a perfil personal"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 1c76b3f..d2b4caa 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Teatised"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Poedemo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-ühendus"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Rakendusi käitatakse taustal"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> käitatakse taustal"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> rakendust käitatakse taustal"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Lülita isiklikule profiilile"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 78aed23..506244bb 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Abisuak"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Saltzaileentzako demoa"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB konexioa"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> exekutatzen ari da atzeko planoan"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> exekutatzen ari dira atzeko planoan"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Sakatu bateriaren eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistema"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Aldatu profil pertsonalera"</string>
@@ -304,7 +299,7 @@
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Behatu idazten duzun testua"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Ez da salbuespenik egiten datu pertsonalekin, hala nola, kreditu-txartelen zenbakiekin eta pasahitzekin."</string>
<string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Kontrolatu pantailaren zoom-maila"</string>
- <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolatu pantailaren zoom-maila eta kokapena."</string>
+ <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Kontrolatu pantailaren zoom-maila eta posizioa."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Keinuak egin"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Sakatu, lerratu, atximurkatu eta beste hainbat keinu egin ditzake."</string>
<string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Hatz-marken keinuak"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index cd8e750..638108b 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"هشدارها"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"نمونه برای خردهفروشان"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"اتصال USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"برنامههایی که در پسزمینه اجرا میشوند"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> در پسزمینه درحال اجرا شدن است"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> برنامه در پسزمینه درحال اجرا شدن هستند"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string>
<string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"رفتن به نمایه شخصی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5690669..4a36411 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Ilmoitukset"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Esittelytila"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-yhteys"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Sovelluksia käynnissä taustalla"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> on käynnissä taustalla."</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> sovellusta on käynnissä taustalla."</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Katso lisätietoja akun ja datan käytöstä napauttamalla."</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Siirry henkilökohtaiseen profiiliin"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 7797274..188663f 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démo en magasin"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Applications qui fonctionnent en arrière-plan"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> fonctionne en arrière-plan"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> applications fonctionnent en arrière-plan"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Touchez ici pour afficher des détails sur l\'usage de la pile et des données"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Passer au profil personnel"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 761947e..56ed795 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertes"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Démonstration en magasin"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Connexion USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Applications en cours d\'exécution en arrière-plan"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> s\'exécute en arrière-plan"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> applications s\'exécutent en arrière-plan"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string>
<string name="android_system_label" msgid="6577375335728551336">"Système Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Passer au profil personnel"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 2c58acb..22c46f1 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demostración comercial"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"conexión USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicacións que se executan en segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Estase executando en segundo plano a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Estanse executando en segundo plano <xliff:g id="NUMBER">%1$d</xliff:g> aplicacións"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toca para obter información sobre a batería e o uso de datos"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Cambiar ao perfil persoal"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 77f7212..31a6dcd 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ચેતવણીઓ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"રિટેલ ડેમો"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB કનેક્શન"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> પૃષ્ઠભૂમિમાં ચાલી રહી છે"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ઍપ્લિકેશન પૃષ્ઠભૂમિમાં ચાલી રહી છે"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android સિસ્ટમ"</string>
<string name="user_owner_label" msgid="1119010402169916617">"વ્યક્તિગત પર સ્વિચ કરો"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 0a672ca..792ca03 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"सूचनाएं"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुदरा डेमो"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्शन"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बैकग्राउंड में चल रहा है"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बैटरी और डेटा उपयोग के विवरण पाने के लिए टैप करें"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
<string name="user_owner_label" msgid="1119010402169916617">"व्यक्तिगत प्रोफ़ाइल में स्विच करें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 48f4cf7..8b9901b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Upozorenja"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Prodajni demo-način"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB veza"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Izvođenje aplikacija u pozadini"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> izvodi se u pozadini"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacije koje se izvode u pozadini: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podataka"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Prijeđite na osobni"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 8af3ff5..89cdb66 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Értesítések"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kiskereskedelmi bemutató"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-kapcsolat"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"A háttérben még futnak alkalmazások"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás még fut a háttérben"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> alkalmazás még fut a háttérben"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Az akkumulátor töltöttségének és az adathasználat részleteinek megtekintéséhez koppintson"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Átváltás személyes profilra"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index 2ca708d..07e1a68 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Ծանուցումներ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Խանութի ցուցադրական ռեժիմ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB կապակցում"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Հետին ֆոնին գործարկվող հավելվածներ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը գործարկվում է հետին ֆոնին"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> հավելվածները գործարկվում են հետին ֆոնին"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Հպել՝ մարտկոցի և տվյալների օգտագործման մասին մանրամասներ ստանալու համար"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Անցնել անհատական պրոֆիլին"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index aa325ac..8d13f5b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -231,12 +231,12 @@
<string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string>
<string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string>
<string name="bugreport_option_interactive_title" msgid="8635056131768862479">"Laporan interaktif"</string>
- <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gunakan ini di berbagai keadaan. Ini memungkinkan Anda melacak kemajuan laporan, memasukkan detail masalah selengkapnya, dan mengambil tangkapan layar. Mungkin menghilangkan beberapa bagian yang jarang digunakan dan yang perlu waktu lama untuk dilaporkan."</string>
+ <string name="bugreport_option_interactive_summary" msgid="229299488536107968">"Gunakan ini di berbagai keadaan. Ini memungkinkan Anda melacak kemajuan laporan, memasukkan detail masalah selengkapnya, dan mengambil screenshot. Mungkin menghilangkan beberapa bagian yang jarang digunakan dan yang perlu waktu lama untuk dilaporkan."</string>
<string name="bugreport_option_full_title" msgid="6354382025840076439">"Laporan lengkap"</string>
- <string name="bugreport_option_full_summary" msgid="7210859858969115745">"Gunakan opsi ini untuk meminimalkan gangguan sistem jika perangkat tidak responsif atau terlalu lambat, atau jika Anda perlu semua bagian laporan. Tidak mengizinkan Anda memasukkan lebih banyak detail atau mengambil tangkapan layar tambahan."</string>
+ <string name="bugreport_option_full_summary" msgid="7210859858969115745">"Gunakan opsi ini untuk meminimalkan gangguan sistem jika perangkat tidak responsif atau terlalu lambat, atau jika Anda perlu semua bagian laporan. Tidak mengizinkan Anda memasukkan lebih banyak detail atau mengambil screenshot tambahan."</string>
<plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368">
- <item quantity="other">Mengambil tangkapan layar untuk laporan bug dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik.</item>
- <item quantity="one">Mengambil tangkapan layar untuk laporan bug dalam <xliff:g id="NUMBER_0">%d</xliff:g> detik.</item>
+ <item quantity="other">Mengambil screenshot untuk laporan bug dalam <xliff:g id="NUMBER_1">%d</xliff:g> detik.</item>
+ <item quantity="one">Mengambil screenshot untuk laporan bug dalam <xliff:g id="NUMBER_0">%d</xliff:g> detik.</item>
</plurals>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode senyap"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Suara MATI"</string>
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Notifikasi"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo promo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikasi yang sedang berjalan di latar belakang"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan di latar belakang"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikasi sedang berjalan di latar belakang"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tap untuk melihat detail baterai dan penggunaan data"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mode aman"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Beralih ke Pribadi"</string>
@@ -820,7 +815,7 @@
<string name="js_dialog_before_unload" msgid="3468816357095378590">"<xliff:g id="MESSAGE">%s</xliff:g>\n\nYakin ingin beranjak dari laman ini?"</string>
<string name="save_password_label" msgid="6860261758665825069">"Konfirmasi"</string>
<string name="double_tap_toast" msgid="4595046515400268881">"Kiat: Ketuk dua kali untuk memperbesar dan memperkecil."</string>
- <string name="autofill_this_form" msgid="4616758841157816676">"Isiotomatis"</string>
+ <string name="autofill_this_form" msgid="4616758841157816676">"IsiOtomatis"</string>
<string name="setup_autofill" msgid="7103495070180590814">"Siapkan Pengisian Otomatis"</string>
<string name="autofill_address_name_separator" msgid="6350145154779706772">" "</string>
<string name="autofill_address_summary_name_format" msgid="3268041054899214945">"$1$2$3"</string>
@@ -981,7 +976,7 @@
<string name="selectTextMode" msgid="1018691815143165326">"Pilih teks"</string>
<string name="undo" msgid="7905788502491742328">"Urungkan"</string>
<string name="redo" msgid="7759464876566803888">"Ulangi"</string>
- <string name="autofill" msgid="3035779615680565188">"Isiotomatis"</string>
+ <string name="autofill" msgid="3035779615680565188">"IsiOtomatis"</string>
<string name="textSelectionCABTitle" msgid="5236850394370820357">"Pemilihan teks"</string>
<string name="addToDictionary" msgid="4352161534510057874">"Tambahkan ke kamus"</string>
<string name="deleteText" msgid="6979668428458199034">"Hapus"</string>
@@ -1618,7 +1613,7 @@
<string name="package_installed_device_owner" msgid="6875717669960212648">"Diinstal oleh admin Anda"</string>
<string name="package_updated_device_owner" msgid="1847154566357862089">"Diupdate oleh admin Anda"</string>
<string name="package_deleted_device_owner" msgid="2307122077550236438">"Dihapus oleh admin Anda"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran, layanan lokasi, dan kebanyakan data latar belakang. Email, perpesanan, dan aplikasi lain yang mengandalkan sinkronisasi mungkin tidak diperbarui kecuali jika dibuka.\n\nPenghemat baterai otomatis nonaktif jika perangkat diisi dayanya."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"Untuk membantu meningkatkan masa pakai baterai, penghemat baterai mengurangi kinerja perangkat dan membatasi getaran, layanan lokasi, dan sebagian besar data latar belakang. Email, pesan, dan aplikasi lain yang mengandalkan sinkronisasi mungkin tidak diperbarui kecuali jika dibuka.\n\nPenghemat baterai otomatis nonaktif jika perangkat diisi dayanya."</string>
<string name="data_saver_description" msgid="6015391409098303235">"Untuk membantu mengurangi penggunaan data, Penghemat Data mencegah beberapa aplikasi mengirim atau menerima data di latar belakang. Aplikasi yang sedang digunakan dapat mengakses data, tetapi frekuensinya agak lebih jarang. Misalnya saja, gambar hanya akan ditampilkan setelah disentuh."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"Aktifkan Penghemat Data?"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"Aktifkan"</string>
@@ -1746,8 +1741,8 @@
<string name="time_picker_prompt_label" msgid="7588093983899966783">"Ketik waktu"</string>
<string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Beralih ke mode masukan teks untuk masukan waktu."</string>
<string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Beralih ke mode jam untuk masukan waktu."</string>
- <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opsi Isiotomatis"</string>
- <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Simpan untuk Isiotomatis"</string>
+ <string name="autofill_picker_accessibility_title" msgid="8469043291648711535">"Opsi IsiOtomatis"</string>
+ <string name="autofill_save_accessibility_title" msgid="7244365268417107822">"Simpan untuk IsiOtomatis"</string>
<string name="autofill_error_cannot_autofill" msgid="7402758580060110371">"Konten tidak dapat diisi otomatis"</string>
<string name="autofill_save_title" msgid="3345527308992082601">"Simpan ke <b><xliff:g id="LABEL">%1$s</xliff:g></b>?"</string>
<string name="autofill_save_title_with_type" msgid="8637809388029313305">"Simpan <xliff:g id="TYPE">%1$s</xliff:g> ke <b><xliff:g id="LABEL">%2$s</xliff:g></b>?"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index e37862b..305bc63 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Tilkynningar"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Kynningarútgáfa fyrir verslanir"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-tenging"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Forrit sem keyra í bakgrunni"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> keyrir í bakgrunni"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> forrit keyra í bakgrunni"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android kerfið"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Skipta yfir í persónulegt snið"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 8057a06..945d202 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Avvisi"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo retail"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Connessione USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"App in esecuzione in background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"L\'app <xliff:g id="APP_NAME">%1$s</xliff:g> è in esecuzione in background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> app sono in esecuzione in background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Passa al profilo personale"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 504d3ad..9c13178 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"התראות"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"הדגמה לקמעונאים"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"חיבור USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"אפליקציות שפועלות ברקע"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> פועלת ברקע"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> אפליקציות פועלות ברקע"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>, <xliff:g id="LEFT_SIDE">%1$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string>
<string name="android_system_label" msgid="6577375335728551336">"מערכת Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"עבור ל\'אישי\'"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 4f18bcb..f75575a 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"販売店デモ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB 接続"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"バックグラウンドで実行中のアプリ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」がバックグラウンドで実行中です"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個のアプリがバックグラウンドで実行中です"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"タップすると、電池やデータの使用量を詳しく確認できます"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"セーフモード"</string>
<string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string>
<string name="user_owner_label" msgid="1119010402169916617">"個人用に切り替える"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 31cd59b..0231708 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"გაფრთხილებები"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"დემო-რეჟიმი საცალო მოვაჭრეებისთვის"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB კავშირი"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ფონურ რეჟიმში გაშვებული აპები"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაშვებულია ფონურ რეჟიმში"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"ფონურ რეჟიმში გაშვებულია <xliff:g id="NUMBER">%1$d</xliff:g> აპი"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string>
<string name="user_owner_label" msgid="1119010402169916617">"პირად პროფილზე გადართვა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index c512e43..87a8a7e 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Дабылдар"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Бөлшек саудаға арналған демо нұсқасы"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB байланысы"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фонда жұмыс істеп тұрған қолданбалар"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы фонда жұмыс істеп тұр"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> қолданба фонда жұмыс істеп тұр"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батарея мен деректер трафигі туралы мәліметтер алу үшін түртіңіз"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android жүйесі"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Жекеге ауысу"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 64306fd..9892d4a 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ការជូនដំណឹង"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"របៀបដាក់បង្ហាញក្នុងហាង"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"ការតភ្ជាប់ USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"កម្មវិធី <xliff:g id="NUMBER">%1$d</xliff:g> កំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ចុចដើម្បីទទួលបានព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ថ្ម និងទិន្នន័យ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string>
<string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ប្តូរទៅផ្ទាល់ខ្លួន"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index aaabd91..750683a 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ಎಚ್ಚರಿಕೆಗಳು"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"ರಿಟೇಲ್ ಡೆಮೋ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB ಸಂಪರ್ಕ"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿದೆ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ಬ್ಯಾಟರಿ ಮತ್ತು ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android ಸಿಸ್ಟಂ"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ವೈಯಕ್ತಿಕಗೆ ಬದಲಿಸಿ"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ab61857..a5727f4 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"알림"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"소매 데모"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB 연결"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"백그라운드에서 실행 중인 앱"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱이 백그라운드에서 실행 중"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g>개의 앱이 백그라운드에서 실행 중"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"탭하여 배터리 및 데이터 사용량에 관한 세부정보 보기"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"안전 모드"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string>
<string name="user_owner_label" msgid="1119010402169916617">"개인으로 전환"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index a24bd7f..524257a 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Эскертүүлөр"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Чекене соода дүкөнү үчүн демо режим"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB аркылуу туташуу"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Фондо иштеп жаткан колдонмолор"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу фондо иштөөдө"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> колдонмо фондо иштөөдө"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батареянын кубаты жана Интернеттин колдонулушу жөнүндө билүү үчүн таптап коюңуз"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android тутуму"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Жеке профилге которулуу"</string>
@@ -283,7 +278,7 @@
<string name="permgroupdesc_contacts" msgid="6951499528303668046">"байланыштарыңызды көрүүгө"</string>
<string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"түзмөктүн жайгашкан жерин аныктоого"</string>
- <string name="permgrouplab_calendar" msgid="5863508437783683902">"Күнбарак"</string>
+ <string name="permgrouplab_calendar" msgid="5863508437783683902">"Жылнаама"</string>
<string name="permgroupdesc_calendar" msgid="3889615280211184106">"жылнаамаңызды пайдалануу"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"SMS билдирүүлөрдү жиберүү жана көрсөтүү"</string>
@@ -838,9 +833,9 @@
<string name="autofill_parish" msgid="8202206105468820057">"Пэриш"</string>
<string name="autofill_area" msgid="3547409050889952423">"Аймак"</string>
<string name="autofill_emirate" msgid="2893880978835698818">"Эмират"</string>
- <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"желе бүктөмөлүрүңүздү жана тарыхыңызды окуу"</string>
+ <string name="permlab_readHistoryBookmarks" msgid="3775265775405106983">"кыстармаларыңыз менен издөө таржымалыңызды карап көрүңүз"</string>
<string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Колдонмого Серепчи ачкан URLдердин тарыхын жана Серепчинин бүктөмөлөрүн окууга уруксат берет. Эскертүү: бул уруксат үчүнчү тараптык интернет-серепчилерге, же интернетке кирүү мүмкүнчүлүгү бар колдонмолорго таасир этпеши мүмкүн."</string>
- <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"желе бүктөмөлөрүн жана тарыхын жазуу"</string>
+ <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"кыстармалар жана издөө таржымалын өзгөртүү"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Колдонмого планшетиңизде сакталган Серепчинин тарыхын жана Серепчинин бүктөмөлөрүн өзгөртүү уруксатын берет. Бул колдонмого Серепчинин берилиштерин өчүрүү же өзгөртүү уруксатын берет. Эскертүү: бул уруксат үчүнчү тараптык интернет-серепчилерге, же интернетке кирүү мүмкүнчүлүгү бар колдонмолорго таасир этпеши мүмкүн."</string>
<string name="permdesc_writeHistoryBookmarks" product="tv" msgid="7007393823197766548">"Колдонмого Серепчиңиздин таржымалын же сыналгыңызда сакталган кыстармаларды өзгөртүү мүмкүнчүлүгүн берет. Ушуну менен, колдонмо Серепчи дайындарын тазалап же өзгөртө алат. Эскертүү: бул уруксат үчүнчү жактын серепчилери же башка желеде серептөө мүмкүнчүлүгү бар колдонмолор аркылуу иштетилбеши керек."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Колдонмого телефонуңузда сакталган Серепчинин тарыхын жана Серепчинин бүктөмөлөрүн өзгөртүү уруксатын берет. Бул колдонмого Серепчинин берилиштерин өчүрүү же өзгөртүү уруксатын берет. Эскертүү: бул уруксат үчүнчү тараптык интернет-серепчилерге, же интернетке кирүү мүмкүнчүлүгү бар колдонмолорго таасир этпеши мүмкүн."</string>
@@ -1128,7 +1123,7 @@
<string name="wifi_connect_default_application" msgid="7143109390475484319">"Колдонмо"</string>
<string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
<string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Дайректи иштетүү. Бул Wi-Fi клиентти/хотспотту өчүрөт."</string>
- <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Дайрект иштетилбеди."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct иштетилген жок."</string>
<string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct иштөөдө"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"Жөндөөлөрдү ачуу үчүн таптап коюңуз"</string>
<string name="accept" msgid="1645267259272829559">"Кабыл алуу"</string>
@@ -1351,7 +1346,7 @@
<string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"Айнуу"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"Жок кылуу"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"Даяр"</string>
- <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Тартип алмаштыруу"</string>
+ <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"Режимди өзгөртүү"</string>
<string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
<string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Кирүү"</string>
<string name="activitychooserview_choose_application" msgid="2125168057199941199">"Колдонмо тандоо"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index d162fe0..79dfa0d 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ການເຕືອນ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"ເດໂມສຳລັບຮ້ານຂາຍ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"ການເຊື່ອມຕໍ່ USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"ແອັບ <xliff:g id="NUMBER">%1$d</xliff:g> ແອັບກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ສະລັບໄປໂປຣໄຟລ໌ສ່ວນຕົວ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 0a62d62..c726648d 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Įspėjimai"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstracinė versija mažmenininkams"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB jungtis"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programos, veikiančios fone"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ veikia fone"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Programos (<xliff:g id="NUMBER">%1$d</xliff:g>) veikia fone"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string>
<string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Perjungti į asmeninį režimą"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 3bcce6f..9ac3bfe 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Brīdinājumi"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrācijas versija veikaliem"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB savienojums"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Lietotnes, kas darbojas fonā"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> darbojas fonā"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> lietotnes darbojas fonā"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Pārslēgt personīgo profilu"</string>
diff --git a/core/res/res/values-mcc204/config.xml b/core/res/res/values-mcc204/config.xml
new file mode 100644
index 0000000..790f768
--- /dev/null
+++ b/core/res/res/values-mcc204/config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <bool name="config_use_sim_language_file">true</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc310-mnc004/config.xml b/core/res/res/values-mcc310-mnc004/config.xml
index 63431a4..3049488 100755
--- a/core/res/res/values-mcc310-mnc004/config.xml
+++ b/core/res/res/values-mcc310-mnc004/config.xml
@@ -36,4 +36,7 @@
<bool name="config_auto_attach_data_on_creation">false</bool>
<string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">true</string>
+
+ <bool name="config_use_sim_language_file">true</bool>
+
</resources>
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index a210f5b..6f85081 100755
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -62,4 +62,6 @@
<string translatable="false" name="prohibit_manual_network_selection_in_gobal_mode">true</string>
+ <bool name="config_use_sim_language_file">true</bool>
+
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index b5e8c90..78c4583 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Предупредувања"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демонстрација за малопродажба"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-врска"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Апликациите се извршуваат во заднина"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> се извршува во заднина"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> апликации се извршуваат во заднина"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбеден режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Систем Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Префрлете на личен профил"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 5dbb334..3e21e9c 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"അലേർട്ടുകൾ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"റീട്ടെയിൽ ഡെമോ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB കണക്ഷൻ"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android സിസ്റ്റം"</string>
<string name="user_owner_label" msgid="1119010402169916617">"വ്യക്തിഗത പ്രൊഫൈലിലേക്ക് മാറുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 765aa5d..fbdce6e 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Сануулга"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Жижиглэнгийн жишээ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB холболт"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Цаана ажиллаж буй апп"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> цаана ажиллаж байна"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> апп цаана ажиллаж байна"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Батерей, дата ашиглалтын талаар дэлгэрэнгүй мэдээллийг харахын тулд товшино уу"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string>
<string name="user_owner_label" msgid="1119010402169916617">"\"Хувийн\" руу шилжих"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 4191828..9381638 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"सूचना"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"किरकोळ डेमो"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB कनेक्शन"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"अॅप्स बॅकग्राउंडमध्ये चालू आहेत"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> बॅकग्राउंडमध्ये चालू आहे"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> अॅप्स बॅकग्राउंडमध्ये चालू आहेत"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"बॅटरी आणि डेटा वापराच्या तपशीलांसाठी टॅप करा"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string>
<string name="user_owner_label" msgid="1119010402169916617">"वैयक्तिकवर स्विच करा"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d4cc2d3..9557d6d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Makluman"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tunjuk cara runcit"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Sambungan USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apl yang berjalan di latar belakang"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang berjalan di latar belakang"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apl sedang berjalan di latar belakang"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Beralih kepada Peribadi"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 1d89730..bc455b4 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"သတိပေးချက်များ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"လက်လီအရောင်းဆိုင် သရုပ်ပြမှု"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB ချိတ်ဆက်မှု"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် နောက်ခံတွင် ပွင့်နေပါသည်"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"အက်ပ် <xliff:g id="NUMBER">%1$d</xliff:g> ခုသည် နောက်ခံတွင် ပွင့်နေပါသည်"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>၊ <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android စနစ်"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ကိုယ်ပိုင်သီးသန့်အဖြစ် ပြောင်းပါ"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index ab32ff8..32556e5 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Varsler"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Butikkdemo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-tilkobling"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apper kjører i bakgrunnen"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> kjører i bakgrunnen"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apper kjører i bakgrunnen"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trykk for detaljer om batteri- og databruk"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Bytt til den personlige profilen"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 33466bc..38370cf 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"अलर्टहरू"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"खुद्रा बिक्री सम्बन्धी डेमो"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB जडान"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> पृष्ठभूमिमा चल्दैछ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> अनुप्रयोगहरू पृष्ठभूमिमा चल्दैछन्"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ब्याट्री र डेटा प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string>
<string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string>
<string name="user_owner_label" msgid="1119010402169916617">"व्यक्तिगत प्रोफाइलमा स्विच गर्नुहोस्"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index c82219c..cf84a9a 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Meldingen"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo voor de detailhandel"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-verbinding"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps uitgevoerd op achtergrond"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> wordt uitgevoerd op de achtergrond"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps worden uitgevoerd op de achtergrond"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tik voor informatie over batterij- en datagebruik"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Overschakelen naar persoonlijk profiel"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 5c606ae..3d85778 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ਸੁਚੇਤਨਾਵਾਂ"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"ਪ੍ਰਚੂਨ ਸਟੋਰਾਂ ਲਈ ਡੈਮੋ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB ਕਨੈਕਸ਼ਨ"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਐਪ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀ ਹੈ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ਐਪਾਂ ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲ ਰਹੀਆਂ ਹਨ"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ਨਿੱਜੀ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 7386f2d..90cc099 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alerty"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Tryb demo dla sklepów"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Połączenie USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacje działające w tle"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> działa w tle"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Aplikacje (<xliff:g id="NUMBER">%1$d</xliff:g>) działają w tle"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i transmisji danych"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string>
<string name="android_system_label" msgid="6577375335728551336">"System Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Włącz profil osobisty"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index d5dc395..2883f2d 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps sendo executados em segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está sendo executado em segundo plano"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão sendo executados em segundo plano"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Alternar para \"Pessoal\""</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 1f297c2..4c212c0 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração para retalho"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Ligação USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicações em execução em segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"A aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> está a ser executada em segundo plano"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicações estão a ser executadas em segundo plano"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Mudar para pessoal"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index d5dc395..2883f2d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alertas"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstração na loja"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Conexão USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Apps sendo executados em segundo plano"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está sendo executado em segundo plano"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> apps estão sendo executados em segundo plano"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Alternar para \"Pessoal\""</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 3a2c38d..c89facd 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Alerte"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrație comercială"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Conexiune USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplicațiile rulează în fundal"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> rulează în fundal"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplicații rulează în fundal"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Comutați la Personal"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 0bc71eb..d32121f 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Уведомления"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Деморежим для магазина"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-подключение"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Приложения, работающие в фоновом режиме"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" работает в фоновом режиме"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Несколько приложений (<xliff:g id="NUMBER">%1$d</xliff:g>) работает в фоновом режиме"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Нажмите, чтобы увидеть данные об энергопотреблении и объеме трафика"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Перейти в личный профиль"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index b7e695a..44ce434 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"ඇඟවීම්"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"සිල්ලර ආදර්ශනය"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB සම්බන්ධතාවය"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> පසුබිමින් ධාවනය වේ"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"යෙදුම් <xliff:g id="NUMBER">%1$d</xliff:g>ක් පසුබිමින් ධාවනය වේ"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"ආරක්ෂිත ආකාරය"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string>
<string name="user_owner_label" msgid="1119010402169916617">"පුද්ගලික වෙත මාරු වන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 018ea4e..f63dd87 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -96,7 +96,7 @@
<string name="RestrictedOnNormalTitle" msgid="3179574012752700984">"Žiadne hlasové hovory"</string>
<string name="RestrictedOnAllVoiceTitle" msgid="158800171499150681">"Hlasové ani tiesňové volania nie sú k dispozícii"</string>
<string name="RestrictedOnDataContent" msgid="8997474569390996587">"Váš operátor dočasne pozastavil dátovú službu na tomto mieste"</string>
- <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Váš operátor dočasne pozastavil núdzové hovory z tohto miesta"</string>
+ <string name="RestrictedOnEmergencyContent" msgid="4573217945494650061">"Váš operátor v tejto oblasti dočasne pozastavil tiesňové volania"</string>
<string name="RestrictedOnNormalContent" msgid="1579434198284512182">"Váš operátor dočasne pozastavil hlasové hovory z tohto miesta"</string>
<string name="RestrictedOnAllVoiceContent" msgid="5243580774142557047">"Váš operátor v tejto oblasti dočasne blokuje hlasové a tiesňové hovory"</string>
<string name="NetworkPreferenceSwitchTitle" msgid="4008877505368566980">"Nepodarilo sa pripojiť k sieti"</string>
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Upozornenia"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predajná ukážka"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Pripojenie USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikácie sú spustené na pozadí"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je spustená na pozadí"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Niekoľko aplikácií (<xliff:g id="NUMBER">%1$d</xliff:g>) je spustených na pozadí"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string>
<string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Prepnúť na osobný"</string>
@@ -1825,7 +1820,7 @@
<string name="etws_primary_default_message_earthquake" msgid="5541962250262769193">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
<string name="etws_primary_default_message_tsunami" msgid="1887685943498368548">"Okamžite začnite evakuáciu z prímorských a nábrežných oblastí na bezpečnejšie miesto, napríklad do vyššie položených regiónov."</string>
<string name="etws_primary_default_message_earthquake_and_tsunami" msgid="998797956848445862">"Zachovajte pokoj a vyhľadajte úkryt v okolí."</string>
- <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test núdzových správ"</string>
+ <string name="etws_primary_default_message_test" msgid="2709597093560037455">"Test tiesňových správ"</string>
<string name="etws_primary_default_message_others" msgid="6293148756130398971"></string>
<string name="mmcc_authentication_reject" msgid="7729819349669603406">"SIM karta je zakázaná"</string>
<string name="mmcc_imsi_unknown_in_hlr" msgid="6321202257374418726">"SIM karta nie je k dispozícii"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 729612f..a5c6742 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Opozorila"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Predstavitev za maloprodajo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Povezava USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacije se izvajajo v ozadju"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> se izvaja v ozadju"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Več aplikacij (<xliff:g id="NUMBER">%1$d</xliff:g>) se izvaja v ozadju"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Dotaknite se za prikaz podrobnosti porabe akumulatorja in prenosa podatkov"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Varni način"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Preklop na osebni profil"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 563f4bd..54198a6 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Sinjalizimet"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demonstrimi i shitjes me pakicë"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Lidhja USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Aplikacionet që ekzekutohen në sfond"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> po ekzekutohet në sfond"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> aplikacione po ekzekutohen në sfond"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Trokit për detaje për baterinë dhe përdorimin e të dhënave"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string>
<string name="android_system_label" msgid="6577375335728551336">"Sistemi \"android\""</string>
<string name="user_owner_label" msgid="1119010402169916617">"Ndryshoje te \"Personale\""</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 2d2cc70..d76e209 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -268,16 +268,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Обавештења"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Режим демонстрације за малопродајне објекте"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB веза"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Апликације покренуте у позадини"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> је покренута у позадини"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Апликације (<xliff:g id="NUMBER">%1$d</xliff:g>) су покренуте у позадини"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Додирните да бисте прегледали детаље о батерији и потрошњи података"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android систем"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Пређи на Лични профил"</string>
@@ -300,13 +295,13 @@
<string name="permgroupdesc_phone" msgid="6234224354060641055">"упућује телефонске позиве и управља њима"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Сензори за тело"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"приступа подацима сензора о виталним функцијама"</string>
- <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Преузима садржај прозора"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"да преузима садржај прозора"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Проверава садржај прозора са којим остварујете интеракцију."</string>
- <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Укључи Истраживања додиром"</string>
+ <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"да укључи Истраживања додиром"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Ставке које додирнете ће бити изговорене наглас, а можете да се крећете по екрану покретима."</string>
- <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Прати текст који уносите"</string>
+ <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"да прати текст који уносите"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Обухвата личне податке као што су бројеви кредитних картица и лозинке."</string>
- <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"Управљај увећањем приказа"</string>
+ <string name="capability_title_canControlMagnification" msgid="3593493281059424855">"да управља увећањем приказа"</string>
<string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Управља нивоом зумирања приказа и одређивањем положаја."</string>
<string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Обављање покрета"</string>
<string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Може да додирује, листа, скупља приказ и обавља друге покрете."</string>
@@ -1053,7 +1048,7 @@
<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_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>
@@ -1312,7 +1307,7 @@
<string name="vpn_lockdown_config" msgid="5099330695245008680">"Додирните да бисте подесили"</string>
<string name="upload_file" msgid="2897957172366730416">"Одабери датотеку"</string>
<string name="no_file_chosen" msgid="6363648562170759465">"Није изабрана ниједна датотека"</string>
- <string name="reset" msgid="2448168080964209908">"Поново постави"</string>
+ <string name="reset" msgid="2448168080964209908">"Ресетуј"</string>
<string name="submit" msgid="1602335572089911941">"Пошаљи"</string>
<string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Режим рада у аутомобилу је омогућен"</string>
<string name="car_mode_disable_notification_message" msgid="6301524980144350051">"Додирните да бисте изашли из режима рада у аутомобилу."</string>
@@ -1346,7 +1341,7 @@
<string name="sync_really_delete" msgid="2572600103122596243">"Избриши ставке"</string>
<string name="sync_undo_deletes" msgid="2941317360600338602">"Опозови брисања"</string>
<string name="sync_do_nothing" msgid="3743764740430821845">"Не ради ништа за сада"</string>
- <string name="choose_account_label" msgid="5655203089746423927">"Избор налога"</string>
+ <string name="choose_account_label" msgid="5655203089746423927">"Изаберите налог"</string>
<string name="add_account_label" msgid="2935267344849993553">"Додај налог"</string>
<string name="add_account_button_label" msgid="3611982894853435874">"Додај налог"</string>
<string name="number_picker_increment_button" msgid="2412072272832284313">"Повећавање"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c480df4..f33a622 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Varningar"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo för återförsäljare"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB-anslutning"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Appar körs i bakgrunden"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> körs i bakgrunden"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> appar körs i bakgrunden"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Tryck för information om batteri- och dataanvändning"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android-system"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Byt till din personliga profil"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index cec75bc..3a22df6 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -263,16 +263,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Arifa"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Onyesho la duka la rejareja"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Muunganisho wa USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Programu zinatumika chinichini"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumika chinichini"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Programu <xliff:g id="NUMBER">%1$d</xliff:g> zinatumika chinichini"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Gonga ili upate maelezo kuhusu betri na matumizi ya data"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string>
<string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Badili uweke wasifu wa Binafsi"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 7062e98..47d3f7a 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"விழிப்பூட்டல்கள்"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"விற்பனையாளர் டெமோ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB இணைப்பு"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாடு பின்னணியில் இயங்குகிறது"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> பயன்பாடுகள் பின்னணியில் இயங்குகின்றன"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"பேட்டரி மற்றும் தரவு உபயோகம் குறித்த விவரங்களுக்கு, தட்டவும்"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android அமைப்பு"</string>
<string name="user_owner_label" msgid="1119010402169916617">"தனிப்பட்ட சுயவிவரத்திற்கு மாறு"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 31e2721..5884df7 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"హెచ్చరికలు"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"రిటైల్ డెమో"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB కనెక్షన్"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"నేపథ్యంలో అమలు అవుతున్న ఆప్లు"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> నేపథ్యంలో అమలు అవుతోంది"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ఆప్లు నేపథ్యంలో అమలు అవుతున్నాయి"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android సిస్టమ్"</string>
<string name="user_owner_label" msgid="1119010402169916617">"వ్యక్తిగతానికి మార్చు"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index fd7158f..e5246c5 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"การแจ้งเตือน"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"การสาธิตสำหรับผู้ค้าปลีก"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"การเชื่อมต่อ USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังทำงานในเบื้องหลัง"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"แอป <xliff:g id="NUMBER">%1$d</xliff:g> กำลังทำงานในเบื้องหลัง"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string>
<string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"เปลี่ยนไปใช้โปรไฟล์ส่วนตัว"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index e58f62f..0f097564 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Mga Alerto"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Retail demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Koneksyon ng USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Tumatakbo ang mga app sa background"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Tumatakbo ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa background"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> (na) app ang tumatakbo sa background"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Lumipat sa Personal"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e395435..397335b 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Uyarılar"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Mağaza demo"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB bağlantısı"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Uygulamalar arka planda çalışıyor"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> arka planda çalışıyor"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> uygulama arka planda çalışıyor"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Kişisel Profile Geç"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 09cec2a..205cbb7 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -271,16 +271,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Сповіщення"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Демо-режим для роздрібної торгівлі"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"З’єднання USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Додатки, які працюють у фоновому режимі"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> працює у фоновому режимі"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"Додатки, які працюють у фоновому режимі: <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Торкніться, щоб переглянути інформацію про використання заряду акумулятора та даних"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string>
<string name="android_system_label" msgid="6577375335728551336">"Система Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Перейти в особистий профіль"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 225faa6..5c27041 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"الرٹس"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"ریٹیل ڈیمو"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB کنکشن"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"ایپس پس منظر میں چل رہی ہیں"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> پس منظر میں چل رہی ہے"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ایپس پس منظر میں چل رہی ہیں"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>، <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android سسٹم"</string>
<string name="user_owner_label" msgid="1119010402169916617">"ذاتی پر سوئچ کریں"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 0e7d4ff..9cb98b0 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -72,7 +72,7 @@
<string name="ClirMmi" msgid="7784673673446833091">"Chiquvchi raqami"</string>
<string name="ColpMmi" msgid="3065121483740183974">"Qo‘ng‘iroq qiluvchining raqami"</string>
<string name="ColrMmi" msgid="4996540314421889589">"Qo‘ng‘iroq qiluvchining raqamini cheklash"</string>
- <string name="CfMmi" msgid="5123218989141573515">"Chaqiruvni yo‘naltirish"</string>
+ <string name="CfMmi" msgid="5123218989141573515">"Chaqiruvlarni uzatish"</string>
<string name="CwMmi" msgid="9129678056795016867">"Chaqiruvni kutish"</string>
<string name="BaMmi" msgid="455193067926770581">"Qo‘ng‘iroqlarni taqiqlash"</string>
<string name="PwdMmi" msgid="7043715687905254199">"Parolni o‘zgartirish"</string>
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Ogohlantirishlar"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Demo rejim"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB orqali ulanish"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Fonda ishlayotgan ilovalar"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> fonda ishlamoqda"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ta ilova fonda ishlamoqda"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Batareya va trafik sarfiga oid tafsilotlarni olish uchun ustiga bosing"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android tizimi"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Shaxsiy profilga o‘tish"</string>
@@ -1083,15 +1078,15 @@
<string name="dump_heap_title" msgid="5864292264307651673">"Hip-damp ma’lumotlari bilan ulashasizmi?"</string>
<string name="dump_heap_text" msgid="4809417337240334941">"<xliff:g id="PROC">%1$s</xliff:g> jarayoni o‘zi uchun ajratilgan <xliff:g id="SIZE">%2$s</xliff:g> xotira chegarasidan o‘tib ketdi. Ilova dasturchisi bilan ulashishingiz uchun hip-damp ma’lumotlari yig‘ilib qoldi. Ehtiyot bo\'ling: ushbu hip-dampda ilova uchun foydalanishga ruxsat berilgan shaxsiy ma’lumotlaringiz bo‘lishi mumkin."</string>
<string name="sendText" msgid="5209874571959469142">"Matn uchun amalni tanlash"</string>
- <string name="volume_ringtone" msgid="6885421406845734650">"Jiringlaganda ovoz balandligi"</string>
+ <string name="volume_ringtone" msgid="6885421406845734650">"Jiringlaganda tovush balandligi"</string>
<string name="volume_music" msgid="5421651157138628171">"Multimedia ovozi"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth orqali ijro etilmoqda"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Ovozsiz rejim tanlandi"</string>
- <string name="volume_call" msgid="3941680041282788711">"Suhbat vaqtidagi ovoz balandligi"</string>
+ <string name="volume_call" msgid="3941680041282788711">"Suhbat vaqtidagi tovush balandligi"</string>
<string name="volume_bluetooth_call" msgid="2002891926351151534">"Kiruvchi bluetooth tovushi"</string>
<string name="volume_alarm" msgid="1985191616042689100">"Signal ovozi"</string>
<string name="volume_notification" msgid="2422265656744276715">"Eslatma tovushi"</string>
- <string name="volume_unknown" msgid="1400219669770445902">"Ovoz balandligi"</string>
+ <string name="volume_unknown" msgid="1400219669770445902">"Tovush balandligi"</string>
<string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth tovushi"</string>
<string name="volume_icon_description_ringer" msgid="3326003847006162496">"Rington balandligi"</string>
<string name="volume_icon_description_incall" msgid="8890073218154543397">"Qo‘ng‘iroq tovushi balandligi"</string>
@@ -1474,7 +1469,7 @@
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Siz grafik kalitni <xliff:g id="NUMBER_0">%1$d</xliff:g> marta noto‘g‘ri chizdingiz. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan so‘ng, sizdan e-pochtangizdan foydalanib, telefon qulfini ochishingiz so‘raladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan so‘ng yana urinib ko‘ring."</string>
<string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"O‘chirish"</string>
- <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Ovoz balandligi tavsiya etilgan darajadan ham yuqori ko‘tarilsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
+ <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Tovush balandligi tavsiya etilgan darajadan ham yuqori qilinsinmi?\n\nUzoq vaqt davomida baland ovozda tinglash eshitish qobiliyatingizga salbiy ta’sir ko‘rsatishi mumkin."</string>
<string name="accessibility_shortcut_warning_dialog_title" msgid="8404780875025725199">"Tezkor ishga tushirishdan foydalanilsinmi?"</string>
<string name="accessibility_shortcut_toogle_warning" msgid="7256507885737444807">"Maxsus imkoniyatlar funksiyasidan foydalanish uchun u yoniqligida ikkala ovoz balandligini boshqarish tugmasini 3 soniya bosib turing.\n\n Joriy maxsus imkoniyatlar funksiyasi:\n <xliff:g id="SERVICE_NAME">%1$s</xliff:g>\n\n Bu funksiyani Sozlamalar > Maxsus imkoniyatlar orqali o‘zgartirish mumkin."</string>
<string name="disable_accessibility_shortcut" msgid="627625354248453445">"Tezkor ishga tushirishni o‘chirib qo‘yish"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index f2ba671..f126a30 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Cảnh báo"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Giới thiệu bán lẻ"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Kết nối USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Ứng dụng đang chạy trong nền"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang chạy trong nền"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> ứng dụng đang chạy trong nền"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Nhấn để biết chi tiết về pin và mức sử dụng dữ liệu"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string>
<string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Chuyển sang Cá nhân"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 6e35e3f..a13a4a2 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"提醒"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售演示模式"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB 连接"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"在后台运行的应用"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在后台运行"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 个应用正在后台运行"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"点按即可详细了解电量和流量消耗情况"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string>
<string name="user_owner_label" msgid="1119010402169916617">"切换到“个人”"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 74f4987..aec1cf6 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"通知"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售示範"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"正在背景中執行的應用程式"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> 正在背景中執行"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景中執行"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕按即可查看電池和數據用量詳情"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
<string name="user_owner_label" msgid="1119010402169916617">"切換至個人設定檔"</string>
@@ -701,7 +696,7 @@
<string name="relationTypeSister" msgid="1735983554479076481">"姊妹"</string>
<string name="relationTypeSpouse" msgid="394136939428698117">"配偶"</string>
<string name="sipAddressTypeCustom" msgid="2473580593111590945">"自訂"</string>
- <string name="sipAddressTypeHome" msgid="6093598181069359295">"家用"</string>
+ <string name="sipAddressTypeHome" msgid="6093598181069359295">"住宅"</string>
<string name="sipAddressTypeWork" msgid="6920725730797099047">"公司"</string>
<string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
<string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可以查看這位聯絡人的應用程式。"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 87e98dd..213f660 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"快訊"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"零售商示範模式"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"USB 連線"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"在背景執行的應用程式"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在背景執行"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> 個應用程式正在背景執行"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"輕觸即可取得電池和數據用量的詳細資料"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>、<xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"安全模式"</string>
<string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string>
<string name="user_owner_label" msgid="1119010402169916617">"切換至個人設定檔"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a656e6c..8512e38 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -265,16 +265,11 @@
<string name="notification_channel_alerts" msgid="4496839309318519037">"Izexwayiso"</string>
<string name="notification_channel_retail_mode" msgid="6088920674914038779">"Idemo yokuthenga"</string>
<string name="notification_channel_usb" msgid="9006850475328924681">"Ukuxhumeka kwe-USB"</string>
- <!-- no translation found for notification_channel_foreground_service (6665375982962336520) -->
- <skip />
- <!-- no translation found for foreground_service_app_in_background (6826789589341671842) -->
- <skip />
- <!-- no translation found for foreground_service_apps_in_background (7150914856893450380) -->
- <skip />
- <!-- no translation found for foreground_service_tap_for_details (372046743534354644) -->
- <skip />
- <!-- no translation found for foreground_service_multiple_separator (4021901567939866542) -->
- <skip />
+ <string name="notification_channel_foreground_service" msgid="6665375982962336520">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
+ <string name="foreground_service_app_in_background" msgid="6826789589341671842">"<xliff:g id="APP_NAME">%1$s</xliff:g> iyasebenza ngemuva"</string>
+ <string name="foreground_service_apps_in_background" msgid="7150914856893450380">"<xliff:g id="NUMBER">%1$d</xliff:g> izinhlelo zokusebenza ziyasebenza ngemuva"</string>
+ <string name="foreground_service_tap_for_details" msgid="372046743534354644">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
+ <string name="foreground_service_multiple_separator" msgid="4021901567939866542">"<xliff:g id="LEFT_SIDE">%1$s</xliff:g>, <xliff:g id="RIGHT_SIDE">%2$s</xliff:g>"</string>
<string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string>
<string name="android_system_label" msgid="6577375335728551336">"Uhlelo lwe-Android"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Shintshela komuntu siqu"</string>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a921fd7..aeb564b 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1299,9 +1299,9 @@
* Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action
protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission.
- This must be set to a valid network recommendation app.
+ This must be set to a valid network recommendation app or empty.
-->
- <string name="config_defaultNetworkRecommendationProviderPackage" translatable="false">com.android.networkrecommendation</string>
+ <string name="config_defaultNetworkRecommendationProviderPackage" translatable="false"></string>
<!-- Whether to enable Hardware FLP overlay which allows Hardware FLP to be
replaced by an app at run-time. When disabled, only the
@@ -2872,4 +2872,8 @@
<!-- Additional non-platform defined secure settings exposed to Instant Apps -->
<string-array name="config_allowedSecureInstantAppSettings"></string-array>
+
+ <!-- Handle volume keys directly in Window Manager without passing them to the foreground app -->
+ <bool name="config_handleVolumeKeysInWindowManager">false</bool>
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e633d66..27f98b3 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -644,8 +644,10 @@
<!-- Text shown when viewing channel settings for notifications related to a usb connection -->
<string name="notification_channel_usb">USB connection</string>
- <!-- Text shown when viewing channel settings for notifications related to running foreground
- services [CHAR LIMIT=NONE] -->
+ <!-- This is the label for the notification channel settings that controls the behavior
+ of the notification about applications that are running in the background (that is,
+ perhaps confusingly, running foreground services but not the foreground UI on the screen).
+ [CHAR LIMIT=NONE] -->
<string name="notification_channel_foreground_service">Apps running in background</string>
<!-- Label for foreground service notification when one app is running. [CHAR LIMIT=NONE] -->
@@ -663,7 +665,10 @@
data usage</string>
<!-- Separator for foreground service notification content listing all apps when there
- are multiple apps running [CHAR LIMIT=NONE] -->
+ are multiple apps running. The left and right side may both already be compound
+ (constructed using this separator). Should be kept as short as possible, this is
+ for summary text in the notification where there is not a lot of space.
+ [CHAR LIMIT=NONE] -->
<string name="foreground_service_multiple_separator"><xliff:g id="left_side">%1$s</xliff:g>,
<xliff:g id="right_side">%2$s</xliff:g></string>
@@ -2696,10 +2701,10 @@
<string name="dial">Phone</string>
<!-- Label for item in the text selection menu to trigger a Map app [CHAR LIMIT=20] -->
- <string name="map">Map</string>
+ <string name="map">Maps</string>
<!-- Label for item in the text selection menu to trigger a Browser app [CHAR LIMIT=20] -->
- <string name="browse">Browse</string>
+ <string name="browse">Browser</string>
<!-- If the device is getting low on internal storage, a notification is shown to the user. This is the title of that notification. -->
<string name="low_internal_storage_view_title">Storage space running out</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 2ae2ca0..690b051 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -511,6 +511,8 @@
<style name="Widget.CheckedTextView">
<item name="textAlignment">viewStart</item>
+ <item name="breakStrategy">high_quality</item>
+ <item name="hyphenationFrequency">normal</item>
</style>
<style name="Widget.TextView.ListSeparator">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1966f6a..cff6eb1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3010,4 +3010,5 @@
<java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
<java-symbol type="array" name="config_allowedSecureInstantAppSettings" />
+ <java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
</resources>
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
index 411a3f8..37b2a50 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
@@ -72,8 +72,6 @@
getAddress();
} else if ("getBondedDevices".equals(command)) {
getBondedDevices();
- } else if ("enableBtSnoop".equals(command)) {
- enableBtSnoop();
} else {
finish(null);
}
@@ -116,12 +114,6 @@
finish(mSuccessResult);
}
- public void enableBtSnoop() {
- Assert.assertTrue("failed to enable snoop log",
- getBluetoothAdapter().configHciSnoopLog(true));
- finish(mSuccessResult);
- }
-
public void finish(Bundle result) {
if (result == null) {
result = new Bundle();
diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
index 5e426e8..9c904d1 100644
--- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
+++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
@@ -68,19 +68,19 @@
assertEquals(4, fileEntries.length);
FontFileResourceEntry font1 = fileEntries[0];
assertEquals(400, font1.getWeight());
- assertEquals(false, font1.isItalic());
+ assertEquals(0, font1.getItalic());
assertEquals("res/font/samplefont.ttf", font1.getFileName());
FontFileResourceEntry font2 = fileEntries[1];
assertEquals(400, font2.getWeight());
- assertEquals(true, font2.isItalic());
+ assertEquals(1, font2.getItalic());
assertEquals("res/font/samplefont2.ttf", font2.getFileName());
FontFileResourceEntry font3 = fileEntries[2];
assertEquals(800, font3.getWeight());
- assertEquals(false, font3.isItalic());
+ assertEquals(0, font3.getItalic());
assertEquals("res/font/samplefont3.ttf", font3.getFileName());
FontFileResourceEntry font4 = fileEntries[3];
assertEquals(800, font4.getWeight());
- assertEquals(true, font4.isItalic());
+ assertEquals(1, font4.getItalic());
assertEquals("res/font/samplefont4.ttf", font4.getFileName());
}
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index aaaf55c..821ee80 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -26,5 +26,8 @@
// From /system/manifest.xml
assertTrue(String.join("", xmls).contains(
"<manifest version=\"1.0\" type=\"framework\">"));
+ // From /system/compatibility-matrix.xml
+ assertTrue(String.join("", xmls).contains(
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">"));
}
}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 99909ac..ee2f1ca 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -109,6 +109,8 @@
Settings.Global.BLE_SCAN_ALWAYS_AVAILABLE,
Settings.Global.BLUETOOTH_A2DP_SINK_PRIORITY_PREFIX,
Settings.Global.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX,
+ Settings.Global.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX,
+ Settings.Global.BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX,
Settings.Global.BLUETOOTH_DISABLED_PROFILES,
Settings.Global.BLUETOOTH_HEADSET_PRIORITY_PREFIX,
Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX,
@@ -306,6 +308,7 @@
Settings.Global.SETUP_PREPAID_DETECTION_REDIR_HOST,
Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL,
Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
+ Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
Settings.Global.SHOW_TEMPERATURE_WARNING,
Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
@@ -369,6 +372,8 @@
Settings.Global.WIFI_REENABLE_DELAY_MS,
Settings.Global.WIFI_SAVED_STATE,
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
+ Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_INTERVAL_MS,
+ Settings.Global.WIFI_SCAN_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
Settings.Global.WIFI_SLEEP_POLICY,
Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
@@ -395,6 +400,7 @@
Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
Settings.Secure.ASSIST_STRUCTURE_ENABLED,
+ Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
@@ -402,7 +408,6 @@
Settings.Secure.BACKUP_ENABLED,
Settings.Secure.BACKUP_PROVISIONED,
Settings.Secure.BACKUP_TRANSPORT,
- Settings.Secure.BLUETOOTH_HCI_LOG,
Settings.Secure.CARRIER_APPS_HANDLED,
Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
Settings.Secure.COMPLETED_CATEGORY_PREFIX,
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
index 5ed6ce5..bc9f44d 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutBlocksTest.java
@@ -16,17 +16,26 @@
package android.text;
-import junit.framework.TestCase;
-
import static android.text.Layout.Alignment.ALIGN_NORMAL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
/**
- * Tests DynamciLayout updateBlocks method.
+ * Tests DynamicLayout updateBlocks method.
*
* Requires disabling access checks in the vm since this calls package-private APIs.
*
*/
-public class DynamicLayoutBlocksTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DynamicLayoutBlocksTest {
private DynamicLayout dl = new DynamicLayout("", new TextPaint(), 0, ALIGN_NORMAL, 0, 0, false);
private static final int ___ = DynamicLayout.INVALID_BLOCK_INDEX;
@@ -88,6 +97,7 @@
assertState(sizes, ids);
}
+ @Test
public void testFrom0() {
defineInitialState( new int[] { 0 }, new int[] { 123 });
@@ -101,6 +111,7 @@
assertState( new int[] { 10 } );
}
+ @Test
public void testFrom1ReplaceByEmpty() {
defineInitialState( new int[] { 100 }, new int[] { 123 });
@@ -126,6 +137,7 @@
assertState( new int[] { 100 } );
}
+ @Test
public void testFrom1ReplaceFromFirstLine() {
defineInitialState( new int[] { 100 }, new int[] { 123 });
@@ -142,6 +154,7 @@
assertState( new int[] { 20 } );
}
+ @Test
public void testFrom1ReplaceFromCenter() {
defineInitialState( new int[] { 100 }, new int[] { 123 });
@@ -158,6 +171,7 @@
assertState( new int[] { 20, 50 } );
}
+ @Test
public void testFrom1ReplaceFromEnd() {
defineInitialState( new int[] { 100 }, new int[] { 123 });
@@ -171,6 +185,7 @@
assertState( new int[] { 100, 10 } );
}
+ @Test
public void testFrom2ReplaceFromFirstLine() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -187,6 +202,7 @@
assertState( new int[] { 50 }, new int[] { ___ } );
}
+ @Test
public void testFrom2ReplaceFromFirstBlock() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -203,6 +219,7 @@
assertState( new int[] { 3, 50 }, new int[] { ___, ___ } );
}
+ @Test
public void testFrom2ReplaceFromBottomBoundary() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -216,6 +233,7 @@
assertState( new int[] { 10, 50 }, new int[] { ___, ___ } );
}
+ @Test
public void testFrom2ReplaceFromTopBoundary() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -229,6 +247,7 @@
assertState( new int[] { 11, 50 }, new int[] { 123, ___ } );
}
+ @Test
public void testFrom2ReplaceFromSecondBlock() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -242,6 +261,7 @@
assertState( new int[] { 11, 14-11, 50 }, new int[] { 123, ___, ___ } );
}
+ @Test
public void testFrom2RemoveFromFirst() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -258,6 +278,7 @@
assertState( new int[] { 0 }, new int[] { ___ } );
}
+ @Test
public void testFrom2RemoveFromFirstBlock() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -274,6 +295,7 @@
assertState( new int[] { 4 }, new int[] { ___ } );
}
+ @Test
public void testFrom2RemoveFromSecondBlock() {
defineInitialState( new int[] { 10, 20 }, new int[] { 123, 456 });
@@ -284,6 +306,7 @@
assertState( new int[] { 11, 14-11 }, new int[] { 123, ___ } );
}
+ @Test
public void testFrom3ReplaceFromFirstBlock() {
defineInitialState( new int[] { 10, 30, 60 }, new int[] { 123, 456, 789 });
@@ -306,6 +329,7 @@
assertState( new int[] { 3, 50 }, new int[] { ___, ___ } );
}
+ @Test
public void testFrom3ReplaceFromSecondBlock() {
defineInitialState( new int[] { 10, 30, 60 }, new int[] { 123, 456, 789 });
diff --git a/core/tests/coretests/src/android/text/DynamicLayoutTest.java b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
index 9362ed9..da6dc7e 100644
--- a/core/tests/coretests/src/android/text/DynamicLayoutTest.java
+++ b/core/tests/coretests/src/android/text/DynamicLayoutTest.java
@@ -17,16 +17,28 @@
package android.text;
import static android.text.Layout.Alignment.ALIGN_NORMAL;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Paint.FontMetricsInt;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.style.ReplacementSpan;
-import junit.framework.TestCase;
-public class DynamicLayoutTest extends TestCase {
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DynamicLayoutTest {
private static final int WIDTH = 10000;
+ @Test
public void testGetBlocksAlwaysNeedToBeRedrawn_en() {
final SpannableStringBuilder builder = new SpannableStringBuilder();
final DynamicLayout layout = new DynamicLayout(builder, new TextPaint(), WIDTH,
@@ -42,19 +54,7 @@
assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
}
-
- private static class MockReplacementSpan extends ReplacementSpan {
- @Override
- public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
- return 10;
- }
-
- @Override
- public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
- int y, int bottom, Paint paint) {
- }
- }
-
+ @Test
public void testGetBlocksAlwaysNeedToBeRedrawn_replacementSpan() {
final SpannableStringBuilder builder = new SpannableStringBuilder();
final DynamicLayout layout = new DynamicLayout(builder, new TextPaint(), WIDTH,
@@ -66,11 +66,17 @@
builder.append("hijk lmn\n");
assertNull(layout.getBlocksAlwaysNeedToBeRedrawn());
- builder.setSpan(new MockReplacementSpan(), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
+ when(mockReplacementSpan.getSize(any(), any(), any(), any(), any()))
+ .thenReturn(10);
+ doNothing().when(mockReplacementSpan)
+ .draw(any(), any(), any(), any(), any(), any(), any(), any(), any());
+
+ builder.setSpan(mockReplacementSpan, 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
assertNotNull(layout.getBlocksAlwaysNeedToBeRedrawn());
assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
- builder.setSpan(new MockReplacementSpan(), 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ builder.setSpan(mockReplacementSpan, 9, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(0));
assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().contains(1));
@@ -83,6 +89,7 @@
assertTrue(layout.getBlocksAlwaysNeedToBeRedrawn().isEmpty());
}
+ @Test
public void testGetBlocksAlwaysNeedToBeRedrawn_thai() {
final SpannableStringBuilder builder = new SpannableStringBuilder();
final DynamicLayout layout = new DynamicLayout(builder, new TextPaint(), WIDTH,
diff --git a/core/tests/coretests/src/android/text/PackedIntVectorTest.java b/core/tests/coretests/src/android/text/PackedIntVectorTest.java
index 1aab8af..9df0f89 100644
--- a/core/tests/coretests/src/android/text/PackedIntVectorTest.java
+++ b/core/tests/coretests/src/android/text/PackedIntVectorTest.java
@@ -16,17 +16,23 @@
package android.text;
-import android.support.test.filters.SmallTest;
+import static org.junit.Assert.assertEquals;
-import junit.framework.TestCase;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* PackedIntVectorTest tests the features of android.util.PackedIntVector.
*/
-public class PackedIntVectorTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PackedIntVectorTest {
- @SmallTest
- public void testBasic() throws Exception {
+ @Test
+ public void testBasic() {
for (int width = 0; width < 10; width++) {
PackedIntVector p = new PackedIntVector(width);
int[] ins = new int[width];
diff --git a/core/tests/coretests/src/android/text/SpannableTest.java b/core/tests/coretests/src/android/text/SpannableTest.java
index d6f0244..5ed6250 100644
--- a/core/tests/coretests/src/android/text/SpannableTest.java
+++ b/core/tests/coretests/src/android/text/SpannableTest.java
@@ -16,15 +16,20 @@
package android.text;
-import android.test.InstrumentationTestCase;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
import android.test.MoreAsserts;
-import android.test.suitebuilder.annotation.MediumTest;
-public abstract class SpannableTest extends InstrumentationTestCase {
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public abstract class SpannableTest {
protected abstract Spannable newSpannableWithText(String text);
- @MediumTest
+ @Test
public void testGetSpans() {
Spannable spannable = newSpannableWithText("abcdef");
Object emptySpan = new Object();
diff --git a/core/tests/coretests/src/android/text/SpannedTest.java b/core/tests/coretests/src/android/text/SpannedTest.java
index 911da4b..60cddb08 100644
--- a/core/tests/coretests/src/android/text/SpannedTest.java
+++ b/core/tests/coretests/src/android/text/SpannedTest.java
@@ -16,34 +16,40 @@
package android.text;
+import static org.junit.Assert.assertEquals;
+
import android.graphics.Typeface;
import android.os.Parcel;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.text.style.TextAppearanceSpan;
import android.text.style.TypefaceSpan;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* SpannedTest tests some features of Spanned
*/
-public class SpannedTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SpannedTest {
private int mExpect;
- @SmallTest
- public void testSpannableString() throws Exception {
+ @Test
+ public void testSpannableString() {
checkPriority(new SpannableString("the quick brown fox"));
}
- @SmallTest
- public void testSpannableStringBuilder() throws Exception {
+ @Test
+ public void testSpannableStringBuilder() {
checkPriority2(new SpannableStringBuilder("the quick brown fox"));
}
- @SmallTest
- public void testAppend() throws Exception {
+ @Test
+ public void testAppend() {
Object o = new Object();
SpannableString ss = new SpannableString("Test");
ss.setSpan(o, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -61,7 +67,7 @@
assertEquals(1, ssb.getSpans(4, 8, Object.class).length);
}
- @SmallTest
+ @Test
public void testWrapParcel() {
SpannableString s = new SpannableString("Hello there world");
CharacterStyle mark = new StyleSpan(Typeface.BOLD);
@@ -129,16 +135,16 @@
mExpect = 0;
- s.setSpan(new Watcher(2), 0, s.length(),
+ s.setSpan(new Watcher(2), 0, s.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE |
(2 << Spannable.SPAN_PRIORITY_SHIFT));
- s.setSpan(new Watcher(4), 0, s.length(),
+ s.setSpan(new Watcher(4), 0, s.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE |
(4 << Spannable.SPAN_PRIORITY_SHIFT));
- s.setSpan(new Watcher(1), 0, s.length(),
+ s.setSpan(new Watcher(1), 0, s.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE |
(1 << Spannable.SPAN_PRIORITY_SHIFT));
- s.setSpan(new Watcher(3), 0, s.length(),
+ s.setSpan(new Watcher(3), 0, s.length(),
Spannable.SPAN_INCLUSIVE_INCLUSIVE |
(3 << Spannable.SPAN_PRIORITY_SHIFT));
@@ -162,10 +168,13 @@
mSequence = sequence;
}
- public void onSpanChanged(Spannable b, Object o, int s, int e,
- int st, int en) { }
+ @Override
+ public void onSpanChanged(Spannable b, Object o, int s, int e, int st, int en) { }
+
+ @Override
public void onSpanRemoved(Spannable b, Object o, int s, int e) { }
+ @Override
public void onSpanAdded(Spannable b, Object o, int s, int e) {
if (mExpect != 0) {
assertEquals(mSequence, mExpect);
@@ -173,16 +182,18 @@
}
}
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) { }
- public void onTextChanged(CharSequence s, int start, int before,
- int count) {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mExpect != 0) {
assertEquals(mSequence, mExpect);
mExpect = mSequence - 1;
}
}
+ @Override
public void afterTextChanged(Editable s) { }
}
}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
index a9865f8..d16cce8 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
@@ -16,15 +16,21 @@
package android.text;
+import static org.junit.Assert.assertEquals;
+
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Quick check of native bidi implementation.
*/
-public class StaticLayoutBidiTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutBidiTest {
public static final int REQ_DL = 2; // Layout.DIR_REQUEST_DEFAULT_LTR;
public static final int REQ_DR = -2; // Layout.DIR_REQUEST_DEFAULT_RTL;
@@ -39,47 +45,47 @@
public static final String GIMEL = "\u05d2";
public static final String DALET = "\u05d3";
- @SmallTest
+ @Test
public void testAllLtr() {
expectNativeBidi(REQ_DL, "a test", "000000", L);
}
- @SmallTest
+ @Test
public void testLtrRtl() {
expectNativeBidi(REQ_DL, "abc " + ALEF + BET + GIMEL, "0000111", L);
}
- @SmallTest
+ @Test
public void testAllRtl() {
expectNativeBidi(REQ_DL, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", R);
}
- @SmallTest
+ @Test
public void testRtlLtr() {
expectNativeBidi(REQ_DL, ALEF + BET + GIMEL + " abc", "1111222", R);
}
- @SmallTest
+ @Test
public void testRAllLtr() {
expectNativeBidi(REQ_R, "a test", "222222", R);
}
- @SmallTest
+ @Test
public void testRLtrRtl() {
expectNativeBidi(REQ_R, "abc " + ALEF + BET + GIMEL, "2221111", R);
}
- @SmallTest
+ @Test
public void testLAllRtl() {
expectNativeBidi(REQ_L, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", L);
}
- @SmallTest
+ @Test
public void testLRtlLtr() {
expectNativeBidi(REQ_DL, ALEF + BET + GIMEL + " abc", "1111222", R);
}
- @SmallTest
+ @Test
public void testNativeBidi() {
expectNativeBidi(REQ_L, ALEF + BET + GIMEL + " abc", "1110000", L);
}
diff --git a/core/tests/coretests/src/android/text/StaticLayoutDirectionsTest.java b/core/tests/coretests/src/android/text/StaticLayoutDirectionsTest.java
index 2300c63..e0b4776 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutDirectionsTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutDirectionsTest.java
@@ -16,16 +16,21 @@
package android.text;
+import static org.junit.Assert.fail;
+
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.Layout.Directions;
import android.text.StaticLayoutTest.LayoutBuilder;
-import junit.framework.TestCase;
-
import java.util.Arrays;
import java.util.Formatter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class StaticLayoutDirectionsTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutDirectionsTest {
private static final char ALEF = '\u05d0';
private static Directions dirs(int ... dirs) {
@@ -107,7 +112,7 @@
return new String(chars, 0, chars.length);
}
- @SmallTest
+ @Test
public void testDirections() {
StringBuilder buf = new StringBuilder("\n");
Formatter f = new Formatter(buf);
@@ -122,7 +127,7 @@
}
}
- @SmallTest
+ @Test
public void testTrailingWhitespace() {
LayoutBuilder b = StaticLayoutTest.builder();
b.setText(pseudoBidiToReal("Ab c"));
@@ -137,7 +142,7 @@
expectDirections("split line", expected, result);
}
- @SmallTest
+ @Test
public void testNextToRightOf() {
LayoutBuilder b = StaticLayoutTest.builder();
b.setText(pseudoBidiToReal("aA1B2"));
@@ -161,7 +166,7 @@
}
}
- @SmallTest
+ @Test
public void testNextToLeftOf() {
LayoutBuilder b = StaticLayoutTest.builder();
b.setText(pseudoBidiToReal("aA1B2"));
@@ -178,40 +183,6 @@
}
}
- // utility, not really a test
- /*
- public void testMeasureText1() {
- LayoutBuilder b = StaticLayoutTest.builder();
- String text = "ABC"; // "abAB"
- b.setText(pseudoBidiToReal(text));
- Layout l = b.build();
- Directions directions = l.getLineDirections(0);
-
- TextPaint workPaint = new TextPaint();
-
- int dir = -1; // LEFT_TO_RIGHT
- boolean trailing = true;
- boolean alt = true;
- do {
- dir = -dir;
- do {
- trailing = !trailing;
- for (int offset = 0, end = b.text.length(); offset <= end; ++offset) {
- float width = Layout.measureText(b.paint,
- workPaint,
- b.text,
- 0, offset, end,
- dir, directions,
- trailing, false,
- null);
- Log.i("BIDI", "dir: " + dir + " trail: " + trailing +
- " offset: " + offset + " width: " + width);
- }
- } while (!trailing);
- } while (dir > 0);
- }
- */
-
// utility for displaying arrays in hex
private static String hexArray(int[] array) {
StringBuilder sb = new StringBuilder();
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTest.java b/core/tests/coretests/src/android/text/StaticLayoutTest.java
index 436840c..b7ca219 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTest.java
@@ -16,25 +16,30 @@
package android.text;
+import static android.text.Layout.Alignment.ALIGN_NORMAL;
+import static org.junit.Assert.assertEquals;
+
import android.graphics.Paint.FontMetricsInt;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.Layout.Alignment;
import android.text.method.EditorState;
import android.util.Log;
-import junit.framework.TestCase;
-
-import static android.text.Layout.Alignment.ALIGN_NORMAL;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests StaticLayout vertical metrics behavior.
*/
-public class StaticLayoutTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutTest {
/**
* Basic test showing expected behavior and relationship between font
* metrics and line metrics.
*/
- @SmallTest
+ @Test
public void testGetters1() {
LayoutBuilder b = builder();
FontMetricsInt fmi = b.paint.getFontMetricsInt();
@@ -60,7 +65,7 @@
* Basic test showing effect of includePad = true with 1 line.
* Top and bottom padding are affected, as is the line descent and height.
*/
- @SmallTest
+ @Test
public void testGetters2() {
LayoutBuilder b = builder()
.setIncludePad(true);
@@ -75,7 +80,7 @@
* Basic test showing effect of includePad = true wrapping to 2 lines.
* Ascent of top line and descent of bottom line are affected.
*/
- @SmallTest
+ @Test
public void testGetters3() {
LayoutBuilder b = builder()
.setIncludePad(true)
@@ -92,7 +97,7 @@
* Basic test showing effect of includePad = true wrapping to 3 lines.
* First line ascent is top, bottom line descent is bottom.
*/
- @SmallTest
+ @Test
public void testGetters4() {
LayoutBuilder b = builder()
.setText("This is a longer test")
@@ -112,7 +117,7 @@
* large text. See effect of leading. Currently, we don't expect there to
* even be non-zero leading.
*/
- @SmallTest
+ @Test
public void testGetters5() {
LayoutBuilder b = builder()
.setText("This is a longer test")
@@ -139,7 +144,7 @@
* Basic test showing effect of includePad = true, spacingAdd = 2, wrapping
* to 3 lines.
*/
- @SmallTest
+ @Test
public void testGetters6() {
int spacingAdd = 2; // int so expressions return int
LayoutBuilder b = builder()
@@ -160,7 +165,7 @@
* Basic test showing effect of includePad = true, spacingAdd = 2,
* spacingMult = 1.5, wrapping to 3 lines.
*/
- @SmallTest
+ @Test
public void testGetters7() {
LayoutBuilder b = builder()
.setText("This is a longer test")
@@ -182,7 +187,7 @@
* Basic test showing effect of includePad = true, spacingAdd = 0,
* spacingMult = 0.8 when wrapping to 3 lines.
*/
- @SmallTest
+ @Test
public void testGetters8() {
LayoutBuilder b = builder()
.setText("This is a longer test")
@@ -336,6 +341,7 @@
* Tests for keycap, variation selectors, flags are in CTS.
* See {@link android.text.cts.StaticLayoutTest}.
*/
+ @Test
public void testEmojiOffset() {
EditorState state = new EditorState();
TextPaint paint = new TextPaint();
diff --git a/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java b/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java
index 7e07acb..f6888e3 100644
--- a/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java
+++ b/core/tests/coretests/src/android/text/StaticLayoutTextMeasuringTest.java
@@ -16,15 +16,23 @@
package android.text;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.Layout.Alignment;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Tests for text measuring methods of StaticLayout.
*/
-public class StaticLayoutTextMeasuringTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class StaticLayoutTextMeasuringTest {
private static final float SPACE_MULTI = 1.0f;
private static final float SPACE_ADD = 0.0f;
private static final int DEFAULT_OUTER_WIDTH = 150;
@@ -32,37 +40,36 @@
private TextPaint mDefaultPaint;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setup() {
if (mDefaultPaint == null) {
mDefaultPaint = new TextPaint();
}
}
- @SmallTest
+ @Test
public void testGetPrimaryHorizontal_zwnbsp() {
// a, ZERO WIDTH NO-BREAK SPACE
String testString = "a\uFEFF";
StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
- assertEquals(0.0f, layout.getPrimaryHorizontal(0));
- assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1));
+ assertEquals(0.0f, layout.getPrimaryHorizontal(0), 0f);
+ assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1), 0f);
}
- @SmallTest
+ @Test
public void testGetPrimaryHorizontal_devanagari() {
// DEVANAGARI LETTER KA, DEVANAGARI VOWEL SIGN AA
String testString = "\u0915\u093E";
StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
- assertEquals(0.0f, layout.getPrimaryHorizontal(0));
- assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1));
+ assertEquals(0.0f, layout.getPrimaryHorizontal(0), 0f);
+ assertEquals(layout.getPrimaryHorizontal(2), layout.getPrimaryHorizontal(1), 0f);
}
- @SmallTest
+ @Test
public void testGetPrimaryHorizontal_flagEmoji() {
// REGIONAL INDICATOR SYMBOL LETTER U, REGIONAL INDICATOR SYMBOL LETTER S, REGIONAL
// INDICATOR SYMBOL LETTER Z
@@ -71,12 +78,12 @@
StaticLayout layout = new StaticLayout(testString, mDefaultPaint,
DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
- assertEquals(0.0f, layout.getPrimaryHorizontal(0));
- assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(1));
- assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(2));
- assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(3));
+ assertEquals(0.0f, layout.getPrimaryHorizontal(0), 0f);
+ assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(1), 0f);
+ assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(2), 0f);
+ assertEquals(layout.getPrimaryHorizontal(4), layout.getPrimaryHorizontal(3), 0f);
assertTrue(layout.getPrimaryHorizontal(6) > layout.getPrimaryHorizontal(4));
- assertEquals(layout.getPrimaryHorizontal(6), layout.getPrimaryHorizontal(5));
+ assertEquals(layout.getPrimaryHorizontal(6), layout.getPrimaryHorizontal(5), 0f);
}
}
diff --git a/core/tests/coretests/src/android/text/TextLayoutTest.java b/core/tests/coretests/src/android/text/TextLayoutTest.java
index f3a28b4..8963189 100644
--- a/core/tests/coretests/src/android/text/TextLayoutTest.java
+++ b/core/tests/coretests/src/android/text/TextLayoutTest.java
@@ -17,31 +17,34 @@
package android.text;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
-import junit.framework.TestCase;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextLayoutTest {
+ private String mString;
+ private TextPaint mPaint;
-public class TextLayoutTest extends TestCase {
-
- protected String mString;
- protected TextPaint mPaint;
-
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setup() {
mString = "The quick brown fox";
mPaint = new TextPaint();
}
- @SmallTest
- public void testStaticLayout() throws Exception {
- Layout l = new StaticLayout(mString, mPaint, 200,
+ @Test
+ public void testStaticLayout() {
+ new StaticLayout(mString, mPaint, 200,
Layout.Alignment.ALIGN_NORMAL, 1, 0,
true);
}
- @SmallTest
- public void testDynamicLayoutTest() throws Exception {
- Layout l = new DynamicLayout(mString, mPaint, 200,
+ @Test
+ public void testDynamicLayoutTest() {
+ new DynamicLayout(mString, mPaint, 200,
Layout.Alignment.ALIGN_NORMAL, 1, 0,
true);
}
diff --git a/core/tests/coretests/src/android/text/TextUtilsTest.java b/core/tests/coretests/src/android/text/TextUtilsTest.java
index 26aabdb..312c4fb 100644
--- a/core/tests/coretests/src/android/text/TextUtilsTest.java
+++ b/core/tests/coretests/src/android/text/TextUtilsTest.java
@@ -16,6 +16,14 @@
package android.text;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.support.test.runner.AndroidJUnit4;
import com.google.android.collect.Lists;
import android.os.Parcel;
@@ -27,19 +35,21 @@
import android.text.util.Rfc822Tokenizer;
import android.view.View;
-import junit.framework.TestCase;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* TextUtilsTest tests {@link TextUtils}.
*/
-public class TextUtilsTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TextUtilsTest {
- @SmallTest
- public void testBasic() throws Exception {
+ @Test
+ public void testBasic() {
assertEquals("", TextUtils.concat());
assertEquals("foo", TextUtils.concat("foo"));
assertEquals("foobar", TextUtils.concat("foo", "bar"));
@@ -71,8 +81,8 @@
assertTrue(TextUtils.concat(foo, bar) instanceof SpannedString);
}
- @SmallTest
- public void testTemplateString() throws Exception {
+ @Test
+ public void testTemplateString() {
CharSequence result;
result = TextUtils.expandTemplate("This is a ^1 of the ^2 broadcast ^3.",
@@ -136,7 +146,7 @@
/** Fail unless text+spans contains a span 'spanName' with the given start and end. */
private void checkContains(Spanned text, String[] spans, String spanName,
- int start, int end) throws Exception {
+ int start, int end) {
for (String i: spans) {
if (i.equals(spanName)) {
assertEquals(start, text.getSpanStart(i));
@@ -147,8 +157,8 @@
fail();
}
- @SmallTest
- public void testTemplateSpan() throws Exception {
+ @Test
+ public void testTemplateSpan() {
SpannableString template;
Spanned result;
String[] spans;
@@ -186,27 +196,27 @@
checkContains(result, spans, "during+after", 1, 2);
}
- @SmallTest
+ @Test
public void testStringSplitterSimple() {
stringSplitterTestHelper("a,b,cde", new String[] {"a", "b", "cde"});
}
- @SmallTest
+ @Test
public void testStringSplitterEmpty() {
stringSplitterTestHelper("", new String[] {});
}
- @SmallTest
+ @Test
public void testStringSplitterWithLeadingEmptyString() {
stringSplitterTestHelper(",a,b,cde", new String[] {"", "a", "b", "cde"});
}
- @SmallTest
+ @Test
public void testStringSplitterWithInternalEmptyString() {
stringSplitterTestHelper("a,b,,cde", new String[] {"a", "b", "", "cde"});
}
- @SmallTest
+ @Test
public void testStringSplitterWithTrailingEmptyString() {
// A single trailing emtpy string should be ignored.
stringSplitterTestHelper("a,b,cde,", new String[] {"a", "b", "cde"});
@@ -222,7 +232,7 @@
MoreAsserts.assertEquals(expectedStrings, strings.toArray(new String[]{}));
}
- @SmallTest
+ @Test
public void testTrim() {
String[] strings = { "abc", " abc", " abc", "abc ", "abc ",
" abc ", " abc ", "\nabc\n", "\nabc", "abc\n" };
@@ -232,7 +242,7 @@
}
}
- @SmallTest
+ @Test
public void testRfc822TokenizerFullAddress() {
Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("Foo Bar (something) <foo@google.com>");
assertNotNull(tokens);
@@ -242,7 +252,7 @@
assertEquals("something",tokens[0].getComment());
}
- @SmallTest
+ @Test
public void testRfc822TokenizeItemWithError() {
Rfc822Token[] tokens = Rfc822Tokenizer.tokenize("\"Foo Bar\\");
assertNotNull(tokens);
@@ -250,7 +260,7 @@
assertEquals("Foo Bar", tokens[0].getAddress());
}
- @SmallTest
+ @Test
public void testRfc822FindToken() {
Rfc822Tokenizer tokenizer = new Rfc822Tokenizer();
// 0 1 2 3 4
@@ -262,12 +272,13 @@
assertEquals(46, tokenizer.findTokenEnd(address, 25));
}
- @SmallTest
+ @Test
public void testRfc822FindTokenWithError() {
assertEquals(9, new Rfc822Tokenizer().findTokenEnd("\"Foo Bar\\", 0));
}
@LargeTest
+ @Test
public void testEllipsize() {
CharSequence s1 = "The quick brown fox jumps over \u00FEhe lazy dog.";
CharSequence s2 = new Wrapper(s1);
@@ -327,7 +338,7 @@
}
}
- @SmallTest
+ @Test
public void testDelimitedStringContains() {
assertFalse(TextUtils.delimitedStringContains("", ',', null));
assertFalse(TextUtils.delimitedStringContains(null, ',', ""));
@@ -347,7 +358,7 @@
assertFalse(TextUtils.delimitedStringContains("network,mock,gpsx", ',', "gps"));
}
- @SmallTest
+ @Test
public void testCharSequenceCreator() {
Parcel p = Parcel.obtain();
TextUtils.writeToParcel(null, p, 0);
@@ -360,7 +371,7 @@
assertEquals("conversion to/from parcel failed", "test", text);
}
- @SmallTest
+ @Test
public void testCharSequenceCreatorNull() {
Parcel p;
CharSequence text;
@@ -371,7 +382,7 @@
assertNull("null CharSequence should generate null from parcel", text);
}
- @SmallTest
+ @Test
public void testCharSequenceCreatorSpannable() {
Parcel p;
CharSequence text;
@@ -382,7 +393,7 @@
assertEquals("conversion to/from parcel failed", "test", text.toString());
}
- @SmallTest
+ @Test
public void testCharSequenceCreatorString() {
Parcel p;
CharSequence text;
@@ -404,10 +415,12 @@
mString = s;
}
+ @Override
public int length() {
return mString.length();
}
+ @Override
public char charAt(int off) {
return mString.charAt(off);
}
@@ -417,12 +430,13 @@
return mString.toString();
}
+ @Override
public CharSequence subSequence(int start, int end) {
return new Wrapper(mString.subSequence(start, end));
}
}
- @LargeTest
+ @Test
public void testRemoveEmptySpans() {
MockSpanned spanned = new MockSpanned();
@@ -484,14 +498,17 @@
}
}
+ @Override
public char charAt(int arg0) {
return 0;
}
+ @Override
public int length() {
return 0;
}
+ @Override
public CharSequence subSequence(int arg0, int arg1) {
return null;
}
@@ -522,7 +539,7 @@
}
}
- @SmallTest
+ @Test
public void testGetLayoutDirectionFromLocale() {
assertEquals(View.LAYOUT_DIRECTION_LTR, TextUtils.getLayoutDirectionFromLocale(null));
assertEquals(View.LAYOUT_DIRECTION_LTR,
diff --git a/core/tests/coretests/src/android/text/VariationParserTest.java b/core/tests/coretests/src/android/text/VariationParserTest.java
index b0f55d6..ec2c96c 100644
--- a/core/tests/coretests/src/android/text/VariationParserTest.java
+++ b/core/tests/coretests/src/android/text/VariationParserTest.java
@@ -16,17 +16,24 @@
package android.text;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
import android.graphics.fonts.FontVariationAxis;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class VariationParserTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VariationParserTest {
private static final String[] INVALID_STYLE_VALUES = {
"", "x", "\t", "\n"
};
- @SmallTest
+ @Test
public void testFromFontVariationSetting_InvalidStyleValue() {
// Test with invalid styleValue
for (String invalidStyle : INVALID_STYLE_VALUES) {
@@ -39,7 +46,8 @@
}
for (String invalidStyle : INVALID_STYLE_VALUES) {
try {
- FontVariationAxis.fromFontVariationSettings("'wght' 1, 'wdth' " + invalidStyle);
+ FontVariationAxis.fromFontVariationSettings("'wght' 1, 'wdth' "
+ + invalidStyle);
fail();
} catch (IllegalArgumentException e) {
// pass
@@ -47,10 +55,13 @@
}
}
- @SmallTest
+ @Test
public void testOpenTypeTagValue() {
- assertEquals(0x77647468, (new FontVariationAxis("wdth", 0).getOpenTypeTagValue()));
- assertEquals(0x41582020, (new FontVariationAxis("AX ", 0).getOpenTypeTagValue()));
- assertEquals(0x20202020, (new FontVariationAxis(" ", 0).getOpenTypeTagValue()));
+ assertEquals(0x77647468,
+ new FontVariationAxis("wdth", 0).getOpenTypeTagValue());
+ assertEquals(0x41582020,
+ new FontVariationAxis("AX ", 0).getOpenTypeTagValue());
+ assertEquals(0x20202020,
+ new FontVariationAxis(" ", 0).getOpenTypeTagValue());
}
}
diff --git a/core/tests/coretests/src/android/text/format/DateFormatTest.java b/core/tests/coretests/src/android/text/format/DateFormatTest.java
index 93bc911..15c86f0 100644
--- a/core/tests/coretests/src/android/text/format/DateFormatTest.java
+++ b/core/tests/coretests/src/android/text/format/DateFormatTest.java
@@ -16,14 +16,21 @@
package android.text.format;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class DateFormatTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DateFormatTest {
- @SmallTest
- public void testHasDesignator() throws Exception {
+ @Test
+ public void testHasDesignator() {
assertTrue(DateFormat.hasDesignator("hh:mm:ss", DateFormat.MINUTE));
assertTrue(DateFormat.hasDesignator("myyyy", DateFormat.MINUTE));
assertTrue(DateFormat.hasDesignator("mmm", DateFormat.MINUTE));
@@ -31,8 +38,8 @@
assertFalse(DateFormat.hasDesignator("hh:MM:ss", DateFormat.MINUTE));
}
- @SmallTest
- public void testHasDesignatorEscaped() throws Exception {
+ @Test
+ public void testHasDesignatorEscaped() {
assertTrue(DateFormat.hasDesignator("hh:mm 'LOL'", DateFormat.MINUTE));
assertFalse(DateFormat.hasDesignator("hh:mm 'yyyy'", DateFormat.YEAR));
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index de43fc6..9271cb4 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -16,45 +16,40 @@
package android.text.format;
+import static org.junit.Assert.assertEquals;
+
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.LocaleList;
import android.support.test.filters.SmallTest;
-
-import junit.framework.TestCase;
+import android.support.test.runner.AndroidJUnit4;
import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class DateUtilsTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DateUtilsTest {
private static final LocaleList LOCALE_LIST_US = new LocaleList(Locale.US);
private LocaleList mOriginalLocales;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setup() {
mOriginalLocales = Resources.getSystem().getConfiguration().getLocales();
setLocales(LOCALE_LIST_US);
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void teardown() {
setLocales(mOriginalLocales);
- super.tearDown();
}
- private void setLocales(LocaleList locales) {
- final Resources systemResources = Resources.getSystem();
- final Configuration config = new Configuration(systemResources.getConfiguration());
- config.setLocales(locales);
- // This is not very safe to call, but since DateUtils.formatDuration() is a static method
- // (it gets its format strings from the system resources), we can't pass a modified Context
- // to it.
- systemResources.updateConfiguration(config, null);
- }
-
- @SmallTest
- public void test_formatDuration_seconds() throws Exception {
+ @Test
+ public void test_formatDuration_seconds() {
assertEquals("0 seconds", DateUtils.formatDuration(0));
assertEquals("0 seconds", DateUtils.formatDuration(1));
assertEquals("0 seconds", DateUtils.formatDuration(499));
@@ -75,8 +70,8 @@
assertEquals("2s", DateUtils.formatDuration(1500, DateUtils.LENGTH_SHORTEST));
}
- @SmallTest
- public void test_formatDuration_Minutes() throws Exception {
+ @Test
+ public void test_formatDuration_Minutes() {
assertEquals("59 seconds", DateUtils.formatDuration(59000));
assertEquals("60 seconds", DateUtils.formatDuration(59500));
assertEquals("1 minute", DateUtils.formatDuration(60000));
@@ -92,8 +87,8 @@
assertEquals("2m", DateUtils.formatDuration(120000, DateUtils.LENGTH_SHORTEST));
}
- @SmallTest
- public void test_formatDuration_Hours() throws Exception {
+ @Test
+ public void test_formatDuration_Hours() {
assertEquals("59 minutes", DateUtils.formatDuration(3540000));
assertEquals("1 hour", DateUtils.formatDuration(3600000));
assertEquals("48 hours", DateUtils.formatDuration(172800000));
@@ -107,4 +102,15 @@
assertEquals("1h", DateUtils.formatDuration(3600000, DateUtils.LENGTH_SHORTEST));
assertEquals("48h", DateUtils.formatDuration(172800000, DateUtils.LENGTH_SHORTEST));
}
+
+ private void setLocales(LocaleList locales) {
+ final Resources systemResources = Resources.getSystem();
+ final Configuration config = new Configuration(systemResources.getConfiguration());
+ config.setLocales(locales);
+ // This is not very safe to call, but since DateUtils.formatDuration() is a static method
+ // (it gets its format strings from the system resources), we can't pass a modified Context
+ // to it.
+ systemResources.updateConfiguration(config, null);
+ }
+
}
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index 2293094..a4ce911 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -16,43 +16,43 @@
package android.text.format;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
import android.text.format.Formatter.BytesResult;
import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class FormatterTest extends AndroidTestCase {
-
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FormatterTest {
private Locale mOriginalLocale;
+ private Context mContext;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mOriginalLocale = mContext.getResources().getConfiguration().locale;
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getContext();
+ mOriginalLocale = mContext.getResources()
+ .getConfiguration().locale;
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() {
if (mOriginalLocale != null) {
setLocale(mOriginalLocale);
}
- super.tearDown();
}
- private void setLocale(Locale locale) {
- Resources res = getContext().getResources();
- Configuration config = res.getConfiguration();
- config.locale = locale;
- res.updateConfiguration(config, res.getDisplayMetrics());
-
- Locale.setDefault(locale);
- }
-
- @SmallTest
+ @Test
public void testFormatBytes() {
setLocale(Locale.ENGLISH);
@@ -90,7 +90,7 @@
checkFormatBytes(-914, false, "-0.91", -910);
// Missing FLAG_CALCULATE_ROUNDED case.
- BytesResult r = Formatter.formatBytes(getContext().getResources(), 1, 0);
+ BytesResult r = Formatter.formatBytes(mContext.getResources(), 1, 0);
assertEquals("1", r.value);
assertEquals(0, r.roundedBytes); // Didn't pass FLAG_CALCULATE_ROUNDED
@@ -101,9 +101,18 @@
private void checkFormatBytes(long bytes, boolean useShort,
String expectedString, long expectedRounded) {
- BytesResult r = Formatter.formatBytes(getContext().getResources(), bytes,
+ BytesResult r = Formatter.formatBytes(mContext.getResources(), bytes,
Formatter.FLAG_CALCULATE_ROUNDED | (useShort ? Formatter.FLAG_SHORTER : 0));
assertEquals(expectedString, r.value);
assertEquals(expectedRounded, r.roundedBytes);
}
+
+ private void setLocale(Locale locale) {
+ Resources res = mContext.getResources();
+ Configuration config = res.getConfiguration();
+ config.locale = locale;
+ res.updateConfiguration(config, res.getDisplayMetrics());
+
+ Locale.setDefault(locale);
+ }
}
diff --git a/core/tests/coretests/src/android/text/format/TimeTest.java b/core/tests/coretests/src/android/text/format/TimeTest.java
index f6dd0d4..8983d15 100644
--- a/core/tests/coretests/src/android/text/format/TimeTest.java
+++ b/core/tests/coretests/src/android/text/format/TimeTest.java
@@ -16,17 +16,25 @@
package android.text.format;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import android.support.test.filters.SmallTest;
import android.support.test.filters.Suppress;
+import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import android.util.TimeFormatException;
-import junit.framework.TestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
-public class TimeTest extends TestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TimeTest {
- @SmallTest
- public void testNormalize0() throws Exception {
+ @Test
+ public void testNormalize0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.parse("20060432T010203");
t.normalize(false /* use isDst */);
@@ -174,8 +182,8 @@
new DateTest(2007, 10, 5, 2, 0, 60, 2007, 10, 5, 3, 0),
};
- @SmallTest
- public void testNormalize1() throws Exception {
+ @Test
+ public void testNormalize1() {
Time local = new Time("America/Los_Angeles");
int len = dayTests.length;
@@ -265,70 +273,70 @@
}
}
- @SmallTest
- public void testSwitchTimezone0() throws Exception {
+ @Test
+ public void testSwitchTimezone0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.parse("20061005T120000");
t.switchTimezone("America/Los_Angeles");
// System.out.println("got: " + t);
}
- @SmallTest
- public void testCtor0() throws Exception {
+ @Test
+ public void testCtor0() {
Time t = new Time(Time.TIMEZONE_UTC);
assertEquals(Time.TIMEZONE_UTC, t.timezone);
}
- @SmallTest
- public void testGetActualMaximum0() throws Exception {
+ @Test
+ public void testGetActualMaximum0() {
Time t = new Time(Time.TIMEZONE_UTC);
- int r = t.getActualMaximum(Time.SECOND);
+ t.getActualMaximum(Time.SECOND);
// System.out.println("r=" + r);
}
- @SmallTest
- public void testClear0() throws Exception {
+ @Test
+ public void testClear0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.clear(Time.TIMEZONE_UTC);
}
- @SmallTest
- public void testCompare0() throws Exception {
+ @Test
+ public void testCompare0() {
Time a = new Time(Time.TIMEZONE_UTC);
Time b = new Time("America/Los_Angeles");
int r = Time.compare(a, b);
// System.out.println("r=" + r);
}
- @SmallTest
- public void testFormat0() throws Exception {
+ @Test
+ public void testFormat0() {
Time t = new Time(Time.TIMEZONE_UTC);
String r = t.format("%Y%m%dT%H%M%S");
// System.out.println("r='" + r + "'");
}
- @SmallTest
- public void testToString0() throws Exception {
+ @Test
+ public void testToString0() {
Time t = new Time(Time.TIMEZONE_UTC);
String r = t.toString();
// System.out.println("r='" + r + "'");
}
- @SmallTest
- public void testGetCurrentTimezone0() throws Exception {
+ @Test
+ public void testGetCurrentTimezone0() {
String r = Time.getCurrentTimezone();
// System.out.println("r='" + r + "'");
}
- @SmallTest
- public void testSetToNow0() throws Exception {
+ @Test
+ public void testSetToNow0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.setToNow();
// System.out.println("t=" + t);
}
- @SmallTest
- public void testMillis0() throws Exception {
+ @Test
+ public void testMillis0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.set(0, 0, 0, 1, 1, 2006);
long r = t.toMillis(true /* ignore isDst */);
@@ -338,23 +346,23 @@
// System.out.println("r=" + r);
}
- @SmallTest
- public void testMillis1() throws Exception {
+ @Test
+ public void testMillis1() {
Time t = new Time(Time.TIMEZONE_UTC);
t.set(1, 0, 0, 1, 0, 1970);
long r = t.toMillis(true /* ignore isDst */);
// System.out.println("r=" + r);
}
- @SmallTest
- public void testParse0() throws Exception {
+ @Test
+ public void testParse0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.parse("12345678T901234");
// System.out.println("t=" + t);
}
- @SmallTest
- public void testParse33390() throws Exception {
+ @Test
+ public void testParse33390() {
Time t = new Time(Time.TIMEZONE_UTC);
t.parse3339("1980-05-23");
@@ -435,8 +443,8 @@
}
}
- @SmallTest
- public void testSet0() throws Exception {
+ @Test
+ public void testSet0() {
Time t = new Time(Time.TIMEZONE_UTC);
t.set(1000L);
// System.out.println("t.year=" + t.year);
@@ -449,13 +457,13 @@
// System.out.println("t=" + t);
}
- @SmallTest
- public void testSet1() throws Exception {
+ @Test
+ public void testSet1() {
Time t = new Time(Time.TIMEZONE_UTC);
t.set(1, 2, 3, 4, 5, 6);
// System.out.println("t=" + t);
}
-
+
// Timezones that cover the world. Some GMT offsets occur more than
// once in case some cities decide to change their GMT offset.
private static final String[] mTimeZones = {
@@ -518,9 +526,9 @@
"Pacific/Honolulu",
"Pacific/Midway",
};
-
+
@Suppress
- public void disableTestGetJulianDay() throws Exception {
+ public void disableTestGetJulianDay() {
Time time = new Time();
// For each day of the year, and for each timezone, get the Julian
@@ -560,11 +568,11 @@
}
}
}
-
+
@Suppress
- public void disableTestSetJulianDay() throws Exception {
+ public void disableTestSetJulianDay() {
Time time = new Time();
-
+
// For each day of the year in 2008, and for each timezone,
// test that we can set the Julian day correctly.
for (int monthDay = 1; monthDay <= 366; monthDay++) {
diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java
index 864b48a..6e41831 100644
--- a/core/tests/coretests/src/android/text/method/BackspaceTest.java
+++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java
@@ -17,9 +17,13 @@
package android.text.method;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.InputType;
import android.view.KeyEvent;
import android.widget.TextView.BufferType;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* Test backspace key handling of {@link android.text.method.BaseKeyListener}.
@@ -27,6 +31,8 @@
* Only contains edge cases. For normal cases, see {@see android.text.method.cts.BackspaceTest}.
* TODO: introduce test cases for surrogate pairs and replacement span.
*/
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class BackspaceTest extends KeyListenerTestCase {
private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
public int getInputType() {
@@ -49,7 +55,7 @@
state.mSelectionEnd = mTextView.getSelectionEnd();
}
- @SmallTest
+ @Test
public void testCombiningEnclosingKeycaps() {
EditorState state = new EditorState();
@@ -77,7 +83,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testVariationSelector() {
EditorState state = new EditorState();
@@ -141,7 +147,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testEmojiZWJSequence() {
EditorState state = new EditorState();
@@ -221,7 +227,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testFlags() {
EditorState state = new EditorState();
@@ -283,7 +289,7 @@
state.assertEquals("'a' |");
}
- @SmallTest
+ @Test
public void testEmojiModifier() {
EditorState state = new EditorState();
@@ -312,7 +318,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testMixedEdgeCases() {
EditorState state = new EditorState();
diff --git a/core/tests/coretests/src/android/text/method/EditorState.java b/core/tests/coretests/src/android/text/method/EditorState.java
index bbbbd6d..12bb8c8 100644
--- a/core/tests/coretests/src/android/text/method/EditorState.java
+++ b/core/tests/coretests/src/android/text/method/EditorState.java
@@ -16,6 +16,11 @@
package android.text.method;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Editable;
@@ -59,19 +64,6 @@
public EditorState() {
}
- /**
- * A mocked {@link android.text.style.ReplacementSpan} for testing purpose.
- */
- private static class MockReplacementSpan extends ReplacementSpan {
- public int getSize(Paint paint, CharSequence text, int start, int end,
- Paint.FontMetricsInt fm) {
- return 0;
- }
- public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top,
- int y, int bottom, Paint paint) {
- }
- }
-
// Returns true if the code point is ASCII and graph.
private boolean isGraphicAscii(int codePoint) {
return 0x20 < codePoint && codePoint < 0x7F;
@@ -169,7 +161,14 @@
throw new IllegalArgumentException(
"ReplacementSpan start position appears after end position.");
}
- spannable.setSpan(new MockReplacementSpan(), replacementSpanStart, replacementSpanEnd,
+
+ ReplacementSpan mockReplacementSpan = mock(ReplacementSpan.class);
+ when(mockReplacementSpan.getSize(any(), any(), any(), any(), any()))
+ .thenReturn(0);
+ doNothing().when(mockReplacementSpan)
+ .draw(any(), any(), any(), any(), any(), any(), any(), any(), any());
+
+ spannable.setSpan(mockReplacementSpan, replacementSpanStart, replacementSpanEnd,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mText = Editable.Factory.getInstance().newEditable(spannable);
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index 839d380..6914e21 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -17,16 +17,23 @@
package android.text.method;
import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import android.text.InputType;
import android.view.KeyEvent;
import android.widget.TextView.BufferType;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
/**
* Test forward delete key handling of {@link android.text.method.BaseKeyListener}.
*
* Only contains edge cases. For normal cases, see {@see android.text.method.cts.ForwardDeleteTest}.
* TODO: introduce test cases for surrogate pairs and replacement span.
*/
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class ForwardDeleteTest extends KeyListenerTestCase {
private static final BaseKeyListener mKeyListener = new BaseKeyListener() {
public int getInputType() {
@@ -49,7 +56,7 @@
state.mSelectionEnd = mTextView.getSelectionEnd();
}
- @SmallTest
+ @Test
public void testCombiningEnclosingKeycaps() {
EditorState state = new EditorState();
@@ -69,7 +76,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testVariationSelector() {
EditorState state = new EditorState();
@@ -117,7 +124,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testEmojiZeroWidthJoinerSequence() {
EditorState state = new EditorState();
@@ -160,7 +167,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testFlags() {
EditorState state = new EditorState();
@@ -217,7 +224,7 @@
state.assertEquals("| 'b'");
}
- @SmallTest
+ @Test
public void testEmojiModifier() {
EditorState state = new EditorState();
@@ -246,7 +253,7 @@
state.assertEquals("|");
}
- @SmallTest
+ @Test
public void testMixedEdgeCases() {
EditorState state = new EditorState();
@@ -354,6 +361,8 @@
// ZERO WIDTH JOINER + regional indicator symbol
state.setByString("| U+1F469 U+200D U+1F1FA");
forwardDelete(state, 0);
+ state.assertEquals("| U+1F1FA");
+ forwardDelete(state, 0);
state.assertEquals("|");
// Regional indicator symbol + end with ZERO WIDTH JOINER
@@ -364,6 +373,8 @@
// Regional indicator symbol + ZERO WIDTH JOINER
state.setByString("| U+1F1FA U+200D U+1F469");
forwardDelete(state, 0);
+ state.assertEquals("| U+1F469");
+ forwardDelete(state, 0);
state.assertEquals("|");
// Start with ZERO WIDTH JOINER + emoji modifier
@@ -384,6 +395,8 @@
// Emoji modifier + ZERO WIDTH JOINER
state.setByString("| U+1F466 U+1F3FB U+200D U+1F469");
forwardDelete(state, 0);
+ state.assertEquals("| U+1F469");
+ forwardDelete(state, 0);
state.assertEquals("|");
// Regional indicator symbol + emoji modifier
diff --git a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
index f005d7b..99a0091 100644
--- a/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
+++ b/core/tests/coretests/src/android/text/method/KeyListenerTestCase.java
@@ -17,25 +17,19 @@
package android.text.method;
import android.app.Instrumentation;
-import android.test.InstrumentationTestCase;
+import android.support.test.InstrumentationRegistry;
import android.view.KeyEvent;
import android.widget.EditText;
-import com.android.frameworks.coretests.R;
-
-public abstract class KeyListenerTestCase extends InstrumentationTestCase {
-
+public abstract class KeyListenerTestCase {
protected Instrumentation mInstrumentation;
protected EditText mTextView;
public KeyListenerTestCase() {
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mInstrumentation = getInstrumentation();
+ protected void setup() {
+ mInstrumentation = InstrumentationRegistry.getInstrumentation();
mTextView = new EditText(mInstrumentation.getContext());
}
diff --git a/core/tests/coretests/src/android/text/method/WordIteratorTest.java b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
index 66cf65f..3499a74 100644
--- a/core/tests/coretests/src/android/text/method/WordIteratorTest.java
+++ b/core/tests/coretests/src/android/text/method/WordIteratorTest.java
@@ -16,16 +16,25 @@
package android.text.method;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+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.support.test.runner.AndroidJUnit4;
+import android.support.test.filters.SmallTest;
import java.text.BreakIterator;
import java.util.Locale;
+import org.junit.Test;
+import org.junit.runner.RunWith;
// TODO(Bug: 24062099): Add more tests for non-ascii text.
-public class WordIteratorTest extends AndroidTestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WordIteratorTest {
- @SmallTest
+ @Test
public void testSetCharSequence() {
final String text = "text";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -48,7 +57,7 @@
wordIterator.setCharSequence(text, text.length(), text.length());
}
- @SmallTest
+ @Test
public void testWindowWidth() {
final String text = "aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -65,7 +74,7 @@
assertEquals(BreakIterator.DONE, wordIterator.following(expectedWindowEnd));
}
- @SmallTest
+ @Test
public void testPreceding() {
final String text = "abc def-ghi. jkl";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -105,7 +114,7 @@
assertEquals(text.indexOf('j'), wordIterator.preceding(text.indexOf('l')));
}
- @SmallTest
+ @Test
public void testFollowing() {
final String text = "abc def-ghi. jkl";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -145,7 +154,7 @@
assertEquals(BreakIterator.DONE, wordIterator.following(text.length()));
}
- @SmallTest
+ @Test
public void testIsBoundary() {
final String text = "abc def-ghi. jkl";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -173,7 +182,7 @@
assertTrue(wordIterator.isBoundary(text.length()));
}
- @SmallTest
+ @Test
public void testNextBoundary() {
final String text = "abc def-ghi. jkl";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -220,7 +229,7 @@
assertEquals(BreakIterator.DONE, currentOffset);
}
- @SmallTest
+ @Test
public void testPrevBoundary() {
final String text = "abc def-ghi. jkl";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -266,7 +275,7 @@
assertEquals(BreakIterator.DONE, currentOffset);
}
- @SmallTest
+ @Test
public void testGetBeginning() {
{
final String text = "abc def-ghi. jkl";
@@ -340,7 +349,7 @@
}
}
- @SmallTest
+ @Test
public void testGetEnd() {
{
final String text = "abc def-ghi. jkl";
@@ -415,7 +424,7 @@
}
}
- @SmallTest
+ @Test
public void testGetPunctuationBeginning() {
final String text = "abc!? (^^;) def";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -450,7 +459,7 @@
assertEquals(text.indexOf(';'), wordIterator.getPunctuationBeginning(text.length()));
}
- @SmallTest
+ @Test
public void testGetPunctuationEnd() {
final String text = "abc!? (^^;) def";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -482,7 +491,7 @@
assertEquals(BreakIterator.DONE, wordIterator.getPunctuationEnd(text.length()));
}
- @SmallTest
+ @Test
public void testIsAfterPunctuation() {
final String text = "abc!? (^^;) def";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -498,7 +507,7 @@
assertFalse(wordIterator.isAfterPunctuation(text.length() + 1));
}
- @SmallTest
+ @Test
public void testIsOnPunctuation() {
final String text = "abc!? (^^;) def";
WordIterator wordIterator = new WordIterator(Locale.ENGLISH);
@@ -517,7 +526,7 @@
assertFalse(wordIterator.isOnPunctuation(text.length() + 1));
}
- @SmallTest
+ @Test
public void testApostropheMiddleOfWord() {
// These tests confirm that the word "isn't" is treated like one word.
final String text = "isn't he";
diff --git a/core/tests/coretests/src/android/text/util/LinkifyTest.java b/core/tests/coretests/src/android/text/util/LinkifyTest.java
index 487f4e9..23c34085 100644
--- a/core/tests/coretests/src/android/text/util/LinkifyTest.java
+++ b/core/tests/coretests/src/android/text/util/LinkifyTest.java
@@ -16,45 +16,49 @@
package android.text.util;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
import android.content.Context;
import android.content.res.Configuration;
import android.os.LocaleList;
+import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
-import android.test.AndroidTestCase;
+import android.support.test.runner.AndroidJUnit4;
import android.text.method.LinkMovementMethod;
import android.widget.TextView;
import java.util.Locale;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
/**
* LinkifyTest tests {@link Linkify}.
*/
-public class LinkifyTest extends AndroidTestCase {
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LinkifyTest {
private static final LocaleList LOCALE_LIST_US = new LocaleList(Locale.US);
private LocaleList mOriginalLocales;
+ private Context mContext;
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getContext();
mOriginalLocales = LocaleList.getDefault();
LocaleList.setDefault(LOCALE_LIST_US);
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void teardown() {
LocaleList.setDefault(mOriginalLocales);
- super.tearDown();
}
- private Context createUsEnglishContext() {
- final Configuration overrideConfig = new Configuration();
- overrideConfig.setLocales(LOCALE_LIST_US);
- return getContext().createConfigurationContext(overrideConfig);
- }
-
- @SmallTest
- public void testNothing() throws Exception {
+ @Test
+ public void testNothing() {
TextView tv;
tv = new TextView(createUsEnglishContext());
@@ -64,8 +68,8 @@
assertTrue(tv.getUrls().length == 0);
}
- @SmallTest
- public void testNormal() throws Exception {
+ @Test
+ public void testNormal() {
TextView tv;
tv = new TextView(createUsEnglishContext());
@@ -76,8 +80,8 @@
assertTrue(tv.getUrls().length == 2);
}
- @SmallTest
- public void testUnclickable() throws Exception {
+ @Test
+ public void testUnclickable() {
TextView tv;
tv = new TextView(createUsEnglishContext());
@@ -88,4 +92,10 @@
assertFalse(tv.getMovementMethod() instanceof LinkMovementMethod);
assertTrue(tv.getUrls().length == 2);
}
+
+ private Context createUsEnglishContext() {
+ final Configuration overrideConfig = new Configuration();
+ overrideConfig.setLocales(LOCALE_LIST_US);
+ return mContext.createConfigurationContext(overrideConfig);
+ }
}
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index f59e4fc..7b7031b 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -40,6 +40,7 @@
public class TextClassificationManagerTest {
private static final LocaleList LOCALES = LocaleList.forLanguageTags("en");
+ private static final String NO_TYPE = null;
private TextClassificationManager mTcm;
private TextClassifier mClassifier;
@@ -102,6 +103,19 @@
}
@Test
+ public void testSmartSelection_withEmoji() {
+ if (isTextClassifierDisabled()) return;
+
+ String text = "\uD83D\uDE02 Hello.";
+ String selected = "Hello";
+ int startIndex = text.indexOf(selected);
+ int endIndex = startIndex + selected.length();
+
+ assertThat(mClassifier.suggestSelection(text, startIndex, endIndex, LOCALES),
+ isTextSelection(startIndex, endIndex, NO_TYPE));
+ }
+
+ @Test
public void testClassifyText() {
if (isTextClassifierDisabled()) return;
@@ -118,7 +132,7 @@
if (isTextClassifierDisabled()) return;
String text = "Visit http://www.android.com for more information";
- String classifiedText = "http://www.android.com";
+ String classifiedText = "www.android.com";
int startIndex = text.indexOf(classifiedText);
int endIndex = startIndex + classifiedText.length();
assertThat(mClassifier.classifyText(text, startIndex, endIndex, LOCALES),
@@ -172,12 +186,17 @@
TextSelection selection = (TextSelection) o;
return startIndex == selection.getSelectionStartIndex()
&& endIndex == selection.getSelectionEndIndex()
- && selection.getEntityCount() > 0
- && type.equals(selection.getEntity(0));
+ && typeMatches(selection, type);
}
return false;
}
+ private boolean typeMatches(TextSelection selection, String type) {
+ return type == null
+ || (selection.getEntityCount() > 0
+ && type.trim().equalsIgnoreCase(selection.getEntity(0)));
+ }
+
@Override
public void describeTo(Description description) {
description.appendValue(
@@ -193,7 +212,19 @@
public boolean matches(Object o) {
if (o instanceof TextClassification) {
TextClassification result = (TextClassification) o;
- return text.equals(result.getText())
+ final boolean typeRequirementSatisfied;
+ switch (type) {
+ case TextClassifier.TYPE_URL:
+ String scheme = result.getIntent().getData().getScheme();
+ typeRequirementSatisfied = "http".equalsIgnoreCase(scheme)
+ || "https".equalsIgnoreCase(scheme);
+ break;
+ default:
+ typeRequirementSatisfied = true;
+ }
+
+ return typeRequirementSatisfied
+ && text.equals(result.getText())
&& result.getEntityCount() > 0
&& type.equals(result.getEntity(0));
// TODO: Include other properties.
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index abdab39..8a36120 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -23,6 +23,7 @@
import android.annotation.Size;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.StrictMode;
import android.os.Trace;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -600,6 +601,13 @@
src.position(position);
}
+ private void noteHardwareBitmapSlowCall() {
+ if (getConfig() == Config.HARDWARE) {
+ StrictMode.noteSlowCall("Warning: attempt to read pixels from hardware "
+ + "bitmap, which is very slow operation");
+ }
+ }
+
/**
* Tries to make a new bitmap based on the dimensions of this bitmap,
* setting the new bitmap's config to the one specified, and then copying
@@ -618,6 +626,7 @@
if (config == Config.HARDWARE && isMutable) {
throw new IllegalArgumentException("Hardware bitmaps are always immutable");
}
+ noteHardwareBitmapSlowCall();
Bitmap b = nativeCopy(mNativePtr, config.nativeInt, isMutable);
if (b != null) {
b.setPremultiplied(mRequestPremultiplied);
@@ -635,6 +644,7 @@
*/
public Bitmap createAshmemBitmap() {
checkRecycled("Can't copy a recycled bitmap");
+ noteHardwareBitmapSlowCall();
Bitmap b = nativeCopyAshmem(mNativePtr);
if (b != null) {
b.setPremultiplied(mRequestPremultiplied);
@@ -652,6 +662,7 @@
*/
public Bitmap createAshmemBitmap(Config config) {
checkRecycled("Can't copy a recycled bitmap");
+ noteHardwareBitmapSlowCall();
Bitmap b = nativeCopyAshmemConfig(mNativePtr, config.nativeInt);
if (b != null) {
b.setPremultiplied(mRequestPremultiplied);
@@ -772,6 +783,7 @@
boolean isHardware = source.getConfig() == Config.HARDWARE;
if (isHardware) {
+ source.noteHardwareBitmapSlowCall();
source = nativeCopyPreserveInternalConfig(source.mNativePtr);
}
@@ -1218,6 +1230,7 @@
if (quality < 0 || quality > 100) {
throw new IllegalArgumentException("quality must be 0..100");
}
+ StrictMode.noteSlowCall("Compression of a bitmap is slow");
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
boolean result = nativeCompress(mNativePtr, format.nativeInt,
quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
@@ -1792,6 +1805,7 @@
*/
public void writeToParcel(Parcel p, int flags) {
checkRecycled("Can't parcel a recycled bitmap");
+ noteHardwareBitmapSlowCall();
if (!nativeWriteToParcel(mNativePtr, mIsMutable, mDensity, p)) {
throw new RuntimeException("native writeToParcel failed");
}
@@ -1838,6 +1852,7 @@
public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
checkRecycled("Can't extractAlpha on a recycled bitmap");
long nativePaint = paint != null ? paint.getNativeInstance() : 0;
+ noteHardwareBitmapSlowCall();
Bitmap bm = nativeExtractAlpha(mNativePtr, nativePaint, offsetXY);
if (bm == null) {
throw new RuntimeException("Failed to extractAlpha on Bitmap");
@@ -1853,6 +1868,8 @@
*/
public boolean sameAs(Bitmap other) {
checkRecycled("Can't call sameAs on a recycled bitmap!");
+ noteHardwareBitmapSlowCall();
+ other.noteHardwareBitmapSlowCall();
if (this == other) return true;
if (other == null) return false;
if (other.isRecycled()) {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index f38d8d2..79898bc 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -233,8 +233,7 @@
// TODO: Add ttc and variation font support. (b/37853920)
if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
- fontFile.getWeight(), fontFile.isItalic() ? STYLE_ITALIC : STYLE_NORMAL,
- null /* axes */)) {
+ fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
return null;
}
}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index bc40191..443aa49 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -188,19 +188,19 @@
// Inset attribute may be overridden by more specific attributes.
if (a.hasValue(R.styleable.InsetDrawable_inset)) {
- final InsetValue inset = getInset(a, R.styleable.InsetDrawable_inset, 0);
+ final InsetValue inset = getInset(a, R.styleable.InsetDrawable_inset, new InsetValue());
state.mInsetLeft = inset;
state.mInsetTop = inset;
state.mInsetRight = inset;
state.mInsetBottom = inset;
}
- state.mInsetLeft = getInset(a, R.styleable.InsetDrawable_insetLeft, 0);
- state.mInsetTop = getInset(a, R.styleable.InsetDrawable_insetTop, 0);
- state.mInsetRight = getInset(a, R.styleable.InsetDrawable_insetRight, 0);
- state.mInsetBottom = getInset(a, R.styleable.InsetDrawable_insetBottom, 0);
+ state.mInsetLeft = getInset(a, R.styleable.InsetDrawable_insetLeft, state.mInsetLeft);
+ state.mInsetTop = getInset(a, R.styleable.InsetDrawable_insetTop, state.mInsetTop);
+ state.mInsetRight = getInset(a, R.styleable.InsetDrawable_insetRight, state.mInsetRight);
+ state.mInsetBottom = getInset(a, R.styleable.InsetDrawable_insetBottom, state.mInsetBottom);
}
- private InsetValue getInset(@NonNull TypedArray a, int index, int defaultValue) {
+ private InsetValue getInset(@NonNull TypedArray a, int index, InsetValue defaultValue) {
if (a.hasValue(index)) {
TypedValue tv = a.peekValue(index);
if (tv.type == TypedValue.TYPE_FRACTION) {
@@ -210,10 +210,13 @@
}
return new InsetValue(f, 0);
} else {
- return new InsetValue(0f, a.getDimensionPixelOffset(index, defaultValue));
+ int dimension = a.getDimensionPixelOffset(index, 0);
+ if (dimension != 0) {
+ return new InsetValue(0, dimension);
+ }
}
}
- return new InsetValue();
+ return defaultValue;
}
private void getInsets(Rect out) {
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index d7f75fc..d765584 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -486,7 +486,6 @@
void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
if (isHardware()) {
- ALOGW("Warning: attempt to read pixels from hardware bitmap, which is very slow operation");
outBitmap->allocPixels(info());
uirenderer::renderthread::RenderProxy::copyGraphicBufferInto(graphicBuffer(), outBitmap);
return;
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index bd798e8..fcdd814 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -819,7 +819,7 @@
EXPECT_EQ(1, renderer.getIndex()) << "ColorOp should not be rejected";
}
-OPENGL_PIPELINE_TEST(FrameBuilder, renderNode) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, renderNode) {
class RenderNodeTestRenderer : public TestRendererBase {
public:
void onRectOp(const RectOp& op, const BakedOpState& state) override {
@@ -2321,7 +2321,7 @@
EXPECT_EQ(1, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedInMiddle) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedInMiddle) {
/* R is backward projected on B
A
/ \
@@ -2351,7 +2351,7 @@
EXPECT_EQ(3, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectLast) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectLast) {
/* R is backward projected on E
A
/ | \
@@ -2383,7 +2383,7 @@
EXPECT_EQ(4, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderNoReceivable) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderNoReceivable) {
/* R is backward projected without receiver
A
/ \
@@ -2412,7 +2412,7 @@
EXPECT_EQ(2, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderParentReceivable) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderParentReceivable) {
/* R is backward projected on C
A
/ \
@@ -2441,7 +2441,7 @@
EXPECT_EQ(3, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderSameNodeReceivable) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderSameNodeReceivable) {
auto nodeA = TestUtils::createNode<RecordingCanvas>(0, 0, 100, 100,
[](RenderProperties& props, RecordingCanvas& canvas) {
drawOrderedNode(&canvas, 0, nullptr); //nodeB
@@ -2464,7 +2464,7 @@
EXPECT_EQ(2, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling) {
//TODO: this test together with the next "projectionReorderProjectedSibling2" likely expose a
//bug in HWUI. First test draws R, while the second test does not draw R for a nearly identical
//tree setup. The correct behaviour is to not draw R, because the receiver cannot be a sibling
@@ -2497,7 +2497,7 @@
EXPECT_EQ(3, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling2) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderProjectedSibling2) {
/* R is set to project on B, but R is not drawn because projecting on a sibling is not allowed.
A
|
@@ -2530,7 +2530,7 @@
EXPECT_EQ(3, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderGrandparentReceivable) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderGrandparentReceivable) {
/* R is backward projected on B
A
|
@@ -2562,7 +2562,7 @@
EXPECT_EQ(3, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivables) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivables) {
/* B and G are receivables, R is backward projected
A
/ \
@@ -2595,7 +2595,7 @@
EXPECT_EQ(4, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesLikelyScenario) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesLikelyScenario) {
/* B and G are receivables, G is backward projected
A
/ \
@@ -2628,7 +2628,7 @@
EXPECT_EQ(4, renderer.getIndex());
}
-OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesDeeper) {
+RENDERTHREAD_OPENGL_PIPELINE_TEST(FrameBuilder, projectionReorderTwoReceivablesDeeper) {
/* B and G are receivables, R is backward projected
A
/ \
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index ccdf5ae..c78c99f 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -705,6 +705,8 @@
}
nativeDetachImage(image);
+ si.clearSurfacePlanes();
+ si.mPlanes = null;
si.setDetached(true);
}
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index 349c9cb..2b7309f 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -359,28 +359,14 @@
}
ImageReader prevOwner = (ImageReader) image.getOwner();
- // Only do the image attach for PRIVATE format images for now. Do the image
- // copy for other formats. TODO: use attach for other formats to
- // improve the performance, and fall back to copy when attach/detach
- // fails. Right now, detach is guaranteed to fail as the buffer is
- // locked when ImageReader#acquireNextImage is called. See bug 19962027.
- if (image.getFormat() == ImageFormat.PRIVATE) {
- prevOwner.detachImage(image);
- attachAndQueueInputImage(image);
- // This clears the native reference held by the original owner.
- // When this Image is detached later by this ImageWriter, the
- // native memory won't be leaked.
- image.close();
- return;
- } else {
- Image inputImage = dequeueInputImage();
- inputImage.setTimestamp(image.getTimestamp());
- inputImage.setCropRect(image.getCropRect());
- ImageUtils.imageCopy(image, inputImage);
- image.close();
- image = inputImage;
- ownedByMe = true;
- }
+
+ prevOwner.detachImage(image);
+ attachAndQueueInputImage(image);
+ // This clears the native reference held by the original owner.
+ // When this Image is detached later by this ImageWriter, the
+ // native memory won't be leaked.
+ image.close();
+ return;
}
Rect crop = image.getCropRect();
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index ed5fbcf..b5ea632 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -499,30 +499,23 @@
sp<Surface> surface = ctx->getProducer();
status_t res = OK;
- if (!isFormatOpaque(imageFormat)) {
- // TODO: need implement, see b/19962027
- jniThrowRuntimeException(env,
- "nativeAttachImage for non-opaque image is not implement yet!!!");
- return -1;
- }
-
- if (!isFormatOpaque(ctx->getBufferFormat())) {
+ if (isFormatOpaque(imageFormat) != isFormatOpaque(ctx->getBufferFormat())) {
jniThrowException(env, "java/lang/IllegalStateException",
- "Trying to attach an opaque image into a non-opaque ImageWriter");
+ "Trying to attach an opaque image into a non-opaque ImageWriter, or vice versa");
return -1;
}
// Image is guaranteed to be from ImageReader at this point, so it is safe to
// cast to BufferItem pointer.
- BufferItem* opaqueBuffer = reinterpret_cast<BufferItem*>(nativeBuffer);
- if (opaqueBuffer == NULL) {
+ BufferItem* buffer = reinterpret_cast<BufferItem*>(nativeBuffer);
+ if (buffer == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
"Image is not initialized or already closed");
return -1;
}
// Step 1. Attach Image
- res = surface->attachBuffer(opaqueBuffer->mGraphicBuffer.get());
+ res = surface->attachBuffer(buffer->mGraphicBuffer.get());
if (res != OK) {
ALOGE("Attach image failed: %s (%d)", strerror(-res), res);
switch (res) {
@@ -559,7 +552,7 @@
}
// Step 3. Queue Image.
- res = anw->queueBuffer(anw.get(), opaqueBuffer->mGraphicBuffer.get(), /*fenceFd*/
+ res = anw->queueBuffer(anw.get(), buffer->mGraphicBuffer.get(), /*fenceFd*/
-1);
if (res != OK) {
ALOGE("%s: Queue buffer failed: %s (%d)", __FUNCTION__, strerror(-res), res);
@@ -817,4 +810,3 @@
return (ret1 || ret2);
}
-
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index 3831cf7..dbfeefd 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -104,7 +104,6 @@
case ObexHelper.OBEX_OPCODE_DISCONNECT:
handleDisconnectRequest();
- done = true;
break;
case ObexHelper.OBEX_OPCODE_GET:
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index 2ef1cf5..c309133 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -34,6 +34,7 @@
<intent-filter>
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
+ <action android:name="android.intent.action.LOCALE_CHANGED" />
</intent-filter>
</receiver>
<service android:name="com.android.carrierdefaultapp.ProvisionObserver"
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 7fd1601..0213306 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -112,8 +112,6 @@
private static void onShowCaptivePortalNotification(Intent intent, Context context) {
logd("onShowCaptivePortalNotification");
- final NotificationManager notificationMgr = context.getSystemService(
- NotificationManager.class);
Intent portalIntent = new Intent(context, CaptivePortalLoginActivity.class);
portalIntent.putExtras(intent);
portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
@@ -123,7 +121,8 @@
Notification notification = getNotification(context, R.string.portal_notification_id,
R.string.portal_notification_detail, pendingIntent);
try {
- notificationMgr.notify(PORTAL_NOTIFICATION_TAG, PORTAL_NOTIFICATION_ID, notification);
+ context.getSystemService(NotificationManager.class)
+ .notify(PORTAL_NOTIFICATION_TAG, PORTAL_NOTIFICATION_ID, notification);
} catch (NullPointerException npe) {
loge("setNotificationVisible: " + npe);
}
@@ -131,12 +130,11 @@
private static void onShowNoDataServiceNotification(Context context) {
logd("onShowNoDataServiceNotification");
- final NotificationManager notificationMgr = context.getSystemService(
- NotificationManager.class);
Notification notification = getNotification(context, R.string.no_data_notification_id,
R.string.no_data_notification_detail, null);
try {
- notificationMgr.notify(NO_DATA_NOTIFICATION_TAG, NO_DATA_NOTIFICATION_ID, notification);
+ context.getSystemService(NotificationManager.class)
+ .notify(NO_DATA_NOTIFICATION_TAG, NO_DATA_NOTIFICATION_ID, notification);
} catch (NullPointerException npe) {
loge("setNotificationVisible: " + npe);
}
@@ -144,26 +142,16 @@
private static void onCancelAllNotifications(Context context) {
logd("onCancelAllNotifications");
- final NotificationManager notificationMgr = context.getSystemService(
- NotificationManager.class);
- notificationMgr.cancelAll();
+ context.getSystemService(NotificationManager.class).cancelAll();
}
private static Notification getNotification(Context context, int titleId, int textId,
PendingIntent pendingIntent) {
final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
- final NotificationManager notificationManager = context.getSystemService(
- NotificationManager.class);
final Resources resources = context.getResources();
final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME,
resources.getString(R.string.android_system_label));
- /* Creates the notification channel and registers it with NotificationManager. If a channel
- * with the same ID is already registered, NotificationManager will ignore this call.
- */
- notificationManager.createNotificationChannel(new NotificationChannel(
- NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS,
- resources.getString(R.string.mobile_data_status_notification_channel_name),
- NotificationManager.IMPORTANCE_DEFAULT));
+ createNotificationChannels(context);
Notification.Builder builder = new Notification.Builder(context)
.setContentTitle(resources.getString(titleId))
.setContentText(String.format(resources.getString(textId),
@@ -187,6 +175,19 @@
return builder.build();
}
+ /**
+ * Creates the notification channel and registers it with NotificationManager. Also used to
+ * update an existing channel's name.
+ */
+ static void createNotificationChannels(Context context) {
+ context.getSystemService(NotificationManager.class)
+ .createNotificationChannel(new NotificationChannel(
+ NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS,
+ context.getResources().getString(
+ R.string.mobile_data_status_notification_channel_name),
+ NotificationManager.IMPORTANCE_DEFAULT));
+ }
+
private static void logd(String s) {
Log.d(TAG, s);
}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierDefaultBroadcastReceiver.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierDefaultBroadcastReceiver.java
index 3fd89d9..3f55ff5 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierDefaultBroadcastReceiver.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierDefaultBroadcastReceiver.java
@@ -32,6 +32,10 @@
Log.d(TAG, "skip carrier actions during provisioning");
return;
}
+ if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+ CarrierActionUtils.createNotificationChannels(context);
+ return;
+ }
List<Integer> actionList = CustomConfigLoader.loadCarrierActionList(context, intent);
for (int actionIdx : actionList) {
Log.d(TAG, "apply carrier action idx: " + actionIdx);
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index fcbb89d..70c6e47 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -203,7 +203,7 @@
<string name="allow_mock_location" msgid="2787962564578664888">"Dozvoli lažne lokacije"</string>
<string name="allow_mock_location_summary" msgid="317615105156345626">"Dozvoli lažne lokacije"</string>
<string name="debug_view_attributes" msgid="6485448367803310384">"Omogući proveru atributa za pregled"</string>
- <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka podaci za mobilne uređaje uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Neka mobilni podaci uvek budu aktivni, čak i kada je Wi‑Fi aktivan (radi brze promene mreže)."</string>
<string name="adb_warning_title" msgid="6234463310896563253">"Dozvoli otklanjanje USB grešaka?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Otklanjanje USB grešaka namenjeno je samo za svrhe programiranja. Koristite ga za kopiranje podataka sa računara na uređaj i obrnuto, instaliranje aplikacija na uređaju bez obaveštenja i čitanje podataka iz evidencije."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"Želite li da opozovete pristup otklanjanju USB grešaka sa svih računara koje ste prethodno odobrili?"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 5891473..f851581 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -93,7 +93,7 @@
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Applications et utilisateurs supprimés"</string>
<string name="tether_settings_title_usb" msgid="6688416425801386511">"Partage de connexion par USB"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"Point d\'accès Wi-Fi mobile"</string>
- <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Via Bluetooth"</string>
+ <string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Par Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Partage de connexion"</string>
<string name="tether_settings_title_all" msgid="8356136101061143841">"Partage de connexion"</string>
<string name="managed_user_title" msgid="8109605045406748842">"Toutes les applis profess."</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 831515a..155f1c5 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -33,7 +33,7 @@
<string name="wifi_no_internet" msgid="3880396223819116454">"Aucun accès à Internet"</string>
<string name="saved_network" msgid="4352716707126620811">"Enregistré par <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Connecté automatiquement via %1$s"</string>
- <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement via un fournisseur d\'avis sur le réseau"</string>
+ <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Connecté automatiquement via un fournisseur d\'évaluation de l\'état du réseau"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Connecté via %1$s"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"Disponible via %1$s"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Connecté, aucun accès à Internet"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index e64e007..182d819 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -203,7 +203,7 @@
<string name="allow_mock_location" msgid="2787962564578664888">"אפשר מיקומים מדומים"</string>
<string name="allow_mock_location_summary" msgid="317615105156345626">"אפשר מיקומים מדומים"</string>
<string name="debug_view_attributes" msgid="6485448367803310384">"אפשר בדיקת תכונת תצוגה"</string>
- <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"השאר את הנתונים לנייד פעילים תמיד, גם כש-Wi‑Fi פעיל (למעבר מהיר בין רשתות)."</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"השאר את חבילת הגלישה פעילה תמיד, גם כש-Wi‑Fi פעיל (למעבר מהיר בין רשתות)."</string>
<string name="adb_warning_title" msgid="6234463310896563253">"לאפשר ניפוי באגים של USB?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"ניפוי באגים באמצעות USB מיועד למטרות פיתוח בלבד. השתמש בו להעתקת נתונים בין המחשב והמכשיר שלך, להתקנת אפליקציות במכשיר ללא התראה ולקריאת נתוני יומן."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"האם לבטל את הגישה לניפוי ב-USB מכל המחשבים שהענקת להם בעבר הרשאה?"</string>
@@ -253,7 +253,7 @@
<string name="usb_audio_disable_routing" msgid="8114498436003102671">"השבת ניתוב אודיו ב-USB"</string>
<string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"השבת ניתוב אוטומטי אל התקני אודיו חיצוניים ב-USB"</string>
<string name="debug_layout" msgid="5981361776594526155">"הצג את גבולות הפריסה"</string>
- <string name="debug_layout_summary" msgid="2001775315258637682">"הצג גבולות קליפ, שוליים וכו\'"</string>
+ <string name="debug_layout_summary" msgid="2001775315258637682">"הצג גבולות אזור, שוליים וכדומה"</string>
<string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"אלץ כיוון פריסה מימין לשמאל"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"אלץ כיוון פריסת מסך מימין לשמאל עבור כל השפות בכל המקומות"</string>
<string name="force_hw_ui" msgid="6426383462520888732">"אלץ עיבוד ב-GPU"</string>
@@ -278,7 +278,7 @@
<string name="force_resizable_activities_summary" msgid="6667493494706124459">"אפשר יכולת קביעת גודל של כל הפעילויות לריבוי חלונות, ללא קשר לערך המניפסט."</string>
<string name="enable_freeform_support" msgid="1461893351278940416">"הפעל את האפשרות לשנות את הגודל והמיקום של החלונות"</string>
<string name="enable_freeform_support_summary" msgid="8247310463288834487">"הפעל תמיכה בתכונה הניסיונית של שינוי הגודל והמיקום של החלונות."</string>
- <string name="local_backup_password_title" msgid="3860471654439418822">"סיסמת גיבוי מקומי"</string>
+ <string name="local_backup_password_title" msgid="3860471654439418822">"סיסמת גיבוי שולחן העבודה"</string>
<string name="local_backup_password_summary_none" msgid="6951095485537767956">"גיבויים מלאים בשולחן העבודה אינם מוגנים כעת"</string>
<string name="local_backup_password_summary_change" msgid="5376206246809190364">"הקש כדי לשנות או להסיר את הסיסמה לגיבויים מלאים בשולחן העבודה"</string>
<string name="local_backup_password_toast_success" msgid="582016086228434290">"הוגדרה סיסמת גיבוי חדשה"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 97830f0..492f71d 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -33,7 +33,7 @@
<string name="wifi_no_internet" msgid="3880396223819116454">"Интернетке туташпай турат"</string>
<string name="saved_network" msgid="4352716707126620811">"<xliff:g id="NAME">%1$s</xliff:g> тарабынан сакталды"</string>
<string name="connected_via_network_scorer" msgid="5713793306870815341">"%1$s аркылуу автоматтык түрдө туташты"</string>
- <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Тармак рейтингинин провайдери аркылуу автоматтык түрдө туташтырылды"</string>
+ <string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Тармактардын рейтингинин автору аркылуу автоматтык түрдө туташты"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"%1$s аркылуу жеткиликтүү"</string>
<string name="available_via_passpoint" msgid="1617440946846329613">"%1$s аркылуу жеткиликтүү"</string>
<string name="wifi_connected_no_internet" msgid="3149853966840874992">"Туташып турат, Интернет жок"</string>
@@ -316,7 +316,7 @@
<string name="daltonizer_mode_protanomaly" msgid="8424148009038666065">"Протаномалия (кызыл-жашыл)"</string>
<string name="daltonizer_mode_tritanomaly" msgid="481725854987912389">"Тританомалия (көк-сары)"</string>
<string name="accessibility_display_daltonizer_preference_title" msgid="5800761362678707872">"Түсүн тууралоо"</string>
- <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string>
+ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, түзмөктүн иштешине таасир этиши мүмкүн."</string>
<string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string>
<string name="power_remaining_duration_only" msgid="845431008899029842">"Батарея түгөнгөнгө чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"Батарея толгонго чейин калган убакыт: <xliff:g id="TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index c11fa9f..52840e3 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -165,7 +165,7 @@
<string name="confirm_enable_oem_unlock_title" msgid="4802157344812385674">"OEM түгжээ тайлагчийг зөвшөөрөх үү?"</string>
<string name="confirm_enable_oem_unlock_text" msgid="5517144575601647022">"АНХААР: Энэ тохиргоо асаалттай байгаа үед тухайн төхөөрөмжийн хамгаалалтын функцүүд ажиллахгүй."</string>
<string name="mock_location_app" msgid="7966220972812881854">"Хуурамч байршлын апп сонгох"</string>
- <string name="mock_location_app_not_set" msgid="809543285495344223">"Хуурамч байршлын апп-ыг тохируулаагүй байна"</string>
+ <string name="mock_location_app_not_set" msgid="809543285495344223">"Хуурамч байршлын аппыг тохируулаагүй байна"</string>
<string name="mock_location_app_set" msgid="8966420655295102685">"Хуурамч байршлын апп: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="7044075693643009662">"Сүлжээ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"Утасгүй дэлгэцийн сертификат"</string>
@@ -233,7 +233,7 @@
<string name="media_category" msgid="4388305075496848353">"Медиа"</string>
<string name="debug_monitoring_category" msgid="7640508148375798343">"Мониторинг"</string>
<string name="strict_mode" msgid="1938795874357830695">"Хатуу горимыг идэвхжүүлсэн"</string>
- <string name="strict_mode_summary" msgid="142834318897332338">"Апп-ууд үндсэн хэлхээс дээр удаан хугацаанд үйлдлүүд хийх үед дэлгэцийг анивчуулах"</string>
+ <string name="strict_mode_summary" msgid="142834318897332338">"Аппууд үндсэн хэлхээс дээр удаан хугацаанд үйлдлүүд хийх үед дэлгэцийг анивчуулах"</string>
<string name="pointer_location" msgid="6084434787496938001">"Чиглүүлэгчийн байршил"</string>
<string name="pointer_location_summary" msgid="840819275172753713">"Дэлгэцийн давхаргаар одоогийн хүрэлтийн өгөгдлийг харуулж байна"</string>
<string name="show_touches" msgid="2642976305235070316">"Товшилтыг харуулах"</string>
@@ -272,7 +272,7 @@
<string name="app_process_limit_title" msgid="4280600650253107163">"Далд процессын хязгаар"</string>
<string name="show_all_anrs" msgid="28462979638729082">"Бүх ANRs харуулах"</string>
<string name="show_all_anrs_summary" msgid="641908614413544127">"Далд апп-уудад Апп Хариу Өгөхгүй байна гэснийг харуулах"</string>
- <string name="force_allow_on_external" msgid="3215759785081916381">"Апп-ыг гадаад санах ойд хадгалахыг зөвшөөрөх"</string>
+ <string name="force_allow_on_external" msgid="3215759785081916381">"Аппыг гадаад санах ойд хадгалахыг зөвшөөрөх"</string>
<string name="force_allow_on_external_summary" msgid="3640752408258034689">"Манифест утгыг нь үл хамааран дурын апп-г гадаад санах ойд бичих боломжтой болгодог"</string>
<string name="force_resizable_activities" msgid="8615764378147824985">"Үйл ажиллагааны хэмжээг өөрчилж болохуйц болгох"</string>
<string name="force_resizable_activities_summary" msgid="6667493494706124459">"Тодорхойлогч файлын утгыг үл хамааран, бүх үйл ажиллагааны хэмжээг олон цонхонд өөрчилж болохуйц болгоно уу."</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ac7d7de..1e55e15 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -167,7 +167,7 @@
<string name="mock_location_app" msgid="7966220972812881854">"ਮੌਕ ਸਥਾਨ ਐਪ ਚੁਣੋ"</string>
<string name="mock_location_app_not_set" msgid="809543285495344223">"ਕੋਈ ਵੀ ਮੌਕ ਸਥਾਨ ਐਪ ਸੈੱਟ ਨਹੀਂ ਕੀਤੀ ਗਈ"</string>
<string name="mock_location_app_set" msgid="8966420655295102685">"ਮੌਕ ਸਥਾਨ ਐਪ: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="debug_networking_category" msgid="7044075693643009662">"ਨੈਟਵਰਕਿੰਗ"</string>
+ <string name="debug_networking_category" msgid="7044075693643009662">"ਨੈੱਟਵਰਕਿੰਗ"</string>
<string name="wifi_display_certification" msgid="8611569543791307533">"ਵਾਇਰਲੈਸ ਡਿਸਪਲੇ ਪ੍ਰਮਾਣੀਕਰਨ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ਵਰਬੋਸ ਲੌਗਿੰਗ ਸਮਰੱਥ ਬਣਾਓ"</string>
<string name="wifi_aggressive_handover" msgid="5309131983693661320">"ਆਕਰਮਣਸ਼ੀਲ Wi‑Fi ਤੋਂ ਮੋਬਾਈਲ ਹੈਂਡਓਵਰ"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index a8f5566..75b766b 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -31,7 +31,7 @@
<string name="wifi_not_in_range" msgid="1136191511238508967">"Mimo dosah"</string>
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"Nedôjde k automatickému pripojeniu"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"Žiadny prístup k internetu"</string>
- <string name="saved_network" msgid="4352716707126620811">"Uložil(a) <xliff:g id="NAME">%1$s</xliff:g>"</string>
+ <string name="saved_network" msgid="4352716707126620811">"Uložila aplikácia <xliff:g id="NAME">%1$s</xliff:g>"</string>
<string name="connected_via_network_scorer" msgid="5713793306870815341">"Automaticky pripojené prostredníctvom %1$s"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"Automaticky pripojené prostredníctvom poskytovateľa hodnotenia siete"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"Pripojené prostredníctvom %1$s"</string>
@@ -91,7 +91,7 @@
<string name="process_kernel_label" msgid="3916858646836739323">"OS Android"</string>
<string name="data_usage_uninstalled_apps" msgid="614263770923231598">"Odstránené aplikácie"</string>
<string name="data_usage_uninstalled_apps_users" msgid="7986294489899813194">"Odstránené aplikácie a používatelia"</string>
- <string name="tether_settings_title_usb" msgid="6688416425801386511">"Zdieľané pripojenie cez USB"</string>
+ <string name="tether_settings_title_usb" msgid="6688416425801386511">"Pripojenie cez USB"</string>
<string name="tether_settings_title_wifi" msgid="3277144155960302049">"Prenosný prístupový bod"</string>
<string name="tether_settings_title_bluetooth" msgid="355855408317564420">"Pripojenie cez Bluetooth"</string>
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"Zdieľané pripojenie"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index 3992dbe..15ba747 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -203,7 +203,7 @@
<string name="allow_mock_location" msgid="2787962564578664888">"Дозволи лажне локације"</string>
<string name="allow_mock_location_summary" msgid="317615105156345626">"Дозволи лажне локације"</string>
<string name="debug_view_attributes" msgid="6485448367803310384">"Омогући проверу атрибута за преглед"</string>
- <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Нека подаци за мобилне уређаје увек буду активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Нека мобилни подаци увек буду активни, чак и када је Wi‑Fi активан (ради брзе промене мреже)."</string>
<string name="adb_warning_title" msgid="6234463310896563253">"Дозволи отклањање USB грешака?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Отклањање USB грешака намењено је само за сврхе програмирања. Користите га за копирање података са рачунара на уређај и обрнуто, инсталирање апликација на уређају без обавештења и читање података из евиденције."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"Желите ли да опозовете приступ отклањању USB грешака са свих рачунара које сте претходно одобрили?"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 43d75b3b..ac7cd4e 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -31,7 +31,7 @@
<string name="wifi_not_in_range" msgid="1136191511238508967">"不在范围内"</string>
<string name="wifi_no_internet_no_reconnect" msgid="5724903347310541706">"无法自动连接"</string>
<string name="wifi_no_internet" msgid="3880396223819116454">"无法连接到互联网"</string>
- <string name="saved_network" msgid="4352716707126620811">"已通过<xliff:g id="NAME">%1$s</xliff:g>保存"</string>
+ <string name="saved_network" msgid="4352716707126620811">"由<xliff:g id="NAME">%1$s</xliff:g>保存"</string>
<string name="connected_via_network_scorer" msgid="5713793306870815341">"已通过%1$s自动连接"</string>
<string name="connected_via_network_scorer_default" msgid="7867260222020343104">"已自动连接(通过网络评分服务提供方)"</string>
<string name="connected_via_passpoint" msgid="2826205693803088747">"已通过%1$s连接"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 24d8187..eb513e1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -998,9 +998,11 @@
if (mRssi != info.getRssi()) {
mRssi = info.getRssi();
updated = true;
+ } else if (mNetworkInfo != null && networkInfo != null
+ && mNetworkInfo.getDetailedState() != networkInfo.getDetailedState()) {
+ updated = true;
}
mInfo = info;
- // TODO(b/37289220): compare NetworkInfo states and set updated = true if necessary
mNetworkInfo = networkInfo;
} else if (mInfo != null) {
updated = true;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 646b6ba..be15e65 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -124,7 +124,8 @@
*/
private final Object mLock = new Object();
- //visible to both worker and main thread. Guarded by #mInternalAccessPoints
+ //visible to both worker and main thread.
+ @GuardedBy("mLock")
private final AccessPointListenerAdapter mAccessPointListenerAdapter
= new AccessPointListenerAdapter();
@@ -1005,12 +1006,13 @@
if (DBG) {
Log.d(TAG, "Starting to copy AP items on the MainHandler");
}
- if (notifyListeners) {
- notificationMap = mAccessPointListenerAdapter.mPendingNotifications.clone();
- }
-
- mAccessPointListenerAdapter.mPendingNotifications.clear();
synchronized (mLock) {
+ if (notifyListeners) {
+ notificationMap = mAccessPointListenerAdapter.mPendingNotifications.clone();
+ }
+
+ mAccessPointListenerAdapter.mPendingNotifications.clear();
+
for (AccessPoint internalAccessPoint : mInternalAccessPoints) {
AccessPoint accessPoint = oldAccessPoints.get(internalAccessPoint.mId);
if (accessPoint == null) {
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index 154fde2..56cb0a3 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -404,4 +404,55 @@
assertThat(ap.getPasspointFqdn()).isEqualTo(fqdn);
assertThat(ap.getConfigName()).isEqualTo(providerFriendlyName);
}
+
+ @Test
+ public void testUpdateNetworkInfo_returnsTrue() {
+ int networkId = 123;
+ int rssi = -55;
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = networkId;
+ WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setNetworkId(networkId);
+ wifiInfo.setRssi(rssi);
+
+ NetworkInfo networkInfo =
+ new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+ networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+ AccessPoint ap = new TestAccessPointBuilder(mContext)
+ .setNetworkInfo(networkInfo)
+ .setNetworkId(networkId)
+ .setRssi(rssi)
+ .setWifiInfo(wifiInfo)
+ .build();
+
+ NetworkInfo newInfo = new NetworkInfo(networkInfo);
+ newInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "", "");
+ assertThat(ap.update(config, wifiInfo, newInfo)).isTrue();
+ }
+
+ @Test
+ public void testUpdateNetworkInfoWithSameInfo_returnsFalse() {
+ int networkId = 123;
+ int rssi = -55;
+ WifiConfiguration config = new WifiConfiguration();
+ config.networkId = networkId;
+ WifiInfo wifiInfo = new WifiInfo();
+ wifiInfo.setNetworkId(networkId);
+ wifiInfo.setRssi(rssi);
+
+ NetworkInfo networkInfo =
+ new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0 /* subtype */, "WIFI", "");
+ networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTING, "", "");
+
+ AccessPoint ap = new TestAccessPointBuilder(mContext)
+ .setNetworkInfo(networkInfo)
+ .setNetworkId(networkId)
+ .setRssi(rssi)
+ .setWifiInfo(wifiInfo)
+ .build();
+
+ NetworkInfo newInfo = new NetworkInfo(networkInfo); // same values
+ assertThat(ap.update(config, wifiInfo, newInfo)).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
index a347203..2213ae6 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/TestAccessPointBuilder.java
@@ -20,6 +20,7 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
import android.os.Bundle;
/**
@@ -36,11 +37,13 @@
// set some sensible defaults
private int mRssi = AccessPoint.UNREACHABLE_RSSI;
- private int networkId = WifiConfiguration.INVALID_NETWORK_ID;
+ private int mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
private String ssid = "TestSsid";
private NetworkInfo mNetworkInfo = null;
private String mFqdn = null;
private String mProviderFriendlyName = null;
+ private WifiConfiguration mWifiConfig;
+ private WifiInfo mWifiInfo;
Context mContext;
@@ -51,12 +54,13 @@
public AccessPoint build() {
Bundle bundle = new Bundle();
- WifiConfiguration wifiConig = new WifiConfiguration();
- wifiConig.networkId = networkId;
+ WifiConfiguration wifiConfig = new WifiConfiguration();
+ wifiConfig.networkId = mNetworkId;
bundle.putString(AccessPoint.KEY_SSID, ssid);
- bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConig);
+ bundle.putParcelable(AccessPoint.KEY_CONFIG, wifiConfig);
bundle.putParcelable(AccessPoint.KEY_NETWORKINFO, mNetworkInfo);
+ bundle.putParcelable(AccessPoint.KEY_WIFIINFO, mWifiInfo);
if (mFqdn != null) {
bundle.putString(AccessPoint.KEY_FQDN, mFqdn);
}
@@ -81,17 +85,12 @@
return this;
}
- public TestAccessPointBuilder setRssi(int rssi) {
- mRssi = rssi;
- return this;
- }
-
/**
- * Set the rssi based upon the desired signal level.
+ * Set the rssi based upon the desired signal level.
*
- * <p>Side effect: if this AccessPoint was previously unreachable,
- * setting the level will also make it reachable.
- */
+ * <p>Side effect: if this AccessPoint was previously unreachable,
+ * setting the level will also make it reachable.
+ */
public TestAccessPointBuilder setLevel(int level) {
// Reversal of WifiManager.calculateSignalLevels
if (level == 0) {
@@ -106,6 +105,16 @@
return this;
}
+ public TestAccessPointBuilder setNetworkInfo(NetworkInfo info) {
+ mNetworkInfo = info;
+ return this;
+ }
+
+ public TestAccessPointBuilder setRssi(int rssi) {
+ mRssi = rssi;
+ return this;
+ }
+
/**
* Set whether the AccessPoint is reachable.
* Side effect: if the signal level was not previously set,
@@ -125,9 +134,9 @@
public TestAccessPointBuilder setSaved(boolean saved){
if (saved) {
- networkId = 1;
+ mNetworkId = 1;
} else {
- networkId = WifiConfiguration.INVALID_NETWORK_ID;
+ mNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
}
return this;
}
@@ -146,4 +155,20 @@
mProviderFriendlyName = friendlyName;
return this;
}
+
+ public TestAccessPointBuilder setWifiInfo(WifiInfo info) {
+ mWifiInfo = info;
+ return this;
+ }
+
+ /**
+ * Set the networkId in the WifiConfig.
+ *
+ * <p>Setting this to a value other than {@link WifiConfiguration#INVALID_NETWORK_ID} makes this
+ * AccessPoint a saved network.
+ */
+ public TestAccessPointBuilder setNetworkId(int networkId) {
+ mNetworkId = networkId;
+ return this;
+ }
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index f519a90..d4ce40c 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -465,9 +465,9 @@
private void updateScoresAndWaitForAccessPointsChangedCallback() throws InterruptedException {
// Updating scores can happen together or one after the other, so the latch countdown is set
// to 2.
- mAccessPointsChangedLatch = new CountDownLatch(3);
+ mAccessPointsChangedLatch = new CountDownLatch(2);
updateScores();
- assertTrue("onAccessPointChanged was not called three times",
+ assertTrue("onAccessPointChanged was not called twice",
mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 885573e..f475361 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -696,6 +696,12 @@
Settings.Global.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX,
GlobalSettingsProto.BLUETOOTH_A2DP_SRC_PRIORITY_PREFIX);
dumpSetting(s, p,
+ Settings.Global.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX,
+ GlobalSettingsProto.BLUETOOTH_A2DP_SUPPORTS_OPTIONAL_CODECS_PREFIX);
+ dumpSetting(s, p,
+ Settings.Global.BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX,
+ GlobalSettingsProto.BLUETOOTH_A2DP_OPTIONAL_CODECS_ENABLED_PREFIX);
+ dumpSetting(s, p,
Settings.Global.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX,
GlobalSettingsProto.BLUETOOTH_INPUT_DEVICE_PRIORITY_PREFIX);
dumpSetting(s, p,
@@ -979,9 +985,6 @@
Settings.Secure.AUTOFILL_SERVICE,
SecureSettingsProto.AUTOFILL_SERVICE);
dumpSetting(s, p,
- Settings.Secure.BLUETOOTH_HCI_LOG,
- SecureSettingsProto.BLUETOOTH_HCI_LOG);
- dumpSetting(s, p,
Settings.Secure.USER_SETUP_COMPLETE,
SecureSettingsProto.USER_SETUP_COMPLETE);
dumpSetting(s, p,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java
deleted file mode 100644
index 0688481..0000000
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/doze/DozeProvider.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.plugins.doze;
-
-import android.app.PendingIntent;
-import android.content.Context;
-
-import com.android.systemui.plugins.Plugin;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
-
-/**
- * Provides a {@link DozeUi}.
- */
-@ProvidesInterface(action = DozeProvider.ACTION, version = DozeProvider.VERSION)
-public interface DozeProvider extends Plugin {
-
- String ACTION = "com.android.systemui.action.PLUGIN_DOZE";
- int VERSION = 1;
-
- /**
- * Caution: Even if this is called, the DozeUi provided may still be in use until it transitions
- * to DozeState.FINISH
- */
- @Override
- default void onDestroy() {
- }
-
- /**
- * @return the plugin's implementation of DozeUi.
- */
- DozeUi provideDozeUi(Context context, DozeMachine machine, WakeLock wakeLock);
-
- /**
- * If true, the plugin allows the default pulse triggers to fire, otherwise they are disabled.
- */
- default boolean allowDefaultPulseTriggers() {
- return false;
- }
-
- /**
- * Ui for use in DozeMachine.
- */
- interface DozeUi {
- /** Called whenever the DozeMachine state transitions */
- void transitionTo(DozeState oldState, DozeState newState);
- }
-
- /** WakeLock wrapper for testability */
- interface WakeLock {
- /** @see android.os.PowerManager.WakeLock#acquire() */
- void acquire();
- /** @see android.os.PowerManager.WakeLock#release() */
- void release();
- /** @see android.os.PowerManager.WakeLock#wrap(Runnable) */
- Runnable wrap(Runnable r);
- }
-
- /** Plugin version of the DozeMachine's state */
- enum DozeState {
- /** Default state. Transition to INITIALIZED to get Doze going. */
- UNINITIALIZED,
- /** Doze components are set up. Followed by transition to DOZE or DOZE_AOD. */
- INITIALIZED,
- /** Regular doze. Device is asleep and listening for pulse triggers. */
- DOZE,
- /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */
- DOZE_AOD,
- /** Pulse has been requested. Device is awake and preparing UI */
- DOZE_REQUEST_PULSE,
- /** Pulse is showing. Device is awake and showing UI. */
- DOZE_PULSING,
- /** Pulse is done showing. Followed by transition to DOZE or DOZE_AOD. */
- DOZE_PULSE_DONE,
- /** Doze is done. DozeService is finished. */
- FINISH,
- /** WakeUp. */
- WAKE_UP,
- }
-
- /** Plugin interface for the doze machine. */
- interface DozeMachine {
- /** Request that the DozeMachine transitions to {@code state} */
- void requestState(DozeState state);
-
- /** Request that the PendingIntent is sent. */
- void requestSendIntent(PendingIntent intent);
- }
-}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 7d78c08..9ef05c5 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -16,6 +16,7 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
+import android.metrics.LogMaker;
import android.service.quicksettings.Tile;
import com.android.systemui.plugins.annotations.DependsOn;
@@ -66,6 +67,10 @@
State getState();
+ default LogMaker populate(LogMaker logMaker) {
+ return logMaker;
+ }
+
@ProvidesInterface(version = Callback.VERSION)
public interface Callback {
public static final int VERSION = 1;
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 1a875e2..8a088f3 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -36,7 +36,7 @@
<string name="keyguard_low_battery" msgid="9218432555787624490">"Зарядтағышты қосыңыз."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="6743537524631420759">"Желі құлыптаулы"</string>
- <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"SIM картасы енгізілмеген"</string>
+ <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"SIM картасы салынбаған"</string>
<string name="keyguard_missing_sim_message" product="tablet" msgid="4550152848200783542">"Планшетте SIM картасы жоқ."</string>
<string name="keyguard_missing_sim_message" product="default" msgid="6585414237800161146">"Телефонда SIM картасы жоқ."</string>
<string name="keyguard_missing_sim_instructions" msgid="7350295932015220392">"SIM картасын енгізіңіз."</string>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index f29e40f..374f9ac 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Tot <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Hou"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervang"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Programme wat op die agtergrond loop"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik vir besonderhede oor battery- en datagebruik"</string>
</resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index a660283..fb85ee3 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"በጀርባ ውስጥ የሚያሄዱ መተግበሪያዎች"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"በባትሪ እና ውሂብ አጠቃቀም ላይ ዝርዝሮችን ለማግኘት መታ ያድርጉ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d4347a6..11ed527 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -777,8 +777,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"التطبيقات التي تعمل في الخلفية"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"انقر للحصول على تفاصيل حول البطارية واستخدام البيانات"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 0f005a1..9363ce8 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> vaxtına qədər"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Saxlayın"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Əvəz edin"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Arxa fonda işləyən tətbiqlər"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya və data istifadəsi haqqında ətraflı məlumat üçün klikləyin"</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 dd26970..282f8d3 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -400,7 +400,7 @@
<string name="user_logout_notification_text" msgid="3350262809611876284">"Odjavite aktuelnog korisnika"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ODJAVI KORISNIKA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Dodajete novog korisnika?"</string>
- <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi sopstveni prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"Kada dodate novog korisnika, ta osoba treba da podesi svoj prostor.\n\nSvaki korisnik može da ažurira aplikacije za sve ostale korisnike."</string>
<string name="user_remove_user_title" msgid="4681256956076895559">"Želite li da uklonite korisnika?"</string>
<string name="user_remove_user_message" msgid="1453218013959498039">"Sve aplikacije i podaci ovog korisnika će biti izbrisani."</string>
<string name="user_remove_user_remove" msgid="7479275741742178297">"Ukloni"</string>
@@ -590,8 +590,8 @@
<string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Taster sa strelicom nalevo"</string>
<string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Taster sa strelicom nadesno"</string>
<string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Taster sa centralnom strelicom"</string>
- <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulator"</string>
- <string name="keyboard_key_space" msgid="2499861316311153293">"Taster za razmak"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Razmak"</string>
<string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
<string name="keyboard_key_backspace" msgid="1559580097512385854">"Taster za brisanje unazad"</string>
<string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Taster za reprodukciju/pauziranje"</string>
@@ -657,7 +657,7 @@
</string-array>
<string name="menu_ime" msgid="4998010205321292416">"Prebacivač za tastaturu"</string>
<string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
- <string name="reset" msgid="2448168080964209908">"Ponovo postavi"</string>
+ <string name="reset" msgid="2448168080964209908">"Resetuj"</string>
<string name="adjust_button_width" msgid="6138616087197632947">"Prilagodi širinu dugmeta"</string>
<string name="clipboard" msgid="1313879395099896312">"Privremena memorija"</string>
<string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -765,8 +765,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zameni"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije pokrenute u pozadini"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste pregledali detalje o bateriji i potrošnji podataka"</string>
</resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 68adda6..fa3552b 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -771,8 +771,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Праграмы, якія працуюць у фонавым рэжыме"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Дакраніцеся, каб атрымаць падрабязныя звесткі пра выкарыстанне трафіка і акумулятара"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 85335c9..4df9a6a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работещи на заден план"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Докоснете за подробности относно използването на батерията и преноса на данни"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index abe5a43..54cd0cd 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"পটভূমিতে অ্যাপ চালু আছে"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ব্যাটারি এবং ডেটার ব্যবহারের বিশদ বিবরণের জন্য ট্যাপ করুন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 377cb1f..ceea5f3d 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -649,7 +649,7 @@
<item msgid="1545641631806817203">"Međumemorija"</item>
<item msgid="5742013440802239414">"Kôd tipke"</item>
<item msgid="8802889973626281575">"Prebacivač tastatura"</item>
- <item msgid="8175437057325747277">"Nema"</item>
+ <item msgid="8175437057325747277">"Ništa"</item>
</string-array>
<string-array name="nav_bar_layouts">
<item msgid="8077901629964902399">"Normalna"</item>
@@ -659,7 +659,7 @@
</string-array>
<string name="menu_ime" msgid="4998010205321292416">"Prebacivač tastatura"</string>
<string name="save" msgid="2311877285724540644">"Sačuvaj"</string>
- <string name="reset" msgid="2448168080964209908">"Vrati na zadano"</string>
+ <string name="reset" msgid="2448168080964209908">"Vraćanje na zadano"</string>
<string name="adjust_button_width" msgid="6138616087197632947">"Podesite širinu dugmeta"</string>
<string name="clipboard" msgid="1313879395099896312">"Međumemorija"</string>
<string name="accessibility_key" msgid="5701989859305675896">"Prilagođeno dugme za navigaciju"</string>
@@ -767,8 +767,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije koje rade u pozadini"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite za detalje o bateriji i prijenosu podataka"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 2262afc..abdd915 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Fins a les <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conserva"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substitueix"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacions que s\'estan executant en segon pla"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca per obtenir informació sobre l\'ús de dades i la bateria"</string>
</resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 1b3eec1..1643fa0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -771,8 +771,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zachovat"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Nahradit"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikace běžící na pozadí"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o využití baterie a dat"</string>
</resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 295fc27..4ba8ac8 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Indtil <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behold"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstat"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps, der kører i baggrunden"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryk for at se oplysninger om batteri- og dataforbrug"</string>
</resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index bf6abe3..6e961c2 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -488,7 +488,7 @@
<string name="managed_profile_foreground_toast" msgid="5421487114739245972">"Du verwendest dein Arbeitsprofil."</string>
<string name="stream_voice_call" msgid="4410002696470423714">"Anruf"</string>
<string name="stream_system" msgid="7493299064422163147">"System"</string>
- <string name="stream_ring" msgid="8213049469184048338">"Klingeln lassen"</string>
+ <string name="stream_ring" msgid="8213049469184048338">"Klingelton"</string>
<string name="stream_music" msgid="9086982948697544342">"Medien"</string>
<string name="stream_alarm" msgid="5209444229227197703">"Wecker"</string>
<string name="stream_notification" msgid="2563720670905665031">"Benachrichtigung"</string>
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Bis <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Beibehalten"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersetzen"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps, die im Hintergrund ausgeführt werden"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Für weitere Informationen zur Akku- und Datennutzung tippen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 0359519..226ca40 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Εφαρμογές που εκτελούνται στο παρασκήνιο"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Πατήστε για λεπτομέρειες σχετικά με τη χρήση μπαταρίας και δεδομένων"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 03829e2..507b896 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 03829e2..507b896 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
</resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 03829e2..507b896 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Until <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Keep"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Replace"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps running in background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap for details on battery and data usage"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 298770e..57048a9 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hasta la(s) <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mantener"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps que se ejecutan en segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Presiona para obtener información sobre el uso de datos y de la batería"</string>
</resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index be4bfbb..3a594c8 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hasta <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conservar"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Reemplazar"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicaciones que se están ejecutando en segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para ver información detallada sobre el uso de datos y la batería"</string>
</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index a47bae8..4c8dbae 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Kuni ajani <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Säilita"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Asenda"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Rakendusi käitatakse taustal"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Aku ja andmekasutuse üksikasjade nägemiseks puudutage"</string>
</resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index a060359..9935fcf 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -354,7 +354,7 @@
<string name="description_target_search" msgid="3091587249776033139">"Bilatu"</string>
<string name="description_direction_up" msgid="7169032478259485180">"Lerratu gora hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
<string name="description_direction_left" msgid="7207478719805562165">"Lerratu ezkerrera hau egiteko: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
- <string name="zen_priority_introduction" msgid="3070506961866919502">"Soinuek eta dardarek ez zaituzte eragotziko, zehazten dituzun alarmek, abisuek, gertaerek eta deitzaileek izan ezik."</string>
+ <string name="zen_priority_introduction" msgid="3070506961866919502">"Soinuek eta dardarek ez zaituzte oztoporik egingo, zehazten dituzun alarmek, abisuek, gertaerek eta deitzaileek izan ezik."</string>
<string name="zen_priority_customize_button" msgid="7948043278226955063">"Pertsonalizatu"</string>
<string name="zen_silence_introduction_voice" msgid="2284540992298200729">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak. Telefono-deiak egiteko aukera izaten jarraituko duzu."</string>
<string name="zen_silence_introduction" msgid="3137882381093271568">"Soinu eta dardara GUZTIAK blokeatuko dira, besteak beste, alarmak, musika, bideoak eta jokoak."</string>
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> arte"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Utzi bere horretan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ordeztu"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikazioak exekutatzen ari dira atzeko planoan"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Sakatu bateriaren eta datuen erabilerari buruzko xehetasunak ikusteko"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 2d72800..569ecb7 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"برنامههایی که در پسزمینه اجرا میشوند"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"برای جزئیات مربوط به مصرف باتری و داده، ضربه بزنید"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 7e93185..b108181 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> asti"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Säilytä"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Korvaa"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Sovelluksia käynnissä taustalla"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Katso lisätietoja akun ja datan käytöstä napauttamalla"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 524d5d1..f141186 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Jusqu\'à <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Garder"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Applications qui fonctionnent en arrière-plan"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Touchez ici pour afficher des détails sur l\'usage de la pile et des données"</string>
</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1840035..2efa5f0d 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -300,7 +300,7 @@
<string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi désactivé"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"Wi-Fi activé"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"Aucun réseau Wi-Fi disponible"</string>
- <string name="quick_settings_cast_title" msgid="7709016546426454729">"Diffuser"</string>
+ <string name="quick_settings_cast_title" msgid="7709016546426454729">"Caster"</string>
<string name="quick_settings_casting" msgid="6601710681033353316">"Diffusion"</string>
<string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Appareil sans nom"</string>
<string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Prêt à caster"</string>
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Jusqu\'à <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Conserver"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Remplacer"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Applications en cours d\'exécution en arrière-plan"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Appuyer pour obtenir des informations sur l\'utilisation de la batterie et des données"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 58ff26f..bf34dbe 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Ata: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituír"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicacións que se executan en segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toca para obter información sobre a batería e o uso de datos"</string>
</resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 685359d..dc11151 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"પૃષ્ઠભૂમિમાં ચાલી રહેલ ઍપ્લિકેશનો"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"બૅટરી અને ડેટા વપરાશ વિશેની વિગતો માટે ટૅપ કરો"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index d6275c3..bf8fed2 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ऐप्लिकेशन बैकग्राउंड में चल रहे हैं"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"बैटरी और डेटा उपयोग के विवरण पाने के लिए टैप करें"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 9b3cf36..b0e1e078 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -765,8 +765,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zadrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamijeni"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Izvođenje aplikacija u pozadini"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podataka"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 34f7d07..59826e9 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Eddig: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Megtartás"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Csere"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"A háttérben még futnak alkalmazások"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Az akkumulátor töltöttségének és az adathasználat részleteinek megtekintéséhez koppintson"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 703c17f..61fcc8c 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Հետին ֆոնին գործարկվող հավելվածներ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Հպել՝ մարտկոցի և տվյալների օգտագործման մասին մանրամասներ ստանալու համար"</string>
</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b48d4a5..fcc5f72 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -67,14 +67,14 @@
<string name="usb_debugging_secondary_user_message" msgid="8572228137833020196">"Pengguna yang saat ini masuk ke perangkat ini tidak dapat mengaktifkan debug USB. Untuk menggunakan fitur ini, beralih ke pengguna Admin."</string>
<string name="compat_mode_on" msgid="6623839244840638213">"Perbesar utk mengisi layar"</string>
<string name="compat_mode_off" msgid="4434467572461327898">"Rentangkn utk mngisi layar"</string>
- <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Menyimpan tangkapan layar..."</string>
- <string name="screenshot_saving_title" msgid="8242282144535555697">"Menyimpan tangkapan layar..."</string>
- <string name="screenshot_saving_text" msgid="2419718443411738818">"Tangkapan layar sedang disimpan."</string>
- <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan layar diambil."</string>
- <string name="screenshot_saved_text" msgid="2685605830386712477">"Ketuk untuk melihat tangkapan layar."</string>
- <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat mengambil tangkapan layar."</string>
- <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Terjadi masalah saat menyimpan tangkapan layar."</string>
- <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Tidak dapat menyimpan tangkapan layar karena ruang penyimpanan terbatas."</string>
+ <string name="screenshot_saving_ticker" msgid="7403652894056693515">"Menyimpan screenshot..."</string>
+ <string name="screenshot_saving_title" msgid="8242282144535555697">"Menyimpan screenshot..."</string>
+ <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot sedang disimpan."</string>
+ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot diambil."</string>
+ <string name="screenshot_saved_text" msgid="2685605830386712477">"Ketuk untuk melihat screenshot."</string>
+ <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat mengambil screenshot."</string>
+ <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Terjadi masalah saat menyimpan screenshot."</string>
+ <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"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="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string>
<string name="use_mtp_button_title" msgid="4333504413563023626">"Pasang sebagai pemutar media (MTP)"</string>
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hingga <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ganti"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikasi yang sedang berjalan di latar belakang"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tap untuk melihat detail baterai dan penggunaan data"</string>
</resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index e5d1c33..c13b1bf 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Þar til <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Halda"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Skipta út"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Forrit sem keyra í bakgrunni"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Ýttu til að fá upplýsingar um rafhlöðu- og gagnanotkun"</string>
</resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 2b08202..e572ecd 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Fino alle ore <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mantieni"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Sostituisci"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"App in esecuzione in background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocca per conoscere i dettagli sull\'utilizzo dei dati e della batteria"</string>
</resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index e73be80..6baf08d 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -769,8 +769,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"אפליקציות שפועלות ברקע"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"הקש לקבלת פרטים על צריכה של נתונים וסוללה"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 03ff5c8..d4c21e4 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -763,8 +763,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"バックグラウンドで実行中のアプリ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"タップで電池やデータの使用量の詳細を確認"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 7896f9c..48b5361 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ფონურ რეჟიმში გაშვებული აპები"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"შეეხეთ ბატარეისა და მონაცემების მოხმარების შესახებ დეტალური ინფორმაციისთვის"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 038f461..212a5ce 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Фонда жұмыс істеп тұрған қолданбалар"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батарея мен деректер трафигі туралы мәліметтер алу үшін түртіңіз"</string>
</resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index cad0182..f583dc3 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"កម្មវិធីដែលកំពុងដំណើរការនៅផ្ទៃខាងក្រោយ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ចុចដើម្បីទទួលបានព័ត៌មានលម្អិតអំពីការប្រើប្រាស់ថ្ម និងទិន្នន័យ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index a821347..b447edf 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗುತ್ತಿವೆ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ಬ್ಯಾಟರಿ ಮತ್ತು ಡೇಟಾ ಬಳಕೆಯ ವಿವರಗಳಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e7446cd..088e2e8 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -763,8 +763,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"백그라운드에서 실행 중인 앱"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"탭하여 배터리 및 데이터 사용량에 관한 세부정보 보기"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 2beef3e..835e76b 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -44,7 +44,7 @@
<string name="battery_saver_start_action" msgid="5576697451677486320">"Батареянын кубатын үнөмдөгүчтү иштетүү"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Жөндөөлөр"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi‑Fi"</string>
- <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Экранды авто-тегеретүү"</string>
+ <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Экрандын авто-айлануусу"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ҮНСҮЗ"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"АВТО"</string>
<string name="status_bar_settings_notifications" msgid="397146176280905137">"Эскертмелер"</string>
@@ -276,7 +276,7 @@
<string name="quick_settings_bluetooth_detail_empty_text" msgid="4910015762433302860">"Жупташкан түзмөктөр жок"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Жарыктыгы"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="7305323031808150099">"Автоматтык бурулуу"</string>
- <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Экранды авто-тегеретүү"</string>
+ <string name="accessibility_quick_settings_rotation" msgid="4231661040698488779">"Экрандын авто-айлануусу"</string>
<string name="accessibility_quick_settings_rotation_value" msgid="8187398200140760213">"<xliff:g id="ID_1">%s</xliff:g> режими"</string>
<string name="quick_settings_rotation_locked_label" msgid="6359205706154282377">"Буруу аракети кулпуланган"</string>
<string name="quick_settings_rotation_locked_portrait_label" msgid="5102691921442135053">"Тигинен"</string>
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Фондо иштеп жаткан колдонмолор"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батареянын кубаты жана Интернеттин колдонулушу жөнүндө билүү үчүн таптап коюңуз"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index ee263fa..988e66c 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ແອັບທີ່ກຳລັງເຮັດວຽກໃນພື້ນຫຼັງ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ແຕະເພື່ອເບິ່ງລາຍລະອຽດການນຳໃຊ້ແບັດເຕີຣີ ແລະ ອິນເຕີເນັດ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index e9374db..98e464b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -769,8 +769,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Iki <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Palikti"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Pakeisti"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Programos, veikiančios fone"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Palieskite ir sužinokite išsamios informacijos apie akumuliatoriaus bei duomenų naudojimą"</string>
</resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index a364b20..b765495 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -765,8 +765,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Līdz: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Paturēt"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Aizstāt"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Lietotnes, kas darbojas fonā"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Pieskarieties, lai skatītu detalizētu informāciju par akumulatora un datu lietojumu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 577b6c2..47571a4 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Апликациите се извршуваат во заднина"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Допрете за детали за батеријата и потрошениот сообраќај"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index d4a448a..f888863 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ആപ്പുകൾ പശ്ചാത്തലത്തിൽ റൺ ചെയ്യുന്നു"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ബാറ്ററി, ഡാറ്റ ഉപയോഗം എന്നിവയുടെ വിശദാംശങ്ങളറിയാൻ ടാപ്പുചെയ്യുക"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 73cfe2a..044bd51 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Цаана ажиллаж буй апп"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Батерей, дата ашиглалтын талаар дэлгэрэнгүй мэдээллийг харахын тулд товшино уу"</string>
</resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 80c7105..6545315 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"अॅप्स बॅकग्राउंडमध्ये चालू आहेत"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"बॅटरी आणि डेटा वापराच्या तपशीलांसाठी टॅप करा"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 9979ee9..c1cec2c 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hingga <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Simpan"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Gantikan"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apl yang berjalan di latar belakang"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Ketik untuk mendapatkan butiran tentang penggunaan kuasa bateri dan data"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index b7240c4..8cf5b49 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"နောက်ခံတွင် ပွင့်နေသော အက်ပ်များ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ဘက်ထရီနှင့် ဒေတာအသုံးပြုမှု အသေးစိတ်ကို ကြည့်ရန် တို့ပါ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index f1ea1b4..e4ea8e4 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Til <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behold"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Erstatt"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apper kjører i bakgrunnen"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trykk for detaljer om batteri- og databruk"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 750ea66..2d81d98 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"पृष्ठभूमिमा चल्ने अनुप्रयोगहरू"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ब्याट्री र डेटा प्रयोग सम्बन्धी विवरणहरूका लागि ट्याप गर्नुहोस्"</string>
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 7bda230..3f6d361 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Tot <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behouden"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Vervangen"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps uitgevoerd op achtergrond"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tik voor informatie over batterij- en datagebruik"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index bfdd66f..25118d7 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ਬੈਕਗ੍ਰਾਊਂਡ ਵਿੱਚ ਚੱਲਣ ਵਾਲੀਆਂ ਐਪਾਂ"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"ਬੈਟਰੀ ਅਤੇ ਡੈਟਾ ਉਪਯੋਗ ਸਬੰਧੀ ਵੇਰਵਿਆਂ ਲਈ ਟੈਪ ਕਰੋ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 3f6f2eb..d1a1d54 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -157,7 +157,7 @@
<string name="accessibility_cell_data" msgid="5326139158682385073">"Mobilna transmisja danych"</string>
<string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobilna transmisja danych włączona"</string>
<string name="accessibility_cell_data_off" msgid="443267573897409704">"Mobilna transmisja danych wyłączona"</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Powiązanie Bluetooth."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Thethering przez Bluetooth."</string>
<string name="accessibility_airplane_mode" msgid="834748999790763092">"Tryb samolotowy."</string>
<string name="accessibility_vpn_on" msgid="5993385083262856059">"Sieć VPN włączona."</string>
<string name="accessibility_no_sims" msgid="3957997018324995781">"Brak karty SIM."</string>
@@ -769,8 +769,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Zachowaj"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zastąp"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacje działające w tle"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Kliknij, by wyświetlić szczegóły wykorzystania baterii i transmisji danych"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a1dc89b..af9bc43 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Até <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps sendo executados em segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c485e68..f5d0a24 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Até à(s) <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicações em execução em segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Toque para obter detalhes acerca da utilização da bateria e dos dados"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a1dc89b..af9bc43 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Até <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Manter"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Substituir"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Apps sendo executados em segundo plano"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tocar para ver detalhes sobre a bateria e o uso de dados"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a2aab3a..c9569ab 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -767,8 +767,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Până la <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Păstrați"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Înlocuiți"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplicațiile rulează în fundal"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Atingeți pentru mai multe detalii privind bateria și utilizarea datelor"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 79dc9ad..f6d8dab 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -771,8 +771,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Приложения, работающие в фоновом режиме"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Нажмите, чтобы увидеть данные об энергопотреблении и объеме трафика"</string>
</resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 970f909..780b05d 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"පසුබිමින් ධාවනය වන යෙදුම්"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"බැටරි හා දත්ත භාවිතය පිළිබඳව විස්තර සඳහා තට්ටු කරන්න"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 3bb08ad..179ab42 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -771,8 +771,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikácie sú spustené na pozadí"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Klepnutím zobrazíte podrobnosti o batérii a spotrebe dát"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 1b19346..1da66b8 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -771,8 +771,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Do <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Obdrži"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zamenjaj"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacije, ki se izvajajo v ozadju"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dotaknite se za prikaz podrobnosti porabe akumulatorja in prenosa podatkov"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 12ef7e4..64e409e 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Deri në <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Mbaj"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Zëvendëso"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Aplikacionet që ekzekutohen në sfond"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Trokit për detaje për baterinë dhe përdorimin e të dhënave"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index a95d9ce..0877ce9 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -400,7 +400,7 @@
<string name="user_logout_notification_text" msgid="3350262809611876284">"Одјавите актуелног корисника"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"ОДЈАВИ КОРИСНИКА"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Додајете новог корисника?"</string>
- <string name="user_add_user_message_short" msgid="2161624834066214559">"Када додате новог корисника, та особа треба да подеси сопствени простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"Када додате новог корисника, та особа треба да подеси свој простор.\n\nСваки корисник може да ажурира апликације за све остале кориснике."</string>
<string name="user_remove_user_title" msgid="4681256956076895559">"Желите ли да уклоните корисника?"</string>
<string name="user_remove_user_message" msgid="1453218013959498039">"Све апликације и подаци овог корисника ће бити избрисани."</string>
<string name="user_remove_user_remove" msgid="7479275741742178297">"Уклони"</string>
@@ -590,8 +590,8 @@
<string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Тастер са стрелицом налево"</string>
<string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Тастер са стрелицом надесно"</string>
<string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Тастер са централном стрелицом"</string>
- <string name="keyboard_key_tab" msgid="3871485650463164476">"Табулатор"</string>
- <string name="keyboard_key_space" msgid="2499861316311153293">"Тастер за размак"</string>
+ <string name="keyboard_key_tab" msgid="3871485650463164476">"Tab"</string>
+ <string name="keyboard_key_space" msgid="2499861316311153293">"Размак"</string>
<string name="keyboard_key_enter" msgid="5739632123216118137">"Enter"</string>
<string name="keyboard_key_backspace" msgid="1559580097512385854">"Тастер за брисање уназад"</string>
<string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Тастер за репродукцију/паузирање"</string>
@@ -657,7 +657,7 @@
</string-array>
<string name="menu_ime" msgid="4998010205321292416">"Пребацивач за тастатуру"</string>
<string name="save" msgid="2311877285724540644">"Сачувај"</string>
- <string name="reset" msgid="2448168080964209908">"Поново постави"</string>
+ <string name="reset" msgid="2448168080964209908">"Ресетуј"</string>
<string name="adjust_button_width" msgid="6138616087197632947">"Прилагоди ширину дугмета"</string>
<string name="clipboard" msgid="1313879395099896312">"Привремена меморија"</string>
<string name="accessibility_key" msgid="5701989859305675896">"Прилагођено дугме за навигацију"</string>
@@ -765,8 +765,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Апликације покренуте у позадини"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Додирните да бисте прегледали детаље о батерији и потрошњи података"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index ca067d9..ede947c 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Till <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Behåll"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Ersätt"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Appar körs i bakgrunden"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Tryck för information om batteri- och dataanvändning"</string>
</resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9367c8d..443dcb1 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hadi <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Usibadilishe"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Badilisha"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Programu zinatumika chinichini"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Gonga ili upate maelezo kuhusu betri na matumizi ya data"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 0a0acdb..87e5a74 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"பின்னணியில் இயங்கும் பயன்பாடுகள்"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"பேட்டரி மற்றும் தரவு உபயோகம் குறித்த விவரங்களுக்கு, தட்டவும்"</string>
</resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5cdb830..fb39bef 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"నేపథ్యంలో అమలు అవుతున్న ఆప్లు"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"బ్యాటరీ మరియు డేటా వినియోగ వివరాల కోసం నొక్కండి"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index d68a9a8..e2d937e 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"แอปที่กำลังทำงานในเบื้องหลัง"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"แตะเพื่อดูรายละเอียดเกี่ยวกับแบตเตอรี่และปริมาณการใช้อินเทอร์เน็ต"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 5dc3e78..4a06790 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Hanggang <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Panatilihin"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Palitan"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Tumatakbo ang mga app sa background"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"I-tap para sa mga detalye tungkol sa paggamit ng baterya at data"</string>
</resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index ce01e29..dabc574 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Bitiş: <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Koru"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Değiştir"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Uygulamalar arka planda çalışıyor"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Pil ve veri kullanımı ile ilgili ayrıntılar için dokunun"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index ba60ba6..8e18815 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -771,8 +771,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Додатки, які працюють у фоновому режимі"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Торкніться, щоб переглянути інформацію про використання заряду акумулятора та даних"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 545ff66..1a33e0c 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"ایپس پس منظر میں چل رہی ہیں"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"بیٹری اور ڈیٹا استعمال کے بارے میں تفصیلات کے لیے تھپتھپائیں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 23716ac..049d1b0 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"<xliff:g id="ID_1">%s</xliff:g> gacha"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Saqlab qolish"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Almashtirish"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Fonda ishlayotgan ilovalar"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Batareya va trafik sarfiga oid tafsilotlarni olish uchun ustiga bosing"</string>
</resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 476098a..149dc99 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -763,8 +763,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Cho tới <xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Giữ"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Thay thế"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Ứng dụng đang chạy trong nền"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Nhấn để biết chi tiết về pin và mức sử dụng dữ liệu"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6b751ec..ef84d76 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"在后台运行的应用"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"点按即可详细了解电量和流量消耗情况"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 95c9356..05cfdb0 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -763,8 +763,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"正在背景中執行的應用程式"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕按即可查看電池和數據用量詳情"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 9a0c13e..6f5a058 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -761,8 +761,6 @@
<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>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"在背景執行的應用程式"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"輕觸即可取得電池和數據用量的詳細資料"</string>
</resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6981bbd..0c2eb6c 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -761,8 +761,6 @@
<string name="qs_dnd_until" msgid="3469471136280079874">"Kuze kube-<xliff:g id="ID_1">%s</xliff:g>"</string>
<string name="qs_dnd_keep" msgid="1825009164681928736">"Gcina"</string>
<string name="qs_dnd_replace" msgid="8019520786644276623">"Buyisela"</string>
- <!-- no translation found for running_foreground_services_title (381024150898615683) -->
- <skip />
- <!-- no translation found for running_foreground_services_msg (6326247670075574355) -->
- <skip />
+ <string name="running_foreground_services_title" msgid="381024150898615683">"Izinhlelo zokusebenza zisebenza ngasemuva"</string>
+ <string name="running_foreground_services_msg" msgid="6326247670075574355">"Thepha ngemininingwane ekusetshenzisweni kwebhethri nedatha"</string>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bf70c5a..d15fcae 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2033,7 +2033,9 @@
<!-- Title of the "running foreground services" dialog. [CHAR LIMIT=NONE] -->
<string name="running_foreground_services_title">Apps running in background</string>
- <!-- Title of the "running foreground services" dialog. [CHAR LIMIT=NONE] -->
+ <!-- Descriptive text of an item in the "running foreground services" dialog, telling the
+ user what will happen when they tap on that item (which is an application that has
+ been identified for them as running). [CHAR LIMIT=NONE] -->
<string name="running_foreground_services_msg">Tap for details on battery and data usage</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
index 086e5e5..9d286cf 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServicesDialog.java
@@ -26,6 +26,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
+import android.util.IconDrawableFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -65,7 +66,7 @@
private DialogInterface.OnClickListener mAppClickListener =
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- String pkg = mPackages[which];
+ String pkg = mAdapter.getItem(which).packageName;
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", pkg, null));
startActivity(intent);
@@ -159,11 +160,13 @@
static private class PackageItemAdapter extends ArrayAdapter<ApplicationInfo> {
final PackageManager mPm;
final LayoutInflater mInflater;
+ final IconDrawableFactory mIconDrawableFactory;
public PackageItemAdapter(Context context) {
super(context, R.layout.foreground_service_item);
mPm = context.getPackageManager();
mInflater = LayoutInflater.from(context);
+ mIconDrawableFactory = IconDrawableFactory.newInstance(context, true);
}
public void setPackages(String[] packages) {
@@ -193,7 +196,7 @@
}
ImageView icon = view.findViewById(R.id.app_icon);
- icon.setImageDrawable(getItem(position).loadIcon(mPm));
+ icon.setImageDrawable(mIconDrawableFactory.getBadgedIcon(getItem(position)));
TextView label = view.findViewById(R.id.app_name);
label.setText(getItem(position).loadLabel(mPm));
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index ba8e54a..eea09df 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -18,23 +18,18 @@
import android.app.AlarmManager;
import android.app.Application;
-import android.app.PendingIntent;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Handler;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.systemui.SystemUIApplication;
-import com.android.systemui.plugins.doze.DozeProvider;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.wakelock.WakeLock;
public class DozeFactory {
- private final DozeProvider mDozePlugin;
-
- public DozeFactory(DozeProvider plugin) {
- mDozePlugin = plugin;
+ public DozeFactory() {
}
/** Creates a DozeMachine with its parts for {@code dozeService}. */
@@ -65,89 +60,14 @@
private DozeTriggers createDozeTriggers(Context context, SensorManager sensorManager,
DozeHost host, AmbientDisplayConfiguration config, DozeParameters params,
Handler handler, WakeLock wakeLock, DozeMachine machine) {
- boolean allowPulseTriggers = mDozePlugin == null || mDozePlugin.allowDefaultPulseTriggers();
+ boolean allowPulseTriggers = true;
return new DozeTriggers(context, machine, host, config, params,
sensorManager, handler, wakeLock, allowPulseTriggers);
}
private DozeMachine.Part createDozeUi(Context context, DozeHost host, WakeLock wakeLock,
DozeMachine machine, Handler handler, AlarmManager alarmManager) {
- if (mDozePlugin != null) {
- DozeProvider.DozeUi dozeUi = mDozePlugin.provideDozeUi(context,
- pluginMachine(context, machine, host),
- wakeLock);
- return (oldState, newState) -> {
- dozeUi.transitionTo(pluginState(oldState),
- pluginState(newState));
- };
- } else {
- return new DozeUi(context, alarmManager, machine, wakeLock, host, handler);
- }
- }
-
- private DozeProvider.DozeMachine pluginMachine(Context context, DozeMachine machine,
- DozeHost host) {
- return new DozeProvider.DozeMachine() {
- @Override
- public void requestState(DozeProvider.DozeState state) {
- if (state == DozeProvider.DozeState.WAKE_UP) {
- machine.wakeUp();
- return;
- }
- machine.requestState(implState(state));
- }
-
- @Override
- public void requestSendIntent(PendingIntent intent) {
- host.startPendingIntentDismissingKeyguard(intent);
- }
- };
- }
-
- private DozeMachine.State implState(DozeProvider.DozeState s) {
- switch (s) {
- case UNINITIALIZED:
- return DozeMachine.State.UNINITIALIZED;
- case INITIALIZED:
- return DozeMachine.State.INITIALIZED;
- case DOZE:
- return DozeMachine.State.DOZE;
- case DOZE_AOD:
- return DozeMachine.State.DOZE_AOD;
- case DOZE_REQUEST_PULSE:
- return DozeMachine.State.DOZE_REQUEST_PULSE;
- case DOZE_PULSING:
- return DozeMachine.State.DOZE_PULSING;
- case DOZE_PULSE_DONE:
- return DozeMachine.State.DOZE_PULSE_DONE;
- case FINISH:
- return DozeMachine.State.FINISH;
- default:
- throw new IllegalArgumentException("Unknown state: " + s);
- }
- }
-
- private DozeProvider.DozeState pluginState(DozeMachine.State s) {
- switch (s) {
- case UNINITIALIZED:
- return DozeProvider.DozeState.UNINITIALIZED;
- case INITIALIZED:
- return DozeProvider.DozeState.INITIALIZED;
- case DOZE:
- return DozeProvider.DozeState.DOZE;
- case DOZE_AOD:
- return DozeProvider.DozeState.DOZE_AOD;
- case DOZE_REQUEST_PULSE:
- return DozeProvider.DozeState.DOZE_REQUEST_PULSE;
- case DOZE_PULSING:
- return DozeProvider.DozeState.DOZE_PULSING;
- case DOZE_PULSE_DONE:
- return DozeProvider.DozeState.DOZE_PULSE_DONE;
- case FINISH:
- return DozeProvider.DozeState.FINISH;
- default:
- throw new IllegalArgumentException("Unknown state: " + s);
- }
+ return new DozeUi(context, alarmManager, machine, wakeLock, host, handler);
}
public static DozeHost getHost(DozeService service) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
index 7139d59..af02e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeLog.java
@@ -37,6 +37,7 @@
private static final int PULSE_REASONS = 5;
+ public static final int PULSE_REASON_NONE = -1;
public static final int PULSE_REASON_INTENT = 0;
public static final int PULSE_REASON_NOTIFICATION = 1;
public static final int PULSE_REASON_SENSOR_SIGMOTION = 2;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 38b32e9..44bb33a 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -106,6 +106,7 @@
private final ArrayList<State> mQueuedRequests = new ArrayList<>();
private State mState = State.UNINITIALIZED;
+ private int mPulseReason;
private boolean mWakeLockHeldForCurrentState = false;
public DozeMachine(Service service, AmbientDisplayConfiguration config,
@@ -133,6 +134,20 @@
*/
@MainThread
public void requestState(State requestedState) {
+ Preconditions.checkArgument(requestedState != State.DOZE_REQUEST_PULSE);
+ requestState(requestedState, DozeLog.PULSE_REASON_NONE);
+ }
+
+ @MainThread
+ public void requestPulse(int pulseReason) {
+ // Must not be called during a transition. There's no inherent problem with that,
+ // but there's currently no need to execute from a transition and it simplifies the
+ // code to not have to worry about keeping the pulseReason in mQueuedRequests.
+ Preconditions.checkState(!isExecutingTransition());
+ requestState(State.DOZE_REQUEST_PULSE, pulseReason);
+ }
+
+ private void requestState(State requestedState, int pulseReason) {
Assert.isMainThread();
if (DEBUG) {
Log.i(TAG, "request: current=" + mState + " req=" + requestedState,
@@ -146,7 +161,7 @@
for (int i = 0; i < mQueuedRequests.size(); i++) {
// Transitions in Parts can call back into requestState, which will
// cause mQueuedRequests to grow.
- transitionTo(mQueuedRequests.get(i));
+ transitionTo(mQueuedRequests.get(i), pulseReason);
}
mQueuedRequests.clear();
mWakeLock.release();
@@ -165,6 +180,20 @@
return mState;
}
+ /**
+ * @return the current pulse reason.
+ *
+ * This is only valid if the machine is currently in one of the pulse states.
+ */
+ @MainThread
+ public int getPulseReason() {
+ Assert.isMainThread();
+ Preconditions.checkState(mState == State.DOZE_REQUEST_PULSE
+ || mState == State.DOZE_PULSING
+ || mState == State.DOZE_PULSE_DONE, "must be in pulsing state, but is " + mState);
+ return mPulseReason;
+ }
+
/** Requests the PowerManager to wake up now. */
public void wakeUp() {
mDozeService.requestWakeUp();
@@ -174,7 +203,7 @@
return !mQueuedRequests.isEmpty();
}
- private void transitionTo(State requestedState) {
+ private void transitionTo(State requestedState, int pulseReason) {
State newState = transitionPolicy(requestedState);
if (DEBUG) {
@@ -190,6 +219,7 @@
State oldState = mState;
mState = newState;
+ updatePulseReason(newState, oldState, pulseReason);
performTransitionOnComponents(oldState, newState);
updateScreenState(newState);
updateWakeLockState(newState);
@@ -197,6 +227,14 @@
resolveIntermediateState(newState);
}
+ private void updatePulseReason(State newState, State oldState, int pulseReason) {
+ if (newState == State.DOZE_REQUEST_PULSE) {
+ mPulseReason = pulseReason;
+ } else if (oldState == State.DOZE_PULSE_DONE) {
+ mPulseReason = DozeLog.PULSE_REASON_NONE;
+ }
+ }
+
private void performTransitionOnComponents(State oldState, State newState) {
for (Part p : mParts) {
p.transitionTo(oldState, newState);
@@ -280,7 +318,8 @@
case INITIALIZED:
case DOZE_PULSE_DONE:
transitionTo(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
- ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
+ ? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE,
+ DozeLog.PULSE_REASON_NONE);
break;
default:
break;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index e55a597..5241266 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -24,7 +24,6 @@
import com.android.systemui.Dependency;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.plugins.doze.DozeProvider;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -50,9 +49,7 @@
return;
}
- DozeProvider provider = Dependency.get(PluginManager.class)
- .getOneShotPlugin(DozeProvider.class);
- mDozeMachine = new DozeFactory(provider).assembleMachine(this);
+ mDozeMachine = new DozeFactory().assembleMachine(this);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 2096956..563b8fe 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -227,7 +227,7 @@
mDozeHost.isPulsingBlocked());
return;
}
- mMachine.requestState(DozeMachine.State.DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(reason);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 03076cc..64a152e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -83,7 +83,7 @@
unscheduleTimeTick();
break;
case DOZE_REQUEST_PULSE:
- pulseWhileDozing(DozeLog.PULSE_REASON_NOTIFICATION /* TODO */);
+ pulseWhileDozing(mMachine.getPulseReason());
break;
case DOZE_PULSE_DONE:
mHost.abortPulsing();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index df03fdc..bdc0871 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -107,12 +107,12 @@
}
@Override
- public void onPinnedActivityRestartAttempt() {
+ public void onPinnedActivityRestartAttempt(boolean clearedTask) {
if (!checkCurrentUserId(false /* debug */)) {
return;
}
- mTouchHandler.getMotionHelper().expandPip();
+ mTouchHandler.getMotionHelper().expandPip(clearedTask /* skipAnimation */);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index d5cf1dd..5afa53f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -132,9 +132,6 @@
}
case MESSAGE_EXPAND_PIP: {
mListeners.forEach(l -> l.onPipExpand());
- // Preemptively mark the menu as invisible once we expand the PiP, but don't
- // resize as we will be animating the stack
- onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
break;
}
case MESSAGE_MINIMIZE_PIP: {
@@ -143,9 +140,6 @@
}
case MESSAGE_DISMISS_PIP: {
mListeners.forEach(l -> l.onPipDismiss());
- // Preemptively mark the menu as invisible once we dismiss the PiP, but don't
- // resize as we'll be removing the stack in place
- onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
break;
}
case MESSAGE_SHOW_MENU: {
@@ -308,6 +302,15 @@
}
/**
+ * Preemptively mark the menu as invisible, used when we are directly manipulating the pinned
+ * stack and don't want to trigger a resize which can animate the stack in a conflicting way
+ * (ie. when manually expanding or dismissing).
+ */
+ public void hideMenuWithoutResize() {
+ onMenuStateChanged(MENU_STATE_NONE, false /* resize */);
+ }
+
+ /**
* @return the current menu state.
*/
public int getMenuState() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index fc52a2e..590e3c6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -77,6 +77,7 @@
private SurfaceFlingerVsyncChoreographer mVsyncChoreographer;
private Handler mHandler;
+ private PipMenuActivityController mMenuController;
private PipSnapAlgorithm mSnapAlgorithm;
private FlingAnimationUtils mFlingAnimationUtils;
@@ -93,10 +94,12 @@
};
public PipMotionHelper(Context context, IActivityManager activityManager,
- PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils) {
+ PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
+ FlingAnimationUtils flingAnimationUtils) {
mContext = context;
mHandler = BackgroundThread.getHandler();
mActivityManager = activityManager;
+ mMenuController = menuController;
mSnapAlgorithm = snapAlgorithm;
mFlingAnimationUtils = flingAnimationUtils;
mVsyncChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, mContext.getDisplay(),
@@ -140,14 +143,26 @@
* Resizes the pinned stack back to fullscreen.
*/
void expandPip() {
+ expandPip(false /* skipAnimation */);
+ }
+
+ /**
+ * Resizes the pinned stack back to fullscreen.
+ */
+ void expandPip(boolean skipAnimation) {
cancelAnimations();
+ mMenuController.hideMenuWithoutResize();
mHandler.post(() -> {
try {
- mActivityManager.resizeStack(PINNED_STACK_ID, null /* bounds */,
- true /* allowResizeInDockedMode */, true /* preserveWindows */,
- true /* animate */, EXPAND_STACK_TO_FULLSCREEN_DURATION);
+ if (skipAnimation) {
+ mActivityManager.moveTasksToFullscreenStack(PINNED_STACK_ID, true /* onTop */);
+ } else {
+ mActivityManager.resizeStack(PINNED_STACK_ID, null /* bounds */,
+ true /* allowResizeInDockedMode */, true /* preserveWindows */,
+ true /* animate */, EXPAND_STACK_TO_FULLSCREEN_DURATION);
+ }
} catch (RemoteException e) {
- Log.e(TAG, "Error showing PiP menu activity", e);
+ Log.e(TAG, "Error expanding PiP activity", e);
}
});
}
@@ -157,6 +172,7 @@
*/
void dismissPip() {
cancelAnimations();
+ mMenuController.hideMenuWithoutResize();
mHandler.post(() -> {
try {
mActivityManager.removeStack(PINNED_STACK_ID);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 9c7e3986..71d3d35 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -191,8 +191,8 @@
mGestures = new PipTouchGesture[] {
mDefaultMovementGesture
};
- mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mSnapAlgorithm,
- mFlingAnimationUtils);
+ mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mMenuController,
+ mSnapAlgorithm, mFlingAnimationUtils);
mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
R.dimen.pip_expanded_shortest_edge_size);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 657f08b..9735bfc 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -625,7 +625,7 @@
}
@Override
- public void onPinnedActivityRestartAttempt() {
+ public void onPinnedActivityRestartAttempt(boolean clearedTask) {
if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
if (!checkCurrentUserId(DEBUG)) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index f5e096eb..c4d88ae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.metrics.LogMaker;
import android.os.Handler;
import android.os.Message;
import android.service.quicksettings.Tile;
@@ -30,6 +31,7 @@
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
+
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
@@ -179,7 +181,7 @@
public void openDetails(String subPanel) {
QSTile tile = getTile(subPanel);
- showDetailAdapter(true, tile.getDetailAdapter(), new int[] {getWidth() / 2, 0});
+ showDetailAdapter(true, tile.getDetailAdapter(), new int[]{getWidth() / 2, 0});
}
private QSTile getTile(String subPanel) {
@@ -485,8 +487,9 @@
private void logTiles() {
for (int i = 0; i < mRecords.size(); i++) {
- TileRecord tileRecord = mRecords.get(i);
- mMetricsLogger.visible(tileRecord.tile.getMetricsCategory());
+ QSTile tile = mRecords.get(i).tile;
+ mMetricsLogger.write(tile.populate(new LogMaker(tile.getMetricsCategory())
+ .setType(MetricsEvent.TYPE_OPEN)));
}
}
@@ -544,12 +547,13 @@
private static final int SHOW_DETAIL = 1;
private static final int SET_TILE_VISIBILITY = 2;
private static final int ANNOUNCE_FOR_ACCESSIBILITY = 3;
+
@Override
public void handleMessage(Message msg) {
if (msg.what == SHOW_DETAIL) {
- handleShowDetail((Record)msg.obj, msg.arg1 != 0);
+ handleShowDetail((Record) msg.obj, msg.arg1 != 0);
} else if (msg.what == ANNOUNCE_FOR_ACCESSIBILITY) {
- announceForAccessibility((CharSequence)msg.obj);
+ announceForAccessibility((CharSequence) msg.obj);
}
}
}
@@ -569,8 +573,11 @@
public interface QSTileLayout {
void addTile(TileRecord tile);
+
void removeTile(TileRecord tile);
+
int getOffsetTop(TileRecord tile);
+
boolean updateResources();
void setListening(boolean listening);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index dc9176f..017365f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -157,7 +157,7 @@
}
@Override
- protected LogMaker populate(LogMaker logMaker) {
+ public LogMaker populate(LogMaker logMaker) {
return super.populate(logMaker).setComponentName(mComponent);
}
@@ -275,7 +275,6 @@
} catch (RemoteException e) {
// Called through wrapper, won't happen here.
}
- MetricsLogger.action(mContext, getMetricsCategory(), mComponent.getPackageName());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 976efb2..32af230 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -175,7 +175,7 @@
mHandler.sendEmptyMessage(H.LONG_CLICK);
}
- protected LogMaker populate(LogMaker logMaker) {
+ public LogMaker populate(LogMaker logMaker) {
if (mState instanceof BooleanState) {
logMaker.addTaggedData(FIELD_QS_VALUE, ((BooleanState) mState).value ? 1 : 0);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index a9e1f61..f431517 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -158,7 +158,7 @@
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
public void onActivityPinned(String packageName) { }
public void onActivityUnpinned() { }
- public void onPinnedActivityRestartAttempt() { }
+ public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
public void onPinnedStackAnimationStarted() { }
public void onPinnedStackAnimationEnded() { }
public void onActivityForcedResizable(String packageName, int taskId, int reason) { }
@@ -223,10 +223,11 @@
}
@Override
- public void onPinnedActivityRestartAttempt()
+ public void onPinnedActivityRestartAttempt(boolean clearedTask)
throws RemoteException{
mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
- mHandler.sendEmptyMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
+ mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, clearedTask ? 1 : 0, 0)
+ .sendToTarget();
}
@Override
@@ -1294,7 +1295,8 @@
}
case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
- mTaskStackListeners.get(i).onPinnedActivityRestartAttempt();
+ mTaskStackListeners.get(i).onPinnedActivityRestartAttempt(
+ msg.arg1 != 0);
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 5817e92..36be49d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -279,6 +279,7 @@
}
MetricsLogger.action(mSv.getContext(), MetricsEvent.OVERVIEW_SCROLL);
+ mLastY = mDownY = y;
}
}
if (mIsScrolling) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java
index 82910b8..454edbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ImageGradientColorizer.java
@@ -34,7 +34,7 @@
* A utility class to colorize bitmaps with a color gradient and a special blending mode
*/
public class ImageGradientColorizer {
- public Bitmap colorize(Drawable drawable, int backgroundColor) {
+ public Bitmap colorize(Drawable drawable, int backgroundColor, boolean isRtl) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
int size = Math.min(width, height);
@@ -70,8 +70,6 @@
0, 0, 0, 1, 0,
});
- drawable.setColorFilter(new ColorMatrixColorFilter(m));
- drawable.draw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
LinearGradient linearGradient = new LinearGradient(0, 0, size, 0,
new int[] {0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
@@ -81,16 +79,27 @@
Canvas fadeInCanvas = new Canvas(fadeIn);
drawable.clearColorFilter();
drawable.draw(fadeInCanvas);
+
+ if (isRtl) {
+ // Let's flip the gradient
+ fadeInCanvas.translate(size, 0);
+ fadeInCanvas.scale(-1, 1);
+ }
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
fadeInCanvas.drawPaint(paint);
+
+ Paint coloredPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ coloredPaint.setColorFilter(new ColorMatrixColorFilter(m));
+ coloredPaint.setAlpha((int) (0.5f * 255));
+ canvas.drawBitmap(fadeIn, 0, 0, coloredPaint);
+
+ linearGradient = new LinearGradient(0, 0, size, 0,
+ new int[] {0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
+ new float[] {0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
+ paint.setShader(linearGradient);
+ fadeInCanvas.drawPaint(paint);
canvas.drawBitmap(fadeIn, 0, 0, null);
- linearGradient = new LinearGradient(0, 0, size, 0,
- new int[] {backgroundColor, Color.argb(0.5f, tr, tg, tb), 0},
- new float[] {0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
- paint.setShader(linearGradient);
- paint.setXfermode(null);
- canvas.drawPaint(paint);
return newBitmap;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
index cef225b..52c053f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/MediaNotificationProcessor.java
@@ -25,6 +25,7 @@
import android.graphics.drawable.Icon;
import android.support.v4.graphics.ColorUtils;
import android.support.v7.graphics.Palette;
+import android.util.LayoutDirection;
import com.android.systemui.R;
@@ -187,7 +188,9 @@
: R.color.notification_material_background_color;
backgroundColor = mContext.getColor(id);
}
- Bitmap colorized = mColorizer.colorize(drawable, backgroundColor);
+ Bitmap colorized = mColorizer.colorize(drawable, backgroundColor,
+ mContext.getResources().getConfiguration().getLayoutDirection() ==
+ LayoutDirection.RTL);
builder.setLargeIcon(Icon.createWithBitmap(colorized));
}
}
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 c1859fe..badbcb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2489,29 +2489,28 @@
}
StringBuilder flagdbg = new StringBuilder();
- flagdbg.append("disable: < ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "EXPAND" : "expand");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "ICONS" : "icons");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_BACK) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_HOME) != 0) ? "HOME" : "home");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_HOME) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_RECENT) != 0) ? "RECENT" : "recent");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_RECENT) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "CLOCK" : "clock");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_CLOCK) != 0) ? "* " : " ");
- flagdbg.append(((state1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "SEARCH" : "search");
- flagdbg.append(((diff1 & StatusBarManager.DISABLE_SEARCH) != 0) ? "* " : " ");
- flagdbg.append(((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "QUICK_SETTINGS"
- : "quick_settings");
- flagdbg.append(((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS) != 0) ? "* " : " ");
- flagdbg.append(">");
+ flagdbg.append("disable<");
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_EXPAND)) ? 'E' : 'e');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_EXPAND)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS)) ? 'I' : 'i');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ICONS)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS)) ? 'A' : 'a');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_NOTIFICATION_ALERTS)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_SYSTEM_INFO)) ? 'S' : 's');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_SYSTEM_INFO)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_BACK)) ? 'B' : 'b');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_BACK)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_HOME)) ? 'H' : 'h');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_HOME)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_RECENT)) ? 'R' : 'r');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_RECENT)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_CLOCK)) ? 'C' : 'c');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_CLOCK)) ? '!' : ' ');
+ flagdbg.append(0 != ((state1 & StatusBarManager.DISABLE_SEARCH)) ? 'S' : 's');
+ flagdbg.append(0 != ((diff1 & StatusBarManager.DISABLE_SEARCH)) ? '!' : ' ');
+ flagdbg.append(0 != ((state2 & StatusBarManager.DISABLE2_QUICK_SETTINGS)) ? 'Q' : 'q');
+ flagdbg.append(0 != ((diff2 & StatusBarManager.DISABLE2_QUICK_SETTINGS)) ? '!' : ' ');
+ flagdbg.append('>');
Log.d(TAG, flagdbg.toString());
if ((diff1 & StatusBarManager.DISABLE_EXPAND) != 0) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
index a2d1baf..c726189 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EmergencyCryptkeeperText.java
@@ -47,6 +47,11 @@
public void onPhoneStateChanged(int phoneState) {
update();
}
+
+ @Override
+ public void onRefreshCarrierInfo() {
+ update();
+ }
};
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
index eea3de3..215604b 100644
--- a/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
+++ b/packages/SystemUI/src/com/android/systemui/util/wakelock/WakeLock.java
@@ -20,10 +20,17 @@
import android.os.PowerManager;
import android.support.annotation.VisibleForTesting;
-import com.android.systemui.plugins.doze.DozeProvider;
-
/** WakeLock wrapper for testability */
-public interface WakeLock extends DozeProvider.WakeLock {
+public interface WakeLock {
+
+ /** @see android.os.PowerManager.WakeLock#acquire() */
+ void acquire();
+
+ /** @see android.os.PowerManager.WakeLock#release() */
+ void release();
+
+ /** @see android.os.PowerManager.WakeLock#wrap(Runnable) */
+ Runnable wrap(Runnable r);
static WakeLock createPartial(Context context, String tag) {
return wrap(createPartialInner(context, tag));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
index cdbde5e..d203602 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeMachineTest.java
@@ -106,7 +106,7 @@
public void testPulseDone_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
mMachine.requestState(INITIALIZED);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -119,7 +119,7 @@
public void testPulseDone_goesToAoD() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -163,7 +163,7 @@
public void testWakeLock_heldInPulseStates() {
mMachine.requestState(INITIALIZED);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertTrue(mWakeLockFake.isHeld());
mMachine.requestState(DOZE_PULSING);
@@ -186,7 +186,7 @@
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
mMachine.requestState(DOZE_PULSE_DONE);
@@ -198,9 +198,9 @@
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSE_DONE);
}
@@ -209,7 +209,7 @@
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSE_DONE);
}
@@ -235,7 +235,7 @@
public void testScreen_onInPulse() {
mMachine.requestState(INITIALIZED);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
@@ -246,7 +246,7 @@
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertEquals(Display.STATE_OFF, mServiceFake.screenState);
}
@@ -256,7 +256,7 @@
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_AOD);
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertEquals(Display.STATE_DOZE, mServiceFake.screenState);
}
@@ -270,12 +270,43 @@
return null;
}).when(mPartMock).transitionTo(any(), eq(DOZE_REQUEST_PULSE));
- mMachine.requestState(DOZE_REQUEST_PULSE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
assertEquals(DOZE_PULSING, mMachine.getState());
}
@Test
+ public void testPulseReason_getMatchesRequest() {
+ mMachine.requestState(INITIALIZED);
+ mMachine.requestState(DOZE);
+ mMachine.requestPulse(DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP);
+
+ assertEquals(DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP, mMachine.getPulseReason());
+ }
+
+ @Test
+ public void testPulseReason_getFromTransition() {
+ mMachine.requestState(INITIALIZED);
+ mMachine.requestState(DOZE);
+ doAnswer(inv -> {
+ DozeMachine.State newState = inv.getArgument(1);
+ if (newState == DOZE_REQUEST_PULSE
+ || newState == DOZE_PULSING
+ || newState == DOZE_PULSE_DONE) {
+ assertEquals(DozeLog.PULSE_REASON_NOTIFICATION, mMachine.getPulseReason());
+ } else {
+ assertTrue("unexpected state " + newState,
+ newState == DOZE || newState == DOZE_AOD);
+ }
+ return null;
+ }).when(mPartMock).transitionTo(any(), any());
+
+ mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
+ mMachine.requestState(DOZE_PULSING);
+ mMachine.requestState(DOZE_PULSE_DONE);
+ }
+
+ @Test
public void testWakeUp_wakesUp() {
mMachine.wakeUp();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
index 12e75a1..8934460 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeTriggersTest.java
@@ -22,26 +22,28 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.withSettings;
import android.app.Instrumentation;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.wakelock.WakeLock;
import com.android.systemui.util.wakelock.WakeLockFake;
+import com.android.systemui.utils.hardware.FakeSensorManager;
import org.junit.Before;
import org.junit.BeforeClass;
-import org.junit.Ignore;
import org.junit.Test;
-import org.mockito.Answers;
-import org.mockito.MockSettings;
+import org.junit.runner.RunWith;
+@SmallTest
+@RunWith(AndroidJUnit4.class)
public class DozeTriggersTest {
private Context mContext;
private DozeTriggers mTriggers;
@@ -49,7 +51,7 @@
private DozeHostFake mHost;
private AmbientDisplayConfiguration mConfig;
private DozeParameters mParameters;
- private SensorManagerFake mSensors;
+ private FakeSensorManager mSensors;
private Handler mHandler;
private WakeLock mWakeLock;
private Instrumentation mInstrumentation;
@@ -68,7 +70,7 @@
mHost = new DozeHostFake();
mConfig = DozeConfigurationUtil.createMockConfig();
mParameters = DozeConfigurationUtil.createMockParameters();
- mSensors = new SensorManagerFake(mContext);
+ mSensors = new FakeSensorManager(mContext);
mHandler = new Handler(Looper.getMainLooper());
mWakeLock = new WakeLockFake();
@@ -79,32 +81,32 @@
}
@Test
- @Ignore("setup crashes on virtual devices")
public void testOnNotification_stillWorksAfterOneFailedProxCheck() throws Exception {
when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE);
mInstrumentation.runOnMainSync(()->{
mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED);
- mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.DOZE);
+ mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
mHost.callback.onNotificationHeadsUp();
});
mInstrumentation.runOnMainSync(() -> {
- mSensors.PROXIMITY.sendProximityResult(false); /* Near */
+ mSensors.getMockProximitySensor().sendProximityResult(false); /* Near */
});
verify(mMachine, never()).requestState(any());
+ verify(mMachine, never()).requestPulse(anyInt());
mInstrumentation.runOnMainSync(()->{
mHost.callback.onNotificationHeadsUp();
});
mInstrumentation.runOnMainSync(() -> {
- mSensors.PROXIMITY.sendProximityResult(true); /* Far */
+ mSensors.getMockProximitySensor().sendProximityResult(true); /* Far */
});
- verify(mMachine).requestState(DozeMachine.State.DOZE_REQUEST_PULSE);
+ verify(mMachine).requestPulse(anyInt());
}
}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/SensorManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
similarity index 60%
rename from packages/SystemUI/tests/src/com/android/systemui/doze/SensorManagerFake.java
rename to packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
index 5b4b891..30be665 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/SensorManagerFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/hardware/FakeSensorManager.java
@@ -11,10 +11,10 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License.
+ * limitations under the License
*/
-package com.android.systemui.doze;
+package com.android.systemui.utils.hardware;
import android.content.Context;
import android.hardware.HardwareBuffer;
@@ -33,6 +33,8 @@
import com.google.android.collect.Lists;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -44,18 +46,38 @@
* Note that this class ignores the "Handler" argument, so the test is responsible for calling the
* listener on the right thread.
*/
-public class SensorManagerFake extends SensorManager {
+public class FakeSensorManager extends SensorManager {
- public MockSensor PROXIMITY;
+ private final MockProximitySensor mMockProximitySensor;
- public SensorManagerFake(Context context) {
- PROXIMITY = new MockSensor(context.getSystemService(SensorManager.class)
- .getDefaultSensor(Sensor.TYPE_PROXIMITY));
+ public FakeSensorManager(Context context) throws Exception {
+ Sensor proxSensor = context.getSystemService(SensorManager.class)
+ .getDefaultSensor(Sensor.TYPE_PROXIMITY);
+ if (proxSensor == null) {
+ // No prox? Let's create a fake one!
+ proxSensor = createSensor(Sensor.TYPE_PROXIMITY);
+ }
+ mMockProximitySensor = new MockProximitySensor(proxSensor);
+ }
+
+ public MockProximitySensor getMockProximitySensor() {
+ return mMockProximitySensor;
+ }
+
+ @Override
+ public Sensor getDefaultSensor(int type) {
+ Sensor s = super.getDefaultSensor(type);
+ if (s != null) {
+ return s;
+ }
+ // Our mock sensors aren't wakeup, and it's a pain to create them that way. Instead, just
+ // return non-wakeup sensors if we can't find a wakeup sensor.
+ return getDefaultSensor(type, false /* wakeup */);
}
@Override
protected List<Sensor> getFullSensorList() {
- return Lists.newArrayList(PROXIMITY.sensor);
+ return Lists.newArrayList(mMockProximitySensor.sensor);
}
@Override
@@ -65,8 +87,8 @@
@Override
protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
- if (sensor == PROXIMITY.sensor || sensor == null) {
- PROXIMITY.listeners.remove(listener);
+ if (sensor == mMockProximitySensor.sensor || sensor == null) {
+ mMockProximitySensor.listeners.remove(listener);
}
}
@@ -74,8 +96,8 @@
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
int delayUs,
Handler handler, int maxReportLatencyUs, int reservedFlags) {
- if (sensor == PROXIMITY.sensor) {
- PROXIMITY.listeners.add(listener);
+ if (sensor == mMockProximitySensor.sensor) {
+ mMockProximitySensor.listeners.add(listener);
return true;
}
return false;
@@ -141,11 +163,44 @@
return false;
}
- public class MockSensor {
+ private Sensor createSensor(int type) throws Exception {
+ Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
+ constr.setAccessible(true);
+ Sensor sensor = constr.newInstance();
+
+ setSensorType(sensor, type);
+ setSensorField(sensor, "mName", "Mock " + sensor.getStringType() + "/" + type);
+ setSensorField(sensor, "mVendor", "Mock Vendor");
+ setSensorField(sensor, "mVersion", 1);
+ setSensorField(sensor, "mHandle", -1);
+ setSensorField(sensor, "mMaxRange", 10);
+ setSensorField(sensor, "mResolution", 1);
+ setSensorField(sensor, "mPower", 1);
+ setSensorField(sensor, "mMinDelay", 1000);
+ setSensorField(sensor, "mMaxDelay", 1000000000);
+ setSensorField(sensor, "mFlags", 0);
+ setSensorField(sensor, "mId", -1);
+
+ return sensor;
+ }
+
+ private void setSensorField(Sensor sensor, String fieldName, Object value) throws Exception {
+ Field field = Sensor.class.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ field.set(sensor, value);
+ }
+
+ private void setSensorType(Sensor sensor, int type) throws Exception {
+ Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
+ setter.setAccessible(true);
+ setter.invoke(sensor, type);
+ }
+
+ public class MockProximitySensor {
final Sensor sensor;
final ArraySet<SensorEventListener> listeners = new ArraySet<>();
- private MockSensor(Sensor sensor) {
+ private MockProximitySensor(Sensor sensor) {
this.sensor = sensor;
}
diff --git a/preloaded-classes b/preloaded-classes
index 892c593..493e980 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1820,6 +1820,7 @@
android.text.GetChars
android.text.GraphicsOperations
android.text.Html
+android.text.Html$HtmlParser
android.text.Hyphenator
android.text.InputFilter
android.text.InputType
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index ff99b19..f37bfac 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3957,6 +3957,11 @@
// OS: O
RUNNING_BACKGROUND_APPS_DIALOG = 944;
+ // FIELD - The delay from the start of the transition until we just call bindApplication on the
+ // client.
+ // OS: O
+ APP_TRANSITION_BIND_APPLICATION_DELAY_MS = 945;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index b536ad9..f3e610e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -602,6 +602,31 @@
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ boolean showHistory = true;
+ boolean uiOnly = false;
+ if (args != null) {
+ for (String arg : args) {
+ switch(arg) {
+ case "--no-history":
+ showHistory = false;
+ break;
+ case "--ui-only":
+ uiOnly = true;
+ break;
+ case "--help":
+ pw.println("Usage: dumpsys autofill [--ui-only|--no-history]");
+ return;
+ default:
+ throw new IllegalArgumentException("Invalid dump arg: " + arg);
+ }
+ }
+ }
+
+ if (uiOnly) {
+ mUi.dump(pw);
+ return;
+ }
+
boolean oldDebug = sDebug;
try {
synchronized (mLock) {
@@ -624,8 +649,10 @@
}
mUi.dump(pw);
}
- pw.println("Requests history:");
- mRequestsHistory.reverseDump(fd, pw, args);
+ if (showHistory) {
+ pw.println("Requests history:");
+ mRequestsHistory.reverseDump(fd, pw, args);
+ }
} finally {
setDebugLocked(oldDebug);
}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 68ade63..cbf97dd 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -20,7 +20,9 @@
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Bundle;
+import android.util.DebugUtils;
import android.view.autofill.AutofillId;
+import android.view.autofill.AutofillManager;
import java.util.Arrays;
import java.util.Objects;
@@ -40,6 +42,10 @@
*/
public static boolean sVerbose = false;
+ private Helper() {
+ throw new UnsupportedOperationException("contains static members only");
+ }
+
static void append(StringBuilder builder, Bundle bundle) {
if (bundle == null || !sVerbose) {
builder.append("null");
@@ -62,8 +68,8 @@
return builder.toString();
}
- private Helper() {
- throw new UnsupportedOperationException("contains static members only");
+ static String getUpdateActionAsString(int action) {
+ return DebugUtils.flagsToString(AutofillManager.class, "ACTION_", action);
}
static ViewNode findViewNodeById(@NonNull AssistStructure structure, @NonNull AutofillId id) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 018fb68..dbc7f2b 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -25,9 +25,13 @@
import static android.view.autofill.AutofillManager.ACTION_VIEW_ENTERED;
import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
+import static com.android.server.autofill.Helper.findViewNodeById;
+import static com.android.server.autofill.Helper.getUpdateActionAsString;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
-import static com.android.server.autofill.Helper.findViewNodeById;
+import static com.android.server.autofill.ViewState.STATE_AUTOFILLED;
+import static com.android.server.autofill.ViewState.STATE_FILLABLE;
+import static com.android.server.autofill.ViewState.STATE_RESTARTED_SESSION;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -221,7 +225,7 @@
final int numContexts = mContexts.size();
for (int i = 0; i < numContexts; i++) {
- fillStructureWithAllowedValues(mContexts.get(i).getStructure());
+ fillStructureWithAllowedValues(mContexts.get(i).getStructure(), flags);
}
request = new FillRequest(requestId, mContexts, mClientState, flags);
@@ -235,10 +239,12 @@
* Updates values of the nodes in the structure so that:
* - proper node is focused
* - autofillValue is sent back to service when it was previously autofilled
+ * - autofillValue is sent in the view used to force a request
*
* @param structure The structure to be filled
+ * @param flags The flags that started the session
*/
- private void fillStructureWithAllowedValues(@NonNull AssistStructure structure) {
+ private void fillStructureWithAllowedValues(@NonNull AssistStructure structure, int flags) {
final int numViewStates = mViewStates.size();
for (int i = 0; i < numViewStates; i++) {
final ViewState viewState = mViewStates.valueAt(i);
@@ -249,16 +255,23 @@
continue;
}
- final AutofillValue initialValue = viewState.getInitialValue();
+ final AutofillValue currentValue = viewState.getCurrentValue();
final AutofillValue filledValue = viewState.getAutofilledValue();
final AutofillOverlay overlay = new AutofillOverlay();
- if (filledValue != null && !filledValue.equals(initialValue)) {
- overlay.value = filledValue;
- }
- if (mCurrentViewId != null) {
- overlay.focused = mCurrentViewId.equals(viewState.id);
+
+ // Sanitizes the value if the current value matches what the service sent.
+ if (filledValue != null && filledValue.equals(currentValue)) {
+ overlay.value = currentValue;
}
+ if (mCurrentViewId != null) {
+ // Updates the focus value.
+ overlay.focused = mCurrentViewId.equals(viewState.id);
+ // Sanitizes the value of the focused field in a manual request.
+ if (overlay.focused && (flags & FLAG_MANUAL_REQUEST) != 0) {
+ overlay.value = currentValue;
+ }
+ }
node.setAutofillOverlay(overlay);
}
}
@@ -883,6 +896,40 @@
}
/**
+ * Starts (if necessary) a new fill request upon entering a view.
+ *
+ * <p>A new request will be started in 2 scenarios:
+ * <ol>
+ * <li>If the user manually requested autofill after the view was already filled.
+ * <li>If the view is part of a new partition.
+ * </ol>
+ *
+ * @param id The id of the view that is entered.
+ * @param viewState The view that is entered.
+ * @param flags The flag that was passed by the AutofillManager.
+ */
+ private void requestNewFillResponseIfNecessaryLocked(@NonNull AutofillId id,
+ @NonNull ViewState viewState, int flags) {
+ // First check if this is a manual request after view was autofilled.
+ final int state = viewState.getState();
+ final boolean restart = (state & STATE_AUTOFILLED) != 0
+ && (flags & FLAG_MANUAL_REQUEST) != 0;
+ if (restart) {
+ if (sDebug) Slog.d(TAG, "Re-starting session on view " + id);
+ viewState.setState(STATE_RESTARTED_SESSION);
+ requestNewFillResponseLocked(flags);
+ return;
+ }
+
+ // If it's not, then check if it it should start a partition.
+ if (shouldStartNewPartitionLocked(id)) {
+ if (sDebug) Slog.d(TAG, "Starting partition for view id " + id);
+ viewState.setState(ViewState.STATE_STARTED_PARTITION);
+ requestNewFillResponseLocked(flags);
+ }
+ }
+
+ /**
* Determines if a new partition should be started for an id.
*
* @param id The id of the view that is entered
@@ -938,6 +985,10 @@
+ id + " destroyed");
return;
}
+ if (sVerbose) {
+ Slog.v(TAG, "updateLocked(): id=" + id + ", action=" + getUpdateActionAsString(action)
+ + ", flags=" + flags);
+ }
ViewState viewState = mViewStates.get(id);
if (viewState == null) {
@@ -992,13 +1043,10 @@
}
break;
case ACTION_VIEW_ENTERED:
- if (shouldStartNewPartitionLocked(id)) {
- if (sDebug) {
- Slog.d(TAG, "Starting partition for view id " + viewState.id);
- }
- viewState.setState(ViewState.STATE_STARTED_PARTITION);
- requestNewFillResponseLocked(flags);
+ if (sVerbose && virtualBounds != null) {
+ Slog.w(TAG, "entered on virtual child " + id + ": " + virtualBounds);
}
+ requestNewFillResponseIfNecessaryLocked(id, viewState, flags);
// Remove the UI if the ViewState has changed.
if (mCurrentViewId != viewState.id) {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index d114e14..561c603 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -47,23 +47,25 @@
private static final String TAG = "ViewState";
// NOTE: state constants must be public because of flagstoString().
- public static final int STATE_UNKNOWN = 0x00;
+ public static final int STATE_UNKNOWN = 0x000;
/** Initial state. */
- public static final int STATE_INITIAL = 0x01;
+ public static final int STATE_INITIAL = 0x001;
/** View id is present in a dataset returned by the service. */
- public static final int STATE_FILLABLE = 0x02;
+ public static final int STATE_FILLABLE = 0x002;
/** View was autofilled after user selected a dataset. */
- public static final int STATE_AUTOFILLED = 0x04;
+ public static final int STATE_AUTOFILLED = 0x004;
/** View value was changed, but not by the service. */
- public static final int STATE_CHANGED = 0x08;
+ public static final int STATE_CHANGED = 0x008;
/** Set only in the View that started a session. */
- public static final int STATE_STARTED_SESSION = 0x10;
+ public static final int STATE_STARTED_SESSION = 0x010;
/** View that started a new partition when focused on. */
- public static final int STATE_STARTED_PARTITION = 0x20;
+ public static final int STATE_STARTED_PARTITION = 0x020;
/** User select a dataset in this view, but service must authenticate first. */
- public static final int STATE_WAITING_DATASET_AUTH = 0x40;
+ public static final int STATE_WAITING_DATASET_AUTH = 0x040;
/** Service does not care about this view. */
- public static final int STATE_IGNORED = 0x80;
+ public static final int STATE_IGNORED = 0x080;
+ /** User manually request autofill in this view, after it was already autofilled. */
+ public static final int STATE_RESTARTED_SESSION = 0x100;
public final AutofillId id;
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 086742e..25814b3 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -282,13 +282,18 @@
pw.println("Autofill UI");
final String prefix = " ";
final String prefix2 = " ";
- pw.print(prefix); pw.print("showsSaveUi: "); pw.println(mSaveUi != null);
if (mFillUi != null) {
pw.print(prefix); pw.println("showsFillUi: true");
mFillUi.dump(pw, prefix2);
} else {
pw.print(prefix); pw.println("showsFillUi: false");
}
+ if (mSaveUi != null) {
+ pw.print(prefix); pw.println("showsSaveUi: true");
+ mSaveUi.dump(pw, prefix2);
+ } else {
+ pw.print(prefix); pw.println("showsSaveUi: false");
+ }
}
@android.annotation.UiThread
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index dd297a6..922962f 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -398,6 +398,7 @@
}
return false;
}
+
}
public void dump(PrintWriter pw, String prefix) {
@@ -408,5 +409,21 @@
pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);
+ pw.print(prefix); pw.print("mWindow: ");
+ if (mWindow == null) {
+ pw.println("N/A");
+ } else {
+ final String prefix2 = prefix + " ";
+ pw.println();
+ pw.print(prefix2); pw.print("showing: "); pw.println(mWindow.mShowing);
+ pw.print(prefix2); pw.print("view: "); pw.println(mWindow.mContentView);
+ pw.print(prefix2); pw.print("screen coordinates: ");
+ if (mWindow.mContentView == null) {
+ pw.println("N/A");
+ } else {
+ final int[] coordinates = mWindow.mContentView.getLocationOnScreen();
+ pw.print(coordinates[0]); pw.print("x"); pw.println(coordinates[1]);
+ }
+ }
}
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index bcdb118..d25ffce 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -37,6 +37,8 @@
import com.android.internal.R;
import com.android.server.UiThread;
+import java.io.PrintWriter;
+
/**
* Autofill Save Prompt
*/
@@ -96,6 +98,9 @@
private final @NonNull OneTimeListener mListener;
+ private final CharSequence mTitle;
+ private final CharSequence mSubTitle;
+
private boolean mDestroyed;
SaveUi(@NonNull Context context, @NonNull CharSequence providerLabel, @NonNull SaveInfo info,
@@ -126,37 +131,36 @@
types.add(context.getString(R.string.autofill_save_type_email_address));
}
- final CharSequence title;
switch (types.size()) {
case 1:
- title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_type,
+ mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_type,
types.valueAt(0), providerLabel), 0);
break;
case 2:
- title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_2types,
+ mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_2types,
types.valueAt(0), types.valueAt(1), providerLabel), 0);
break;
case 3:
- title = Html.fromHtml(context.getString(R.string.autofill_save_title_with_3types,
+ mTitle = Html.fromHtml(context.getString(R.string.autofill_save_title_with_3types,
types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel), 0);
break;
default:
// Use generic if more than 3 or invalid type (size 0).
- title = Html.fromHtml(
+ mTitle = Html.fromHtml(
context.getString(R.string.autofill_save_title, providerLabel), 0);
}
- titleView.setText(title);
- final CharSequence subTitle = info.getDescription();
- if (subTitle != null) {
+ titleView.setText(mTitle);
+ mSubTitle = info.getDescription();
+ if (mSubTitle != null) {
final TextView subTitleView = (TextView) view.findViewById(R.id.autofill_save_subtitle);
- subTitleView.setText(subTitle);
+ subTitleView.setText(mSubTitle);
subTitleView.setVisibility(View.VISIBLE);
}
- Slog.i(TAG, "Showing save dialog: " + title);
+ Slog.i(TAG, "Showing save dialog: " + mTitle);
if (sDebug) {
- Slog.d(TAG, "SubTitle: " + subTitle);
+ Slog.d(TAG, "SubTitle: " + mSubTitle);
}
final TextView noButton = view.findViewById(R.id.autofill_save_no);
@@ -207,4 +211,18 @@
throw new IllegalStateException("cannot interact with a destroyed instance");
}
}
+
+ void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.print("title: "); pw.println(mTitle);
+ pw.print(prefix); pw.print("subtitle: "); pw.println(mSubTitle);
+
+ final View view = mDialog.getWindow().getDecorView();
+ final int[] loc = view.getLocationOnScreen();
+ pw.print(prefix); pw.print("coordinates: ");
+ pw.print('('); pw.print(loc[0]); pw.print(','); pw.print(loc[1]);pw.print(')');
+ pw.print('(');
+ pw.print(loc[0] + view.getWidth()); pw.print(',');
+ pw.print(loc[1] + view.getHeight());pw.println(')');
+ pw.print(prefix); pw.print("destroyed: "); pw.println(mDestroyed);
+ }
}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 1b970e5..d1a43d2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -774,7 +774,7 @@
}
// High level policy: apps are generally ineligible for backup if certain conditions apply
- public static boolean appIsEligibleForBackup(ApplicationInfo app) {
+ public static boolean appIsEligibleForBackup(ApplicationInfo app, PackageManager pm) {
// 1. their manifest states android:allowBackup="false"
if ((app.flags&ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) {
return false;
@@ -790,15 +790,18 @@
return false;
}
- return true;
+ // Everything else checks out; the only remaining roadblock would be if the
+ // package were disabled
+ return !appIsDisabled(app, pm);
}
- // Checks if the app is in a stopped state, that means it won't receive broadcasts.
+ // Checks if the app is in a stopped state. This is not part of the general "eligible for
+ // backup?" check because we *do* still need to restore data to apps in this state (e.g.
+ // newly-installing ones)
private static boolean appIsStopped(ApplicationInfo app) {
return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
}
- // We also avoid backups of 'disabled' apps
private static boolean appIsDisabled(ApplicationInfo app, PackageManager pm) {
switch (pm.getApplicationEnabledSetting(app.packageName)) {
case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
@@ -1526,7 +1529,8 @@
foundApps.add(pkgName); // all apps that we've addressed already
try {
PackageInfo pkg = mPackageManager.getPackageInfo(pkgName, 0);
- if (appGetsFullBackup(pkg) && appIsEligibleForBackup(pkg.applicationInfo)) {
+ if (appGetsFullBackup(pkg)
+ && appIsEligibleForBackup(pkg.applicationInfo, mPackageManager)) {
schedule.add(new FullBackupEntry(pkgName, lastBackup));
} else {
if (DEBUG) {
@@ -1545,7 +1549,8 @@
// New apps can arrive "out of band" via OTA and similar, so we also need to
// scan to make sure that we're tracking all full-backup candidates properly
for (PackageInfo app : apps) {
- if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
+ if (appGetsFullBackup(app)
+ && appIsEligibleForBackup(app.applicationInfo, mPackageManager)) {
if (!foundApps.contains(app.packageName)) {
if (MORE_DEBUG) {
Slog.i(TAG, "New full backup app " + app.packageName + " found");
@@ -1574,7 +1579,8 @@
changed = true;
schedule = new ArrayList<FullBackupEntry>(apps.size());
for (PackageInfo info : apps) {
- if (appGetsFullBackup(info) && appIsEligibleForBackup(info.applicationInfo)) {
+ if (appGetsFullBackup(info)
+ && appIsEligibleForBackup(info.applicationInfo, mPackageManager)) {
schedule.add(new FullBackupEntry(info.packageName, 0));
}
}
@@ -2032,7 +2038,8 @@
for (String packageName : pkgList) {
try {
PackageInfo app = mPackageManager.getPackageInfo(packageName, 0);
- if (appGetsFullBackup(app) && appIsEligibleForBackup(app.applicationInfo)) {
+ if (appGetsFullBackup(app)
+ && appIsEligibleForBackup(app.applicationInfo, mPackageManager)) {
enqueueFullBackup(packageName, now);
scheduleNextFullBackupJob(0);
} else {
@@ -2387,7 +2394,7 @@
long token = mAncestralToken;
synchronized (mQueueLock) {
- if (mEverStoredApps.contains(packageName)) {
+ if (mCurrentToken != 0 && mEverStoredApps.contains(packageName)) {
if (MORE_DEBUG) {
Slog.i(TAG, "App in ever-stored, so using current token");
}
@@ -2432,7 +2439,7 @@
try {
PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
- if (!appIsEligibleForBackup(packageInfo.applicationInfo)) {
+ if (!appIsEligibleForBackup(packageInfo.applicationInfo, mPackageManager)) {
sendBackupOnPackageResult(observer, packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
continue;
@@ -2952,7 +2959,7 @@
try {
mCurrentPackage = mPackageManager.getPackageInfo(request.packageName,
PackageManager.GET_SIGNATURES);
- if (!appIsEligibleForBackup(mCurrentPackage.applicationInfo)) {
+ if (!appIsEligibleForBackup(mCurrentPackage.applicationInfo, mPackageManager)) {
// The manifest has changed but we had a stale backup request pending.
// This won't happen again because the app won't be requesting further
// backups.
@@ -3868,9 +3875,14 @@
writeApkToBackup(mPackage, output);
}
+ final boolean isSharedStorage =
+ mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
+ final long timeout = isSharedStorage ?
+ TIMEOUT_SHARED_BACKUP_INTERVAL : TIMEOUT_FULL_BACKUP_INTERVAL;
+
if (DEBUG) Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
- prepareOperationTimeout(mToken, TIMEOUT_FULL_BACKUP_INTERVAL,
- mTimeoutMonitor /* in parent class */, OP_TYPE_BACKUP_WAIT);
+ prepareOperationTimeout(mToken, timeout, mTimeoutMonitor /* in parent class */,
+ OP_TYPE_BACKUP_WAIT);
mAgent.doFullBackup(mPipe, mQuota, mToken, mBackupManagerBinder);
} catch (IOException e) {
Slog.e(TAG, "Error running full backup for " + mPackage.packageName);
@@ -4394,7 +4406,7 @@
Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator();
while (iter.hasNext()) {
PackageInfo pkg = iter.next().getValue();
- if (!appIsEligibleForBackup(pkg.applicationInfo)
+ if (!appIsEligibleForBackup(pkg.applicationInfo, mPackageManager)
|| appIsStopped(pkg.applicationInfo)) {
iter.remove();
if (DEBUG) {
@@ -4676,7 +4688,7 @@
PackageInfo info = mPackageManager.getPackageInfo(pkg,
PackageManager.GET_SIGNATURES);
mCurrentPackage = info;
- if (!appIsEligibleForBackup(info.applicationInfo)) {
+ if (!appIsEligibleForBackup(info.applicationInfo, mPackageManager)) {
// Cull any packages that have indicated that backups are not permitted,
// that run as system-domain uids but do not define their own backup agents,
// as well as any explicit mention of the 'special' shared-storage agent
@@ -7578,9 +7590,12 @@
if (okay) {
boolean agentSuccess = true;
long toCopy = info.size;
+ final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
+ final long timeout = isSharedStorage ?
+ TIMEOUT_SHARED_BACKUP_INTERVAL : TIMEOUT_RESTORE_INTERVAL;
final int token = generateToken();
try {
- prepareOperationTimeout(token, TIMEOUT_RESTORE_INTERVAL, null,
+ prepareOperationTimeout(token, timeout, null,
OP_TYPE_RESTORE_WAIT);
if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
if (DEBUG) Slog.d(TAG, "Restoring OBB file for " + pkg
@@ -8650,7 +8665,7 @@
continue;
}
- if (appIsEligibleForBackup(info.applicationInfo)) {
+ if (appIsEligibleForBackup(info.applicationInfo, mPackageManager)) {
mAcceptSet.add(info);
}
} catch (NameNotFoundException e) {
@@ -10456,8 +10471,7 @@
final long oldId = Binder.clearCallingIdentity();
try {
String prevTransport = mTransportManager.selectTransport(transport);
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.BACKUP_TRANSPORT, transport);
+ updateStateForTransport(transport);
Slog.v(TAG, "selectBackupTransport() set " + mTransportManager.getCurrentTransportName()
+ " returning " + prevTransport);
return prevTransport;
@@ -10480,9 +10494,7 @@
@Override
public void onSuccess(String transportName) {
mTransportManager.selectTransport(transportName);
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.BACKUP_TRANSPORT,
- mTransportManager.getCurrentTransportName());
+ updateStateForTransport(mTransportManager.getCurrentTransportName());
Slog.v(TAG, "Transport successfully selected: " + transport.flattenToShortString());
try {
listener.onSuccess(transportName);
@@ -10505,6 +10517,28 @@
Binder.restoreCallingIdentity(oldId);
}
+ private void updateStateForTransport(String newTransportName) {
+ // Publish the name change
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.BACKUP_TRANSPORT, newTransportName);
+
+ // And update our current-dataset bookkeeping
+ IBackupTransport transport = mTransportManager.getTransportBinder(newTransportName);
+ if (transport != null) {
+ try {
+ mCurrentToken = transport.getCurrentRestoreSet();
+ } catch (Exception e) {
+ // Oops. We can't know the current dataset token, so reset and figure it out
+ // when we do the next k/v backup operation on this transport.
+ mCurrentToken = 0;
+ }
+ } else {
+ // The named transport isn't bound at this particular moment, so we can't
+ // know yet what its current dataset token is. Reset as above.
+ mCurrentToken = 0;
+ }
+ }
+
// Supply the configuration Intent for the given transport. If the name is not one
// of the available transports, or if the transport does not supply any configuration
// UI, the method returns null.
@@ -10803,9 +10837,8 @@
try {
PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName,
PackageManager.GET_SIGNATURES);
- if (!appIsEligibleForBackup(packageInfo.applicationInfo) ||
- appIsStopped(packageInfo.applicationInfo) ||
- appIsDisabled(packageInfo.applicationInfo, mPackageManager)) {
+ if (!appIsEligibleForBackup(packageInfo.applicationInfo, mPackageManager) ||
+ appIsStopped(packageInfo.applicationInfo)) {
return false;
}
IBackupTransport transport = mTransportManager.getCurrentTransportBinder();
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index 09f240f..642b8bf 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -140,7 +140,7 @@
int N = pkgs.size();
for (int a = N-1; a >= 0; a--) {
PackageInfo pkg = pkgs.get(a);
- if (!BackupManagerService.appIsEligibleForBackup(pkg.applicationInfo)) {
+ if (!BackupManagerService.appIsEligibleForBackup(pkg.applicationInfo, pm)) {
pkgs.remove(a);
}
}
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 2c14a7c..aafa88a 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -304,6 +304,14 @@
BackupManagerService svc = mService;
if (svc != null) {
svc.selectBackupTransportAsync(transport, listener);
+ } else {
+ if (listener != null) {
+ try {
+ listener.onFailure(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ } catch (RemoteException ex) {
+ // Ignore
+ }
+ }
}
}
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index 67f105e..da1f32c 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -182,13 +182,13 @@
String[] getBoundTransportNames() {
synchronized (mTransportLock) {
- return mBoundTransports.keySet().toArray(new String[0]);
+ return mBoundTransports.keySet().toArray(new String[mBoundTransports.size()]);
}
}
ComponentName[] getAllTransportCompenents() {
synchronized (mTransportLock) {
- return mValidTransports.keySet().toArray(new ComponentName[0]);
+ return mValidTransports.keySet().toArray(new ComponentName[mValidTransports.size()]);
}
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 05ffcf0..550774a 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1049,6 +1049,7 @@
if (timeZoneWasChanged) {
Intent intent = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
| Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
intent.putExtra("time-zone", zone.getID());
getContext().sendBroadcastAsUser(intent, UserHandle.ALL);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 18b4571..c785fb9 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1494,16 +1494,6 @@
if (mGetNameAddressOnly) return;
}
- try {
- boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
- Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
- if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {
- Slog.e(TAG,"IBluetooth.configHciSnoopLog return false");
- }
- } catch (RemoteException e) {
- Slog.e(TAG,"Unable to call configHciSnoopLog", e);
- }
-
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 114d761..fdc0bba 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -631,6 +631,11 @@
PackageManager.PERMISSION_GRANTED;
}
+ private boolean callerCanScoreNetworks() {
+ return mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS) ==
+ PackageManager.PERMISSION_GRANTED;
+ }
+
@Override
public boolean clearScores() {
// Only the active scorer or the system should be allowed to flush all scores.
@@ -651,9 +656,9 @@
@Override
public boolean setActiveScorer(String packageName) {
// Only the system can set the active scorer
- if (!isCallerSystemProcess(getCallingUid()) && !callerCanRequestScores()) {
+ if (!isCallerSystemProcess(getCallingUid()) && !callerCanScoreNetworks()) {
throw new SecurityException(
- "Caller is neither the system process nor a score requester.");
+ "Caller is neither the system process or a network scorer.");
}
return mNetworkScorerAppManager.setActiveScorer(packageName);
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 8404025..42777bf 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -208,11 +208,11 @@
*
* <p>The caller must have permission to write to {@link Settings.Global}.
*
- * @param packageName the packageName of the new scorer to use. If null, the scoring app will
- * revert back to the configured default. Otherwise, the scorer will only
- * be set if it is a valid scorer application.
- * @return true if the scorer was changed, or false if the package is not a valid scorer or
- * a valid network recommendation provider exists.
+ * @param packageName the packageName of the new scorer to use. If null, scoring will be forced
+ * off, otherwise the scorer will only be set if it is a valid scorer
+ * application.
+ * @return true if the package was a valid scorer (including <code>null</code>) and now
+ * represents the active scorer, false otherwise.
*/
@VisibleForTesting
public boolean setActiveScorer(String packageName) {
@@ -223,16 +223,19 @@
return true;
}
- if (packageName == null) {
- // revert to the default setting.
- packageName = getDefaultPackageSetting();
+ if (TextUtils.isEmpty(packageName)) {
+ Log.i(TAG, "Network scorer forced off, was: " + oldPackageName);
+ setNetworkRecommendationsPackage(null);
+ setNetworkRecommendationsEnabledSetting(
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF);
+ return true;
}
- Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName);
-
// We only make the change if the new package is valid.
if (getScorer(packageName) != null) {
+ Log.i(TAG, "Changing network scorer from " + oldPackageName + " to " + packageName);
setNetworkRecommendationsPackage(packageName);
+ setNetworkRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON);
return true;
} else {
Log.w(TAG, "Requested network scorer is not valid: " + packageName);
diff --git a/services/core/java/com/android/server/vr/CompatibilityDisplay.java b/services/core/java/com/android/server/Vr2dDisplay.java
similarity index 93%
rename from services/core/java/com/android/server/vr/CompatibilityDisplay.java
rename to services/core/java/com/android/server/Vr2dDisplay.java
index d7cdf08..1116e4e 100644
--- a/services/core/java/com/android/server/vr/CompatibilityDisplay.java
+++ b/services/core/java/com/android/server/Vr2dDisplay.java
@@ -3,7 +3,7 @@
import static android.view.Display.INVALID_DISPLAY;
import android.app.ActivityManagerInternal;
-import android.app.CompatibilityDisplayProperties;
+import android.app.Vr2dDisplayProperties;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -31,8 +31,8 @@
* Creates a 2D Virtual Display while VR Mode is enabled. This display will be used to run and
* render 2D app within a VR experience. For example, bringing up the 2D calculator app in VR.
*/
-class CompatibilityDisplay {
- private final static String TAG = "CompatDisplay";
+class Vr2dDisplay {
+ private final static String TAG = "Vr2dDisplay";
private final static boolean DEBUG = false;
// TODO: Go over these values and figure out what is best
@@ -42,13 +42,13 @@
private final static int STOP_VIRTUAL_DISPLAY_DELAY_MILLIS = 2000;
private final static String DEBUG_ACTION_SET_MODE =
- "com.android.server.vr.CompatibilityDisplay.SET_MODE";
+ "com.android.server.vr.Vr2dDisplay.SET_MODE";
private final static String DEBUG_EXTRA_MODE_ON =
- "com.android.server.vr.CompatibilityDisplay.EXTRA_MODE_ON";
+ "com.android.server.vr.Vr2dDisplay.EXTRA_MODE_ON";
private final static String DEBUG_ACTION_SET_SURFACE =
- "com.android.server.vr.CompatibilityDisplay.SET_SURFACE";
+ "com.android.server.vr.Vr2dDisplay.SET_SURFACE";
private final static String DEBUG_EXTRA_SURFACE =
- "com.android.server.vr.CompatibilityDisplay.EXTRA_SURFACE";
+ "com.android.server.vr.Vr2dDisplay.EXTRA_SURFACE";
/**
* The default width of the VR virtual display
@@ -99,7 +99,7 @@
private boolean mIsVrModeOverrideEnabled;
private boolean mIsVrModeEnabled;
- public CompatibilityDisplay(DisplayManager displayManager,
+ public Vr2dDisplay(DisplayManager displayManager,
ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
mDisplayManager = displayManager;
mActivityManagerInternal = activityManagerInternal;
@@ -190,7 +190,7 @@
}
/**
- * Sets the resolution and DPI of the compatibility virtual display used to display
+ * Sets the resolution and DPI of the Vr2d virtual display used to display
* 2D applications in VR mode.
*
* <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
@@ -198,7 +198,7 @@
* @param compatDisplayProperties Properties of the virtual display for 2D applications
* in VR mode.
*/
- public void setVirtualDisplayProperties(CompatibilityDisplayProperties compatDisplayProperties) {
+ public void setVirtualDisplayProperties(Vr2dDisplayProperties compatDisplayProperties) {
synchronized(mVdLock) {
if (DEBUG) {
Log.i(TAG, "VD setVirtualDisplayProperties: res = " +
@@ -273,13 +273,13 @@
null /* Surface */, 0 /* flags */);
if (mVirtualDisplay != null) {
- mActivityManagerInternal.setVrCompatibilityDisplayId(
+ mActivityManagerInternal.setVr2dDisplayId(
mVirtualDisplay.getDisplay().getDisplayId());
// Now create the ImageReader to supply a Surface to the new virtual display.
startImageReader();
} else {
Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
- mActivityManagerInternal.setVrCompatibilityDisplayId(INVALID_DISPLAY);
+ mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
return;
}
}
@@ -302,7 +302,7 @@
} else {
Log.i(TAG, "Stopping Virtual Display");
synchronized (mVdLock) {
- mActivityManagerInternal.setVrCompatibilityDisplayId(INVALID_DISPLAY);
+ mActivityManagerInternal.setVr2dDisplayId(INVALID_DISPLAY);
setSurfaceLocked(null); // clean up and release the surface first.
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e0fc531..e9997c0 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -166,8 +166,11 @@
*/
static final class ActiveForegroundApp {
String mPackageName;
+ int mUid;
CharSequence mLabel;
boolean mShownWhileScreenOn;
+ boolean mAppOnTop;
+ boolean mShownWhileTop;
long mStartTime;
long mStartVisibleTime;
long mEndTime;
@@ -728,11 +731,12 @@
synchronized (mAm) {
final long now = SystemClock.elapsedRealtime();
final long nowPlusMin = now + mAm.mConstants.FOREGROUND_SERVICE_UI_MIN_TIME;
+ long nextUpdateTime = Long.MAX_VALUE;
if (smap != null) {
for (int i = smap.mActiveForegroundApps.size()-1; i >= 0; i--) {
ActiveForegroundApp aa = smap.mActiveForegroundApps.valueAt(i);
if (aa.mEndTime != 0 && (mScreenOn || aa.mShownWhileScreenOn)) {
- if (aa.mEndTime < (aa.mStartVisibleTime
+ if (!aa.mShownWhileTop && aa.mEndTime < (aa.mStartVisibleTime
+ mAm.mConstants.FOREGROUND_SERVICE_UI_MIN_TIME)) {
// Check to see if this should still be displayed... we continue
// until it has been shown for at least the timeout duration.
@@ -741,6 +745,12 @@
smap.mActiveForegroundApps.removeAt(i);
smap.mActiveForegroundAppsChanged = true;
continue;
+ } else {
+ long hideTime = aa.mStartVisibleTime
+ + mAm.mConstants.FOREGROUND_SERVICE_UI_MIN_TIME;
+ if (hideTime < nextUpdateTime) {
+ nextUpdateTime = hideTime;
+ }
}
} else {
// This was up for longer than the timeout, so just remove immediately.
@@ -749,10 +759,17 @@
continue;
}
}
- if (active == null) {
- active = new ArrayList<>();
+ if (!aa.mAppOnTop) {
+ if (active == null) {
+ active = new ArrayList<>();
+ }
+ active.add(aa);
}
- active.add(aa);
+ }
+ smap.removeMessages(ServiceMap.MSG_UPDATE_FOREGROUND_APPS);
+ if (nextUpdateTime < Long.MAX_VALUE) {
+ Message msg = smap.obtainMessage();
+ smap.sendMessageAtTime(msg, nextUpdateTime);
}
}
if (!smap.mActiveForegroundAppsChanged) {
@@ -842,7 +859,7 @@
active.mNumActive--;
if (active.mNumActive <= 0) {
active.mEndTime = SystemClock.elapsedRealtime();
- if (active.mEndTime >= (active.mStartVisibleTime
+ if (active.mShownWhileTop || active.mEndTime >= (active.mStartVisibleTime
+ mAm.mConstants.FOREGROUND_SERVICE_UI_MIN_TIME)) {
// Have been active for long enough that we will remove it immediately.
smap.mActiveForegroundApps.remove(r.packageName);
@@ -887,6 +904,31 @@
}
}
+ void foregroundServiceProcStateChangedLocked(UidRecord uidRec) {
+ ServiceMap smap = mServiceMap.get(UserHandle.getUserId(uidRec.uid));
+ if (smap != null) {
+ boolean changed = false;
+ for (int j = smap.mActiveForegroundApps.size()-1; j >= 0; j--) {
+ ActiveForegroundApp active = smap.mActiveForegroundApps.valueAt(j);
+ if (active.mUid == uidRec.uid) {
+ if (uidRec.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
+ if (!active.mAppOnTop) {
+ active.mAppOnTop = true;
+ changed = true;
+ }
+ active.mShownWhileTop = true;
+ } else if (active.mAppOnTop) {
+ active.mAppOnTop = false;
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ requestUpdateActiveForegroundAppsLocked(smap, 0);
+ }
+ }
+ }
+
private void setServiceForegroundInnerLocked(ServiceRecord r, int id,
Notification notification, int flags) {
if (id != 0) {
@@ -948,7 +990,13 @@
if (active == null) {
active = new ActiveForegroundApp();
active.mPackageName = r.packageName;
+ active.mUid = r.appInfo.uid;
active.mShownWhileScreenOn = mScreenOn;
+ if (r.app != null) {
+ active.mAppOnTop = active.mShownWhileTop =
+ r.app.uidRecord.curProcState
+ <= ActivityManager.PROCESS_STATE_TOP;
+ }
active.mStartTime = active.mStartVisibleTime
= SystemClock.elapsedRealtime();
smap.mActiveForegroundApps.put(r.packageName, active);
@@ -1258,6 +1306,10 @@
mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
s.appInfo.uid, s.name, s.processName);
+ // Once the apps have become associated, if one of them is caller is ephemeral
+ // the target app should now be able to see the calling app
+ mAm.grantEphemeralAccessLocked(callerApp.userId, service,
+ s.appInfo.uid, UserHandle.getAppId(callerApp.uid));
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
@@ -1312,7 +1364,7 @@
// This could have made the service more important.
mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
|| s.app.treatLikeActivity, b.client);
- mAm.updateOomAdjLocked(s.app);
+ mAm.updateOomAdjLocked(s.app, true);
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
@@ -1427,13 +1479,15 @@
r.binding.service.app.hasClientActivities
|| r.binding.service.app.treatLikeActivity, null);
}
- mAm.updateOomAdjLocked(r.binding.service.app);
+ mAm.updateOomAdjLocked(r.binding.service.app, false);
}
}
} finally {
Binder.restoreCallingIdentity(origId);
}
+ mAm.updateOomAdjLocked();
+
return true;
}
@@ -2173,7 +2227,7 @@
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
- mAm.updateOomAdjLocked(r.app);
+ mAm.updateOomAdjLocked(r.app, true);
}
if (r.fgRequired && !r.fgWaiting) {
if (!r.isForeground) {
@@ -2297,7 +2351,7 @@
if (ibr.hasBound) {
try {
bumpServiceExecutingLocked(r, false, "bring down unbind");
- mAm.updateOomAdjLocked(r.app);
+ mAm.updateOomAdjLocked(r.app, true);
ibr.hasBound = false;
ibr.requested = false;
r.app.thread.scheduleUnbindService(r,
@@ -2389,7 +2443,7 @@
bumpServiceExecutingLocked(r, false, "destroy");
mDestroyingServices.add(r);
r.destroying = true;
- mAm.updateOomAdjLocked(r.app);
+ mAm.updateOomAdjLocked(r.app, true);
r.app.thread.scheduleStopService(r);
} catch (Exception e) {
Slog.w(TAG, "Exception when destroying service "
@@ -2490,7 +2544,7 @@
// it to go down there and we want it to start out near the top.
mAm.updateLruProcessLocked(s.app, false, null);
}
- mAm.updateOomAdjLocked(s.app);
+ mAm.updateOomAdjLocked(s.app, true);
b.intent.hasBound = false;
// Assume the client doesn't want to know about a rebind;
// we will deal with that later if it asks for one.
@@ -2643,7 +2697,7 @@
mDestroyingServices.remove(r);
r.bindings.clear();
}
- mAm.updateOomAdjLocked(r.app);
+ mAm.updateOomAdjLocked(r.app, true);
}
r.executeFg = false;
if (r.tracker != null) {
@@ -2786,6 +2840,9 @@
if (!doit && didSomething) {
return true;
}
+ if (doit && filterByClasses == null) {
+ forceStopPackageLocked(packageName, mServiceMap.valueAt(i).mUserId);
+ }
}
} else {
ServiceMap smap = mServiceMap.get(userId);
@@ -2794,6 +2851,9 @@
didSomething = collectPackageServicesLocked(packageName, filterByClasses,
evenPersistent, doit, killProcess, items);
}
+ if (doit && filterByClasses == null) {
+ forceStopPackageLocked(packageName, userId);
+ }
}
if (mTmpCollectionResults != null) {
@@ -2802,10 +2862,11 @@
}
mTmpCollectionResults.clear();
}
+
return didSomething;
}
- void removeUninstalledPackageLocked(String packageName, int userId) {
+ void forceStopPackageLocked(String packageName, int userId) {
ServiceMap smap = mServiceMap.get(userId);
if (smap != null && smap.mActiveForegroundApps.size() > 0) {
for (int i = smap.mActiveForegroundApps.size()-1; i >= 0; i--) {
@@ -3636,6 +3697,10 @@
}
pw.print(" mNumActive=");
pw.print(aa.mNumActive);
+ pw.print(" mAppOnTop=");
+ pw.print(aa.mAppOnTop);
+ pw.print(" mShownWhileTop=");
+ pw.print(aa.mShownWhileTop);
pw.print(" mShownWhileScreenOn=");
pw.println(aa.mShownWhileScreenOn);
pw.print(" mStartTime=");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d46a24b..b3ef9e5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -120,7 +120,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
@@ -572,11 +571,10 @@
// Determines whether to take full screen screenshots
static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
- // STOPSHIP: Update default to a smaller value.
/**
* Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
*/
- private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 2000; // 2 sec
+ private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
/**
* State indicating that there is no need for any blocking for network.
@@ -627,8 +625,8 @@
private final VrController mVrController;
- // VR Compatibility Display Id.
- int mVrCompatibilityDisplayId = INVALID_DISPLAY;
+ // VR Vr2d Display Id.
+ int mVr2dDisplayId = INVALID_DISPLAY;
// Whether we should use SCHED_FIFO for UI and RenderThreads.
private boolean mUseFifoUiScheduling = false;
@@ -4332,6 +4330,7 @@
validateUid.idle = false;
}
validateUid.curProcState = validateUid.setProcState = item.processState;
+ validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
}
}
}
@@ -5427,7 +5426,7 @@
public static class DumpStackFileObserver extends FileObserver {
// Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
- static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
+ static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
private final String mTracesPath;
private boolean mClosed;
@@ -5443,21 +5442,41 @@
notify();
}
- public void dumpWithTimeout(int pid) {
+ public long dumpWithTimeout(int pid, long timeout) {
sendSignal(pid, SIGNAL_QUIT);
+ final long start = SystemClock.elapsedRealtime();
+
+ final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
synchronized (this) {
try {
- wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
+ wait(waitTime); // Wait for traces file to be closed.
} catch (InterruptedException e) {
Slog.wtf(TAG, e);
}
}
+
+ // This avoids a corner case of passing a negative time to the native
+ // trace in case we've already hit the overall timeout.
+ final long timeWaited = SystemClock.elapsedRealtime() - start;
+ if (timeWaited >= timeout) {
+ return timeWaited;
+ }
+
if (!mClosed) {
Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
". Attempting native stack collection.");
- Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
+
+ final long nativeDumpTimeoutMs = Math.min(
+ NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
+
+ Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
+ (int) (nativeDumpTimeoutMs / 1000));
}
+
+ final long end = SystemClock.elapsedRealtime();
mClosed = false;
+
+ return (end - start);
}
}
@@ -5467,6 +5486,9 @@
// Use a FileObserver to detect when traces finish writing.
// The order of traces is considered important to maintain for legibility.
DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
+
+ // We must complete all stack dumps within 20 seconds.
+ long remainingTime = 20 * 1000;
try {
observer.startWatching();
@@ -5476,10 +5498,18 @@
for (int i = 0; i < num; i++) {
if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
+ firstPids.get(i));
- final long sime = SystemClock.elapsedRealtime();
- observer.dumpWithTimeout(firstPids.get(i));
- if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
- + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
+ final long timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
+
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
+ "); deadline exceeded.");
+ return;
+ }
+
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
+ }
}
}
@@ -5487,12 +5517,24 @@
if (nativePids != null) {
for (int pid : nativePids) {
if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
- final long sime = SystemClock.elapsedRealtime();
+ final long nativeDumpTimeoutMs = Math.min(
+ DumpStackFileObserver.NATIVE_DUMP_TIMEOUT_MS, remainingTime);
+ final long start = SystemClock.elapsedRealtime();
Debug.dumpNativeBacktraceToFileTimeout(
- pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
- if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
- + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
+ pid, tracesPath, (int) (nativeDumpTimeoutMs / 1000));
+ final long timeTaken = SystemClock.elapsedRealtime() - start;
+
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
+ "); deadline exceeded.");
+ return;
+ }
+
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
+ }
}
}
@@ -5516,12 +5558,20 @@
ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
if (lastPids.indexOfKey(stats.pid) >= 0) {
numProcs++;
- if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
- + stats.pid);
- final long stime = SystemClock.elapsedRealtime();
- observer.dumpWithTimeout(stats.pid);
- if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
- + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
+
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
+
+ final long timeTaken = observer.dumpWithTimeout(stats.pid, remainingTime);
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + stats.pid +
+ "); deadline exceeded.");
+ return;
+ }
+
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with extra pid " + stats.pid + " in " + timeTaken + "ms");
+ }
} else if (DEBUG_ANR) {
Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+ stats.pid);
@@ -6795,6 +6845,7 @@
}
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
+ mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
@@ -11262,7 +11313,7 @@
checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
final int verifiedAdj = cpr.proc.verifiedAdj;
- boolean success = updateOomAdjLocked(cpr.proc);
+ boolean success = updateOomAdjLocked(cpr.proc, true);
// XXX things have changed so updateOomAdjLocked doesn't actually tell us
// if the process has been successfully adjusted. So to reduce races with
// it, we will check whether the process still exists. Note that this doesn't
@@ -11724,7 +11775,7 @@
dst.proc = r;
dst.notifyAll();
}
- updateOomAdjLocked(r);
+ updateOomAdjLocked(r, true);
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
@@ -13455,7 +13506,7 @@
}
}
if (changed) {
- updateOomAdjLocked(pr);
+ updateOomAdjLocked(pr, true);
}
}
} finally {
@@ -18228,7 +18279,7 @@
mBackupAppName = app.packageName;
// Try not to kill the process during backup
- updateOomAdjLocked(proc);
+ updateOomAdjLocked(proc, true);
// If the process is already attached, schedule the creation of the backup agent now.
// If it is not yet live, this will be done when it attaches to the framework.
@@ -18325,7 +18376,7 @@
// Not backing this app up any more; reset its OOM adjustment
final ProcessRecord proc = mBackupTarget.app;
- updateOomAdjLocked(proc);
+ updateOomAdjLocked(proc, true);
proc.inFullBackup = false;
oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
@@ -19007,7 +19058,7 @@
removeTasksByPackageNameLocked(ssp, userId);
- mServices.removeUninstalledPackageLocked(ssp, userId);
+ mServices.forceStopPackageLocked(ssp, userId);
// Hide the "unsupported display" dialog if necessary.
if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
@@ -19890,8 +19941,9 @@
}
/**
- * NOTE: For the pinned stack, this method is only called after the bounds animation has
- * animated the stack to the fullscreen.
+ * NOTE: For the pinned stack, this method is usually called after the bounds animation has
+ * animated the stack to the fullscreen, but can also be called if we are relaunching an
+ * activity and clearing the task at the same time.
*/
@Override
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
@@ -22084,7 +22136,14 @@
return act;
}
- final boolean updateOomAdjLocked(ProcessRecord app) {
+ /**
+ * Update OomAdj for a specific process.
+ * @param app The process to update
+ * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
+ * if necessary, or skip.
+ * @return whether updateOomAdjLocked(app) was successful.
+ */
+ final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
final ActivityRecord TOP_ACT = resumedAppLocked();
final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
final boolean wasCached = app.cached;
@@ -22099,7 +22158,8 @@
? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
SystemClock.uptimeMillis());
- if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
+ if (oomAdjAll
+ && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
// Changed to/from cached state, so apps after it in the LRU
// list may also be changed.
updateOomAdjLocked();
@@ -22277,6 +22337,9 @@
if (uidRec.curProcState > app.curProcState) {
uidRec.curProcState = app.curProcState;
}
+ if (app.foregroundServices) {
+ uidRec.foregroundServices = true;
+ }
}
}
@@ -22518,6 +22581,9 @@
uidRec.setWhitelist = uidRec.curWhitelist;
enqueueUidChangeLocked(uidRec, -1, uidChange);
noteUidProcessState(uidRec.uid, uidRec.curProcState);
+ if (uidRec.foregroundServices) {
+ mServices.foregroundServiceProcStateChangedLocked(uidRec);
+ }
}
}
if (mLocalPowerManager != null) {
@@ -23671,7 +23737,7 @@
}
pr.hasOverlayUi = hasOverlayUi;
//Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
- updateOomAdjLocked(pr);
+ updateOomAdjLocked(pr, true);
}
}
@@ -23726,17 +23792,17 @@
/**
* Called after virtual display Id is updated by
- * {@link com.android.server.vr.CompatibilityDisplay} with a specific
- * {@param vrCompatibilityDisplayId}.
+ * {@link com.android.server.vr.Vr2dDisplay} with a specific
+ * {@param vrVr2dDisplayId}.
*/
@Override
- public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
+ public void setVr2dDisplayId(int vr2dDisplayId) {
if (DEBUG_STACK) {
- Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
- vrCompatibilityDisplayId);
+ Slog.d(TAG, "setVr2dDisplayId called for: " +
+ vr2dDisplayId);
}
synchronized (ActivityManagerService.this) {
- mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
+ mVr2dDisplayId = vr2dDisplayId;
}
}
}
@@ -23800,11 +23866,8 @@
if (totalTime >= mWaitForNetworkTimeoutMs) {
Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
+ totalTime + ". Uid: " + callingUid + " procStateSeq: "
- + procStateSeq);
- } else if (DEBUG_NETWORK || totalTime >= mWaitForNetworkTimeoutMs / 2) {
- Slog.d(TAG_NETWORK, "Total time waited for network rules to get updated: "
- + totalTime + ". Uid: " + callingUid + " procStateSeq: "
- + procStateSeq);
+ + procStateSeq + " UidRec: " + record
+ + " validateUidRec: " + mValidateUids.get(callingUid));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index d4de521..bf7b663 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -10,6 +10,7 @@
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_DEVICE_UPTIME_SECONDS;
@@ -78,7 +79,8 @@
private int startResult;
private boolean currentTransitionProcessRunning;
private int windowsDrawnDelayMs;
- private int startingWindowDelayMs;
+ private int startingWindowDelayMs = -1;
+ private int bindApplicationDelayMs = -1;
private int reason = APP_TRANSITION_TIMEOUT;
private boolean loggedWindowsDrawn;
private boolean loggedStartingWindowDrawn;
@@ -296,6 +298,22 @@
}
}
+ /**
+ * Notifies the tracker that we called immediately before we call bindApplication on the client.
+ *
+ * @param app The client into which we'll call bindApplication.
+ */
+ void notifyBindApplication(ProcessRecord app) {
+ for (int i = mStackTransitionInfo.size() - 1; i >= 0; i--) {
+ final StackTransitionInfo info = mStackTransitionInfo.valueAt(i);
+
+ // App isn't attached to record yet, so match with info.
+ if (info.launchedActivity.appInfo == app.info) {
+ info.bindApplicationDelayMs = calculateCurrentDelay();
+ }
+ }
+ }
+
private boolean allStacksWindowsDrawn() {
for (int index = mStackTransitionInfo.size() - 1; index >= 0; index--) {
if (!mStackTransitionInfo.valueAt(index).loggedWindowsDrawn) {
@@ -356,6 +374,10 @@
builder.addTaggedData(APP_TRANSITION_STARTING_WINDOW_DELAY_MS,
info.startingWindowDelayMs);
}
+ if (info.bindApplicationDelayMs != -1) {
+ builder.addTaggedData(APP_TRANSITION_BIND_APPLICATION_DELAY_MS,
+ info.bindApplicationDelayMs);
+ }
builder.addTaggedData(APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS, info.windowsDrawnDelayMs);
mMetricsLogger.write(builder);
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 18c8b32..ba2c0cd 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -40,6 +40,7 @@
import static android.content.Intent.CATEGORY_HOME;
import static android.content.Intent.CATEGORY_LAUNCHER;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.content.Intent.FLAG_ACTIVITY_NO_HISTORY;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
@@ -61,6 +62,7 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
import static android.content.res.Configuration.EMPTY;
@@ -128,7 +130,6 @@
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
-import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Debug;
@@ -1951,13 +1952,9 @@
if (!nowVisible) {
nowVisible = true;
lastVisibleTime = SystemClock.uptimeMillis();
- if (!idle) {
- // Instead of doing the full stop routine here, let's just hide any activities
- // we now can, and let them stop when the normal idle happens.
- mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
- false /* remove */, true /* processPausingActivities */);
- } else {
- // If this activity was already idle, then we now need to make sure we perform
+ if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) {
+ // If this activity was already idle or there is an activity that must be
+ // stopped immediately after visible, then we now need to make sure we perform
// the full stop of any activities that are waiting to do so. This is because
// we won't do that while they are still waiting for this one to become visible.
final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size();
@@ -1970,6 +1967,11 @@
mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear();
mStackSupervisor.scheduleIdleLocked();
}
+ } else {
+ // Instead of doing the full stop routine here, let's just hide any activities
+ // we now can, and let them stop when the normal idle happens.
+ mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
+ false /* remove */, true /* processPausingActivities */);
}
service.scheduleAppGcsLocked();
}
@@ -2662,6 +2664,15 @@
return true;
}
+ /**
+ * Returns {@code true} if the associated activity has the no history flag set on it.
+ * {@code false} otherwise.
+ */
+ boolean isNoHistory() {
+ return (intent.getFlags() & FLAG_ACTIVITY_NO_HISTORY) != 0
+ || (info.flags & FLAG_NO_HISTORY) != 0;
+ }
+
void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException {
out.attribute(null, ATTR_ID, String.valueOf(createTime));
out.attribute(null, ATTR_LAUNCHEDFROMUID, String.valueOf(launchedFromUid));
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 912b22c..c5d5867 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -232,7 +232,7 @@
static final int STACK_VISIBLE = 1;
// Stack is considered visible, but only becuase it has activity that is visible behind other
// activities and there is a specific combination of stacks.
- private static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;
+ static final int STACK_VISIBLE_ACTIVITY_BEHIND = 2;
@VisibleForTesting
/* The various modes for the method {@link #removeTask}. */
@@ -1652,28 +1652,20 @@
if (StackId.isBackdropToTranslucentActivity(mStackId)
&& hasVisibleBehindActivity() && StackId.isHomeOrRecentsStack(topStackId)
- && !topStack.topActivity().fullscreen) {
+ && (topStack.topActivity() == null || !topStack.topActivity().fullscreen)) {
// The fullscreen or assistant stack should be visible if it has a visible behind
// activity behind the home or recents stack that is translucent.
return STACK_VISIBLE_ACTIVITY_BEHIND;
}
if (mStackId == DOCKED_STACK_ID) {
- final ActivityRecord r = topStack.topRunningActivityLocked();
-
// If the assistant stack is focused and translucent, then the docked stack is always
// visible
if (topStack.isAssistantStack()) {
return (topStack.isStackTranslucent(starting, DOCKED_STACK_ID)) ? STACK_VISIBLE
: STACK_INVISIBLE;
}
-
- // Otherwise, the docked stack is always visible, except in the case where the top
- // running activity task in the focus stack doesn't support any form of resizing but we
- // show it for the home task even though it's not resizable.
- final TaskRecord task = r != null ? r.getTask() : null;
- return task == null || task.supportsSplitScreen() || task.isHomeTask() ? STACK_VISIBLE
- : STACK_INVISIBLE;
+ return STACK_VISIBLE;
}
// Set home stack to invisible when it is below but not immediately below the docked stack
@@ -1692,14 +1684,17 @@
mStacks.get(stackBehindTopIndex).topRunningActivityLocked() == null) {
stackBehindTopIndex--;
}
- if ((topStackId == DOCKED_STACK_ID || topStackId == PINNED_STACK_ID)
- && stackIndex == stackBehindTopIndex) {
- // Stacks directly behind the docked or pinned stack are always visible.
- return STACK_VISIBLE;
- }
-
final int stackBehindTopId = (stackBehindTopIndex >= 0)
? mStacks.get(stackBehindTopIndex).mStackId : INVALID_STACK_ID;
+ if ((topStackId == DOCKED_STACK_ID || topStackId == PINNED_STACK_ID)
+ && (stackIndex == stackBehindTopIndex
+ || (stackBehindTopId == DOCKED_STACK_ID
+ && stackIndex == stackBehindTopIndex - 1))) {
+ // Stacks directly behind the docked or pinned stack are always visible.
+ // Also this stack is visible if behind docked stack and the docked stack is behind the
+ // top-most pinned stack
+ return STACK_VISIBLE;
+ }
if (StackId.isBackdropToTranslucentActivity(topStackId)
&& topStack.isStackTranslucent(starting, stackBehindTopId)) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 358d36d..d5b54ca 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3500,6 +3500,23 @@
return mService.mUserController.isCurrentProfileLocked(userId);
}
+ /**
+ * Returns whether a stopping activity is present that should be stopped after visible, rather
+ * than idle.
+ * @return {@code true} if such activity is present. {@code false} otherwise.
+ */
+ boolean isStoppingNoHistoryActivity() {
+ // Activities that are marked as nohistory should be stopped immediately after the resumed
+ // activity has become visible.
+ for (ActivityRecord record : mStoppingActivities) {
+ if (record.isNoHistory()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
final ArrayList<ActivityRecord> processStoppingActivitiesLocked(ActivityRecord idleActivity,
boolean remove, boolean processPausingActivities) {
ArrayList<ActivityRecord> stops = null;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 19b9b45..e33ae0d 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -186,7 +186,7 @@
private IVoiceInteractionSession mVoiceSession;
private IVoiceInteractor mVoiceInteractor;
- private boolean mUsingVrCompatibilityDisplay;
+ private boolean mUsingVr2dDisplay;
private void reset() {
mStartActivity = null;
@@ -226,14 +226,14 @@
mVoiceSession = null;
mVoiceInteractor = null;
- mUsingVrCompatibilityDisplay = false;
+ mUsingVr2dDisplay = false;
}
ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
mService = service;
mSupervisor = supervisor;
mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
- mUsingVrCompatibilityDisplay = false;
+ mUsingVr2dDisplay = false;
}
final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
@@ -534,7 +534,8 @@
verificationBundle, userId);
}
return InstantAppResolver.buildEphemeralInstallerIntent(originalIntent,
- callingPackage, verificationBundle, resolvedType, userId, auxiliaryResponse.packageName,
+ auxiliaryResponse.failureIntent, callingPackage, verificationBundle,
+ resolvedType, userId, auxiliaryResponse.packageName,
auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
}
@@ -575,12 +576,15 @@
return;
}
- if (startedActivityStackId == PINNED_STACK_ID
- && (result == START_TASK_TO_FRONT || result == START_DELIVERED_TO_TOP)) {
+ boolean clearedTask = (mLaunchFlags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK))
+ == (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK) && (mReuseTask != null);
+ if (startedActivityStackId == PINNED_STACK_ID && (result == START_TASK_TO_FRONT
+ || result == START_DELIVERED_TO_TOP || clearedTask)) {
// The activity was already running in the pinned stack so it wasn't started, but either
// brought to the front or the new intent was delivered to it since it was already in
// front. Notify anyone interested in this piece of information.
- mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt();
+ mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
+ clearedTask);
return;
}
}
@@ -953,7 +957,7 @@
// If we are not able to proceed, disassociate the activity from the task. Leaving an
// activity in an incomplete state can lead to issues, such as performing operations
// without a window container.
- if (result != START_SUCCESS && mStartActivity.getTask() != null) {
+ if (result < START_SUCCESS && mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
@@ -1059,7 +1063,7 @@
// We didn't do anything... but it was needed (a.k.a., client don't use that
// intent!) And for paranoia, make sure we have correctly resumed the top activity.
resumeTargetStackIfNeeded();
- if (outActivity.length > 0) {
+ if (outActivity != null && outActivity.length > 0) {
outActivity[0] = reusedActivity;
}
return START_TASK_TO_FRONT;
@@ -1476,12 +1480,12 @@
}
// Get the virtual display id from ActivityManagerService.
- int displayId = mService.mVrCompatibilityDisplayId;
+ int displayId = mService.mVr2dDisplayId;
if (displayId != INVALID_DISPLAY) {
if (DEBUG_STACK) {
Slog.d(TAG, "getSourceDisplayId :" + displayId);
}
- mUsingVrCompatibilityDisplay = true;
+ mUsingVr2dDisplay = true;
return displayId;
}
@@ -2105,8 +2109,8 @@
return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
}
- // If we are using Vr compatibility display, find the virtual display stack.
- if (mUsingVrCompatibilityDisplay) {
+ // If we are using Vr2d display, find the virtual display stack.
+ if (mUsingVr2dDisplay) {
ActivityStack as = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, r);
if (DEBUG_STACK) {
Slog.v(TAG, "Launch stack for app: " + r.toString() +
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index d08298b..4ce62e0 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -51,7 +51,6 @@
import android.util.EventLog;
import android.util.Slog;
import android.util.TimeUtils;
-import com.android.server.DeviceIdleController;
import static com.android.server.am.ActivityManagerDebugConfig.*;
@@ -682,7 +681,7 @@
// are already core system stuff so don't matter for this.
r.curApp = filter.receiverList.app;
filter.receiverList.app.curReceivers.add(r);
- mService.updateOomAdjLocked(r.curApp);
+ mService.updateOomAdjLocked(r.curApp, true);
}
}
try {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b025385..fbc2bd2 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -103,7 +103,6 @@
int renderThreadTid; // TID for RenderThread
boolean serviceb; // Process currently is on the service B list
boolean serviceHighRam; // We are forcing to service B list due to its RAM use
- boolean setIsForeground; // Running foreground UI when last set?
boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
boolean hasClientActivities; // Are there any client services with activities?
boolean hasStartedServices; // Are there any started services running in this process?
@@ -303,9 +302,8 @@
pw.print(" hasAboveClient="); pw.print(hasAboveClient);
pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
}
- if (setIsForeground || foregroundServices || forcingToForeground != null) {
- pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
- pw.print(" foregroundServices="); pw.print(foregroundServices);
+ if (foregroundServices || forcingToForeground != null) {
+ pw.print(prefix); pw.print("foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
}
if (reportedInteraction || fgInteractionTime != 0) {
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 7d2bc5b..f5d7b68 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -104,7 +104,7 @@
};
private final TaskStackConsumer mNotifyPinnedActivityRestartAttempt = (l, m) -> {
- l.onPinnedActivityRestartAttempt();
+ l.onPinnedActivityRestartAttempt(m.arg1 != 0);
};
private final TaskStackConsumer mNotifyPinnedStackAnimationStarted = (l, m) -> {
@@ -300,10 +300,11 @@
* running in the pinned stack and the activity was not actually started, but the task is
* either brought to the front or a new Intent is delivered to it.
*/
- void notifyPinnedActivityRestartAttempt() {
+ void notifyPinnedActivityRestartAttempt(boolean clearedTask) {
mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
final Message msg =
- mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
+ mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
+ clearedTask ? 1 : 0, 0);
forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
msg.sendToTarget();
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index c0fb77f..c411bce 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -35,6 +35,7 @@
int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
long lastBackgroundTime;
boolean ephemeral;
+ boolean foregroundServices;
boolean curWhitelist;
boolean setWhitelist;
boolean idle;
@@ -102,6 +103,7 @@
public void reset() {
curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+ foregroundServices = false;
}
public void updateHasInternetPermission() {
@@ -131,6 +133,9 @@
if (ephemeral) {
sb.append(" ephemeral");
}
+ if (foregroundServices) {
+ sb.append(" fgServices");
+ }
if (curWhitelist) {
sb.append(" whitelist");
}
diff --git a/services/core/java/com/android/server/audio/FocusRequester.java b/services/core/java/com/android/server/audio/FocusRequester.java
index 93a22494..73cbffd 100644
--- a/services/core/java/com/android/server/audio/FocusRequester.java
+++ b/services/core/java/com/android/server/audio/FocusRequester.java
@@ -310,7 +310,6 @@
*/
void handleFocusGain(int focusGain) {
try {
- final int oldLoss = mFocusLossReceived;
mFocusLossReceived = AudioManager.AUDIOFOCUS_NONE;
mFocusController.notifyExtPolicyFocusGrant_syncAf(toAudioFocusInfo(),
AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
@@ -322,9 +321,8 @@
}
if (mFocusLossWasNotified) {
fd.dispatchAudioFocusChange(focusGain, mClientId);
- } else if (oldLoss == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
- mFocusController.unduckPlayers(this);
}
+ mFocusController.unduckPlayers(this);
}
mFocusLossWasNotified = false;
} catch (android.os.RemoteException e) {
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index d35104f..3053879 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -18,12 +18,10 @@
import android.annotation.NonNull;
import android.media.AudioAttributes;
-import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioSystem;
import android.media.IPlaybackConfigDispatcher;
-import android.media.MediaRecorder;
import android.media.PlayerBase;
import android.media.VolumeShaper;
import android.os.Binder;
@@ -99,13 +97,6 @@
apc.init();
synchronized(mPlayerLock) {
mPlayers.put(newPiid, apc);
- if (mDuckedUids.contains(new Integer(apc.getClientUid()))) {
- if (DEBUG) { Log.v(TAG, " > trackPlayer() piid=" + newPiid + " must be ducked"); }
- mDuckedPlayers.add(new Integer(newPiid));
- // FIXME here the player needs to be put in a state that is the same as if it
- // had been ducked as it starts. At the moment, this works already for linked
- // players, as is the case in gapless playback.
- }
}
return newPiid;
}
@@ -131,10 +122,11 @@
final boolean change;
synchronized(mPlayerLock) {
final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
- // FIXME SoundPool not ready for state reporting
- if (apc != null
- && apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL)
- {
+ if (apc == null) {
+ return;
+ }
+ if (apc.getPlayerType() == AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
+ // FIXME SoundPool not ready for state reporting
return;
}
if (checkConfigurationCaller(piid, apc, binderUid)) {
@@ -144,12 +136,8 @@
Log.e(TAG, "Error handling event " + event);
change = false;
}
- if (change && event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
- && mDuckedUids.contains(new Integer(apc.getClientUid()))) {
- if (DEBUG) { Log.v(TAG, " > playerEvent() piid=" + piid + " must be ducked"); }
- if (!mDuckedPlayers.contains(new Integer(piid))) {
- mDuckedPlayers.add(new Integer(piid));
- }
+ if (change && event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED) {
+ mDuckingManager.checkDuck(apc);
}
}
if (change) {
@@ -163,6 +151,7 @@
final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
if (checkConfigurationCaller(piid, apc, binderUid)) {
mPlayers.remove(new Integer(piid));
+ mDuckingManager.removeReleased(apc);
}
}
}
@@ -182,10 +171,8 @@
conf.dump(pw);
}
// ducked players
- pw.println("\n ducked player piids:");
- for (int piid : mDuckedPlayers) {
- pw.println(" " + piid);
- }
+ pw.println("\n ducked players:");
+ mDuckingManager.dump(pw);
// players muted due to the device ringing or being in a call
pw.println("\n muted player piids:");
for (int piid : mMutedPlayers) {
@@ -274,10 +261,9 @@
//=================================================================
// PlayerFocusEnforcer implementation
- private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>();
private final ArrayList<Integer> mMutedPlayers = new ArrayList<Integer>();
- // size of 2 for typical cases of double-ducking, not expected to grow beyond that, but can
- private final ArrayList<Integer> mDuckedUids = new ArrayList<Integer>(2);
+
+ private final DuckingManager mDuckingManager = new DuckingManager();
@Override
public boolean duckPlayers(FocusRequester winner, FocusRequester loser) {
@@ -286,60 +272,46 @@
winner.getClientUid(), loser.getClientUid()));
}
synchronized (mPlayerLock) {
- final Integer loserUid = new Integer(loser.getClientUid());
- if (!mDuckedUids.contains(loserUid)) {
- mDuckedUids.add(loserUid);
- }
if (mPlayers.isEmpty()) {
return true;
}
- final Set<Integer> piidSet = mPlayers.keySet();
- final Iterator<Integer> piidIterator = piidSet.iterator();
- // find which players to duck
- while (piidIterator.hasNext()) {
- final Integer piid = piidIterator.next();
- final AudioPlaybackConfiguration apc = mPlayers.get(piid);
- if (apc == null) {
- continue;
- }
+ // check if this UID needs to be ducked (return false if not), and gather list of
+ // eligible players to duck
+ final Iterator<AudioPlaybackConfiguration> apcIterator = mPlayers.values().iterator();
+ final ArrayList<AudioPlaybackConfiguration> apcsToDuck =
+ new ArrayList<AudioPlaybackConfiguration>();
+ while (apcIterator.hasNext()) {
+ final AudioPlaybackConfiguration apc = apcIterator.next();
if (!winner.hasSameUid(apc.getClientUid())
&& loser.hasSameUid(apc.getClientUid())
&& apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED)
{
- if (mDuckedPlayers.contains(new Integer(piid))) {
- if (DEBUG) { Log.v(TAG, "player " + piid + " already ducked"); }
- } else if (MediaFocusControl.ENFORCE_DUCKING
+ if (MediaFocusControl.ENFORCE_DUCKING
&& MediaFocusControl.ENFORCE_DUCKING_FOR_NEW
&& loser.getSdkTarget() <= MediaFocusControl.DUCKING_IN_APP_SDK_LEVEL) {
// legacy behavior, apps used to be notified when they should be ducking
- if (DEBUG) { Log.v(TAG, "not ducking player " + piid + ": old SDK"); }
+ if (DEBUG) {Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
+ + ": old SDK"); }
return false;
} else if (apc.getAudioAttributes().getContentType() ==
AudioAttributes.CONTENT_TYPE_SPEECH) {
// the player is speaking, ducking will make the speech unintelligible
// so let the app handle it instead
- if (DEBUG) { Log.v(TAG, "not ducking player " + piid + ": SPEECH"); }
+ if (DEBUG) { Log.v(TAG, "not ducking player " + apc.getPlayerInterfaceId()
+ + ": SPEECH"); }
return false;
} else if (apc.getPlayerType()
== AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL) {
// TODO support ducking of SoundPool players
return false;
- } else {
- try {
- Log.v(TAG, "ducking player " + piid);
- apc.getPlayerProxy().applyVolumeShaper(
- DUCK_VSHAPE,
- PLAY_CREATE_IF_NEEDED);
- mDuckedPlayers.add(new Integer(piid));
- } catch (Exception e) {
- Log.e(TAG, "Error ducking player " + piid, e);
- // something went wrong trying to duck, so let the app handle it
- // instead, it may know things we don't
- return false;
- }
}
+ apcsToDuck.add(apc);
}
}
+ // add the players eligible for ducking to the list, and duck them
+ // (if apcsToDuck is empty, this will at least mark this uid as ducked, so when
+ // players of the same uid start, they will be ducked by DuckingManager.checkDuck())
+ mDuckingManager.duckUid(loser.getClientUid(), apcsToDuck);
}
return true;
}
@@ -348,37 +320,7 @@
public void unduckPlayers(FocusRequester winner) {
if (DEBUG) { Log.v(TAG, "unduckPlayers: uids winner=" + winner.getClientUid()); }
synchronized (mPlayerLock) {
- if (mDuckedPlayers.isEmpty()) {
- mDuckedUids.remove(new Integer(winner.getClientUid()));
- return;
- }
- final ArrayList<Integer> playersToRemove =
- new ArrayList<Integer>(mDuckedPlayers.size());
- for (int piid : mDuckedPlayers) {
- final AudioPlaybackConfiguration apc = mPlayers.get(piid);
- if (apc != null) {
- if (winner.hasSameUid(apc.getClientUid())) {
- try {
- Log.v(TAG, "unducking player " + piid);
- apc.getPlayerProxy().applyVolumeShaper(
- DUCK_ID,
- VolumeShaper.Operation.REVERSE);
- } catch (Exception e) {
- Log.e(TAG, "Error unducking player " + piid, e);
- } finally {
- playersToRemove.add(piid);
- }
- }
- } else {
- // this piid was in the list of ducked players, but wasn't found, discard it
- Log.v(TAG, "Error unducking player " + piid + ", player not found");
- playersToRemove.add(piid);
- }
- }
- for (int piid : playersToRemove) {
- mDuckedPlayers.remove(new Integer(piid));
- }
- mDuckedUids.remove(new Integer(winner.getClientUid()));
+ mDuckingManager.unduckUid(winner.getClientUid(), mPlayers);
}
}
@@ -541,4 +483,118 @@
mDispatcherCb.asBinder().unlinkToDeath(this, 0);
}
}
+
+ //=================================================================
+ // Class to handle ducking related operations for a given UID
+ private static final class DuckingManager {
+ private final HashMap<Integer, DuckedApp> mDuckers = new HashMap<Integer, DuckedApp>();
+
+ void duckUid(int uid, ArrayList<AudioPlaybackConfiguration> apcsToDuck) {
+ if (!mDuckers.containsKey(uid)) {
+ mDuckers.put(uid, new DuckedApp(uid));
+ }
+ final DuckedApp da = mDuckers.get(uid);
+ for (AudioPlaybackConfiguration apc : apcsToDuck) {
+ da.addDuck(apc);
+ }
+ }
+
+ void unduckUid(int uid, HashMap<Integer, AudioPlaybackConfiguration> players) {
+ final DuckedApp da = mDuckers.remove(uid);
+ if (da == null) {
+ return;
+ }
+ da.removeUnduckAll(players);
+ }
+
+ // pre-condition: apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
+ void checkDuck(@NonNull AudioPlaybackConfiguration apc) {
+ final DuckedApp da = mDuckers.get(apc.getClientUid());
+ if (da == null) {
+ return;
+ }
+ // FIXME here the player needs to be put in a state that is the same as if it
+ // had been ducked as it starts. At the moment, this works already for linked
+ // players, as is the case in gapless playback.
+ da.addDuck(apc);
+ }
+
+ void dump(PrintWriter pw) {
+ for (DuckedApp da : mDuckers.values()) {
+ da.dump(pw);
+ }
+ }
+
+ void removeReleased(@NonNull AudioPlaybackConfiguration apc) {
+ final DuckedApp da = mDuckers.get(apc.getClientUid());
+ if (da == null) {
+ return;
+ }
+ da.removeReleased(apc);
+ }
+
+ private static final class DuckedApp {
+ private final int mUid;
+ private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>();
+
+ DuckedApp(int uid) {
+ mUid = uid;
+ }
+
+ void dump(PrintWriter pw) {
+ pw.print("\t uid:" + mUid + " piids:");
+ for (int piid : mDuckedPlayers) {
+ pw.print(" " + piid);
+ }
+ pw.println("");
+ }
+
+ // pre-conditions:
+ // * apc != null
+ // * apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
+ void addDuck(@NonNull AudioPlaybackConfiguration apc) {
+ final int piid = new Integer(apc.getPlayerInterfaceId());
+ if (mDuckedPlayers.contains(piid)) {
+ if (DEBUG) { Log.v(TAG, "player " + piid + " already ducked"); }
+ return;
+ }
+ try {
+ Log.v(TAG, "ducking player " + apc.getPlayerInterfaceId());
+ apc.getPlayerProxy().applyVolumeShaper(
+ DUCK_VSHAPE,
+ PLAY_CREATE_IF_NEEDED);
+ mDuckedPlayers.add(piid);
+ } catch (Exception e) {
+ Log.e(TAG, "Error ducking player " + piid, e);
+ }
+ }
+
+ void removeUnduckAll(HashMap<Integer, AudioPlaybackConfiguration> players) {
+ for (int piid : mDuckedPlayers) {
+ final AudioPlaybackConfiguration apc = players.get(piid);
+ if (apc != null) {
+ try {
+ Log.v(TAG, "unducking player " + piid);
+ apc.getPlayerProxy().applyVolumeShaper(
+ DUCK_ID,
+ VolumeShaper.Operation.REVERSE);
+ } catch (Exception e) {
+ Log.e(TAG, "Error unducking player " + piid, e);
+ }
+ } else {
+ // this piid was in the list of ducked players, but wasn't found
+ if (DEBUG) {
+ Log.v(TAG, "Error unducking player " + piid + ", player not found for"
+ + " uid " + mUid);
+ }
+ }
+ }
+ mDuckedPlayers.clear();
+ }
+
+ void removeReleased(@NonNull AudioPlaybackConfiguration apc) {
+ mDuckedPlayers.remove(new Integer(apc.getPlayerInterfaceId()));
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/display/NightDisplayService.java b/services/core/java/com/android/server/display/NightDisplayService.java
index d1275bb..7849896 100644
--- a/services/core/java/com/android/server/display/NightDisplayService.java
+++ b/services/core/java/com/android/server/display/NightDisplayService.java
@@ -47,7 +47,6 @@
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
-import com.android.server.vr.VrManagerService;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.Calendar;
@@ -62,7 +61,6 @@
implements NightDisplayController.Callback {
private static final String TAG = "NightDisplayService";
- private static final boolean DEBUG = false;
/**
* The transition time, in milliseconds, for Night Display to turn on/off.
@@ -151,8 +149,9 @@
@Override
public void onBootPhase(int phase) {
- if (phase == PHASE_SYSTEM_SERVICES_READY) {
- IVrManager vrManager = (IVrManager) getBinderService(Context.VR_SERVICE);
+ if (phase >= PHASE_SYSTEM_SERVICES_READY) {
+ final IVrManager vrManager = IVrManager.Stub.asInterface(
+ getBinderService(Context.VR_SERVICE));
if (vrManager != null) {
try {
vrManager.registerListener(mVrStateCallbacks);
@@ -160,7 +159,9 @@
Slog.e(TAG, "Failed to register VR mode state listener: " + e);
}
}
- } else if (phase == PHASE_BOOT_COMPLETED) {
+ }
+
+ if (phase >= PHASE_BOOT_COMPLETED) {
mBootCompleted = true;
// Register listeners now that boot is complete.
@@ -284,12 +285,18 @@
if (mIsActivated == null || mIsActivated != activated) {
Slog.i(TAG, activated ? "Turning on night display" : "Turning off night display");
- if (mAutoMode != null) {
- mAutoMode.onActivated(activated);
+ if (mIsActivated != null) {
+ Secure.putLongForUser(getContext().getContentResolver(),
+ Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, System.currentTimeMillis(),
+ mCurrentUser);
}
mIsActivated = activated;
+ if (mAutoMode != null) {
+ mAutoMode.onActivated(activated);
+ }
+
applyTint(false);
}
}
@@ -401,7 +408,7 @@
* Set the color transformation {@code MATRIX_NIGHT} to the given color temperature.
*
* @param colorTemperature color temperature in Kelvin
- * @param outTemp the 4x4 display transformation matrix for that color temperature
+ * @param outTemp the 4x4 display transformation matrix for that color temperature
*/
private void setMatrix(int colorTemperature, float[] outTemp) {
if (outTemp.length != 16) {
@@ -423,8 +430,22 @@
outTemp[10] = blue;
}
+ private Calendar getLastActivatedTime() {
+ final ContentResolver cr = getContext().getContentResolver();
+ final long lastActivatedTimeMillis = Secure.getLongForUser(
+ cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, -1, mCurrentUser);
+ if (lastActivatedTimeMillis < 0) {
+ return null;
+ }
+
+ final Calendar lastActivatedTime = Calendar.getInstance();
+ lastActivatedTime.setTimeInMillis(lastActivatedTimeMillis);
+ return lastActivatedTime;
+ }
+
private abstract class AutoMode implements NightDisplayController.Callback {
public abstract void onStart();
+
public abstract void onStop();
}
@@ -438,7 +459,7 @@
private Calendar mLastActivatedTime;
- public CustomAutoMode() {
+ CustomAutoMode() {
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
mTimeChangedReceiver = new BroadcastReceiver() {
@Override
@@ -452,10 +473,10 @@
final Calendar now = Calendar.getInstance();
final Calendar startTime = mStartTime.getDateTimeBefore(now);
final Calendar endTime = mEndTime.getDateTimeAfter(startTime);
- final boolean activated = now.before(endTime);
- boolean setActivated = mIsActivated == null || mLastActivatedTime == null;
- if (!setActivated && mIsActivated != activated) {
+ boolean activate = now.before(endTime);
+ if (mLastActivatedTime != null) {
+ // Convert mLastActivatedTime to the current timezone if needed.
final TimeZone currentTimeZone = now.getTimeZone();
if (!currentTimeZone.equals(mLastActivatedTime.getTimeZone())) {
final int year = mLastActivatedTime.get(Calendar.YEAR);
@@ -470,17 +491,16 @@
mLastActivatedTime.set(Calendar.MINUTE, minute);
}
- if (mIsActivated) {
- setActivated = now.before(mStartTime.getDateTimeBefore(mLastActivatedTime))
- || now.after(mEndTime.getDateTimeAfter(mLastActivatedTime));
- } else {
- setActivated = now.before(mEndTime.getDateTimeBefore(mLastActivatedTime))
- || now.after(mStartTime.getDateTimeAfter(mLastActivatedTime));
+ // Maintain the existing activated state if within the current period.
+ if (mLastActivatedTime.before(now)
+ && mLastActivatedTime.after(startTime)
+ && (mLastActivatedTime.after(endTime) || now.before(endTime))) {
+ activate = mController.isActivated();
}
}
- if (setActivated) {
- mController.setActivated(activated);
+ if (mIsActivated == null || mIsActivated != activate) {
+ mController.setActivated(activate);
}
updateNextAlarm(mIsActivated, now);
}
@@ -502,6 +522,8 @@
mStartTime = mController.getCustomStartTime();
mEndTime = mController.getCustomEndTime();
+ mLastActivatedTime = getLastActivatedTime();
+
// Force an update to initialize state.
updateActivated();
}
@@ -516,11 +538,8 @@
@Override
public void onActivated(boolean activated) {
- final Calendar now = Calendar.getInstance();
- if (mIsActivated != null) {
- mLastActivatedTime = now;
- }
- updateNextAlarm(activated, now);
+ mLastActivatedTime = getLastActivatedTime();
+ updateNextAlarm(activated, Calendar.getInstance());
}
@Override
@@ -550,33 +569,33 @@
private Calendar mLastActivatedTime;
- public TwilightAutoMode() {
+ TwilightAutoMode() {
mTwilightManager = getLocalService(TwilightManager.class);
}
private void updateActivated(TwilightState state) {
- final boolean isNight = state != null && state.isNight();
- boolean setActivated = mIsActivated == null || mIsActivated != isNight;
- if (setActivated && state != null && mLastActivatedTime != null) {
+ boolean activate = state != null && state.isNight();
+ if (state != null && mLastActivatedTime != null) {
+ final Calendar now = Calendar.getInstance();
final Calendar sunrise = state.sunrise();
final Calendar sunset = state.sunset();
- if (sunrise.before(sunset)) {
- setActivated = mLastActivatedTime.before(sunrise)
- || mLastActivatedTime.after(sunset);
- } else {
- setActivated = mLastActivatedTime.before(sunset)
- || mLastActivatedTime.after(sunrise);
+
+ // Maintain the existing activated state if within the current period.
+ if (mLastActivatedTime.before(now)
+ && (mLastActivatedTime.after(sunrise) ^ mLastActivatedTime.after(sunset))) {
+ activate = mController.isActivated();
}
}
- if (setActivated) {
- mController.setActivated(isNight);
+ if (mIsActivated == null || mIsActivated != activate) {
+ mController.setActivated(activate);
}
}
@Override
public void onStart() {
mTwilightManager.registerListener(this, mHandler);
+ mLastActivatedTime = getLastActivatedTime();
// Force an update to initialize state.
updateActivated(mTwilightManager.getLastTwilightState());
@@ -591,7 +610,7 @@
@Override
public void onActivated(boolean activated) {
if (mIsActivated != null) {
- mLastActivatedTime = Calendar.getInstance();
+ mLastActivatedTime = getLastActivatedTime();
}
}
diff --git a/services/core/java/com/android/server/fingerprint/RemovalClient.java b/services/core/java/com/android/server/fingerprint/RemovalClient.java
index 6610634..88a6bdd 100644
--- a/services/core/java/com/android/server/fingerprint/RemovalClient.java
+++ b/services/core/java/com/android/server/fingerprint/RemovalClient.java
@@ -91,7 +91,7 @@
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify Removed:", e);
}
- return fingerId == 0;
+ return remaining == 0;
}
@Override
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 91c32e4..51bebb09 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -382,6 +382,8 @@
// Wakelocks
private final static String WAKELOCK_KEY = "GnssLocationProvider";
private final PowerManager.WakeLock mWakeLock;
+ private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
+ private final PowerManager.WakeLock mDownloadXtraWakeLock;
// Alarms
private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
@@ -686,6 +688,11 @@
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
mWakeLock.setReferenceCounted(true);
+ // Create a separate wake lock for xtra downloader as it may be released due to timeout.
+ mDownloadXtraWakeLock = mPowerManager.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
+ mDownloadXtraWakeLock.setReferenceCounted(true);
+
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
@@ -989,7 +996,7 @@
mDownloadXtraDataPending = STATE_DOWNLOADING;
// hold wake lock while task runs
- mWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
+ mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
@Override
@@ -1011,13 +1018,17 @@
mXtraBackOff.nextBackoffMillis());
}
- // release wake lock held by task
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- } else {
- Log.e(TAG, "WakeLock expired before release in handleDownloadXtraData()");
+ // Release wake lock held by task, synchronize on mLock in case multiple
+ // download tasks overrun.
+ synchronized (mLock) {
+ if (mDownloadXtraWakeLock.isHeld()) {
+ mDownloadXtraWakeLock.release();
+ if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
+ } else {
+ Log.e(TAG, "WakeLock expired before release in "
+ + "handleDownloadXtraData()");
+ }
}
- Log.i(TAG, "WakeLock released by handleDownloadXtraData()");
}
});
}
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 63647ff..8caaaa1 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -73,11 +73,13 @@
// Next: sufficiently import person to person communication
boolean leftPeople = isImportantPeople(left);
boolean rightPeople = isImportantPeople(right);
+ final int contactAffinityComparison =
+ Float.compare(left.getContactAffinity(), right.getContactAffinity());
if (leftPeople && rightPeople){
// by contact proximity, close to far. if same proximity, check further fields.
- if (Float.compare(left.getContactAffinity(), right.getContactAffinity()) != 0) {
- return -1 * Float.compare(left.getContactAffinity(), right.getContactAffinity());
+ if (contactAffinityComparison != 0) {
+ return -1 * contactAffinityComparison;
}
} else if (leftPeople != rightPeople) {
// People, messaging higher than non-messaging
@@ -91,6 +93,11 @@
return -1 * Integer.compare(leftImportance, rightImportance);
}
+ // by contact proximity, close to far. if same proximity, check further fields.
+ if (contactAffinityComparison != 0) {
+ return -1 * contactAffinityComparison;
+ }
+
// Whether or not the notification can bypass DND.
final int leftPackagePriority = left.getPackagePriority();
final int rightPackagePriority = right.getPackagePriority();
diff --git a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
index 31ed350..4981d5c 100644
--- a/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
+++ b/services/core/java/com/android/server/notification/NotificationIntrusivenessExtractor.java
@@ -19,6 +19,7 @@
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
+import android.net.Uri;
import android.service.notification.NotificationListenerService;
import android.util.Log;
import android.util.Slog;
@@ -46,12 +47,13 @@
}
if (record.getImportance() >= NotificationManager.IMPORTANCE_DEFAULT) {
- final Notification notification = record.getNotification();
- if ((notification.defaults & Notification.DEFAULT_VIBRATE) != 0 ||
- notification.vibrate != null ||
- (notification.defaults & Notification.DEFAULT_SOUND) != 0 ||
- notification.sound != null ||
- notification.fullScreenIntent != null) {
+ if (record.getSound() != null && record.getSound() != Uri.EMPTY) {
+ record.setRecentlyIntrusive(true);
+ }
+ if (record.getVibration() != null) {
+ record.setRecentlyIntrusive(true);
+ }
+ if (record.getNotification().fullScreenIntent != null) {
record.setRecentlyIntrusive(true);
}
}
@@ -64,7 +66,11 @@
@Override
public void applyChangesLocked(NotificationRecord record) {
- record.setRecentlyIntrusive(false);
+ // there will be another reconsideration in the message queue HANG_TIME_MS
+ // from each time this record alerts, which can finally clear this flag.
+ if ((System.currentTimeMillis() - record.getLastIntrusive()) >= HANG_TIME_MS) {
+ record.setRecentlyIntrusive(false);
+ }
}
};
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d8d099b..83ac94f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -884,6 +884,8 @@
} else if (action.equals(Intent.ACTION_USER_REMOVED)) {
final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mZenModeHelper.onUserRemoved(user);
+ mRankingHelper.onUserRemoved(user);
+ savePolicyFile();
} else if (action.equals(Intent.ACTION_USER_UNLOCKED)) {
final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mConditionProviders.onUserUnlocked(user);
@@ -3189,12 +3191,6 @@
final NotificationChannel channel = mRankingHelper.getNotificationChannel(pkg,
notificationUid, channelId, false /* includeDeleted */);
if (channel == null) {
- // STOPSHIP TODO: remove before release - should always throw without a valid channel.
- if (channelId == null) {
- Log.e(TAG, "Cannot post notification without channel ID when targeting O "
- + " - notification=" + notification);
- return;
- }
final String noChannelStr = "No Channel found for "
+ "pkg=" + pkg
+ ", channelId=" + channelId
@@ -3204,19 +3200,11 @@
+ ", incomingUserId=" + incomingUserId
+ ", notificationUid=" + notificationUid
+ ", notification=" + notification;
- // STOPSHIP TODO: should throw instead of logging or toasting.
- // throw new IllegalArgumentException(noChannelStr);
Log.e(TAG, noChannelStr);
- doDebugOnlyToast("Developer warning for package \"" + pkg + "\"\n" +
+ doChannelWarningToast("Developer warning for package \"" + pkg + "\"\n" +
"Failed to post notification on channel \"" + channelId + "\"\n" +
"See log for more details");
return;
- } else if (channelId == null && shouldWarnUseChannels(pkg, notificationUid)) {
- // STOPSHIP TODO: remove once default channel is removed for all apps that target O.
- Log.e(TAG, "Developer Warning for package " + pkg
- + ", no channel specified for posted notification: " + notification);
- doDebugOnlyToast("Developer warning for package \"" + pkg + "\"\n" +
- "Posted notification should specify a channel");
}
final StatusBarNotification n = new StatusBarNotification(
@@ -3248,8 +3236,10 @@
mHandler.post(new EnqueueNotificationRunnable(userId, r));
}
- private void doDebugOnlyToast(CharSequence toastText) {
- if (Build.IS_DEBUGGABLE) {
+ private void doChannelWarningToast(CharSequence toastText) {
+ final boolean warningEnabled = Settings.System.getInt(getContext().getContentResolver(),
+ Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, 0) != 0;
+ if (warningEnabled || Build.IS_DEBUGGABLE) {
try {
Toast toast = Toast.makeText(getContext(), toastText, Toast.LENGTH_LONG);
toast.show();
@@ -3259,19 +3249,6 @@
}
}
- // STOPSHIP - Remove once RankingHelper deletes default channel for all apps targeting O.
- private boolean shouldWarnUseChannels(String pkg, int uid) {
- try {
- final int userId = UserHandle.getUserId(uid);
- final ApplicationInfo applicationInfo =
- mPackageManagerClient.getApplicationInfoAsUser(pkg, 0, userId);
- return applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1;
- } catch (NameNotFoundException e) {
- Slog.e(TAG, e.toString());
- return false;
- }
- }
-
private int resolveNotificationUid(String opPackageName, int callingUid, int userId) {
// The system can post notifications on behalf of any package it wants
if (isCallerSystemOrPhone() && opPackageName != null && !"android".equals(opPackageName)) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index b51a4d1..5a5e658 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -85,6 +85,7 @@
// to communicate with the ranking module.
private float mContactAffinity;
private boolean mRecentlyIntrusive;
+ private long mLastIntrusive;
// is this notification currently being intercepted by Zen Mode?
private boolean mIntercept;
@@ -531,12 +532,19 @@
public void setRecentlyIntrusive(boolean recentlyIntrusive) {
mRecentlyIntrusive = recentlyIntrusive;
+ if (recentlyIntrusive) {
+ mLastIntrusive = System.currentTimeMillis();
+ }
}
public boolean isRecentlyIntrusive() {
return mRecentlyIntrusive;
}
+ public long getLastIntrusive() {
+ return mLastIntrusive;
+ }
+
public void setPackagePriority(int packagePriority) {
mPackagePriority = packagePriority;
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 6d18c83..7758516 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -275,29 +275,13 @@
private boolean shouldHaveDefaultChannel(Record r) throws NameNotFoundException {
final int userId = UserHandle.getUserId(r.uid);
final ApplicationInfo applicationInfo = mPm.getApplicationInfoAsUser(r.pkg, 0, userId);
- if (applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
- // Pre-O apps should have it.
- return true;
+ if (applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1) {
+ // O apps should not have the default channel.
+ return false;
}
- // STOPSHIP TODO: remove before release - O+ apps should never have a default channel.
- // But for now, leave the default channel until an app has created its first channel.
- boolean hasCreatedAChannel = false;
- final int size = r.channels.size();
- for (int i = 0; i < size; i++) {
- final NotificationChannel notificationChannel = r.channels.valueAt(i);
- if (notificationChannel != null &&
- !notificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
- hasCreatedAChannel = true;
- break;
- }
- }
- if (!hasCreatedAChannel) {
- return true;
- }
-
- // Otherwise, should not have the default channel.
- return false;
+ // Otherwise, this app should have the default channel.
+ return true;
}
private void deleteDefaultChannelIfNeeded(Record r) throws NameNotFoundException {
@@ -1027,6 +1011,18 @@
return packageChannels;
}
+ public void onUserRemoved(int userId) {
+ synchronized (mRecords) {
+ int N = mRecords.size();
+ for (int i = N - 1; i >= 0 ; i--) {
+ Record record = mRecords.valueAt(i);
+ if (UserHandle.getUserId(record.uid) == userId) {
+ mRecords.removeAt(i);
+ }
+ }
+ }
+ }
+
public void onPackagesChanged(boolean removingPackage, int changeUserId, String[] pkgList,
int[] uidList) {
if (pkgList == null || pkgList.length == 0) {
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 9d08004..09e9433 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -43,6 +43,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.NoSuchElementException;
import java.util.concurrent.TimeoutException;
/**
@@ -206,7 +207,9 @@
private void handleBinderDiedLocked() {
if (mRemoteInstance != null) {
- mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/);
+ try {
+ mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/);
+ } catch (NoSuchElementException ignore) { }
}
mRemoteInstance = null;
}
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 624d8c9..f3c9cbb 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -125,6 +125,7 @@
final String packageName;
final String splitName;
final int versionCode;
+ final Intent failureIntent;
if (instantAppResolveInfoList != null && instantAppResolveInfoList.size() > 0) {
final AuxiliaryResolveInfo instantAppIntentInfo =
InstantAppResolver.filterInstantAppIntent(
@@ -135,18 +136,22 @@
packageName = instantAppIntentInfo.resolveInfo.getPackageName();
splitName = instantAppIntentInfo.splitName;
versionCode = instantAppIntentInfo.resolveInfo.getVersionCode();
+ failureIntent = instantAppIntentInfo.failureIntent;
} else {
packageName = null;
splitName = null;
versionCode = -1;
+ failureIntent = null;
}
} else {
packageName = null;
splitName = null;
versionCode = -1;
+ failureIntent = null;
}
final Intent installerIntent = buildEphemeralInstallerIntent(
requestObj.origIntent,
+ failureIntent,
requestObj.callingPackage,
requestObj.verificationBundle,
requestObj.resolvedType,
@@ -172,7 +177,9 @@
/**
* Builds and returns an intent to launch the instant installer.
*/
- public static Intent buildEphemeralInstallerIntent(@NonNull Intent origIntent,
+ public static Intent buildEphemeralInstallerIntent(
+ @NonNull Intent origIntent,
+ @NonNull Intent failureIntent,
@NonNull String callingPackage,
@Nullable Bundle verificationBundle,
@NonNull String resolvedType,
@@ -200,22 +207,21 @@
// We have all of the data we need; just start the installer without a second phase
if (!needsPhaseTwo) {
// Intent that is launched if the package couldn't be installed for any reason.
- final Intent failureIntent = new Intent(origIntent);
- failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
- failureIntent.setLaunchToken(token);
- try {
- final IIntentSender failureIntentTarget = ActivityManager.getService()
- .getIntentSender(
- ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
- null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
- new Intent[] { failureIntent },
- new String[] { resolvedType },
- PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
- | PendingIntent.FLAG_IMMUTABLE,
- null /*bOptions*/, userId);
- intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE,
- new IntentSender(failureIntentTarget));
- } catch (RemoteException ignore) { /* ignore; same process */ }
+ if (failureIntent != null) {
+ try {
+ final IIntentSender failureIntentTarget = ActivityManager.getService()
+ .getIntentSender(
+ ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
+ null /*token*/, null /*resultWho*/, 1 /*requestCode*/,
+ new Intent[] { failureIntent },
+ new String[] { resolvedType },
+ PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
+ | PendingIntent.FLAG_IMMUTABLE,
+ null /*bOptions*/, userId);
+ intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE,
+ new IntentSender(failureIntentTarget));
+ } catch (RemoteException ignore) { /* ignore; same process */ }
+ }
// Intent that is launched if the package was installed successfully.
final Intent successIntent = new Intent(origIntent);
@@ -248,10 +254,13 @@
private static AuxiliaryResolveInfo filterInstantAppIntent(
List<InstantAppResolveInfo> instantAppResolveInfoList,
- Intent intent, String resolvedType, int userId, String packageName,
+ Intent origIntent, String resolvedType, int userId, String packageName,
InstantAppDigest digest, String token) {
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
+ final Intent failureIntent = new Intent(origIntent);
+ failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+ failureIntent.setLaunchToken(token);
// Go in reverse order so we match the narrowest scope first.
for (int i = shaPrefix.length - 1; i >= 0 ; --i) {
for (InstantAppResolveInfo instantAppInfo : instantAppResolveInfoList) {
@@ -271,7 +280,8 @@
}
return new AuxiliaryResolveInfo(instantAppInfo,
new IntentFilter(Intent.ACTION_VIEW) /*intentFilter*/,
- null /*splitName*/, token, true /*needsPhase2*/);
+ null /*splitName*/, token, true /*needsPhase2*/,
+ null /*failureIntent*/);
}
// We have a domain match; resolve the filters to see if anything matches.
final PackageManagerService.EphemeralIntentResolver instantAppResolver =
@@ -286,12 +296,12 @@
final AuxiliaryResolveInfo intentInfo =
new AuxiliaryResolveInfo(instantAppInfo,
splitFilters.get(k), instantAppFilter.getSplitName(),
- token, false /*needsPhase2*/);
+ token, false /*needsPhase2*/, failureIntent);
instantAppResolver.addFilter(intentInfo);
}
}
List<AuxiliaryResolveInfo> matchedResolveInfoList = instantAppResolver.queryIntent(
- intent, resolvedType, false /*defaultOnly*/, userId);
+ origIntent, resolvedType, false /*defaultOnly*/, userId);
if (!matchedResolveInfoList.isEmpty()) {
if (DEBUG_EPHEMERAL) {
final AuxiliaryResolveInfo info = matchedResolveInfoList.get(0);
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 254bc2a..59bce8f 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -24,6 +24,7 @@
import android.os.Environment;
import android.os.FileUtils;
import android.os.PowerManager;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;
@@ -54,6 +55,7 @@
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
+import static com.android.server.pm.PackageManagerService.WATCHDOG_TIMEOUT;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getNonProfileGuidedCompilerFilter;
import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
@@ -67,13 +69,17 @@
public static final int DEX_OPT_SKIPPED = 0;
public static final int DEX_OPT_PERFORMED = 1;
public static final int DEX_OPT_FAILED = -1;
+ // One minute over PM WATCHDOG_TIMEOUT
+ private static final long WAKELOCK_TIMEOUT_MS = WATCHDOG_TIMEOUT + 1000 * 60;
/** Special library name that skips shared libraries check during compilation. */
public static final String SKIP_SHARED_LIBRARY_CHECK = "&";
+ @GuardedBy("mInstallLock")
private final Installer mInstaller;
private final Object mInstallLock;
+ @GuardedBy("mInstallLock")
private final PowerManager.WakeLock mDexoptWakeLock;
private volatile boolean mSystemReady;
@@ -111,21 +117,12 @@
return DEX_OPT_SKIPPED;
}
synchronized (mInstallLock) {
- // During boot the system doesn't need to instantiate and obtain a wake lock.
- // PowerManager might not be ready, but that doesn't mean that we can't proceed with
- // dexopt.
- final boolean useLock = mSystemReady;
- if (useLock) {
- mDexoptWakeLock.setWorkSource(new WorkSource(pkg.applicationInfo.uid));
- mDexoptWakeLock.acquire();
- }
+ final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
try {
return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
targetCompilationFilter, packageStats, isUsedByOtherApps);
} finally {
- if (useLock) {
- mDexoptWakeLock.release();
- }
+ releaseWakeLockLI(acquireTime);
}
}
}
@@ -250,26 +247,50 @@
public int dexOptSecondaryDexPath(ApplicationInfo info, String path, Set<String> isas,
String compilerFilter, boolean isUsedByOtherApps) {
synchronized (mInstallLock) {
- // During boot the system doesn't need to instantiate and obtain a wake lock.
- // PowerManager might not be ready, but that doesn't mean that we can't proceed with
- // dexopt.
- final boolean useLock = mSystemReady;
- if (useLock) {
- mDexoptWakeLock.setWorkSource(new WorkSource(info.uid));
- mDexoptWakeLock.acquire();
- }
+ final long acquireTime = acquireWakeLockLI(info.uid);
try {
return dexOptSecondaryDexPathLI(info, path, isas, compilerFilter,
isUsedByOtherApps);
} finally {
- if (useLock) {
- mDexoptWakeLock.release();
- }
+ releaseWakeLockLI(acquireTime);
}
}
}
@GuardedBy("mInstallLock")
+ private long acquireWakeLockLI(final int uid) {
+ // During boot the system doesn't need to instantiate and obtain a wake lock.
+ // PowerManager might not be ready, but that doesn't mean that we can't proceed with
+ // dexopt.
+ if (!mSystemReady) {
+ return -1;
+ }
+ mDexoptWakeLock.setWorkSource(new WorkSource(uid));
+ mDexoptWakeLock.acquire(WAKELOCK_TIMEOUT_MS);
+ return SystemClock.elapsedRealtime();
+ }
+
+ @GuardedBy("mInstallLock")
+ private void releaseWakeLockLI(final long acquireTime) {
+ if (acquireTime < 0) {
+ return;
+ }
+ try {
+ if (mDexoptWakeLock.isHeld()) {
+ mDexoptWakeLock.release();
+ }
+ final long duration = SystemClock.elapsedRealtime() - acquireTime;
+ if (duration >= WAKELOCK_TIMEOUT_MS) {
+ Slog.wtf(TAG, "WakeLock " + mDexoptWakeLock.getTag()
+ + " time out. Operation took " + duration + " ms. Thread: "
+ + Thread.currentThread().getName());
+ }
+ } catch (Exception e) {
+ Slog.wtf(TAG, "Error while releasing " + mDexoptWakeLock.getTag() + " lock", e);
+ }
+ }
+
+ @GuardedBy("mInstallLock")
private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas,
String compilerFilter, boolean isUsedByOtherApps) {
compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
@@ -361,10 +382,10 @@
boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
if (vmSafeMode) {
// For the compilation, it doesn't really matter what we return here because installd
- // will replace the filter with interpret-only anyway.
+ // will replace the filter with 'quicken' anyway.
// However, we return a non profile guided filter so that we simplify the logic of
// merging profiles.
- // TODO(calin): safe mode path could be simplified if we pass interpret-only from
+ // TODO(calin): safe mode path could be simplified if we pass 'quicken' from
// here rather than letting installd decide on the filter.
return getNonProfileGuidedCompilerFilter(targetCompilerFilter);
}
@@ -613,9 +634,13 @@
@Override
protected int adjustDexoptNeeded(int dexoptNeeded) {
- // Ensure compilation, no matter the current state.
- // TODO: The return value is wrong when patchoat is needed.
- return DexFile.DEX2OAT_FROM_SCRATCH;
+ if (dexoptNeeded == DexFile.NO_DEXOPT_NEEDED) {
+ // Ensure compilation by pretending a compiler filter change on the
+ // apk/odex location (the reason for the '-'. A positive value means
+ // the 'oat' location).
+ return -DexFile.DEX2OAT_FOR_FILTER;
+ }
+ return dexoptNeeded;
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 61d83e5..0173533 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -444,7 +444,7 @@
* minute but we sometimes do very lengthy I/O operations on this thread,
* such as installing multi-gigabyte applications, so ours needs to be longer.
*/
- private static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
+ static final long WATCHDOG_TIMEOUT = 1000*60*10; // ten minutes
/**
* Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
@@ -5870,10 +5870,9 @@
return mEphemeralAppsDisabled;
}
- private boolean isEphemeralAllowed(
+ private boolean isInstantAppAllowed(
Intent intent, List<ResolveInfo> resolvedActivities, int userId,
boolean skipPackageCheck) {
- final int callingUser = UserHandle.getCallingUserId();
if (mInstantAppResolverConnection == null) {
return false;
}
@@ -5973,7 +5972,13 @@
for (int i = 0; i < N; i++) {
ri = query.get(i);
if (ri.activityInfo.applicationInfo.isInstantApp()) {
- return ri;
+ final String packageName = ri.activityInfo.packageName;
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+ final int status = (int)(packedStatus >> 32);
+ if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
+ return ri;
+ }
}
}
ri = new ResolveInfo(mResolveInfo);
@@ -6417,7 +6422,7 @@
result = filterIfNotSystemUser(mActivities.queryIntent(
intent, resolvedType, flags, userId), userId);
addEphemeral = !ephemeralDisabled
- && isEphemeralAllowed(intent, result, userId, false /*skipPackageCheck*/);
+ && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
// Check for cross profile results.
boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
xpResolveInfo = queryCrossProfileIntents(
@@ -6474,45 +6479,14 @@
// the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result
addEphemeral = !ephemeralDisabled
- && isEphemeralAllowed(
+ && isInstantAppAllowed(
intent, null /*result*/, userId, true /*skipPackageCheck*/);
result = new ArrayList<ResolveInfo>();
}
}
}
if (addEphemeral) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
- final InstantAppRequest requestObject = new InstantAppRequest(
- null /*responseObj*/, intent /*origIntent*/, resolvedType,
- null /*callingPackage*/, userId, null /*verificationBundle*/);
- final AuxiliaryResolveInfo auxiliaryResponse =
- InstantAppResolver.doInstantAppResolutionPhaseOne(
- mContext, mInstantAppResolverConnection, requestObject);
- if (auxiliaryResponse != null) {
- if (DEBUG_EPHEMERAL) {
- Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
- }
- final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
- final PackageSetting ps =
- mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
- if (ps != null) {
- ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
- mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
- ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
- ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
- // make sure this resolver is the default
- ephemeralInstaller.isDefault = true;
- ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
- | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
- // add a non-generic filter
- ephemeralInstaller.filter = new IntentFilter(intent.getAction());
- ephemeralInstaller.filter.addDataPath(
- intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
- ephemeralInstaller.isInstantAppAvailable = true;
- result.add(ephemeralInstaller);
- }
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
}
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
@@ -6520,6 +6494,99 @@
return applyPostResolutionFilter(result, instantAppPkgName);
}
+ private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
+ String resolvedType, int flags, int userId) {
+ // first, check to see if we've got an instant app already installed
+ final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
+ ResolveInfo localInstantApp = null;
+ boolean blockResolution = false;
+ if (!alreadyResolvedLocally) {
+ final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
+ flags
+ | PackageManager.GET_RESOLVED_FILTER
+ | PackageManager.MATCH_INSTANT
+ | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
+ userId);
+ for (int i = instantApps.size() - 1; i >= 0; --i) {
+ final ResolveInfo info = instantApps.get(i);
+ final String packageName = info.activityInfo.packageName;
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps.getInstantApp(userId)) {
+ final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+ final int status = (int)(packedStatus >> 32);
+ final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
+ if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
+ // there's a local instant application installed, but, the user has
+ // chosen to never use it; skip resolution and don't acknowledge
+ // an instant application is even available
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
+ }
+ blockResolution = true;
+ break;
+ } else {
+ // we have a locally installed instant application; skip resolution
+ // but acknowledge there's an instant application available
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
+ }
+ localInstantApp = info;
+ break;
+ }
+ }
+ }
+ }
+ // no app installed, let's see if one's available
+ AuxiliaryResolveInfo auxiliaryResponse = null;
+ if (!blockResolution) {
+ if (localInstantApp == null) {
+ // we don't have an instant app locally, resolve externally
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
+ final InstantAppRequest requestObject = new InstantAppRequest(
+ null /*responseObj*/, intent /*origIntent*/, resolvedType,
+ null /*callingPackage*/, userId, null /*verificationBundle*/);
+ auxiliaryResponse =
+ InstantAppResolver.doInstantAppResolutionPhaseOne(
+ mContext, mInstantAppResolverConnection, requestObject);
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ } else {
+ // we have an instant application locally, but, we can't admit that since
+ // callers shouldn't be able to determine prior browsing. create a dummy
+ // auxiliary response so the downstream code behaves as if there's an
+ // instant application available externally. when it comes time to start
+ // the instant application, we'll do the right thing.
+ final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
+ auxiliaryResponse = new AuxiliaryResolveInfo(
+ ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
+ }
+ }
+ if (auxiliaryResponse != null) {
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+ }
+ final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
+ final PackageSetting ps =
+ mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
+ if (ps != null) {
+ ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
+ mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
+ ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
+ ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
+ // make sure this resolver is the default
+ ephemeralInstaller.isDefault = true;
+ ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+ | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+ // add a non-generic filter
+ ephemeralInstaller.filter = new IntentFilter(intent.getAction());
+ ephemeralInstaller.filter.addDataPath(
+ intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
+ ephemeralInstaller.isInstantAppAvailable = true;
+ result.add(ephemeralInstaller);
+ }
+ }
+ return result;
+ }
+
private static class CrossProfileDomainInfo {
/* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
ResolveInfo resolveInfo;
@@ -6648,7 +6715,7 @@
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.activityInfo.packageName, info.activityInfo.splitName,
- info.activityInfo.applicationInfo.versionCode);
+ info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7321,7 +7388,7 @@
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.serviceInfo.packageName, info.serviceInfo.splitName,
- info.serviceInfo.applicationInfo.versionCode);
+ info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -7442,7 +7509,7 @@
final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
info.providerInfo.packageName, info.providerInfo.splitName,
- info.providerInfo.applicationInfo.versionCode);
+ info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
// make sure this resolver is the default
installerInfo.isDefault = true;
installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
@@ -8667,7 +8734,7 @@
// are verify-profile but for preopted apps there's no profile.
// Do a hacky check to ensure that if we have no profiles (a reasonable indication
// that before the OTA the app was preopted) the app gets compiled with a non-profile
- // filter (by default interpret-only).
+ // filter (by default 'quicken').
// Note that at this stage unused apps are already filtered.
if (isSystemApp(pkg) &&
DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
@@ -18460,11 +18527,6 @@
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null);
synchronized (mPackages) {
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null) {
- Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
- return false;
- }
// Cannot block uninstall of static shared libs as they are
// considered a part of the using app (emulating static linking).
// Also static libs are installed always on internal storage.
@@ -18474,12 +18536,7 @@
+ " providing static shared library: " + pkg.staticSharedLibName);
return false;
}
- if (!ps.getInstalled(userId)) {
- // Can't block uninstall for an app that is not installed or enabled.
- Log.i(TAG, "Package not installed in set block uninstall " + packageName);
- return false;
- }
- ps.setBlockUninstall(blockUninstall, userId);
+ mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
mSettings.writePackageRestrictionsLPr(userId);
}
return true;
@@ -18488,12 +18545,7 @@
@Override
public boolean getBlockUninstallForUser(String packageName, int userId) {
synchronized (mPackages) {
- PackageSetting ps = mSettings.mPackages.get(packageName);
- if (ps == null) {
- Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
- return false;
- }
- return ps.getBlockUninstall(userId);
+ return mSettings.getBlockUninstallLPr(userId, packageName);
}
}
@@ -18700,7 +18752,6 @@
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- false /*blockUninstall*/,
ps.readUserState(nextUserId).domainVerificationStatus,
0, PackageManager.INSTALL_REASON_UNKNOWN);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 25a596a..c1d68b8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1598,10 +1598,10 @@
pw.println(" -f: force compilation even if not needed");
pw.println(" -m: select compilation mode");
pw.println(" MODE is one of the dex2oat compiler filters:");
- pw.println(" verify-none");
- pw.println(" verify-at-runtime");
- pw.println(" verify-profile");
- pw.println(" interpret-only");
+ pw.println(" assume-verified");
+ pw.println(" extract");
+ pw.println(" verify");
+ pw.println(" quicken");
pw.println(" space-profile");
pw.println(" space");
pw.println(" speed-profile");
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index dfed72f..14f65eb 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -402,14 +402,6 @@
modifyUserState(userId).suspended = suspended;
}
- boolean getBlockUninstall(int userId) {
- return readUserState(userId).blockUninstall;
- }
-
- void setBlockUninstall(boolean blockUninstall, int userId) {
- modifyUserState(userId).blockUninstall = blockUninstall;
- }
-
boolean getInstantApp(int userId) {
return readUserState(userId).instantApp;
}
@@ -421,8 +413,8 @@
void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
String lastDisableAppCaller, ArraySet<String> enabledComponents,
- ArraySet<String> disabledComponents, boolean blockUninstall,
- int domainVerifState, int linkGeneration, int installReason) {
+ ArraySet<String> disabledComponents, int domainVerifState,
+ int linkGeneration, int installReason) {
PackageUserState state = modifyUserState(userId);
state.ceDataInode = ceDataInode;
state.enabled = enabled;
@@ -434,7 +426,6 @@
state.lastDisableAppCaller = lastDisableAppCaller;
state.enabledComponents = enabledComponents;
state.disabledComponents = disabledComponents;
- state.blockUninstall = blockUninstall;
state.domainVerificationStatus = domainVerifState;
state.appLinkGeneration = linkGeneration;
state.installReason = installReason;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index cea031e..44bcff2 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -186,6 +186,8 @@
private static final String TAG_PERMISSIONS = "perms";
private static final String TAG_CHILD_PACKAGE = "child-package";
private static final String TAG_USES_STATIC_LIB = "uses-static-lib";
+ private static final String TAG_BLOCK_UNINSTALL_PACKAGES = "block-uninstall-packages";
+ private static final String TAG_BLOCK_UNINSTALL = "block-uninstall";
private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
"persistent-preferred-activities";
@@ -215,6 +217,8 @@
// New name for the above attribute.
private static final String ATTR_HIDDEN = "hidden";
private static final String ATTR_SUSPENDED = "suspended";
+ // Legacy, uninstall blocks are stored separately.
+ @Deprecated
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_ENABLED = "enabled";
private static final String ATTR_ENABLED_CALLER = "enabledCaller";
@@ -271,6 +275,9 @@
private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
new ArrayMap<String, PackageSetting>();
+ /** List of packages that are blocked for uninstall for specific users */
+ private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>();
+
// Set of restored intent-filter verification states
private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
new ArrayMap<String, IntentFilterVerificationInfo>();
@@ -756,7 +763,6 @@
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- false /*blockUninstall*/,
INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
0, PackageManager.INSTALL_REASON_UNKNOWN);
}
@@ -1614,6 +1620,34 @@
}
}
+ void readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ ArraySet<String> packages = new ArraySet<>();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_BLOCK_UNINSTALL)) {
+ String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
+ packages.add(packageName);
+ } else {
+ String msg = "Unknown element under " + TAG_BLOCK_UNINSTALL_PACKAGES + ": " +
+ parser.getName();
+ PackageManagerService.reportSettingsProblem(Log.WARN, msg);
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ if (packages.isEmpty()) {
+ mBlockUninstallPackages.remove(userId);
+ } else {
+ mBlockUninstallPackages.put(userId, packages);
+ }
+ }
+
void readPackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Reading package restrictions for user=" + userId);
@@ -1662,7 +1696,6 @@
null /*lastDisableAppCaller*/,
null /*enabledComponents*/,
null /*disabledComponents*/,
- false /*blockUninstall*/,
INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
0, PackageManager.INSTALL_REASON_UNKNOWN);
}
@@ -1768,9 +1801,12 @@
}
}
+ if (blockUninstall) {
+ setBlockUninstallLPw(userId, name, true);
+ }
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
hidden, suspended, instantApp, enabledCaller, enabledComponents,
- disabledComponents, blockUninstall, verifState, linkGeneration,
+ disabledComponents, verifState, linkGeneration,
installReason);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
@@ -1780,6 +1816,8 @@
readCrossProfileIntentFiltersLPw(parser, userId);
} else if (tagName.equals(TAG_DEFAULT_APPS)) {
readDefaultAppsLPw(parser, userId);
+ } else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
+ readBlockUninstallPackagesLPw(parser, userId);
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
+ parser.getName());
@@ -1806,6 +1844,30 @@
}
}
+ void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) {
+ ArraySet<String> packages = mBlockUninstallPackages.get(userId);
+ if (blockUninstall) {
+ if (packages == null) {
+ packages = new ArraySet<String>();
+ mBlockUninstallPackages.put(userId, packages);
+ }
+ packages.add(packageName);
+ } else if (packages != null) {
+ packages.remove(packageName);
+ if (packages.isEmpty()) {
+ mBlockUninstallPackages.remove(userId);
+ }
+ }
+ }
+
+ boolean getBlockUninstallLPr(int userId, String packageName) {
+ ArraySet<String> packages = mBlockUninstallPackages.get(userId);
+ if (packages == null) {
+ return false;
+ }
+ return packages.contains(packageName);
+ }
+
private ArraySet<String> readComponentsLPr(XmlPullParser parser)
throws IOException, XmlPullParserException {
ArraySet<String> components = null;
@@ -1976,6 +2038,20 @@
serializer.endTag(null, TAG_DEFAULT_APPS);
}
+ void writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)
+ throws IOException {
+ ArraySet<String> packages = mBlockUninstallPackages.get(userId);
+ if (packages != null) {
+ serializer.startTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
+ for (int i = 0; i < packages.size(); i++) {
+ serializer.startTag(null, TAG_BLOCK_UNINSTALL);
+ serializer.attribute(null, ATTR_PACKAGE_NAME, packages.valueAt(i));
+ serializer.endTag(null, TAG_BLOCK_UNINSTALL);
+ }
+ serializer.endTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
+ }
+ }
+
void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -2038,9 +2114,6 @@
if (ustate.suspended) {
serializer.attribute(null, ATTR_SUSPENDED, "true");
}
- if (ustate.blockUninstall) {
- serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
- }
if (ustate.instantApp) {
serializer.attribute(null, ATTR_INSTANT_APP, "true");
}
@@ -2091,6 +2164,7 @@
writePersistentPreferredActivitiesLPr(serializer, userId);
writeCrossProfileIntentFiltersLPr(serializer, userId);
writeDefaultAppsLPr(serializer, userId);
+ writeBlockUninstallPackagesLPr(serializer, userId);
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index bed8f1a..7f0528a 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1611,6 +1611,11 @@
*/
private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate,
boolean forPinRequest) {
+ if (shortcut.isReturnedByServer()) {
+ Log.w(TAG,
+ "Re-publishing ShortcutInfo returned by server is not supported."
+ + " Some information such as icon may lost from shortcut.");
+ }
Preconditions.checkNotNull(shortcut, "Null shortcut detected");
if (shortcut.getActivity() != null) {
Preconditions.checkState(
@@ -1670,6 +1675,13 @@
}
}
+ private List<ShortcutInfo> setReturnedByServer(List<ShortcutInfo> shortcuts) {
+ for (int i = shortcuts.size() - 1; i >= 0; i--) {
+ shortcuts.get(i).setReturnedByServer();
+ }
+ return shortcuts;
+ }
+
// === APIs ===
@Override
@@ -2049,7 +2061,7 @@
final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId);
ps.findAll(ret, query, cloneFlags);
- return new ParceledListSlice<>(ret);
+ return new ParceledListSlice<>(setReturnedByServer(ret));
}
@Override
@@ -2406,7 +2418,7 @@
});
}
}
- return ret;
+ return setReturnedByServer(ret);
}
private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
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 3d7cedc..9b44646 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -60,6 +60,7 @@
// Maps package name to code locations.
// It caches the code locations for the installed packages. This allows for
// faster lookups (no locks) when finding what package owns the dex file.
+ @GuardedBy("mPackageCodeLocationsCache")
private final Map<String, PackageCodeLocations> mPackageCodeLocationsCache;
// PackageDexUsage handles the actual I/O operations. It is responsible to
@@ -204,7 +205,7 @@
// In case there was an update, write the package use info to disk async.
// Note that we do the writing here and not in PackageDexUsage in order to be
// consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
- // multiple updates in PackaeDexUsage before writing it).
+ // multiple updates in PackageDexUsage before writing it).
if (mPackageDexUsage.clearUsedByOtherApps(packageName)) {
mPackageDexUsage.maybeWriteAsync();
}
@@ -224,7 +225,7 @@
// In case there was an update, write the package use info to disk async.
// Note that we do the writing here and not in PackageDexUsage in order to be
// consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
- // multiple updates in PackaeDexUsage before writing it).
+ // multiple updates in PackageDexUsage before writing it).
if (updated) {
mPackageDexUsage.maybeWriteAsync();
}
@@ -243,17 +244,22 @@
private void cachePackageCodeLocation(String packageName, String baseCodePath,
String[] splitCodePaths, String[] dataDirs, int userId) {
- PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
- new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
- pcl.updateCodeLocation(baseCodePath, splitCodePaths);
- if (dataDirs != null) {
- for (String dataDir : dataDirs) {
- // The set of data dirs includes deviceProtectedDataDir and
- // credentialProtectedDataDir which might be null for shared
- // libraries. Currently we don't track these but be lenient
- // and check in case we ever decide to store their usage data.
- if (dataDir != null) {
- pcl.mergeAppDataDirs(dataDir, userId);
+ synchronized (mPackageCodeLocationsCache) {
+ PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
+ new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
+ // TODO(calin): We are forced to extend the scope of this synchronization because
+ // the values of the cache (PackageCodeLocations) are updated in place.
+ // Make PackageCodeLocations immutable to simplify the synchronization reasoning.
+ pcl.updateCodeLocation(baseCodePath, splitCodePaths);
+ if (dataDirs != null) {
+ for (String dataDir : dataDirs) {
+ // The set of data dirs includes deviceProtectedDataDir and
+ // credentialProtectedDataDir which might be null for shared
+ // libraries. Currently we don't track these but be lenient
+ // and check in case we ever decide to store their usage data.
+ if (dataDir != null) {
+ pcl.mergeAppDataDirs(dataDir, userId);
+ }
}
}
}
@@ -479,10 +485,12 @@
// The loadingPackage does not own the dex file.
// Perform a reverse look-up in the cache to detect if any package has ownership.
// Note that we can have false negatives if the cache falls out of date.
- for (PackageCodeLocations pcl : mPackageCodeLocationsCache.values()) {
- outcome = pcl.searchDex(dexPath, userId);
- if (outcome != DEX_SEARCH_NOT_FOUND) {
- return new DexSearchResult(pcl.mPackageName, outcome);
+ synchronized (mPackageCodeLocationsCache) {
+ for (PackageCodeLocations pcl : mPackageCodeLocationsCache.values()) {
+ outcome = pcl.searchDex(dexPath, userId);
+ if (outcome != DEX_SEARCH_NOT_FOUND) {
+ return new DexSearchResult(pcl.mPackageName, outcome);
+ }
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7e03d80..f0ae1a7 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -184,6 +184,7 @@
import android.service.dreams.DreamManagerInternal;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.service.vr.IPersistentVrStateCallbacks;
import android.speech.RecognizerIntent;
import android.telecom.TelecomManager;
import android.util.DisplayMetrics;
@@ -512,6 +513,8 @@
volatile boolean mGoingToSleep;
volatile boolean mRecentsVisible;
volatile boolean mPictureInPictureVisible;
+ // Written by vr manager thread, only read in this class.
+ volatile private boolean mPersistentVrModeEnabled;
volatile private boolean mDismissImeOnBackKeyPressed;
// Used to hold the last user key used to wake the device. This helps us prevent up events
@@ -581,6 +584,8 @@
boolean mTranslucentDecorEnabled = true;
boolean mUseTvRouting;
+ private boolean mHandleVolumeKeysInWM;
+
int mPointerLocationMode = 0; // guarded by mLock
// The last window we were told about in focusChanged.
@@ -777,6 +782,10 @@
private boolean mBugreportTvKey2Pressed;
private boolean mBugreportTvScheduled;
+ private boolean mAccessibilityTvKey1Pressed;
+ private boolean mAccessibilityTvKey2Pressed;
+ private boolean mAccessibilityTvScheduled;
+
/* The number of steps between min and max brightness */
private static final int BRIGHTNESS_STEPS = 10;
@@ -821,6 +830,7 @@
private static final int MSG_BACK_DELAYED_PRESS = 20;
private static final int MSG_ACCESSIBILITY_SHORTCUT = 21;
private static final int MSG_BUGREPORT_TV = 22;
+ private static final int MSG_ACCESSIBILITY_TV = 23;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -902,6 +912,11 @@
case MSG_BUGREPORT_TV:
takeBugreport();
break;
+ case MSG_ACCESSIBILITY_TV:
+ if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(false)) {
+ accessibilityShortcutActivated();
+ }
+ break;
}
}
}
@@ -1002,6 +1017,14 @@
}
MyOrientationListener mOrientationListener;
+ final IPersistentVrStateCallbacks mPersistentVrModeListener =
+ new IPersistentVrStateCallbacks.Stub() {
+ @Override
+ public void onPersistentVrStateChanged(boolean enabled) {
+ mPersistentVrModeEnabled = enabled;
+ }
+ };
+
private final StatusBarController mStatusBarController = new StatusBarController();
private final BarController mNavigationBarController = new BarController("NavigationBar",
@@ -1917,6 +1940,9 @@
mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
+ mHandleVolumeKeysInWM = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_handleVolumeKeysInWindowManager);
+
readConfigurationDependentBehaviors();
mAccessibilityManager = (AccessibilityManager) context.getSystemService(
@@ -3308,6 +3334,11 @@
if (!down) {
cancelPreloadRecentApps();
+ if (mHasFeatureLeanback) {
+ // Clear flags
+ mAccessibilityTvKey2Pressed = down;
+ }
+
mHomePressed = false;
if (mHomeConsumed) {
mHomeConsumed = false;
@@ -3362,6 +3393,13 @@
preloadRecentApps();
}
} else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
+ if (mHasFeatureLeanback) {
+ mAccessibilityTvKey2Pressed = down;
+ if (interceptAccessibilityGestureTv()) {
+ return -1;
+ }
+ }
+
if (!keyguardOn) {
handleLongPressOnHome(event.getDeviceId());
}
@@ -3511,16 +3549,28 @@
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP
|| keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
- if (mUseTvRouting) {
- // On TVs volume keys never go to the foreground app.
+ if (mUseTvRouting || mHandleVolumeKeysInWM) {
+ // On TVs or when the configuration is enabled, volume keys never
+ // go to the foreground app.
dispatchDirectAudioEvent(event);
return -1;
}
+
+ // If the device is in Vr mode, drop the volume keys and don't
+ // forward it to the application/dispatch the audio event.
+ if (mPersistentVrModeEnabled) {
+ return -1;
+ }
} else if (keyCode == KeyEvent.KEYCODE_TAB && event.isMetaPressed()) {
// Pass through keyboard navigation keys.
return 0;
} else if (mHasFeatureLeanback && interceptBugreportGestureTv(keyCode, down)) {
return -1;
+ } else if (mHasFeatureLeanback && keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
+ mAccessibilityTvKey1Pressed = down;
+ if (interceptAccessibilityGestureTv()) {
+ return -1;
+ }
}
// Toggle Caps Lock on META-ALT.
@@ -3739,6 +3789,25 @@
return mBugreportTvScheduled;
}
+ /**
+ * TV only: recognizes a remote control gesture as Accessibility shortcut.
+ * Shortcut: Long press (HOME + DPAD_CENTER)
+ */
+ private boolean interceptAccessibilityGestureTv() {
+ if (mAccessibilityTvKey1Pressed && mAccessibilityTvKey2Pressed) {
+ if (!mAccessibilityTvScheduled) {
+ mAccessibilityTvScheduled = true;
+ Message msg = Message.obtain(mHandler, MSG_ACCESSIBILITY_TV);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
+ }
+ } else if (mAccessibilityTvScheduled) {
+ mHandler.removeMessages(MSG_ACCESSIBILITY_TV);
+ mAccessibilityTvScheduled = false;
+ }
+ return mAccessibilityTvScheduled;
+ }
+
private void takeBugreport() {
if ("1".equals(SystemProperties.get("ro.debuggable"))
|| Settings.Global.getInt(mContext.getContentResolver(),
@@ -5900,8 +5969,8 @@
}
}
}
- if (mUseTvRouting) {
- // On TVs, defer special key handlings to
+ if (mUseTvRouting || mHandleVolumeKeysInWM) {
+ // Defer special key handlings to
// {@link interceptKeyBeforeDispatching()}.
result |= ACTION_PASS_TO_USER;
} else if ((result & ACTION_PASS_TO_USER) == 0) {
@@ -6909,7 +6978,13 @@
|| mAllowAllRotations == 1
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
|| orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
- preferredRotation = sensorRotation;
+ // In VrMode, we report the sensor as always being in default orientation so:
+ // 1) The orientation doesn't change as the user moves their head.
+ // 2) 2D apps within VR show in the device's default orientation.
+ // This only overwrites the sensor-provided orientation and does not affect any
+ // explicit orientation preferences specified by any activities.
+ preferredRotation =
+ mPersistentVrModeEnabled ? Surface.ROTATION_0 : sensorRotation;
} else {
preferredRotation = lastRotation;
}
@@ -7083,6 +7158,9 @@
mKeyguardDelegate.onSystemReady();
mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
+ if (mVrManagerInternal != null) {
+ mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
+ }
readCameraLensCoverState();
updateUiMode();
@@ -8215,6 +8293,14 @@
pw.print(prefix); pw.print("mDemoHdmiRotation="); pw.print(mDemoHdmiRotation);
pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation);
+ if (mHasFeatureLeanback) {
+ pw.print(prefix);
+ pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed);
+ pw.print(prefix);
+ pw.print("mAccessibilityTvKey2Pressed="); pw.println(mAccessibilityTvKey2Pressed);
+ pw.print(prefix);
+ pw.print("mAccessibilityTvScheduled="); pw.println(mAccessibilityTvScheduled);
+ }
mGlobalKeyManager.dump(prefix, pw);
mStatusBarController.dump(pw, prefix);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 8c3d80f..423bc0c 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -4632,12 +4632,6 @@
}
@Override
- public void setButtonBrightnessOverrideFromWindowManager(int screenBrightness) {
- // Do nothing.
- // Button lights are not currently supported in the new implementation.
- }
-
- @Override
public void setDozeOverrideFromDreamManager(int screenState, int screenBrightness) {
switch (screenState) {
case Display.STATE_UNKNOWN:
diff --git a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
index 4035ade..9a08ac3 100644
--- a/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
+++ b/services/core/java/com/android/server/storage/DiskStatsLoggingService.java
@@ -73,13 +73,13 @@
final int userId = UserHandle.myUserId();
UserEnvironment environment = new UserEnvironment(userId);
LogRunnable task = new LogRunnable();
- task.setRootDirectory(environment.getExternalStorageDirectory());
task.setDownloadsDirectory(
environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
task.setSystemSize(FileCollector.getSystemSize(this));
task.setLogOutputFile(new File(DUMPSYS_CACHE_PATH));
task.setAppCollector(collector);
task.setJobService(this, params);
+ task.setContext(this);
AsyncTask.execute(task);
return true;
}
@@ -106,7 +106,8 @@
}
private static boolean isCharging(Context context) {
- BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
+ BatteryManager batteryManager =
+ (BatteryManager) context.getSystemService(Context.BATTERY_SERVICE);
if (batteryManager != null) {
return batteryManager.isCharging();
}
@@ -127,14 +128,10 @@
private JobParameters mParams;
private AppCollector mCollector;
private File mOutputFile;
- private File mRootDirectory;
private File mDownloadsDirectory;
+ private Context mContext;
private long mSystemSize;
- public void setRootDirectory(File file) {
- mRootDirectory = file;
- }
-
public void setDownloadsDirectory(File file) {
mDownloadsDirectory = file;
}
@@ -151,14 +148,25 @@
mSystemSize = size;
}
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
public void setJobService(JobService jobService, JobParameters params) {
mJobService = jobService;
mParams = params;
}
public void run() {
- FileCollector.MeasurementResult mainCategories =
- FileCollector.getMeasurementResult(mRootDirectory);
+ FileCollector.MeasurementResult mainCategories;
+ try {
+ mainCategories = FileCollector.getMeasurementResult(mContext);
+ } catch (IllegalStateException e) {
+ // This can occur if installd has an issue.
+ Log.e(TAG, "Error while measuring storage", e);
+ finishJob(true);
+ return;
+ }
FileCollector.MeasurementResult downloads =
FileCollector.getMeasurementResult(mDownloadsDirectory);
@@ -168,12 +176,10 @@
needsReschedule = false;
logToFile(mainCategories, downloads, stats, mSystemSize);
} else {
- Log.w("TAG", "Timed out while fetching package stats.");
+ Log.w(TAG, "Timed out while fetching package stats.");
}
- if (mJobService != null) {
- mJobService.jobFinished(mParams, needsReschedule);
- }
+ finishJob(needsReschedule);
}
private void logToFile(MeasurementResult mainCategories, MeasurementResult downloads,
@@ -187,5 +193,11 @@
Log.e(TAG, "Exception while writing opportunistic disk file cache.", e);
}
}
+
+ private void finishJob(boolean needsReschedule) {
+ if (mJobService != null) {
+ mJobService.jobFinished(mParams, needsReschedule);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/storage/FileCollector.java b/services/core/java/com/android/server/storage/FileCollector.java
index 90f9f139..0c119a7 100644
--- a/services/core/java/com/android/server/storage/FileCollector.java
+++ b/services/core/java/com/android/server/storage/FileCollector.java
@@ -17,13 +17,17 @@
package com.android.server.storage;
import android.annotation.IntDef;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.util.ArrayMap;
import java.io.File;
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;
@@ -154,15 +158,46 @@
}
/**
+ * Returns the file categorization result for the primary internal storage UUID.
+ *
+ * @param context
+ */
+ public static MeasurementResult getMeasurementResult(Context context) {
+ MeasurementResult result = new MeasurementResult();
+ StorageStatsManager ssm =
+ (StorageStatsManager) context.getSystemService(Context.STORAGE_STATS_SERVICE);
+ ExternalStorageStats stats = null;
+ try {
+ stats =
+ ssm.queryExternalStatsForUser(
+ StorageManager.UUID_PRIVATE_INTERNAL,
+ UserHandle.of(context.getUserId()));
+ result.imagesSize = stats.getImageBytes();
+ result.videosSize = stats.getVideoBytes();
+ result.audioSize = stats.getAudioBytes();
+ result.miscSize =
+ stats.getTotalBytes()
+ - result.imagesSize
+ - result.videosSize
+ - result.audioSize;
+ } catch (IOException e) {
+ throw new IllegalStateException("Could not query storage");
+ }
+
+ return result;
+ }
+
+ /**
* Returns the size of a system for a given context. This is done by finding the difference
* between the shared data and the total primary storage size.
+ *
* @param context Context to use to get storage information.
*/
public static long getSystemSize(Context context) {
PackageManager pm = context.getPackageManager();
VolumeInfo primaryVolume = pm.getPrimaryStorageCurrentVolume();
- StorageManager sm = context.getSystemService(StorageManager.class);
+ StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
VolumeInfo shared = sm.findEmulatedForPrivate(primaryVolume);
if (shared == null) {
return 0;
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index f4f7e24..8e06a51 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -325,8 +325,6 @@
agentInfo.label = resolveInfo.loadLabel(pm);
agentInfo.icon = resolveInfo.loadIcon(pm);
agentInfo.settings = getSettingsAttrs(pm, resolveInfo);
- agentInfo.agent = new TrustAgentWrapper(mContext, this,
- new Intent().setComponent(name), userInfo.getUserHandle());
} else {
int index = mActiveAgents.indexOf(agentInfo);
agentInfo = mActiveAgents.valueAt(index);
@@ -363,6 +361,11 @@
}
}
+ if (agentInfo.agent == null) {
+ agentInfo.agent = new TrustAgentWrapper(mContext, this,
+ new Intent().setComponent(name), userInfo.getUserHandle());
+ }
+
if (!mActiveAgents.contains(agentInfo)) {
mActiveAgents.add(agentInfo);
} else {
diff --git a/services/core/java/com/android/server/twilight/TwilightState.java b/services/core/java/com/android/server/twilight/TwilightState.java
index a12965d..30a8ccc 100644
--- a/services/core/java/com/android/server/twilight/TwilightState.java
+++ b/services/core/java/com/android/server/twilight/TwilightState.java
@@ -31,7 +31,7 @@
private final long mSunriseTimeMillis;
private final long mSunsetTimeMillis;
- TwilightState(long sunriseTimeMillis, long sunsetTimeMillis) {
+ public TwilightState(long sunriseTimeMillis, long sunsetTimeMillis) {
mSunriseTimeMillis = sunriseTimeMillis;
mSunsetTimeMillis = sunsetTimeMillis;
}
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 63c6195..1f75640 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -16,7 +16,7 @@
package com.android.server.vr;
import android.annotation.NonNull;
-import android.app.CompatibilityDisplayProperties;
+import android.app.Vr2dDisplayProperties;
import android.content.ComponentName;
import android.service.vr.IPersistentVrStateCallbacks;
@@ -83,16 +83,16 @@
public abstract int hasVrPackage(@NonNull ComponentName packageName, int userId);
/**
- * Sets the resolution and DPI of the compatibility virtual display used to display
+ * Sets the resolution and DPI of the vr2d virtual display used to display
* 2D applications in VR mode.
*
* <p>Requires {@link android.Manifest.permission#ACCESS_VR_MANAGER} permission.</p>
*
- * @param compatDisplayProp Properties of the virtual display for 2D applications
+ * @param vr2dDisplayProp Properties of the virtual display for 2D applications
* in VR mode.
*/
- public abstract void setCompatibilityDisplayProperties(
- CompatibilityDisplayProperties compatDisplayProp);
+ public abstract void setVr2dDisplayProperties(
+ Vr2dDisplayProperties vr2dDisplayProp);
/**
* Sets the persistent VR mode state of a device. When a device is in persistent VR mode it will
@@ -110,7 +110,7 @@
* @return {@link android.view.Display.INVALID_DISPLAY} if there is no virtual display
* currently, else return the display id of the virtual display
*/
- public abstract int getCompatibilityDisplayId();
+ public abstract int getVr2dDisplayId();
/**
* Adds listener that reports state changes to persistent VR mode.
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 860b241..0e183f0 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -21,7 +21,7 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityManager;
import android.app.AppOpsManager;
-import android.app.CompatibilityDisplayProperties;
+import android.app.Vr2dDisplayProperties;
import android.app.NotificationManager;
import android.annotation.NonNull;
import android.content.ComponentName;
@@ -141,7 +141,7 @@
private final NotificationAccessManager mNotifAccessManager = new NotificationAccessManager();
/** Tracks the state of the screen and keyguard UI.*/
private int mSystemSleepFlags = FLAG_AWAKE;
- private CompatibilityDisplay mCompatibilityDisplay;
+ private Vr2dDisplay mVr2dDisplay;
private static final int MSG_VR_STATE_CHANGE = 0;
private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
@@ -428,15 +428,15 @@
}
@Override
- public void setCompatibilityDisplayProperties(
- CompatibilityDisplayProperties compatDisplayProp) {
+ public void setVr2dDisplayProperties(
+ Vr2dDisplayProperties vr2dDisplayProp) {
enforceCallerPermission(Manifest.permission.RESTRICTED_VR_ACCESS);
- VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+ VrManagerService.this.setVr2dDisplayProperties(vr2dDisplayProp);
}
@Override
- public int getCompatibilityDisplayId() {
- return VrManagerService.this.getCompatibilityDisplayId();
+ public int getVr2dDisplayId() {
+ return VrManagerService.this.getVr2dDisplayId();
}
@Override
@@ -549,14 +549,14 @@
}
@Override
- public void setCompatibilityDisplayProperties(
- CompatibilityDisplayProperties compatDisplayProp) {
- VrManagerService.this.setCompatibilityDisplayProperties(compatDisplayProp);
+ public void setVr2dDisplayProperties(
+ Vr2dDisplayProperties compatDisplayProp) {
+ VrManagerService.this.setVr2dDisplayProperties(compatDisplayProp);
}
@Override
- public int getCompatibilityDisplayId() {
- return VrManagerService.this.getCompatibilityDisplayId();
+ public int getVr2dDisplayId() {
+ return VrManagerService.this.getVr2dDisplayId();
}
@Override
@@ -608,8 +608,8 @@
DisplayManager dm =
(DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
- mCompatibilityDisplay = new CompatibilityDisplay(dm, ami, mVrManager);
- mCompatibilityDisplay.init(getContext());
+ mVr2dDisplay = new Vr2dDisplay(dm, ami, mVrManager);
+ mVr2dDisplay.init(getContext());
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
mVrModeAllowed = true;
@@ -1116,20 +1116,20 @@
}
}
- public void setCompatibilityDisplayProperties(
- CompatibilityDisplayProperties compatDisplayProp) {
- if (mCompatibilityDisplay != null) {
- mCompatibilityDisplay.setVirtualDisplayProperties(compatDisplayProp);
+ public void setVr2dDisplayProperties(
+ Vr2dDisplayProperties compatDisplayProp) {
+ if (mVr2dDisplay != null) {
+ mVr2dDisplay.setVirtualDisplayProperties(compatDisplayProp);
return;
}
- Slog.w(TAG, "CompatibilityDisplay is null!");
+ Slog.w(TAG, "Vr2dDisplay is null!");
}
- private int getCompatibilityDisplayId() {
- if (mCompatibilityDisplay != null) {
- return mCompatibilityDisplay.getVirtualDisplayId();
+ private int getVr2dDisplayId() {
+ if (mVr2dDisplay != null) {
+ return mVr2dDisplay.getVirtualDisplayId();
}
- Slog.w(TAG, "CompatibilityDisplay is null!");
+ Slog.w(TAG, "Vr2dDisplay is null!");
return INVALID_DISPLAY;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index c625cbe..b5e194b 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -36,7 +36,6 @@
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.Trace;
import android.util.Slog;
import android.view.IApplicationToken;
@@ -319,7 +318,7 @@
+ " token: " + mToken);
return;
}
- mContainer.setDisablePreviewSnapshots(disable);
+ mContainer.setDisablePreviewScreenshots(disable);
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 36418be..640bac2 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -23,6 +23,7 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
@@ -48,6 +49,7 @@
import static com.android.server.wm.WindowManagerService.logWithStack;
import android.annotation.NonNull;
+import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Binder;
@@ -1528,12 +1530,24 @@
return candidate;
}
- void setDisablePreviewSnapshots(boolean disable) {
+ /**
+ * See {@link Activity#setDisablePreviewScreenshots}.
+ */
+ void setDisablePreviewScreenshots(boolean disable) {
mDisbalePreviewScreenshots = disable;
}
- boolean shouldDisablePreviewScreenshots() {
- return mDisbalePreviewScreenshots;
+ /**
+ * Retrieves whether we'd like to generate a snapshot that's based solely on the theme. This is
+ * the case when preview screenshots are disabled {@link #setDisablePreviewScreenshots} or when
+ * we can't take a snapshot for other reasons, for example, if we have a secure window.
+ *
+ * @return True if we need to generate an app theme snapshot, false if we'd like to take a real
+ * screenshot.
+ */
+ boolean shouldUseAppThemeSnapshot() {
+ return mDisbalePreviewScreenshots || forAllWindows(w -> (w.mAttrs.flags & FLAG_SECURE) != 0,
+ true /* topToBottom */);
}
@Override
diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java
index 4100446..d44cd13 100644
--- a/services/core/java/com/android/server/wm/DimLayerController.java
+++ b/services/core/java/com/android/server/wm/DimLayerController.java
@@ -188,6 +188,7 @@
boolean animateDimLayers() {
int fullScreen = -1;
int fullScreenAndDimming = -1;
+ int topFullScreenUserLayer = 0;
boolean result = false;
for (int i = mState.size() - 1; i >= 0; i--) {
@@ -213,8 +214,18 @@
// and we have to make sure we always animate the layer.
if (user.dimFullscreen() && state.dimLayer == mSharedFullScreenDimLayer) {
fullScreen = i;
- if (mState.valueAt(i).continueDimming) {
+ if (!state.continueDimming) {
+ continue;
+ }
+
+ // When choosing which user to assign the shared fullscreen layer to
+ // we need to look at Z-order.
+ if (topFullScreenUserLayer == 0 ||
+ (state.animator != null && state.animator.mAnimLayer > topFullScreenUserLayer)) {
fullScreenAndDimming = i;
+ if (state.animator != null) {
+ topFullScreenUserLayer = state.animator.mAnimLayer;
+ }
}
} else {
// We always want to animate the non fullscreen windows, they don't share their
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 67704e7..92d26cb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1503,8 +1503,16 @@
return mImeWindowsContainers.forAllWindows(callback, traverseTopToBottom);
}
- @Override
- int getOrientation() {
+ /**
+ * Returns the orientation that this display should be in factoring in its children containers.
+ *
+ * @param includeAppContainers True if then app containers (stacks, tasks, ...) should be
+ * factored in when determining the orientation. If false only
+ * non-app/system containers will be used to determine the returned
+ * orientation.
+ * @return The orientation the display should be in.
+ */
+ int getOrientation(boolean includeAppContainers) {
final WindowManagerPolicy policy = mService.mPolicy;
if (mService.mDisplayFrozen) {
@@ -1533,8 +1541,14 @@
}
}
- // Top system windows are not requesting an orientation. Start searching from apps.
- return mTaskStackContainers.getOrientation();
+ // Top system windows are not requesting an orientation. Get orientation from app containers
+ // if allowed. Otherwise, return the last orientation.
+ return includeAppContainers ? mTaskStackContainers.getOrientation() : mLastOrientation;
+ }
+
+ @Override
+ int getOrientation() {
+ return getOrientation(true /* includeAppContainers */);
}
void updateDisplayInfo() {
@@ -2877,21 +2891,6 @@
final Rect frame = new Rect();
final Rect stackBounds = new Rect();
- boolean includeImeInScreenshot;
- synchronized(mService.mWindowMap) {
- final AppWindowToken imeTargetAppToken = mService.mInputMethodTarget != null
- ? mService.mInputMethodTarget.mAppToken : null;
- // We only include the Ime in the screenshot if the app we are screenshoting is the IME
- // target and isn't in multi-window mode. We don't screenshot the IME in multi-window
- // mode because the frame of the IME might not overlap with that of the app.
- // E.g. IME target app at the top in split-screen mode and the IME at the bottom
- // overlapping with the bottom app.
- includeImeInScreenshot = imeTargetAppToken != null
- && imeTargetAppToken.appToken != null
- && imeTargetAppToken.appToken.asBinder() == appToken
- && !mService.mInputMethodTarget.isInMultiWindowMode();
- }
-
final int aboveAppLayer = (mService.mPolicy.getWindowLayerFromTypeLw(TYPE_APPLICATION) + 1)
* TYPE_LAYER_MULTIPLIER + TYPE_LAYER_OFFSET;
final MutableBoolean mutableIncludeFullDisplay = new MutableBoolean(includeFullDisplay);
@@ -2909,9 +2908,7 @@
return false;
}
if (w.mIsImWindow) {
- if (!includeImeInScreenshot) {
- return false;
- }
+ return false;
} else if (w.mIsWallpaper) {
// If this is the wallpaper layer and we're only looking for the wallpaper layer
// then the target window state is this one.
@@ -2951,27 +2948,29 @@
}
// Don't include wallpaper in bounds calculation
- if (!mutableIncludeFullDisplay.value && includeDecor) {
- final TaskStack stack = w.getStack();
- if (stack != null) {
- stack.getBounds(frame);
- }
+ if (!w.mIsWallpaper && !mutableIncludeFullDisplay.value) {
+ if (includeDecor) {
+ final TaskStack stack = w.getStack();
+ if (stack != null) {
+ stack.getBounds(frame);
+ }
- // We want to screenshot with the exact bounds of the surface of the app. Thus,
- // intersect it with the frame.
- frame.intersect(w.mFrame);
- }else if (!mutableIncludeFullDisplay.value && !w.mIsWallpaper) {
- final Rect wf = w.mFrame;
- final Rect cr = w.mContentInsets;
- int left = wf.left + cr.left;
- int top = wf.top + cr.top;
- int right = wf.right - cr.right;
- int bottom = wf.bottom - cr.bottom;
- frame.union(left, top, right, bottom);
- w.getVisibleBounds(stackBounds);
- if (!Rect.intersects(frame, stackBounds)) {
- // Set frame empty if there's no intersection.
- frame.setEmpty();
+ // We want to screenshot with the exact bounds of the surface of the app. Thus,
+ // intersect it with the frame.
+ frame.intersect(w.mFrame);
+ } else {
+ final Rect wf = w.mFrame;
+ final Rect cr = w.mContentInsets;
+ int left = wf.left + cr.left;
+ int top = wf.top + cr.top;
+ int right = wf.right - cr.right;
+ int bottom = wf.bottom - cr.bottom;
+ frame.union(left, top, right, bottom);
+ w.getVisibleBounds(stackBounds);
+ if (!Rect.intersects(frame, stackBounds)) {
+ // Set frame empty if there's no intersection.
+ frame.setEmpty();
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 60b136f..be3558b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -21,7 +21,10 @@
import android.hardware.power.V1_0.PowerHint;
import android.os.Binder;
import android.os.Debug;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -34,6 +37,8 @@
import android.view.Display;
import android.view.DisplayInfo;
import android.view.WindowManager;
+
+import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
import com.android.server.EventLogTags;
@@ -87,13 +92,15 @@
class RootWindowContainer extends WindowContainer<DisplayContent> {
private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
+ private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
+ private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
+
WindowManagerService mService;
private boolean mWallpaperForceHidingChanged = false;
private Object mLastWindowFreezeSource = null;
private Session mHoldScreen = null;
private float mScreenBrightness = -1;
- private float mButtonBrightness = -1;
private long mUserActivityTimeout = -1;
private boolean mUpdateRotation = false;
// Following variables are for debugging screen wakelock only.
@@ -128,6 +135,8 @@
private final WindowLayersController mLayersController;
final WallpaperController mWallpaperController;
+ private final Handler mHandler;
+
private String mCloseSystemDialogsReason;
private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
if (w.mHasSurface) {
@@ -147,6 +156,7 @@
RootWindowContainer(WindowManagerService service) {
mService = service;
+ mHandler = new MyHandler(service.mH.getLooper());
mLayersController = new WindowLayersController(mService);
mWallpaperController = new WallpaperController(mService);
}
@@ -552,7 +562,6 @@
mHoldScreen = null;
mScreenBrightness = -1;
- mButtonBrightness = -1;
mUserActivityTimeout = -1;
mObscureApplicationContentOnSecondaryDisplays = false;
mSustainedPerformanceModeCurrent = false;
@@ -702,20 +711,13 @@
mService.setHoldScreenLocked(mHoldScreen);
if (!mService.mDisplayFrozen) {
- if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
- mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
- } else {
- mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mScreenBrightness));
- }
- if (mButtonBrightness < 0 || mButtonBrightness > 1.0f) {
- mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
- } else {
- mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mButtonBrightness));
- }
- mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
- mUserActivityTimeout);
+ final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
+ ? -1 : toBrightnessOverride(mScreenBrightness);
+
+ // Post these on a handler such that we don't call into power manager service while
+ // holding the window manager lock to avoid lock contention with power manager lock.
+ mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightness, 0).sendToTarget();
+ mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
}
if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
@@ -863,9 +865,6 @@
if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
mScreenBrightness = w.mAttrs.screenBrightness;
}
- if (!syswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
- mButtonBrightness = w.mAttrs.buttonBrightness;
- }
if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
mUserActivityTimeout = w.mAttrs.userActivityTimeout;
}
@@ -935,6 +934,29 @@
return (int)(value * PowerManager.BRIGHTNESS_ON);
}
+ private final class MyHandler extends Handler {
+
+ public MyHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case SET_SCREEN_BRIGHTNESS_OVERRIDE:
+ mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
+ msg.arg1);
+ break;
+ case SET_USER_ACTIVITY_TIMEOUT:
+ mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
+ (Long) msg.obj);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void enableSurfaceTrace(ParcelFileDescriptor pfd) {
final FileDescriptor fd = pfd.getFileDescriptor();
if (mSurfaceTraceEnabled) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index fbb826d..b79173c 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -31,11 +31,13 @@
import android.graphics.Rect;
import android.os.Environment;
import android.util.ArraySet;
+import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.StartingSurface;
import com.google.android.collect.Sets;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.TaskSnapshotSurface.SystemBarBackgroundPainter;
import java.io.PrintWriter;
@@ -206,7 +208,7 @@
final AppWindowToken topChild = task.getTopChild();
if (StackId.isHomeOrRecentsStack(task.mStack.mStackId)) {
return SNAPSHOT_MODE_NONE;
- } else if (topChild != null && topChild.shouldDisablePreviewScreenshots()) {
+ } else if (topChild != null && topChild.shouldUseAppThemeSnapshot()) {
return SNAPSHOT_MODE_APP_THEME;
} else {
return SNAPSHOT_MODE_REAL;
@@ -227,6 +229,8 @@
return null;
}
final int color = task.getTaskDescription().getBackgroundColor();
+ final int statusBarColor = task.getTaskDescription().getStatusBarColor();
+ final int navigationBarColor = task.getTaskDescription().getNavigationBarColor();
final GraphicBuffer buffer = GraphicBuffer.create(mainWindow.getFrameLw().width(),
mainWindow.getFrameLw().height(),
RGBA_8888, USAGE_HW_TEXTURE | USAGE_SW_WRITE_RARELY | USAGE_SW_READ_NEVER);
@@ -235,6 +239,11 @@
}
final Canvas c = buffer.lockCanvas();
c.drawColor(color);
+ final LayoutParams attrs = mainWindow.getAttrs();
+ final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,
+ attrs.privateFlags, attrs.systemUiVisibility, statusBarColor, navigationBarColor);
+ decorPainter.setInsets(mainWindow.mContentInsets, mainWindow.mStableInsets);
+ decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
buffer.unlockCanvasAndPost(c);
return new TaskSnapshot(buffer, topChild.getConfiguration().orientation,
mainWindow.mStableInsets, false /* reduced */, 1.0f /* scale */);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index f2a92df..e5c7a72 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -24,6 +24,7 @@
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Bitmap.Config;
import android.os.Process;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -266,12 +267,13 @@
final File file = getBitmapFile(mTaskId, mUserId);
final File reducedFile = getReducedResolutionBitmapFile(mTaskId, mUserId);
final Bitmap bitmap = Bitmap.createHardwareBitmap(mSnapshot.getSnapshot());
- final Bitmap reduced = Bitmap.createScaledBitmap(bitmap,
+ final Bitmap swBitmap = bitmap.copy(Config.ARGB_8888, false /* isMutable */);
+ final Bitmap reduced = Bitmap.createScaledBitmap(swBitmap,
(int) (bitmap.getWidth() * REDUCED_SCALE),
(int) (bitmap.getHeight() * REDUCED_SCALE), true /* filter */);
try {
FileOutputStream fos = new FileOutputStream(file);
- bitmap.compress(JPEG, QUALITY, fos);
+ swBitmap.compress(JPEG, QUALITY, fos);
fos.close();
FileOutputStream reducedFos = new FileOutputStream(reducedFile);
reduced.compress(JPEG, QUALITY, reducedFos);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index c816ba3..2b9e800 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -42,8 +42,11 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityManager.TaskSnapshot;
+import android.app.ActivityThread;
+import android.content.Context;
import android.graphics.Canvas;
import android.graphics.GraphicBuffer;
import android.graphics.Paint;
@@ -118,13 +121,8 @@
private final Handler mHandler;
private boolean mSizeMismatch;
private final Paint mBackgroundPaint = new Paint();
- private final Paint mStatusBarPaint = new Paint();
- private final Paint mNavigationBarPaint = new Paint();
private final int mStatusBarColor;
- private final int mNavigationBarColor;
- private final int mSysUiVis;
- private final int mWindowFlags;
- private final int mWindowPrivateFlags;
+ @VisibleForTesting final SystemBarBackgroundPainter mSystemBarBackgroundPainter;
static TaskSnapshotSurface create(WindowManagerService service, AppWindowToken token,
TaskSnapshot snapshot) {
@@ -224,15 +222,9 @@
mTitle = title;
mBackgroundPaint.setColor(backgroundColor != 0 ? backgroundColor : WHITE);
mTaskBounds = taskBounds;
- mSysUiVis = sysUiVis;
- mWindowFlags = windowFlags;
- mWindowPrivateFlags = windowPrivateFlags;
- mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
- service.mContext.getColor(R.color.system_bar_background_semi_transparent),
- statusBarColor);
- mNavigationBarColor = navigationBarColor;
- mStatusBarPaint.setColor(mStatusBarColor);
- mNavigationBarPaint.setColor(navigationBarColor);
+ mSystemBarBackgroundPainter = new SystemBarBackgroundPainter(windowFlags,
+ windowPrivateFlags, sysUiVis, statusBarColor, navigationBarColor);
+ mStatusBarColor = statusBarColor;
}
@Override
@@ -258,6 +250,7 @@
mStableInsets.set(stableInsets);
mSizeMismatch = (mFrame.width() != mSnapshot.getSnapshot().getWidth()
|| mFrame.height() != mSnapshot.getSnapshot().getHeight());
+ mSystemBarBackgroundPainter.setInsets(contentInsets, stableInsets);
}
private void drawSnapshot() {
@@ -346,7 +339,7 @@
@VisibleForTesting
void drawBackgroundAndBars(Canvas c, Rect frame) {
- final int statusBarHeight = getStatusBarColorViewHeight();
+ final int statusBarHeight = mSystemBarBackgroundPainter.getStatusBarColorViewHeight();
final boolean fillHorizontally = c.getWidth() > frame.right;
final boolean fillVertically = c.getHeight() > frame.bottom;
if (fillHorizontally) {
@@ -359,44 +352,7 @@
if (fillVertically) {
c.drawRect(0, frame.bottom, c.getWidth(), c.getHeight(), mBackgroundPaint);
}
- drawStatusBarBackground(c, frame, statusBarHeight);
- drawNavigationBarBackground(c);
- }
-
- private int getStatusBarColorViewHeight() {
- final boolean forceStatusBarBackground =
- (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
- if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
- mSysUiVis, mStatusBarColor, mWindowFlags, forceStatusBarBackground)) {
- return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
- } else {
- return 0;
- }
- }
-
- private boolean isNavigationBarColorViewVisible() {
- return NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
- mSysUiVis, mNavigationBarColor, mWindowFlags, false /* force */);
- }
-
- @VisibleForTesting
- void drawStatusBarBackground(Canvas c, Rect frame, int statusBarHeight) {
- if (statusBarHeight > 0 && c.getWidth() > frame.right) {
- final int rightInset = DecorView.getColorViewRightInset(mStableInsets.right,
- mContentInsets.right);
- c.drawRect(frame.right, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
- }
- }
-
- @VisibleForTesting
- void drawNavigationBarBackground(Canvas c) {
- final Rect navigationBarRect = new Rect();
- getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
- navigationBarRect);
- final boolean visible = isNavigationBarColorViewVisible();
- if (visible && !navigationBarRect.isEmpty()) {
- c.drawRect(navigationBarRect, mNavigationBarPaint);
- }
+ mSystemBarBackgroundPainter.drawDecors(c, frame);
}
private void reportDrawn() {
@@ -450,4 +406,84 @@
}
}
}
+
+ /**
+ * Helper class to draw the background of the system bars in regions the task snapshot isn't
+ * filling the window.
+ */
+ static class SystemBarBackgroundPainter {
+
+ private final Rect mContentInsets = new Rect();
+ private final Rect mStableInsets = new Rect();
+ private final Paint mStatusBarPaint = new Paint();
+ private final Paint mNavigationBarPaint = new Paint();
+ private final int mStatusBarColor;
+ private final int mNavigationBarColor;
+ private final int mWindowFlags;
+ private final int mWindowPrivateFlags;
+ private final int mSysUiVis;
+
+ SystemBarBackgroundPainter( int windowFlags, int windowPrivateFlags, int sysUiVis,
+ int statusBarColor, int navigationBarColor) {
+ mWindowFlags = windowFlags;
+ mWindowPrivateFlags = windowPrivateFlags;
+ mSysUiVis = sysUiVis;
+ final Context context = ActivityThread.currentActivityThread().getSystemUiContext();
+ mStatusBarColor = DecorView.calculateStatusBarColor(windowFlags,
+ context.getColor(R.color.system_bar_background_semi_transparent),
+ statusBarColor);
+ mNavigationBarColor = navigationBarColor;
+ mStatusBarPaint.setColor(mStatusBarColor);
+ mNavigationBarPaint.setColor(navigationBarColor);
+ }
+
+ void setInsets(Rect contentInsets, Rect stableInsets) {
+ mContentInsets.set(contentInsets);
+ mStableInsets.set(stableInsets);
+ }
+
+ int getStatusBarColorViewHeight() {
+ final boolean forceStatusBarBackground =
+ (mWindowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND) != 0;
+ if (STATUS_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
+ mSysUiVis, mStatusBarColor, mWindowFlags, forceStatusBarBackground)) {
+ return getColorViewTopInset(mStableInsets.top, mContentInsets.top);
+ } else {
+ return 0;
+ }
+ }
+
+ private boolean isNavigationBarColorViewVisible() {
+ return NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES.isVisible(
+ mSysUiVis, mNavigationBarColor, mWindowFlags, false /* force */);
+ }
+
+ void drawDecors(Canvas c, @Nullable Rect alreadyDrawnFrame) {
+ drawStatusBarBackground(c, alreadyDrawnFrame, getStatusBarColorViewHeight());
+ drawNavigationBarBackground(c);
+ }
+
+ @VisibleForTesting
+ void drawStatusBarBackground(Canvas c, @Nullable Rect alreadyDrawnFrame,
+ int statusBarHeight) {
+ if (statusBarHeight > 0
+ && (alreadyDrawnFrame == null || c.getWidth() > alreadyDrawnFrame.right)) {
+ final int rightInset = DecorView.getColorViewRightInset(mStableInsets.right,
+ mContentInsets.right);
+ final int left = alreadyDrawnFrame != null ? alreadyDrawnFrame.right : 0;
+ c.drawRect(left, 0, c.getWidth() - rightInset, statusBarHeight, mStatusBarPaint);
+ }
+ }
+
+ @VisibleForTesting
+ void drawNavigationBarBackground(Canvas c) {
+ final Rect navigationBarRect = new Rect();
+ getNavigationBarRect(c.getWidth(), c.getHeight(), mStableInsets, mContentInsets,
+ navigationBarRect);
+ final boolean visible = isNavigationBarColorViewVisible();
+ if (visible && !navigationBarRect.isEmpty()) {
+ c.drawRect(navigationBarRect, mNavigationBarPaint);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a7f6600..a48397b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2373,7 +2373,7 @@
try {
synchronized(mWindowMap) {
config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
- displayId);
+ displayId, true /* includeAppContainers */);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2383,13 +2383,13 @@
}
private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
- IBinder freezeThisOneIfNeeded, int displayId) {
+ IBinder freezeThisOneIfNeeded, int displayId, boolean includeAppContainers) {
if (!mDisplayReady) {
return null;
}
Configuration config = null;
- if (updateOrientationFromAppTokensLocked(false, displayId)) {
+ if (updateOrientationFromAppTokensLocked(false, displayId, includeAppContainers)) {
// If we changed the orientation but mOrientationChangeComplete is already true,
// we used seamless rotation, and we don't need to freeze the screen.
if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
@@ -2427,6 +2427,11 @@
return config;
}
+ boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
+ return updateOrientationFromAppTokensLocked(inTransaction, displayId,
+ false /* includeAppContainers */);
+ }
+
/**
* Determine the new desired orientation of the display, returning a non-null new Configuration
* if it has changed from the current orientation. IF TRUE IS RETURNED SOMEONE MUST CALL
@@ -2437,13 +2442,25 @@
* The orientation is computed from non-application windows first. If none of the
* non-application windows specify orientation, the orientation is computed from application
* tokens.
+ *
+ * @param inTransaction True if we are currently in a surface transaction.
+ * @param displayId Id of the display to update orientation for.
+ * @param includeAppContainers True if then app containers (stacks, tasks, ...) should be
+ * factored in when determining the orientation. If false only
+ * non-app/system containers will be used to determine the returned
+ * orientation.
+ * NOTE: Only call originating from activity manager are expected to
+ * set this to true as it needs to synchronize several app states
+ * like visibility with the update of display orientation.
+ * @return True if the display orientation was updated.
* @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
*/
- boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId) {
- long ident = Binder.clearCallingIdentity();
+ private boolean updateOrientationFromAppTokensLocked(boolean inTransaction, int displayId,
+ boolean includeAppContainers) {
+ final long ident = Binder.clearCallingIdentity();
try {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
- final int req = dc.getOrientation();
+ final int req = dc.getOrientation(includeAppContainers);
if (req != dc.getLastOrientation()) {
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index ce899e3..7bef033 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -314,8 +314,6 @@
assertEquals(channel1, mHelper.getNotificationChannel(PKG, UID, channel1.getId(), false));
compareChannels(channel2,
mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
- assertNotNull(mHelper.getNotificationChannel(
- PKG, UID, NotificationChannel.DEFAULT_CHANNEL_ID, false));
List<NotificationChannelGroup> actualGroups =
mHelper.getNotificationChannelGroups(PKG, UID, false).getList();
@@ -381,12 +379,7 @@
@Test
public void testChannelXml_defaultChannelLegacyApp_noUserSettings() throws Exception {
- NotificationChannel channel1 =
- new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_DEFAULT);
-
- mHelper.createNotificationChannel(PKG, UID, channel1, true);
-
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
NotificationChannel.DEFAULT_CHANNEL_ID);
loadStreamXml(baos);
@@ -401,16 +394,12 @@
@Test
public void testChannelXml_defaultChannelUpdatedApp_userSettings() throws Exception {
- NotificationChannel channel1 =
- new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_MIN);
- mHelper.createNotificationChannel(PKG, UID, channel1, true);
-
final NotificationChannel defaultChannel = mHelper.getNotificationChannel(PKG, UID,
NotificationChannel.DEFAULT_CHANNEL_ID, false);
defaultChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mHelper.updateNotificationChannel(PKG, UID, defaultChannel);
- ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false, channel1.getId(),
+ ByteArrayOutputStream baos = writeXmlAndPurge(PKG, UID, false,
NotificationChannel.DEFAULT_CHANNEL_ID);
loadStreamXml(baos);
@@ -445,12 +434,9 @@
| NotificationChannel.USER_LOCKED_VISIBILITY,
updated1.getUserLockedFields());
- // STOPSHIP - this should be reversed after the STOPSHIP is removed in the tested code.
// No Default Channel created for updated packages
- // assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
- // NotificationChannel.DEFAULT_CHANNEL_ID, false));
- assertTrue(mHelper.getNotificationChannel(UPDATED_PKG, UID2,
- NotificationChannel.DEFAULT_CHANNEL_ID, false) != null);
+ assertEquals(null, mHelper.getNotificationChannel(UPDATED_PKG, UID2,
+ NotificationChannel.DEFAULT_CHANNEL_ID, false));
}
@Test
@@ -466,12 +452,9 @@
when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(upgraded);
loadStreamXml(baos);
- // STOPSHIP - this should be reversed after the STOPSHIP is removed in the tested code.
// Default Channel should be gone.
- // assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
- // NotificationChannel.DEFAULT_CHANNEL_ID, false));
- assertTrue(mHelper.getNotificationChannel(UPDATED_PKG, UID2,
- NotificationChannel.DEFAULT_CHANNEL_ID, false) != null);
+ assertEquals(null, mHelper.getNotificationChannel(PKG, UID,
+ NotificationChannel.DEFAULT_CHANNEL_ID, false));
}
@Test
@@ -866,6 +849,36 @@
}
@Test
+ public void testOnUserRemoved() throws Exception {
+ int[] user0Uids = {98, 235, 16, 3782};
+ int[] user1Uids = new int[user0Uids.length];
+ for (int i = 0; i < user0Uids.length; i++) {
+ user1Uids[i] = UserHandle.PER_USER_RANGE + user0Uids[i];
+
+ final ApplicationInfo legacy = new ApplicationInfo();
+ legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+ when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
+
+ // create records with the default channel for all user 0 and user 1 uids
+ mHelper.getImportance(PKG, user0Uids[i]);
+ mHelper.getImportance(PKG, user1Uids[i]);
+ }
+
+ mHelper.onUserRemoved(1);
+
+ // user 0 records remain
+ for (int i = 0; i < user0Uids.length; i++) {
+ assertEquals(1,
+ mHelper.getNotificationChannels(PKG, user0Uids[i], false).getList().size());
+ }
+ // user 1 records are gone
+ for (int i = 0; i < user1Uids.length; i++) {
+ assertEquals(0,
+ mHelper.getNotificationChannels(PKG, user1Uids[i], false).getList().size());
+ }
+ }
+
+ @Test
public void testOnPackageChanged_packageRemoval() throws Exception {
// Deleted
NotificationChannel channel1 =
@@ -1067,7 +1080,7 @@
for (int i = 0; i < numPackages; i++) {
JSONObject object = actual.getJSONObject(i);
assertTrue(expectedChannels.containsKey(object.get("packageName")));
- assertEquals(expectedChannels.get(object.get("packageName")).intValue() + 1,
+ assertEquals(expectedChannels.get(object.get("packageName")).intValue(),
object.getInt("channelCount"));
}
}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index cc682c4..fa72416 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -18,6 +18,7 @@
package="com.android.frameworks.servicestests">
<uses-permission android:name="android.permission.READ_LOGS" />
+ <uses-permission android:name="android.permission.ACCESS_VR_MANAGER" />
<uses-permission android:name="android.permission.ACCOUNT_MANAGER" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index c78488f..bb7e20b 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -368,8 +368,8 @@
}
@Test
- public void testSetActiveScorer_noRequestNetworkScoresPermission() {
- when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
+ public void testSetActiveScorer_noScoreNetworksPermission() {
+ when(mContext.checkCallingOrSelfPermission(permission.SCORE_NETWORKS))
.thenReturn(PackageManager.PERMISSION_DENIED);
try {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index 0694eae..ceb92de 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -228,30 +228,23 @@
}
@Test
- public void testSetActiveScorer_nullPackage_validDefault() throws Exception {
- String packageName = "package";
- String defaultPackage = "defaultPackage";
- setNetworkRecoPackageSetting(packageName);
- setDefaultNetworkRecommendationPackage(defaultPackage);
- final ComponentName recoComponent = new ComponentName(defaultPackage, "class1");
- mockScoreNetworksGranted(recoComponent.getPackageName());
- mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */, null);
+ public void testSetActiveScorer_nullPackage_currentIsSet() throws Exception {
+ setNetworkRecoPackageSetting("package");
assertTrue(mNetworkScorerAppManager.setActiveScorer(null));
verify(mSettingsFacade).putString(mMockContext,
- Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, defaultPackage);
+ Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, null);
+ verify(mSettingsFacade).putInt(mMockContext,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF);
}
@Test
- public void testSetActiveScorer_nullPackage_invalidDefault() throws Exception {
- String packageName = "package";
- String defaultPackage = "defaultPackage";
- setNetworkRecoPackageSetting(packageName);
- setDefaultNetworkRecommendationPackage(defaultPackage);
+ public void testSetActiveScorer_nullPackage_currentIsNull() throws Exception {
+ setNetworkRecoPackageSetting(null);
- assertFalse(mNetworkScorerAppManager.setActiveScorer(null));
- verify(mSettingsFacade, never()).putString(any(),
- eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any());
+ assertTrue(mNetworkScorerAppManager.setActiveScorer(null));
+ verify(mSettingsFacade, never()).putString(any(), any(), any());
}
@Test
@@ -266,6 +259,9 @@
assertTrue(mNetworkScorerAppManager.setActiveScorer(newPackage));
verify(mSettingsFacade).putString(mMockContext,
Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, newPackage);
+ verify(mSettingsFacade).putInt(mMockContext,
+ Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED,
+ NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON);
}
@Test
@@ -341,6 +337,32 @@
}
@Test
+ public void testUpdateState_currentPackageNull_defaultNull() throws Exception {
+ setDefaultNetworkRecommendationPackage(null);
+ setNetworkRecoPackageSetting(null);
+
+ mNetworkScorerAppManager.updateState();
+
+ verify(mSettingsFacade, never()).putString(any(),
+ eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString());
+ verify(mSettingsFacade, never()).putInt(any(),
+ eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt());
+ }
+
+ @Test
+ public void testUpdateState_currentPackageEmpty_defaultEmpty() throws Exception {
+ setDefaultNetworkRecommendationPackage("");
+ setNetworkRecoPackageSetting("");
+
+ mNetworkScorerAppManager.updateState();
+
+ verify(mSettingsFacade, never()).putString(any(),
+ eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString());
+ verify(mSettingsFacade, never()).putInt(any(),
+ eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt());
+ }
+
+ @Test
public void testUpdateState_currentPackageNotValid_sameAsDefault() throws Exception {
String defaultPackage = "defaultPackage";
setDefaultNetworkRecommendationPackage(defaultPackage);
diff --git a/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java
new file mode 100644
index 0000000..9a9c243
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NightDisplayServiceTest.java
@@ -0,0 +1,620 @@
+/*
+ * 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.server;
+
+import android.app.ActivityManager;
+import android.app.AlarmManager;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.app.NightDisplayController;
+import com.android.internal.app.NightDisplayController.LocalTime;
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.display.DisplayTransformManager;
+import com.android.server.display.NightDisplayService;
+import com.android.server.twilight.TwilightManager;
+import com.android.server.twilight.TwilightState;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import java.util.Calendar;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.mockito.Mockito.doReturn;
+
+@RunWith(AndroidJUnit4.class)
+public class NightDisplayServiceTest {
+
+ private Context mContext;
+ private int mUserId;
+
+ private TwilightManager mTwilightManager;
+
+ private NightDisplayController mNightDisplayController;
+ private NightDisplayService mNightDisplayService;
+
+ @Before
+ public void setUp() {
+ mContext = Mockito.spy(new ContextWrapper(InstrumentationRegistry.getTargetContext()));
+ mUserId = ActivityManager.getCurrentUser();
+
+ doReturn(mContext).when(mContext).getApplicationContext();
+
+ final MockContentResolver cr = new MockContentResolver(mContext);
+ cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ doReturn(cr).when(mContext).getContentResolver();
+
+ final AlarmManager am = Mockito.mock(AlarmManager.class);
+ doReturn(am).when(mContext).getSystemService(Context.ALARM_SERVICE);
+
+ final DisplayTransformManager dtm = Mockito.mock(DisplayTransformManager.class);
+ LocalServices.addService(DisplayTransformManager.class, dtm);
+
+ mTwilightManager = Mockito.mock(TwilightManager.class);
+ LocalServices.addService(TwilightManager.class, mTwilightManager);
+
+ mNightDisplayController = new NightDisplayController(mContext, mUserId);
+ mNightDisplayService = new NightDisplayService(mContext);
+ }
+
+ @After
+ public void tearDown() {
+ LocalServices.removeServiceForTest(DisplayTransformManager.class);
+ LocalServices.removeServiceForTest(TwilightManager.class);
+
+ mNightDisplayService = null;
+ mNightDisplayController = null;
+
+ mTwilightManager = null;
+
+ mUserId = UserHandle.USER_NULL;
+ mContext = null;
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
+ setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
+ setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void customSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
+ setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
+ setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
+ setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(false /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ @Test
+ public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
+ setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
+ setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+
+ startService();
+ assertActivated(true /* activated */);
+ }
+
+ /**
+ * Convenience for making a {@link LocalTime} instance with an offset relative to now.
+ *
+ * @param offsetMinutes the offset relative to now (in minutes)
+ * @return the LocalTime instance
+ */
+ private LocalTime getLocalTimeRelativeToNow(int offsetMinutes) {
+ final Calendar c = Calendar.getInstance();
+ c.add(Calendar.MINUTE, offsetMinutes);
+ return new LocalTime(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE));
+ }
+
+ /**
+ * Configures Night display to use a custom schedule.
+ *
+ * @param startTimeOffset the offset relative to now to activate Night display (in minutes)
+ * @param endTimeOffset the offset relative to now to deactivate Night display (in minutes)
+ */
+ private void setAutoModeCustom(int startTimeOffset, int endTimeOffset) {
+ mNightDisplayController.setAutoMode(NightDisplayController.AUTO_MODE_CUSTOM);
+ mNightDisplayController.setCustomStartTime(getLocalTimeRelativeToNow(startTimeOffset));
+ mNightDisplayController.setCustomEndTime(getLocalTimeRelativeToNow(endTimeOffset));
+ }
+
+ /**
+ * Configures Night display to use the twilight schedule.
+ *
+ * @param sunsetOffset the offset relative to now for sunset (in minutes)
+ * @param sunriseOffset the offset relative to now for sunrise (in minutes)
+ */
+ private void setAutoModeTwilight(int sunsetOffset, int sunriseOffset) {
+ mNightDisplayController.setAutoMode(NightDisplayController.AUTO_MODE_TWILIGHT);
+
+ final LocalTime sunset = getLocalTimeRelativeToNow(sunsetOffset);
+ final LocalTime sunrise = getLocalTimeRelativeToNow(sunriseOffset);
+
+ final Calendar now = Calendar.getInstance();
+ long sunsetMillis = sunset.getDateTimeBefore(now).getTimeInMillis();
+ long sunriseMillis = sunrise.getDateTimeBefore(now).getTimeInMillis();
+ if (sunsetMillis < sunriseMillis) {
+ sunsetMillis = sunset.getDateTimeAfter(now).getTimeInMillis();
+ } else {
+ sunriseMillis = sunrise.getDateTimeAfter(now).getTimeInMillis();
+ }
+
+ final TwilightState state = new TwilightState(sunriseMillis, sunsetMillis);
+ doReturn(state).when(mTwilightManager).getLastTwilightState();
+ }
+
+ /**
+ * Configures the Night display activated state.
+ *
+ * @param activated {@code true} if Night display should be activated
+ * @param lastActivatedTimeOffset the offset relative to now to record that Night display was
+ activated (in minutes)
+ */
+ private void setActivated(boolean activated, int lastActivatedTimeOffset) {
+ mNightDisplayController.setActivated(activated);
+
+ final Calendar c = Calendar.getInstance();
+ c.add(Calendar.MINUTE, lastActivatedTimeOffset);
+ Secure.putLongForUser(mContext.getContentResolver(),
+ Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, c.getTimeInMillis(), mUserId);
+ }
+
+ /**
+ * Convenience method to start {@link #mNightDisplayService}.
+ */
+ private void startService() {
+ Secure.putIntForUser(mContext.getContentResolver(), Secure.USER_SETUP_COMPLETE, 1, mUserId);
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+ @Override
+ public void run() {
+ mNightDisplayService.onStart();
+ mNightDisplayService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ mNightDisplayService.onStartUser(mUserId);
+ }
+ });
+ }
+
+ /**
+ * Convenience method for asserting whether Night display should be activated.
+ *
+ * @param activated the expected activated state of Night display
+ */
+ private void assertActivated(boolean activated) {
+ assertWithMessage("Invalid Night display activated state")
+ .that(mNightDisplayController.isActivated())
+ .isEqualTo(activated);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index c87eaed..711c36b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.pm.ActivityInfo;
import android.platform.test.annotations.Presubmit;
@@ -97,4 +98,25 @@
testStack.stopActivityLocked(activityRecord);
}
+
+ /**
+ * This test verifies that {@link ActivityStack#STACK_VISIBLE_ACTIVITY_BEHIND} is returned from
+ * {@link ActivityStack#shouldBeVisible(ActivityRecord)} from a fullscreen workspace stack with
+ * a visible behind activity when top focused stack is the home stack.
+ */
+ @Test
+ public void testShouldBeVisibleWithVisibleBehindActivity() throws Exception {
+ final ActivityManagerService service = createActivityManagerService();
+ final TaskRecord task = createTask(service, testActivityComponent,
+ ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID);
+ final ActivityStack fullscreenWorkspaceStackId = task.getStack();
+ final ActivityStack homeStack = service.mStackSupervisor.getStack(
+ ActivityManager.StackId.HOME_STACK_ID, true /*createStaticStackIfNeeded*/,
+ true /*onTop*/);
+ final ActivityRecord activityRecord = createActivity(service, testActivityComponent, task);
+ service.mStackSupervisor.setFocusStackUnchecked("testEmptyStackShouldBeVisible", homeStack);
+ service.mStackSupervisor.requestVisibleBehindLocked(activityRecord, true);
+ assertEquals(ActivityStack.STACK_VISIBLE_ACTIVITY_BEHIND,
+ fullscreenWorkspaceStackId.shouldBeVisible(null /*starting*/));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 28051f9..9cfa542 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -151,9 +151,12 @@
* setup not available in the test environment. Also specifies an injector for
*/
protected static class TestActivityStackSupervisor extends ActivityStackSupervisor {
+ private final ActivityDisplay mDisplay;
+
public TestActivityStackSupervisor(ActivityManagerService service, Looper looper) {
super(service, looper);
mWindowManager = prepareMockWindowManager();
+ mDisplay = new ActivityDisplay();
}
// No home stack is set.
@@ -185,9 +188,8 @@
public <T extends ActivityStack> T createTestStack(ActivityManagerService service,
int stackId, boolean onTop) {
- final ActivityDisplay display = new ActivityDisplay();
final TestActivityContainer container =
- new TestActivityContainer(service, stackId, display, onTop);
+ new TestActivityContainer(service, stackId, mDisplay, onTop);
mActivityContainers.put(stackId, container);
return (T) container.getStack();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index 325d99a..5e4ba7be 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -31,13 +31,10 @@
import static org.junit.Assert.fail;
import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
import android.content.pm.UserInfo;
-import android.os.Process;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.support.test.InstrumentationRegistry;
@@ -49,26 +46,17 @@
import android.util.LongSparseArray;
import com.android.internal.os.AtomicFile;
-import com.android.internal.util.FastPrintWriter;
import com.android.server.LocalServices;
-import org.hamcrest.core.IsNot;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.PrintStream;
import java.security.PublicKey;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
@RunWith(AndroidJUnit4.class)
@@ -547,7 +535,6 @@
private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) {
- assertThat(userState.blockUninstall, is(false));
assertThat(userState.enabled, is(0));
assertThat(userState.hidden, is(false));
assertThat(userState.installed, is(installed));
@@ -783,31 +770,14 @@
@Before
public void createUserManagerServiceRef() throws ReflectiveOperationException {
- InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
- @Override
- public void run() {
- Constructor<UserManagerService> umsc;
- try {
- // unregister the user manager from the local service
- Method removeServiceForTest = LocalServices.class.getDeclaredMethod(
- "removeServiceForTest", Class.class);
- removeServiceForTest.invoke(null, UserManagerInternal.class);
-
- // now create a new user manager [which registers again with the local service]
- umsc = UserManagerService.class.getDeclaredConstructor(
- Context.class,
- PackageManagerService.class,
- Object.class,
- File.class);
- umsc.setAccessible(true);
- UserManagerService ums = umsc.newInstance(InstrumentationRegistry.getContext(),
- null /*PackageManagerService*/, new Object() /*packagesLock*/,
- new File(InstrumentationRegistry.getContext().getFilesDir(), "user"));
- } catch (SecurityException
- | ReflectiveOperationException
- | IllegalArgumentException e) {
- fail("Could not create user manager service; " + e);
- }
+ InstrumentationRegistry.getInstrumentation().runOnMainSync((Runnable) () -> {
+ try {
+ // unregister the user manager from the local service
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
+ new UserManagerService(InstrumentationRegistry.getContext());
+ } catch (Exception e) {
+ e.printStackTrace();
+ fail("Could not create user manager service; " + e);
}
});
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index bf05f21..50be8db 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -49,10 +49,6 @@
assertThat(testUserState.equals(oldUserState), is(false));
oldUserState = new PackageUserState();
- oldUserState.blockUninstall = true;
- assertThat(testUserState.equals(oldUserState), is(false));
-
- oldUserState = new PackageUserState();
oldUserState.ceDataInode = 4000L;
assertThat(testUserState.equals(oldUserState), is(false));
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4c7bf4d..f4944f9 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -7399,4 +7399,50 @@
"s21", "s22");
});
}
+
+ public void testReturnedByServer() {
+ // Package 1 updated, with manifest shortcuts.
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_1);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertWith(mManager.getManifestShortcuts())
+ .haveIds("ms1")
+ .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+
+ assertTrue(mManager.setDynamicShortcuts(list(makeShortcut("s1"))));
+
+ assertWith(mManager.getDynamicShortcuts())
+ .haveIds("s1")
+ .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+ });
+
+ // Pin them.
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1,
+ list("ms1", "s1"), getCallingUser());
+ assertWith(getShortcutAsLauncher(USER_0))
+ .haveIds("ms1", "s1")
+ .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertWith(mManager.getPinnedShortcuts())
+ .haveIds("ms1", "s1")
+ .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+ });
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ // This shows a warning log, but should still work.
+ assertTrue(mManager.setDynamicShortcuts(mManager.getDynamicShortcuts()));
+
+ assertWith(mManager.getDynamicShortcuts())
+ .haveIds("s1")
+ .forAllShortcuts(si -> assertTrue(si.isReturnedByServer()));
+ });
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
index 3789086..375edf3 100644
--- a/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/storage/DiskStatsLoggingServiceTest.java
@@ -20,16 +20,31 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.eq;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import android.app.job.JobService;
-import android.app.job.JobParameters;
+import android.app.job.JobServiceEngine;
+import android.app.usage.ExternalStorageStats;
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.pm.PackageStats;
+import android.os.BatteryManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.storage.StorageManager;
+import android.os.storage.VolumeInfo;
+import android.provider.Settings;
import android.test.AndroidTestCase;
+import android.test.mock.MockContentResolver;
+import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.storage.DiskStatsLoggingService.LogRunnable;
import libcore.io.IoUtils;
@@ -46,14 +61,17 @@
import java.io.File;
import java.io.PrintStream;
+import java.lang.reflect.Field;
import java.util.ArrayList;
@RunWith(JUnit4.class)
public class DiskStatsLoggingServiceTest extends AndroidTestCase {
@Rule public TemporaryFolder mTemporaryFolder;
@Rule public TemporaryFolder mDownloads;
- @Rule public TemporaryFolder mRootDirectory;
@Mock private AppCollector mCollector;
+ @Mock private JobService mJobService;
+ @Mock private StorageStatsManager mSsm;
+ private ExternalStorageStats mStorageStats;
private File mInputFile;
@@ -66,8 +84,10 @@
mInputFile = mTemporaryFolder.newFile();
mDownloads = new TemporaryFolder();
mDownloads.create();
- mRootDirectory = new TemporaryFolder();
- mRootDirectory.create();
+ mStorageStats = new ExternalStorageStats();
+ when(mSsm.queryExternalStatsForUser(isNull(String.class), any(UserHandle.class)))
+ .thenReturn(mStorageStats);
+ when(mJobService.getSystemService(anyString())).thenReturn(mSsm);
}
@Test
@@ -75,9 +95,9 @@
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(0L);
+ task.setContext(mJobService);
task.run();
JSONObject json = getJsonOutput();
@@ -99,10 +119,10 @@
public void testPopulatedLogTask() throws Exception {
// Write data to directories.
writeDataToFile(mDownloads.newFile(), "lol");
- writeDataToFile(mRootDirectory.newFile("test.jpg"), "1234");
- writeDataToFile(mRootDirectory.newFile("test.mp4"), "12345");
- writeDataToFile(mRootDirectory.newFile("test.mp3"), "123456");
- writeDataToFile(mRootDirectory.newFile("test.whatever"), "1234567");
+ mStorageStats.audioBytes = 6L;
+ mStorageStats.imageBytes = 4L;
+ mStorageStats.videoBytes = 5L;
+ mStorageStats.totalBytes = 22L;
// Write apps.
ArrayList<PackageStats> apps = new ArrayList<>();
@@ -110,15 +130,16 @@
testApp.dataSize = 5L;
testApp.cacheSize = 55L;
testApp.codeSize = 10L;
+ testApp.userHandle = UserHandle.USER_SYSTEM;
apps.add(testApp);
- when(mCollector.getPackageStats(anyInt())).thenReturn(apps);
+ when(mCollector.getPackageStats(anyLong())).thenReturn(apps);
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(10L);
+ task.setContext(mJobService);
task.run();
JSONObject json = getJsonOutput();
@@ -143,14 +164,57 @@
LogRunnable task = new LogRunnable();
task.setAppCollector(mCollector);
task.setDownloadsDirectory(mDownloads.getRoot());
- task.setRootDirectory(mRootDirectory.getRoot());
task.setLogOutputFile(mInputFile);
task.setSystemSize(10L);
+ task.setContext(mJobService);
task.run();
// No exception should be thrown.
}
+ @Test
+ public void testDontCrashOnRun() throws Exception {
+ DiskStatsLoggingService service = spy(new DiskStatsLoggingService());
+ BatteryManager batteryManager = mock(BatteryManager.class);
+ when(batteryManager.isCharging()).thenReturn(true);
+ doReturn(batteryManager).when(service).getSystemService(Context.BATTERY_SERVICE);
+ UserManager userManager = mock(UserManager.class);
+ when(userManager.getUsers()).thenReturn(new ArrayList<>());
+ doReturn(userManager).when(service).getSystemService(Context.USER_SERVICE);
+ doReturn(mSsm).when(service).getSystemService(Context.STORAGE_STATS_SERVICE);
+ doReturn(mock(StorageManager.class))
+ .when(service)
+ .getSystemService(Context.STORAGE_SERVICE);
+
+ MockContentResolver cr = new MockContentResolver();
+ cr.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ doReturn(cr).when(service).getContentResolver();
+
+ PackageManager pm = mock(PackageManager.class);
+ VolumeInfo volumeInfo =
+ new VolumeInfo(VolumeInfo.ID_PRIVATE_INTERNAL, VolumeInfo.TYPE_PRIVATE, null, null);
+ when(pm.getPrimaryStorageCurrentVolume()).thenReturn(volumeInfo);
+ doReturn(pm).when(service).getPackageManager();
+
+ doReturn(0).when(service).getUserId();
+
+ // UGGGGGHHHHHHH! jobFinished is a final method on JobService which crashes when called if
+ // the JobService isn't initialized for real. ServiceTestCase doesn't let us initialize a
+ // service which is built into the framework without crashing, though, so we can't make a
+ // real initialized service.
+ //
+ // And so, we use reflection to set the JobServiceEngine, which is used by the final method,
+ // to be something which won't crash when called.
+ final Field field = JobService.class.getDeclaredField("mEngine");
+ field.setAccessible(true);
+ field.set(service, mock(JobServiceEngine.class));
+
+ // Note: This won't clobber your on-device cache file because, technically,
+ // FrameworkServicesTests don't have write permission to actually overwrite the cache file.
+ // We log and fail on the write silently in this case.
+ service.onStartJob(null);
+ }
+
private void writeDataToFile(File f, String data) throws Exception{
PrintStream out = new PrintStream(f);
out.print(data);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index a23a6b22..649de4a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -20,6 +20,7 @@
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
+import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -33,8 +34,7 @@
* runtest frameworks-services -c com.android.server.wm.TaskSnapshotCacheTest
*/
@SmallTest
-// TODO(b/35196891): Add back to presubmit once the bug is fixed.
-//@Presubmit
+@Presubmit
@RunWith(AndroidJUnit4.class)
public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 2b4d9fb..f253632 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -17,6 +17,7 @@
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
import static com.android.server.wm.TaskSnapshotController.*;
import static junit.framework.Assert.assertEquals;
@@ -76,12 +77,19 @@
public void testGetSnapshotMode() throws Exception {
final WindowState disabledWindow = createWindow(null,
FIRST_APPLICATION_WINDOW, mDisplayContent, "disabledWindow");
- disabledWindow.mAppToken.setDisablePreviewSnapshots(true);
+ disabledWindow.mAppToken.setDisablePreviewScreenshots(true);
assertEquals(SNAPSHOT_MODE_APP_THEME,
sWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
+
final WindowState normalWindow = createWindow(null,
FIRST_APPLICATION_WINDOW, mDisplayContent, "normalWindow");
assertEquals(SNAPSHOT_MODE_REAL,
sWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
+
+ final WindowState secureWindow = createWindow(null,
+ FIRST_APPLICATION_WINDOW, mDisplayContent, "secureWindow");
+ secureWindow.mAttrs.flags |= FLAG_SECURE;
+ assertEquals(SNAPSHOT_MODE_APP_THEME,
+ sWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask()));
}
}
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 18d0c32..8146763 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -68,7 +68,11 @@
}
private void cleanDirectory() {
- for (File file : new File(sFilesDir, "snapshots").listFiles()) {
+ final File[] files = new File(sFilesDir, "snapshots").listFiles();
+ if (files == null) {
+ return;
+ }
+ for (File file : files) {
if (!file.isDirectory()) {
file.delete();
}
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 717ddf2..e2868d7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -171,11 +171,25 @@
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
- mSurface.drawStatusBarBackground(mockCanvas, new Rect(0, 0, 50, 100), 10);
+ mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+ mockCanvas, new Rect(0, 0, 50, 100), 10);
verify(mockCanvas).drawRect(eq(50.0f), eq(0.0f), eq(90.0f), eq(10.0f), any());
}
@Test
+ public void testDrawStatusBarBackground_nullFrame() {
+ setupSurface(100, 100);
+ final Rect insets = new Rect(0, 10, 10, 0);
+ mSurface.setFrames(new Rect(0, 0, 100, 100), insets, insets);
+ final Canvas mockCanvas = mock(Canvas.class);
+ when(mockCanvas.getWidth()).thenReturn(100);
+ when(mockCanvas.getHeight()).thenReturn(100);
+ mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+ mockCanvas, null, 10);
+ verify(mockCanvas).drawRect(eq(0.0f), eq(0.0f), eq(90.0f), eq(10.0f), any());
+ }
+
+ @Test
public void testDrawStatusBarBackground_nope() {
setupSurface(100, 100);
final Rect insets = new Rect(0, 10, 10, 0);
@@ -183,7 +197,8 @@
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
- mSurface.drawStatusBarBackground(mockCanvas, new Rect(0, 0, 100, 100), 10);
+ mSurface.mSystemBarBackgroundPainter.drawStatusBarBackground(
+ mockCanvas, new Rect(0, 0, 100, 100), 10);
verify(mockCanvas, never()).drawRect(anyInt(), anyInt(), anyInt(), anyInt(), any());
}
@@ -196,7 +211,7 @@
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
- mSurface.drawNavigationBarBackground(mockCanvas);
+ mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
verify(mockCanvas).drawRect(eq(new Rect(0, 90, 100, 100)), any());
}
@@ -209,7 +224,7 @@
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
- mSurface.drawNavigationBarBackground(mockCanvas);
+ mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
verify(mockCanvas).drawRect(eq(new Rect(0, 0, 10, 100)), any());
}
@@ -222,7 +237,7 @@
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
when(mockCanvas.getHeight()).thenReturn(100);
- mSurface.drawNavigationBarBackground(mockCanvas);
+ mSurface.mSystemBarBackgroundPainter.drawNavigationBarBackground(mockCanvas);
verify(mockCanvas).drawRect(eq(new Rect(90, 0, 100, 100)), any());
}
}
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java
index 38ea6e6f..a75cd86 100644
--- a/telephony/java/android/telephony/ims/ImsServiceProxy.java
+++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java
@@ -120,7 +120,7 @@
public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature,
incomingCallIntent, listener);
}
@@ -129,7 +129,7 @@
@Override
public void endSession(int sessionId) throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
}
}
@@ -138,7 +138,7 @@
public boolean isConnected(int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature,
callServiceType, callType);
}
@@ -147,7 +147,7 @@
@Override
public boolean isOpened() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature);
}
}
@@ -156,7 +156,7 @@
public void addRegistrationListener(IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature,
listener);
}
@@ -166,7 +166,7 @@
public void removeRegistrationListener(IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature,
listener);
}
@@ -176,7 +176,7 @@
public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature,
sessionId, callServiceType, callType);
}
@@ -186,7 +186,7 @@
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
IImsCallSessionListener listener) throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature,
sessionId, profile, listener);
}
@@ -196,7 +196,7 @@
public IImsCallSession getPendingCallSession(int sessionId, String callId)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature,
sessionId, callId);
}
@@ -205,7 +205,7 @@
@Override
public IImsUt getUtInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature);
}
}
@@ -213,7 +213,7 @@
@Override
public IImsConfig getConfigInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature);
}
}
@@ -221,7 +221,7 @@
@Override
public void turnOnIms() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature);
}
}
@@ -229,7 +229,7 @@
@Override
public void turnOffIms() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature);
}
}
@@ -237,7 +237,7 @@
@Override
public IImsEcbm getEcbmInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature);
}
}
@@ -246,7 +246,7 @@
public void setUiTTYMode(int uiTtyMode, Message onComplete)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, uiTtyMode,
onComplete);
}
@@ -255,7 +255,7 @@
@Override
public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId,
mSupportedFeature);
}
@@ -264,7 +264,8 @@
@Override
public int getFeatureStatus() {
synchronized (mLock) {
- if (mFeatureStatusCached != null) {
+ if (isBinderAlive() && mFeatureStatusCached != null) {
+ Log.i(LOG_TAG, "getFeatureStatus - returning cached: " + mFeatureStatusCached);
return mFeatureStatusCached;
}
}
@@ -277,6 +278,7 @@
// Cache only non-null value for feature status.
mFeatureStatusCached = status;
}
+ Log.i(LOG_TAG, "getFeatureStatus - returning " + status);
return status;
}
@@ -301,10 +303,28 @@
mStatusCallback = c;
}
+ /**
+ * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
+ * method returns false, it doesn't mean that the Binder connection is not available (use
+ * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
+ * at this time.
+ *
+ * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
+ * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
+ */
+ public boolean isBinderReady() {
+ return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
+ }
+
@Override
public boolean isBinderAlive() {
- return mIsAvailable && getFeatureStatus() == ImsFeature.STATE_READY && mBinder != null &&
- mBinder.isBinderAlive();
+ return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
+ }
+
+ protected void checkServiceIsReady() throws RemoteException {
+ if (!isBinderReady()) {
+ throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
+ }
}
private IImsServiceController getServiceInterface(IBinder b) {
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 988dd58..395f1cc 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -150,7 +150,7 @@
private void notifyFeatureState(@ImsState int state) {
if (mStatusCallback != null) {
try {
- Log.i(LOG_TAG, "notifying ImsFeatureState");
+ Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
mStatusCallback.notifyImsFeatureStatus(state);
} catch (RemoteException e) {
mStatusCallback = null;
diff --git a/wifi/java/android/net/wifi/RttManager.java b/wifi/java/android/net/wifi/RttManager.java
index ff632a5..b133a44 100644
--- a/wifi/java/android/net/wifi/RttManager.java
+++ b/wifi/java/android/net/wifi/RttManager.java
@@ -660,10 +660,10 @@
@Deprecated
public int tx_rate;
- /** average transmit rate. Unit (100kbps). */
+ /** average transmit rate. Unit (kbps). */
public int txRate;
- /** average receiving rate Unit (100kbps). */
+ /** average receiving rate Unit (kbps). */
public int rxRate;
/**
@@ -673,7 +673,7 @@
@Deprecated
public long rtt_ns;
- /** average round trip time in 0.1 nano second. */
+ /** average round trip time in picoseconds. */
public long rtt;
/**
@@ -683,7 +683,7 @@
@Deprecated
public long rtt_sd_ns;
- /** standard deviation of RTT in 0.1 ns. */
+ /** standard deviation of RTT in picoseconds. */
public long rttStandardDeviation;
/**
@@ -693,7 +693,7 @@
@Deprecated
public long rtt_spread_ns;
- /** spread (i.e. max - min) RTT in 0.1 ns. */
+ /** spread (i.e. max - min) RTT in picoseconds. */
public long rttSpread;
/**
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index e31a74b..f7333e2 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -839,6 +839,10 @@
*/
public static final int NETWORK_SELECTION_ENABLE = 0;
/**
+ * The starting index for network selection disabled reasons
+ */
+ public static final int NETWORK_SELECTION_DISABLED_STARTING_INDEX = 1;
+ /**
* @deprecated it is not used any more.
* This network is disabled because higher layer (>2) network is bad
*/
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 03ef319..adf897d 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -22,6 +22,7 @@
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_GENERIC;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_INCOMPATIBLE_MODE;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_NO_CHANNEL;
+import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.ERROR_TETHERING_DISALLOWED;
import static android.net.wifi.WifiManager.LocalOnlyHotspotCallback.REQUEST_REGISTERED;
import static org.junit.Assert.assertEquals;
@@ -335,14 +336,13 @@
*/
@Test
public void testCorrectLooperIsUsedForHandler() throws Exception {
- // record thread from looper.getThread and check ids.
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
.thenReturn(ERROR_INCOMPATIBLE_MODE);
mWifiManager.startLocalOnlyHotspot(callback, mHandler);
mLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
- assertEquals(mLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
+ verify(mContext, never()).getMainLooper();
}
/**
@@ -361,6 +361,7 @@
altLooper.dispatchAll();
assertEquals(ERROR_INCOMPATIBLE_MODE, callback.mFailureReason);
assertEquals(altLooper.getLooper().getThread().getId(), callback.mCallingThreadId);
+ verify(mContext).getMainLooper();
}
/**
@@ -464,11 +465,10 @@
}
/**
- * Verify the handler passed in to startLocalOnlyHotspot is correctly used for callbacks when a
- * null WifiConfig is returned.
+ * Verify callback triggered from startLocalOnlyHotspot with an incompatible mode failure.
*/
@Test
- public void testLocalOnlyHotspotCallbackFullOnNullConfig() throws Exception {
+ public void testLocalOnlyHotspotCallbackFullOnIncompatibleMode() throws Exception {
TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
.thenReturn(ERROR_INCOMPATIBLE_MODE);
@@ -481,6 +481,22 @@
}
/**
+ * Verify callback triggered from startLocalOnlyHotspot with a tethering disallowed failure.
+ */
+ @Test
+ public void testLocalOnlyHotspotCallbackFullOnTetheringDisallowed() throws Exception {
+ TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
+ when(mWifiService.startLocalOnlyHotspot(any(Messenger.class), any(IBinder.class)))
+ .thenReturn(ERROR_TETHERING_DISALLOWED);
+ mWifiManager.startLocalOnlyHotspot(callback, mHandler);
+ mLooper.dispatchAll();
+ assertEquals(ERROR_TETHERING_DISALLOWED, callback.mFailureReason);
+ assertFalse(callback.mOnStartedCalled);
+ assertFalse(callback.mOnStoppedCalled);
+ assertEquals(null, callback.mRes);
+ }
+
+ /**
* Verify a SecurityException resulting from an application without necessary permissions will
* bubble up through the call to start LocalOnlyHotspot and will not trigger other callbacks.
*/
@@ -616,12 +632,11 @@
*/
@Test
public void testCorrectLooperIsUsedForObserverHandler() throws Exception {
- // record thread from looper.getThread and check ids.
TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
mWifiManager.watchLocalOnlyHotspot(observer, mHandler);
mLooper.dispatchAll();
assertTrue(observer.mOnRegistered);
- assertEquals(mLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
+ verify(mContext, never()).getMainLooper();
}
/**
@@ -638,6 +653,7 @@
altLooper.dispatchAll();
assertTrue(observer.mOnRegistered);
assertEquals(altLooper.getLooper().getThread().getId(), observer.mCallingThreadId);
+ verify(mContext).getMainLooper();
}
/**