Merge "Fix a11y cache correctness bug" into pi-dev
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index a3b3a9f..79d1361 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -17,7 +17,6 @@
package android.accounts;
import android.Manifest;
-import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -32,8 +31,8 @@
/**
* Abstract base class for creating AccountAuthenticators.
- * In order to be an authenticator one must extend this class, provider implementations for the
- * abstract methods and write a service that returns the result of {@link #getIBinder()}
+ * In order to be an authenticator one must extend this class, provide implementations for the
+ * abstract methods, and write a service that returns the result of {@link #getIBinder()}
* in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked
* with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service
* must specify the following intent filter and metadata tags in its AndroidManifest.xml file
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index f765620..1925f43 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -393,7 +393,7 @@
* <td>The final call you receive before your
* activity is destroyed. This can happen either because the
* activity is finishing (someone called {@link Activity#finish} on
- * it, or because the system is temporarily destroying this
+ * it), or because the system is temporarily destroying this
* instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link
* Activity#isFinishing} method.</td>
@@ -1342,6 +1342,7 @@
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onResume " + this);
getApplication().dispatchActivityResumed(this);
mActivityTransitionState.onResume(this, isTopOfTask());
+ enableAutofillCompatibilityIfNeeded();
if (mAutoFillResetNeeded) {
if (!mAutoFillIgnoreFirstResumePause) {
View focus = getCurrentFocus();
@@ -1936,7 +1937,7 @@
/**
* Perform any final cleanup before an activity is destroyed. This can
* happen either because the activity is finishing (someone called
- * {@link #finish} on it, or because the system is temporarily destroying
+ * {@link #finish} on it), or because the system is temporarily destroying
* this instance of the activity to save space. You can distinguish
* between these two scenarios with the {@link #isFinishing} method.
*
@@ -7108,7 +7109,6 @@
mWindow.setColorMode(info.colorMode);
setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
- enableAutofillCompatibilityIfNeeded();
}
private void enableAutofillCompatibilityIfNeeded() {
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index adc592a..6564a30 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -232,7 +232,7 @@
* Changes to night mode take effect globally and will result in a configuration change
* (and potentially an Activity lifecycle event) being applied to all running apps.
* Developers interested in an app-local implementation of night mode should consider using
- * {@link androidx.appcompat.app.AppCompatDelegate#setDefaultNightMode(int)} to manage the
+ * {@link android.support.v7.app.AppCompatDelegate#setDefaultNightMode(int)} to manage the
* -night qualifier locally.
*
* @param mode the night mode to set
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index cdeaea3..8d8b257 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -95,6 +95,7 @@
* <p>For more information about using content providers, read the
* <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
* developer guide.</p>
+ * </div>
*/
public abstract class ContentProvider implements ComponentCallbacks2 {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 1c96579..359d078 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -326,6 +326,15 @@
public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
/**
+ * Flag for {@link #bindService}: If binding from something better than perceptible,
+ * still set the adjust below perceptible. This would be used for bound services that can
+ * afford to be evicted when under extreme memory pressure, but should be restarted as soon
+ * as possible.
+ * @hide
+ */
+ public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
+
+ /**
* @hide Flag for {@link #bindService}: allows binding to a service provided
* by an instant app. Note that the caller may not have access to the instant
* app providing the service which is a violation of the instant app sandbox.
diff --git a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
index 5bf3a7c..06c069c 100644
--- a/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
+++ b/core/java/android/database/sqlite/SQLiteCompatibilityWalFlags.java
@@ -41,6 +41,7 @@
private static volatile boolean sFlagsSet;
private static volatile boolean sCompatibilityWalSupported;
private static volatile String sWALSyncMode;
+ private static volatile long sTruncateSize = -1;
// This flag is used to avoid recursive initialization due to circular dependency on Settings
private static volatile boolean sCallingGlobalSettings;
@@ -71,6 +72,19 @@
return sWALSyncMode;
}
+ /**
+ * Override {@link com.android.internal.R.integer#db_wal_truncate_size}.
+ *
+ * @return the value set in the global setting, or -1 if a value is not set.
+ *
+ * @hide
+ */
+ @VisibleForTesting
+ public static long getTruncateSize() {
+ initIfNeeded();
+ return sTruncateSize;
+ }
+
private static void initIfNeeded() {
if (sInitialized || sCallingGlobalSettings) {
return;
@@ -115,6 +129,7 @@
sCompatibilityWalSupported = parser.getBoolean("compatibility_wal_supported",
SQLiteGlobal.isCompatibilityWalSupported());
sWALSyncMode = parser.getString("wal_syncmode", SQLiteGlobal.getWALSyncMode());
+ sTruncateSize = parser.getInt("truncate_size", -1);
Log.i(TAG, "Read compatibility WAL flags: compatibility_wal_supported="
+ sCompatibilityWalSupported + ", wal_syncmode=" + sWALSyncMode);
sFlagsSet = true;
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 101fb82..9c639a5 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -32,6 +32,7 @@
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@@ -303,6 +304,7 @@
} else {
setSyncMode(SQLiteGlobal.getWALSyncMode());
}
+ maybeTruncateWalFile();
} else {
setJournalMode(mConfiguration.journalMode == null
? SQLiteGlobal.getDefaultJournalMode() : mConfiguration.journalMode);
@@ -312,6 +314,40 @@
}
}
+ /**
+ * If the WAL file exists and larger than a threshold, truncate it by executing
+ * PRAGMA wal_checkpoint.
+ */
+ private void maybeTruncateWalFile() {
+ final long threshold = SQLiteGlobal.getWALTruncateSize();
+ if (DEBUG) {
+ Log.d(TAG, "Truncate threshold=" + threshold);
+ }
+ if (threshold == 0) {
+ return;
+ }
+
+ final File walFile = new File(mConfiguration.path + "-wal");
+ if (!walFile.isFile()) {
+ return;
+ }
+ final long size = walFile.length();
+ if (size < threshold) {
+ if (DEBUG) {
+ Log.d(TAG, walFile.getAbsolutePath() + " " + size + " bytes: No need to truncate");
+ }
+ return;
+ }
+
+ Log.i(TAG, walFile.getAbsolutePath() + " " + size + " bytes: Bigger than "
+ + threshold + "; truncating");
+ try {
+ executeForString("PRAGMA wal_checkpoint(TRUNCATE)", null, null);
+ } catch (SQLiteException e) {
+ Log.w(TAG, "Failed to truncate the -wal file", e);
+ }
+ }
+
private void setSyncMode(String newValue) {
String value = executeForString("PRAGMA synchronous", null, null);
if (!canonicalizeSyncMode(value).equalsIgnoreCase(
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 96cd043..db99148 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -641,7 +641,7 @@
* successful so far. Do not call setTransactionSuccessful before calling this. When this
* returns a new transaction will have been created but not marked as successful.
* @return true if the transaction was yielded
- * @deprecated if the db is locked more than once (becuase of nested transactions) then the lock
+ * @deprecated if the db is locked more than once (because of nested transactions) then the lock
* will not be yielded. Use yieldIfContendedSafely instead.
*/
@Deprecated
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index e6b6acf..67e5f65 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -164,4 +164,21 @@
com.android.internal.R.integer.db_default_idle_connection_timeout));
}
+ /**
+ * When opening a database, if the WAL file is larger than this size, we'll truncate it.
+ *
+ * (If it's 0, we do not truncate.)
+ *
+ * @hide
+ */
+ public static long getWALTruncateSize() {
+ final long setting = SQLiteCompatibilityWalFlags.getTruncateSize();
+ if (setting >= 0) {
+ return setting;
+ }
+ return SystemProperties.getInt("debug.sqlite.wal.truncatesize",
+ Resources.getSystem().getInteger(
+ com.android.internal.R.integer.db_wal_truncate_size));
+ }
+
}
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 94f2ac0..0d7b695 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -31,7 +31,7 @@
* Android may use a newer version of the model.
*/
public class GeomagneticField {
- // The magnetic field at a given point, in nonoteslas in geodetic
+ // The magnetic field at a given point, in nanoteslas in geodetic
// coordinates.
private float mX;
private float mY;
@@ -278,7 +278,7 @@
}
/**
- * @return Horizontal component of the field strength in nonoteslas.
+ * @return Horizontal component of the field strength in nanoteslas.
*/
public float getHorizontalStrength() {
return (float) Math.hypot(mX, mY);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fbe6f3e..501d7f1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4152,7 +4152,8 @@
SHOW_BATTERY_PERCENT,
NOTIFICATION_VIBRATION_INTENSITY,
HAPTIC_FEEDBACK_INTENSITY,
- DISPLAY_COLOR_MODE
+ DISPLAY_COLOR_MODE,
+ NOTIFICATION_LIGHT_PULSE,
};
/**
@@ -4355,6 +4356,7 @@
VALIDATORS.put(WIFI_STATIC_DNS1, WIFI_STATIC_DNS1_VALIDATOR);
VALIDATORS.put(WIFI_STATIC_DNS2, WIFI_STATIC_DNS2_VALIDATOR);
VALIDATORS.put(SHOW_BATTERY_PERCENT, SHOW_BATTERY_PERCENT_VALIDATOR);
+ VALIDATORS.put(NOTIFICATION_LIGHT_PULSE, BOOLEAN_VALIDATOR);
}
/**
@@ -8173,6 +8175,8 @@
ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR); //legacy restore setting
VALIDATORS.put(HUSH_GESTURE_USED, HUSH_GESTURE_USED_VALIDATOR);
VALIDATORS.put(MANUAL_RINGER_TOGGLE_COUNT, MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR);
+ VALIDATORS.put(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
}
/**
@@ -12777,6 +12781,7 @@
* Supported keys:
* compatibility_wal_supported (boolean)
* wal_syncmode (String)
+ * truncate_size (int)
*
* @hide
*/
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index c861499..01e2db2 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -33,6 +33,8 @@
public static final String FFLAG_PREFIX = "sys.fflag.";
public static final String FFLAG_OVERRIDE_PREFIX = FFLAG_PREFIX + "override.";
+ public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
+ public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -44,6 +46,7 @@
DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
+ DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "true");
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2c9e543..04e8182 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -15493,7 +15493,7 @@
/**
* Sets the visual z position of this view, in pixels. This is equivalent to setting the
* {@link #setTranslationZ(float) translationZ} property to be the difference between
- * the x value passed in and the current {@link #getElevation() elevation} property.
+ * the z value passed in and the current {@link #getElevation() elevation} property.
*
* @param z The visual z position of this view, in pixels.
*/
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index d21cb3e..8b3ce42 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -44,6 +44,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
+import android.util.Slog;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.KeyEvent;
@@ -548,6 +549,9 @@
// different bridge based on which activity is currently focused
// in the current process. Since compat would be rarely used, just
// create and register a new instance every time.
+ if (sDebug) {
+ Slog.d(TAG, "creating CompatibilityBridge for " + mContext);
+ }
mCompatibilityBridge = new CompatibilityBridge();
}
}
diff --git a/core/java/android/widget/DigitalClock.java b/core/java/android/widget/DigitalClock.java
index c503ef2..8ebf303 100644
--- a/core/java/android/widget/DigitalClock.java
+++ b/core/java/android/widget/DigitalClock.java
@@ -27,7 +27,7 @@
import java.util.Calendar;
/**
- * Like AnalogClock, but digital. Shows seconds.
+ * Like AnalogClock, but digital.
*
* @deprecated It is recommended you use {@link TextClock} instead.
*/
diff --git a/core/java/com/android/internal/os/KernelCpuProcReader.java b/core/java/com/android/internal/os/KernelCpuProcReader.java
index 396deb4..c233ea8 100644
--- a/core/java/com/android/internal/os/KernelCpuProcReader.java
+++ b/core/java/com/android/internal/os/KernelCpuProcReader.java
@@ -24,13 +24,14 @@
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
+import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
+import java.util.Arrays;
/**
* Reads cpu time proc files with throttling (adjustable interval).
@@ -55,7 +56,6 @@
private static final int ERROR_THRESHOLD = 5;
// Throttle interval in milliseconds
private static final long DEFAULT_THROTTLE_INTERVAL = 3000L;
- private static final int INITIAL_BUFFER_SIZE = 8 * 1024;
private static final int MAX_BUFFER_SIZE = 1024 * 1024;
private static final String PROC_UID_FREQ_TIME = "/proc/uid_cpupower/time_in_state";
private static final String PROC_UID_ACTIVE_TIME = "/proc/uid_cpupower/concurrent_active_time";
@@ -84,13 +84,12 @@
private long mThrottleInterval = DEFAULT_THROTTLE_INTERVAL;
private long mLastReadTime = Long.MIN_VALUE;
private final Path mProc;
- private ByteBuffer mBuffer;
+ private byte[] mBuffer = new byte[8 * 1024];
+ private int mContentSize;
@VisibleForTesting
public KernelCpuProcReader(String procFile) {
mProc = Paths.get(procFile);
- mBuffer = ByteBuffer.allocateDirect(INITIAL_BUFFER_SIZE);
- mBuffer.clear();
}
/**
@@ -108,38 +107,45 @@
return null;
}
if (SystemClock.elapsedRealtime() < mLastReadTime + mThrottleInterval) {
- if (mBuffer.limit() > 0 && mBuffer.limit() < mBuffer.capacity()) {
- // mBuffer has data.
- return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
+ if (mContentSize > 0) {
+ return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer()
+ .order(ByteOrder.nativeOrder());
}
return null;
}
mLastReadTime = SystemClock.elapsedRealtime();
- mBuffer.clear();
+ mContentSize = 0;
final int oldMask = StrictMode.allowThreadDiskReadsMask();
- try (FileChannel fc = FileChannel.open(mProc, StandardOpenOption.READ)) {
- while (fc.read(mBuffer) == mBuffer.capacity()) {
- if (!resize()) {
- mErrors++;
- Slog.e(TAG, "Proc file is too large: " + mProc);
- return null;
+ try (InputStream in = Files.newInputStream(mProc)) {
+ int numBytes = 0;
+ int curr;
+ while ((curr = in.read(mBuffer, numBytes, mBuffer.length - numBytes)) >= 0) {
+ numBytes += curr;
+ if (numBytes == mBuffer.length) {
+ // Hit the limit. Resize mBuffer.
+ if (mBuffer.length == MAX_BUFFER_SIZE) {
+ mErrors++;
+ Slog.e(TAG, "Proc file is too large: " + mProc);
+ return null;
+ }
+ mBuffer = Arrays.copyOf(mBuffer,
+ Math.min(mBuffer.length << 1, MAX_BUFFER_SIZE));
}
- fc.position(0);
}
+ mContentSize = numBytes;
+ return ByteBuffer.wrap(mBuffer, 0, mContentSize).asReadOnlyBuffer()
+ .order(ByteOrder.nativeOrder());
} catch (NoSuchFileException | FileNotFoundException e) {
// Happens when the kernel does not provide this file. Not a big issue. Just log it.
mErrors++;
Slog.w(TAG, "File not exist: " + mProc);
- return null;
} catch (IOException e) {
mErrors++;
Slog.e(TAG, "Error reading: " + mProc, e);
- return null;
} finally {
StrictMode.setThreadPolicyMask(oldMask);
}
- mBuffer.flip();
- return mBuffer.asReadOnlyBuffer().order(ByteOrder.nativeOrder());
+ return null;
}
/**
@@ -153,14 +159,4 @@
mThrottleInterval = throttleInterval;
}
}
-
- private boolean resize() {
- if (mBuffer.capacity() >= MAX_BUFFER_SIZE) {
- return false;
- }
- int newSize = Math.min(mBuffer.capacity() << 1, MAX_BUFFER_SIZE);
- // Slog.i(TAG, "Resize buffer " + mBuffer.capacity() + " => " + newSize);
- mBuffer = ByteBuffer.allocateDirect(newSize);
- return true;
- }
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cda1293..42bbe20 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -995,7 +995,7 @@
<!-- Allows a calling application which manages it own calls through the self-managed
{@link android.telecom.ConnectionService} APIs. See
- {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED for more information on the
+ {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED} for more information on the
self-managed ConnectionService APIs.
<p>Protection level: normal
-->
@@ -1080,9 +1080,9 @@
android:priority="700" />
<!-- Required to be able to access the camera device.
- <p>This will automatically enforce the <a
- href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
- <uses-feature>}</a> manifest element for <em>all</em> camera features.
+ <p>This will automatically enforce the
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">
+ uses-feature</a> manifest element for <em>all</em> camera features.
If you do not require all camera features or can properly operate if a camera
is not available, then you must modify your manifest as appropriate in order to
install on devices that don't support all camera features.</p>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 21c10ce..6b5a914 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1423,7 +1423,7 @@
at {@link android.view.inputmethod.InputConnection#performEditorAction(int)
InputConnection.performEditorAction(int)}.
<p>Corresponds to
- {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_FULLSCREEN}. -->
+ {@link android.view.inputmethod.EditorInfo#IME_FLAG_NAVIGATE_PREVIOUS}. -->
<flag name="flagNavigatePrevious" value="0x4000000" />
<!-- Used to specify that there is something
interesting that a forward navigation can focus on. This is like using
@@ -4166,9 +4166,9 @@
row is full. The rowCount attribute may be used similarly in the vertical case.
The default is horizontal. -->
<attr name="orientation" />
- <!-- The maxmimum number of rows to create when automatically positioning children. -->
+ <!-- The maximum number of rows to create when automatically positioning children. -->
<attr name="rowCount" format="integer" />
- <!-- The maxmimum number of columns to create when automatically positioning children. -->
+ <!-- The maximum number of columns to create when automatically positioning children. -->
<attr name="columnCount" format="integer" />
<!-- When set to true, tells GridLayout to use default margins when none are specified
in a view's layout parameters.
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a9d69c1..a10c197 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1873,6 +1873,10 @@
truncate it after committing the transaction. -->
<integer name="db_journal_size_limit">524288</integer>
+ <!-- When opening a database with WAL enabled and if the wal file already exists and larger
+ than this size in bytes, we'll truncate it. -->
+ <integer name="db_wal_truncate_size">1048576</integer>
+
<!-- The database synchronization mode when using the default journal mode.
FULL is safest and preserves durability at the cost of extra fsyncs.
NORMAL also preserves durability in non-WAL modes and uses checksums to ensure
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a3ed1b0..95af9a6 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3415,4 +3415,6 @@
<java-symbol type="string" name="config_misprovisionedDeviceModel" />
<java-symbol type="string" name="config_misprovisionedBrandValue" />
+
+ <java-symbol type="integer" name="db_wal_truncate_size" />
</resources>
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteCompatibilityWalFlagsTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteCompatibilityWalFlagsTest.java
index 230655d..551a58e 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteCompatibilityWalFlagsTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteCompatibilityWalFlagsTest.java
@@ -62,18 +62,24 @@
assertTrue(SQLiteCompatibilityWalFlags.areFlagsSet());
assertFalse(SQLiteCompatibilityWalFlags.isCompatibilityWalSupported());
assertEquals("OFF", SQLiteCompatibilityWalFlags.getWALSyncMode());
+ assertEquals(-1, SQLiteCompatibilityWalFlags.getTruncateSize());
SQLiteCompatibilityWalFlags.init("wal_syncmode=VALUE");
assertTrue(SQLiteCompatibilityWalFlags.areFlagsSet());
assertEquals(SQLiteGlobal.isCompatibilityWalSupported(),
SQLiteCompatibilityWalFlags.isCompatibilityWalSupported());
assertEquals("VALUE", SQLiteCompatibilityWalFlags.getWALSyncMode());
+ assertEquals(-1, SQLiteCompatibilityWalFlags.getTruncateSize());
SQLiteCompatibilityWalFlags.init("compatibility_wal_supported=true");
assertTrue(SQLiteCompatibilityWalFlags.areFlagsSet());
assertEquals(SQLiteGlobal.getWALSyncMode(),
SQLiteCompatibilityWalFlags.getWALSyncMode());
assertTrue(SQLiteCompatibilityWalFlags.isCompatibilityWalSupported());
+ assertEquals(-1, SQLiteCompatibilityWalFlags.getTruncateSize());
+
+ SQLiteCompatibilityWalFlags.init("truncate_size=1024");
+ assertEquals(1024, SQLiteCompatibilityWalFlags.getTruncateSize());
SQLiteCompatibilityWalFlags.reset();
SQLiteCompatibilityWalFlags.init("Invalid value");
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 616fb2c..c4a3b7a 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -67,7 +67,6 @@
Settings.System.LOCKSCREEN_DISABLED, // ?
Settings.System.MEDIA_BUTTON_RECEIVER, // candidate for backup?
Settings.System.MUTE_STREAMS_AFFECTED, // candidate for backup?
- Settings.System.NOTIFICATION_LIGHT_PULSE, // candidate for backup?
Settings.System.NOTIFICATION_SOUND_CACHE, // internal cache
Settings.System.POINTER_LOCATION, // backup candidate?
Settings.System.RINGTONE_CACHE, // internal cache
@@ -554,10 +553,8 @@
Settings.Secure.LAST_SETUP_SHOWN,
Settings.Secure.LOCATION_CHANGER,
Settings.Secure.LOCATION_MODE,
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, // Candidate?
Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT, // Candidate?
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, // Candidate?
Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
Settings.Secure.MULTI_PRESS_TIMEOUT,
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index a6099be..74eb445 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -21,9 +21,9 @@
/**
* A class indicating the application criteria for selecting a
- * location provider. Providers maybe ordered according to accuracy,
- * power usage, ability to report altitude, speed,
- * and bearing, and monetary cost.
+ * location provider. Providers may be ordered according to accuracy,
+ * power usage, ability to report altitude, speed, bearing, and monetary
+ * cost.
*/
public class Criteria implements Parcelable {
/**
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 54800ae..2c67f32 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -467,7 +467,7 @@
* .setSampleRate(32000)
* .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
* .build())
- * .setBufferSize(2*minBuffSize)
+ * .setBufferSizeInBytes(2*minBuffSize)
* .build();
* </pre>
* <p>
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index d532e52..97d0a6e 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -335,7 +335,7 @@
*
* <table border="0" cellspacing="0" cellpadding="0">
* <tr><td>Method Name </p></td>
- * <td>Valid Sates </p></td>
+ * <td>Valid States </p></td>
* <td>Invalid States </p></td>
* <td>Comments </p></td></tr>
* <tr><td>attachAuxEffect </p></td>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 745d6fc..c979ff5 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"La configuració de la VPN no està disponible per a aquest usuari."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"La configuració de compartició de xarxa no està disponible per a aquest usuari."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"La configuració del nom del punt d\'accés no està disponible per a aquest usuari."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Depuració USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Depuració per USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Activa el mode de depuració quan el dispositiu estigui connectat per USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració per USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Drecera per a informe d\'errors"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Mostra un botó al menú d\'engegada per crear un informe d\'errors"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla sempre activa"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Inspecció d\'atributs de visualització"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén les dades mòbils sempre actives, fins i tot quan la Wi‑Fi està activada (per canviar de xarxa ràpidament)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Fes servir l\'acceleració per maquinari per compartir la xarxa, si està disponible"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració USB?"</string>
- <string name="adb_warning_message" msgid="7316799925425402244">"La depuració USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració d\'USB dels ordinadors que has autoritzat anteriorment?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració per USB?"</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"La depuració per USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració per USB dels ordinadors que has autoritzat anteriorment?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Vols permetre la conf. de desenvolupament?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Aquesta configuració només està prevista per a usos de desenvolupament. Pot fer que el dispositiu i que les aplicacions s\'interrompin o tinguin un comportament inadequat."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica aplicacions per USB"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index cf011d5..b586bdf 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"Nastavení sítě VPN pro tohoto uživatele není dostupné."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"Nastavení sdíleného připojení pro tohoto uživatele není dostupné."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"Nastavení přístupového bodu pro tohoto uživatele není dostupné."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Ladění USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Ladění přes USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Povolit režim ladění s připojeným zařízením USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění přes USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Zástupce hlášení chyb"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Zobrazit v hlavní nabídce tlačítko k vygenerování chybového hlášení"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Nevypínat obrazovku"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atributu zobrazení"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilní data budou vždy ponechána aktivní, i když bude aktivní Wi-Fi (za účelem rychlého přepínání sítí)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Pokud je k dispozici hardwarová akceleraci tetheringu, použít ji"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění USB?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění přes USB?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Ladění prostřednictvím rozhraní USB je určeno pouze pro účely vývoje. Použijte je ke kopírování dat mezi počítačem a zařízením, instalaci aplikací do zařízení bez upozornění a čtení dat protokolů."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění přes USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Povolit nastavení pro vývojáře?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Tato nastavení jsou určena pouze pro vývojáře. Mohou způsobit rozbití nebo nesprávné fungování zařízení a nainstalovaných aplikací."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ověřit aplikace z USB"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 0f670b4..fb9df2b 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -196,7 +196,7 @@
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Vis en knap til oprettelse af fejlrapporter i menu for slukknap"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Lås ikke"</string>
<string name="keep_screen_on_summary" msgid="2173114350754293009">"Skærmen går ikke i dvale under opladning"</string>
- <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivér Bluetooth HCI snoop log"</string>
+ <string name="bt_hci_snoop_log" msgid="3340699311158865670">"Aktivér Bluetooth HCI spionlog"</string>
<string name="bt_hci_snoop_log_summary" msgid="366083475849911315">"Gem alle Bluetooth HCI-pakker i en fil (slå Bluetooth fra og til igen, når du har ændret denne indstilling)"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"OEM-oplåsning"</string>
<string name="oem_unlock_enable_summary" msgid="4720281828891618376">"Tillad, at startindlæseren låses op"</string>
@@ -388,8 +388,8 @@
<string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Denne tablet lukker muligvis snart ned (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Enheden lukker muligvis snart ned (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
- <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> til det er fuldt opladet"</string>
- <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til det er fuldt opladet"</string>
+ <string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"fuldt opladet om <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – fuldt opladet om <xliff:g id="TIME">%2$s</xliff:g>"</string>
<string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string>
<string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string>
<string name="battery_info_status_charging_lower" msgid="8689770213898117994">"oplader"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 7fc5e4c..3b1d7f5 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -350,7 +350,7 @@
<string name="runningservices_settings_summary" msgid="854608995821032748">"Momentan ausgeführte Dienste anzeigen und steuern"</string>
<string name="select_webview_provider_title" msgid="4628592979751918907">"WebView-Implementierung"</string>
<string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"WebView-Implementierung festlegen"</string>
- <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Diese Auswahl ist nicht mehr gültig. Versuche es erneut."</string>
+ <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Diese Auswahl ist nicht mehr gültig. Bitte versuche es noch einmal."</string>
<string name="convert_to_file_encryption" msgid="3060156730651061223">"Zu Dateiverschlüsselung wechseln"</string>
<string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Wechseln…"</string>
<string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Dateiverschlüsselung wird bereits verwendet."</string>
@@ -381,12 +381,12 @@
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Weniger als <xliff:g id="THRESHOLD">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_only_more_than_subtext" msgid="8931654680569617380">"Mehr als <xliff:g id="TIME_REMAINING">%1$s</xliff:g> verbleibend"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Smartphone wird möglicherweise bald ausgeschaltet"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet wird möglicherweise bald ausgeschaltet"</string>
- <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Gerät wird möglicherweise bald ausgeschaltet"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Smartphone wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
- <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Gerät wird möglicherweise bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="default" msgid="1181059207608751924">"Smartphone wird eventuell bald ausgeschaltet"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="tablet" msgid="2606370266981054691">"Tablet wird eventuell bald ausgeschaltet"</string>
+ <string name="power_remaining_duration_only_shutdown_imminent" product="device" msgid="2918084807716859985">"Gerät wird eventuell bald ausgeschaltet"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="default" msgid="3090926004324573908">"Smartphone wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="tablet" msgid="7466484148515796216">"Tablet wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
+ <string name="power_remaining_duration_shutdown_imminent" product="device" msgid="603933521600231649">"Gerät wird eventuell bald ausgeschaltet (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="1421102457410268886">"<xliff:g id="TIME">%1$s</xliff:g> bis zur vollständigen Aufladung"</string>
<string name="power_charging_duration" msgid="4676999980973411875">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> bis vollständig geladen"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index a9c164b..5a1ffa8 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -242,7 +242,7 @@
<string name="select_logd_size_dialog_title" msgid="1206769310236476760">"Elige el tamaño del Logger por búfer"</string>
<string name="dev_logpersist_clear_warning_title" msgid="684806692440237967">"¿Borrar almacenamiento continuo del registrador?"</string>
<string name="dev_logpersist_clear_warning_message" msgid="2256582531342994562">"Cuando ya no supervisamos la actividad con el registrador de forma continua, estamos obligados a borrar los datos del registrador almacenados en el dispositivo."</string>
- <string name="select_logpersist_title" msgid="7530031344550073166">"Guardar datos de forma continua"</string>
+ <string name="select_logpersist_title" msgid="7530031344550073166">"Guardar datos de registro de forma continua"</string>
<string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Seleccionar búferes de registro para guardarlos de forma continua en dispositivo"</string>
<string name="select_usb_configuration_title" msgid="2649938511506971843">"Seleccionar configuración de USB"</string>
<string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Seleccionar configuración de USB"</string>
@@ -398,7 +398,7 @@
<string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string>
<string name="disabled_by_admin_summary_text" msgid="6750513964908334617">"Controlada por el administrador"</string>
<string name="enabled_by_admin" msgid="5302986023578399263">"Habilitada por el administrador"</string>
- <string name="disabled_by_admin" msgid="8505398946020816620">"Inhabilitada por el administrador"</string>
+ <string name="disabled_by_admin" msgid="8505398946020816620">"Inhabilitado por el administrador"</string>
<string name="disabled" msgid="9206776641295849915">"Inhabilitada"</string>
<string name="external_source_trusted" msgid="2707996266575928037">"Autorizadas"</string>
<string name="external_source_untrusted" msgid="2677442511837596726">"No autorizadas"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 4c4f99f..8542f90 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -165,7 +165,7 @@
<string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> motorraren ezarpenak"</string>
<string name="tts_engine_settings_button" msgid="1030512042040722285">"Abiarazi motorraren ezarpenak"</string>
<string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor hobetsia"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorra"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorrak"</string>
<string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Berrezarri ahots-tonua"</string>
<string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Berrezarri testua esateko ahots-tonu lehenetsia."</string>
<string-array name="tts_rate_entries">
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index eb03b53..6b0690e 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -246,7 +246,7 @@
<string name="select_logpersist_dialog_title" msgid="4003400579973269060">"Sélectionner les mémoires tampon journal à stocker en permanence sur l\'appareil"</string>
<string name="select_usb_configuration_title" msgid="2649938511506971843">"Sélectionner une configuration USB"</string>
<string name="select_usb_configuration_dialog_title" msgid="6385564442851599963">"Sélectionner une configuration USB"</string>
- <string name="allow_mock_location" msgid="2787962564578664888">"Positions fictives"</string>
+ <string name="allow_mock_location" msgid="2787962564578664888">"Autoriser les positions fictives"</string>
<string name="allow_mock_location_summary" msgid="317615105156345626">"Autoriser les positions fictives"</string>
<string name="debug_view_attributes" msgid="6485448367803310384">"Activer inspect. attribut affich."</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Maintenir les données mobiles à l\'état actif, même lorsque le Wi‑Fi est actif (pour changer rapidement de réseau)"</string>
@@ -373,10 +373,10 @@
<string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="3463575350656389957">"Temps restant : <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation"</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 9430345..9d6f9ac 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -22,7 +22,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="wifi_fail_to_scan" msgid="1265540342578081461">"नेटवर्क के लिए स्कैन नहीं कर सकता"</string>
<string name="wifi_security_none" msgid="7985461072596594400">"कोई नहीं"</string>
- <string name="wifi_remembered" msgid="4955746899347821096">"सहेजा गया"</string>
+ <string name="wifi_remembered" msgid="4955746899347821096">"सेव किया गया"</string>
<string name="wifi_disabled_generic" msgid="4259794910584943386">"अक्षम"</string>
<string name="wifi_disabled_network_failure" msgid="2364951338436007124">"IP कॉन्फ़िगरेशन की विफलता"</string>
<string name="wifi_disabled_by_recommendation_provider" msgid="5168315140978066096">"खराब नेटवर्क होने के कारण कनेक्ट नहीं हुआ"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 17009dc..4a5410c 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -281,7 +281,7 @@
<string name="strict_mode_summary" msgid="142834318897332338">"Kedipkan layar saat apl beroperasi lama pada utas utama"</string>
<string name="pointer_location" msgid="6084434787496938001">"Lokasi penunjuk"</string>
<string name="pointer_location_summary" msgid="840819275172753713">"Hamparan layar menampilkan data sentuhan saat ini"</string>
- <string name="show_touches" msgid="2642976305235070316">"Tampilkan ketukan"</string>
+ <string name="show_touches" msgid="2642976305235070316">"Tampilkan tap"</string>
<string name="show_touches_summary" msgid="6101183132903926324">"Tampilkan masukan visual untuk ketukan"</string>
<string name="show_screen_updates" msgid="5470814345876056420">"Lihat pembaruan permukaan"</string>
<string name="show_screen_updates_summary" msgid="2569622766672785529">"Sorot seluruh permukaan jendela saat diperbarui"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 0aa80e7..a7f3624 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -135,7 +135,7 @@
<string name="tether_settings_title_usb_bluetooth" msgid="5355828977109785001">"테더링"</string>
<string name="tether_settings_title_all" msgid="8356136101061143841">"테더링 및 휴대용 핫스팟"</string>
<string name="managed_user_title" msgid="8109605045406748842">"모든 직장 앱"</string>
- <string name="user_guest" msgid="8475274842845401871">"손님"</string>
+ <string name="user_guest" msgid="8475274842845401871">"게스트"</string>
<string name="unknown" msgid="1592123443519355854">"알 수 없음"</string>
<string name="running_process_item_user_label" msgid="3129887865552025943">"사용자: <xliff:g id="USER_NAME">%1$s</xliff:g>"</string>
<string name="launch_defaults_some" msgid="313159469856372621">"일부 기본값이 설정됨"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 6dec8df..399dc5d 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -102,7 +102,7 @@
<string name="bluetooth_pairing_accept" msgid="6163520056536604875">"Koppelen"</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="6061699265220789149">"KOPPELEN"</string>
<string name="bluetooth_pairing_decline" msgid="4185420413578948140">"Annuleren"</string>
- <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Koppelen verleent toegang tot je contacten en oproepgeschiedenis wanneer de apparaten zijn verbonden."</string>
+ <string name="bluetooth_pairing_will_share_phonebook" msgid="4982239145676394429">"Koppelen verleent toegang tot je contacten en gespreksgeschiedenis wanneer de apparaten zijn verbonden."</string>
<string name="bluetooth_pairing_error_message" msgid="3748157733635947087">"Kan niet koppelen aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="bluetooth_pairing_pin_error_message" msgid="8337234855188925274">"Kan niet koppelen aan <xliff:g id="DEVICE_NAME">%1$s</xliff:g> vanwege een onjuiste pincode of toegangscode."</string>
<string name="bluetooth_pairing_device_down_error_message" msgid="7870998403045801381">"Kan niet communiceren met <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
@@ -373,10 +373,10 @@
<string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> resterend op basis van je gebruik"</string>
<string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Ongeveer <xliff:g id="TIME_REMAINING">%1$s</xliff:g> resterend op basis van je gebruik (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_duration_only_short" msgid="3463575350656389957">"<xliff:g id="TIME_REMAINING">%1$s</xliff:g> resterend"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Is nog genoeg voor ongeveer <xliff:g id="TIME">%1$s</xliff:g> op basis van je gebruik (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Is nog genoeg voor ongeveer <xliff:g id="TIME">%1$s</xliff:g> op basis van je gebruik"</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"Is nog genoeg voor ongeveer <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Is nog genoeg voor ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g> op basis van je gebruik (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g> op basis van je gebruik"</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Is nog genoeg tot ongeveer <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> resterend"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Minder dan <xliff:g id="THRESHOLD">%1$s</xliff:g> resterend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Meer dan <xliff:g id="TIME_REMAINING">%1$s</xliff:g> resterend (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
@@ -417,7 +417,7 @@
<string name="screen_zoom_summary_very_large" msgid="7108563375663670067">"Groter"</string>
<string name="screen_zoom_summary_extremely_large" msgid="7427320168263276227">"Grootst"</string>
<string name="screen_zoom_summary_custom" msgid="5611979864124160447">"Aangepast (<xliff:g id="DENSITYDPI">%d</xliff:g>)"</string>
- <string name="help_feedback_label" msgid="6815040660801785649">"Help en feedback"</string>
+ <string name="help_feedback_label" msgid="6815040660801785649">"Hulp en feedback"</string>
<string name="content_description_menu_button" msgid="8182594799812351266">"Menu"</string>
<string name="retail_demo_reset_message" msgid="118771671364131297">"Geef wachtwoord op om terug te zetten op fabrieksinstellingen in demomodus"</string>
<string name="retail_demo_reset_next" msgid="8356731459226304963">"Volgende"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 8d5dbe1..548176f 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -77,7 +77,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
<string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
<string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensagens de texto"</string>
- <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
+ <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso ao chip"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Aparelho auditivo"</string>
@@ -93,7 +93,7 @@
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"Compartilhamento de conexão local de Internet c/ disposit."</string>
<string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Usar para acesso à Internet"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Usar para mapa"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use para acesso SIM"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use para acesso ao chip"</string>
<string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Usar para áudio de mídia"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Usar para áudio do smartphone"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Usado para transferência de arquivo"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 8d5dbe1..548176f 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -77,7 +77,7 @@
<string name="bluetooth_profile_pbap_summary" msgid="6605229608108852198">"Usar para compartilhamento de contatos"</string>
<string name="bluetooth_profile_pan_nap" msgid="8429049285027482959">"Compartilhamento de conexão à Internet"</string>
<string name="bluetooth_profile_map" msgid="1019763341565580450">"Mensagens de texto"</string>
- <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso SIM"</string>
+ <string name="bluetooth_profile_sap" msgid="5764222021851283125">"Acesso ao chip"</string>
<string name="bluetooth_profile_a2dp_high_quality" msgid="5444517801472820055">"Áudio HD: <xliff:g id="CODEC_NAME">%1$s</xliff:g>"</string>
<string name="bluetooth_profile_a2dp_high_quality_unknown_codec" msgid="8510588052415438887">"Áudio HD"</string>
<string name="bluetooth_profile_hearing_aid" msgid="7999237886427812595">"Aparelho auditivo"</string>
@@ -93,7 +93,7 @@
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="1322694224800769308">"Compartilhamento de conexão local de Internet c/ disposit."</string>
<string name="bluetooth_pan_profile_summary_use_for" msgid="5736111170225304239">"Usar para acesso à Internet"</string>
<string name="bluetooth_map_profile_summary_use_for" msgid="5154200119919927434">"Usar para mapa"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use para acesso SIM"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="7085362712786907993">"Use para acesso ao chip"</string>
<string name="bluetooth_a2dp_profile_summary_use_for" msgid="4630849022250168427">"Usar para áudio de mídia"</string>
<string name="bluetooth_headset_profile_summary_use_for" msgid="8705753622443862627">"Usar para áudio do smartphone"</string>
<string name="bluetooth_opp_profile_summary_use_for" msgid="1255674547144769756">"Usado para transferência de arquivo"</string>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index e4a341a..7935a2a 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -22,7 +22,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="wifi_status">
<item msgid="1922181315419294640"></item>
- <item msgid="8934131797783724664">"În curs de scanare..."</item>
+ <item msgid="8934131797783724664">"Se caută..."</item>
<item msgid="8513729475867537913">"Se conectează..."</item>
<item msgid="515055375277271756">"În curs de autentificare…"</item>
<item msgid="1943354004029184381">"Se obține adresa IP..."</item>
@@ -36,7 +36,7 @@
</string-array>
<string-array name="wifi_status_with_ssid">
<item msgid="7714855332363650812"></item>
- <item msgid="8878186979715711006">"În curs de scanare..."</item>
+ <item msgid="8878186979715711006">"Se caută..."</item>
<item msgid="355508996603873860">"Se conectează la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>..."</item>
<item msgid="554971459996405634">"Se autentifică cu <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
<item msgid="7928343808033020343">"Se obține adresa IP de la <xliff:g id="NETWORK_NAME">%1$s</xliff:g>…"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 9293148..4df9408 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -308,8 +308,8 @@
<string name="track_frame_time" msgid="6146354853663863443">"Profilens GPU-rendering"</string>
<string name="enable_gpu_debug_layers" msgid="3848838293793255097">"Aktivera GPU-felsökningslager"</string>
<string name="enable_gpu_debug_layers_summary" msgid="8009136940671194940">"Tillåt att felsökningsappar läser in GPU-felsökningslager"</string>
- <string name="window_animation_scale_title" msgid="6162587588166114700">"Skala, fönsteranimering"</string>
- <string name="transition_animation_scale_title" msgid="387527540523595875">"Skala, övergångsanimering"</string>
+ <string name="window_animation_scale_title" msgid="6162587588166114700">"Skala – fönsteranimering"</string>
+ <string name="transition_animation_scale_title" msgid="387527540523595875">"Skala – övergångsanimering"</string>
<string name="animator_duration_scale_title" msgid="3406722410819934083">"Längdskala för Animator"</string>
<string name="overlay_display_devices_title" msgid="5364176287998398539">"Simulera sekundär skärm"</string>
<string name="debug_applications_category" msgid="4206913653849771549">"Appar"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index bb8fbe2..1a8e24f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -143,8 +143,8 @@
void onProfileStateChanged(LocalBluetoothProfile profile, int newProfileState) {
if (Utils.D) {
- Log.d(TAG, "onProfileStateChanged: profile " + profile +
- " newProfileState " + newProfileState);
+ Log.d(TAG, "onProfileStateChanged: profile " + profile + ", device=" + mDevice
+ + ", newProfileState " + newProfileState);
}
if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_TURNING_OFF)
{
@@ -224,6 +224,10 @@
connectWithoutResettingTimer(connectAllProfiles);
}
+ public boolean isHearingAidDevice() {
+ return mHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID;
+ }
+
void onBondingDockConnect() {
// Attempt to connect if UUIDs are available. Otherwise,
// we will connect when the ACTION_UUID intent arrives.
@@ -1189,7 +1193,8 @@
* @return {@code true} if {@code cachedBluetoothDevice} is a2dp device
*/
public boolean isA2dpDevice() {
- return mProfileManager.getA2dpProfile().getConnectionStatus(mDevice) ==
+ A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ return a2dpProfile != null && a2dpProfile.getConnectionStatus(mDevice) ==
BluetoothProfile.STATE_CONNECTED;
}
@@ -1197,7 +1202,17 @@
* @return {@code true} if {@code cachedBluetoothDevice} is HFP device
*/
public boolean isHfpDevice() {
- return mProfileManager.getHeadsetProfile().getConnectionStatus(mDevice) ==
+ HeadsetProfile headsetProfile = mProfileManager.getHeadsetProfile();
+ return headsetProfile != null && headsetProfile.getConnectionStatus(mDevice) ==
+ BluetoothProfile.STATE_CONNECTED;
+ }
+
+ /**
+ * @return {@code true} if {@code cachedBluetoothDevice} is Hearing Aid device
+ */
+ public boolean isConnectedHearingAidDevice() {
+ HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile();
+ return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) ==
BluetoothProfile.STATE_CONNECTED;
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index e9d96ae..1bfcf9a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -162,14 +162,14 @@
*/
public synchronized String getHearingAidPairDeviceSummary(CachedBluetoothDevice device) {
String pairDeviceSummary = null;
- if (device.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
- for (CachedBluetoothDevice hearingAidDevice : mHearingAidDevicesNotAddedInCache) {
- if (hearingAidDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID
- && hearingAidDevice.getHiSyncId() == device.getHiSyncId()) {
- pairDeviceSummary = hearingAidDevice.getConnectionSummary();
- }
- }
+ CachedBluetoothDevice otherHearingAidDevice =
+ getHearingAidOtherDevice(device, device.getHiSyncId());
+ if (otherHearingAidDevice != null) {
+ pairDeviceSummary = otherHearingAidDevice.getConnectionSummary();
}
+ log("getHearingAidPairDeviceSummary: pairDeviceSummary=" + pairDeviceSummary
+ + ", otherHearingAidDevice=" + otherHearingAidDevice);
+
return pairDeviceSummary;
}
@@ -358,7 +358,7 @@
}
}
- private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
+ public CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice,
long hiSyncId) {
if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
return null;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 62f8724..7ff5448 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -123,6 +123,14 @@
ParcelUuid[] uuids = adapter.getUuids();
+ List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
+ if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
+ mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
+ this);
+ addProfile(mHearingAidProfile, HearingAidProfile.NAME,
+ BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ }
+
// uuids may be null if Bluetooth is turned off
if (uuids != null) {
updateLocalProfiles(uuids);
@@ -159,13 +167,6 @@
addProfile(mPbapProfile, PbapServerProfile.NAME,
BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED);
- List<Integer> supportedList = mLocalAdapter.getSupportedProfiles();
- if (supportedList.contains(BluetoothProfile.HEARING_AID)) {
- mHearingAidProfile = new HearingAidProfile(mContext, mLocalAdapter, mDeviceManager,
- this);
- addProfile(mHearingAidProfile, HearingAidProfile.NAME,
- BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
- }
if (DEBUG) Log.d(TAG, "LocalBluetoothProfileManager construction complete");
}
@@ -360,9 +361,10 @@
Log.i(TAG, "Failed to connect " + mProfile + " device");
}
- if (getHearingAidProfile() != null &&
- mProfile instanceof HearingAidProfile &&
- (newState == BluetoothProfile.STATE_CONNECTED)) {
+ boolean isHearingAidProfile = (getHearingAidProfile() != null) &&
+ (mProfile instanceof HearingAidProfile);
+
+ if (isHearingAidProfile && (newState == BluetoothProfile.STATE_CONNECTED)) {
// Check if the HiSyncID has being initialized
if (cachedDevice.getHiSyncId() == BluetoothHearingAid.HI_SYNC_ID_INVALID) {
@@ -375,10 +377,22 @@
}
}
- mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
- mProfile.getProfileId());
cachedDevice.onProfileStateChanged(mProfile, newState);
cachedDevice.refresh();
+
+ if (isHearingAidProfile) {
+ CachedBluetoothDevice otherDevice =
+ mDeviceManager.getHearingAidOtherDevice(cachedDevice, cachedDevice.getHiSyncId());
+ if (otherDevice != null) {
+ if (DEBUG) {
+ Log.d(TAG, "Refreshing other hearing aid=" + otherDevice
+ + ", newState=" + newState);
+ }
+ otherDevice.refresh();
+ }
+ }
+ mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
+ mProfile.getProfileId());
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index 16ed85c..db9b44f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -835,4 +835,20 @@
assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
}
+
+ /**
+ * Test to verify getHearingAidOtherDevice() for hearing aid devices with same HiSyncId.
+ */
+ @Test
+ public void testGetHearingAidOtherDevice_bothHearingAidsPaired_returnsOtherDevice() {
+ mCachedDevice1.setHiSyncId(HISYNCID1);
+ mCachedDevice2.setHiSyncId(HISYNCID1);
+ mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
+ mCachedDeviceManager.mHearingAidDevicesNotAddedInCache.add(mCachedDevice2);
+ doAnswer((invocation) -> DEVICE_SUMMARY_1).when(mCachedDevice1).getConnectionSummary();
+ doAnswer((invocation) -> DEVICE_SUMMARY_2).when(mCachedDevice2).getConnectionSummary();
+
+ assertThat(mCachedDeviceManager.getHearingAidOtherDevice(mCachedDevice1, HISYNCID1))
+ .isEqualTo(mCachedDevice2);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 927a94f..30da882 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -28,6 +28,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioManager;
@@ -572,4 +573,55 @@
assertThat(mCachedDevice.isHfpDevice()).isFalse();
}
+
+ @Test
+ public void isConnectedHearingAidDevice_connected_returnTrue() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mHearingAidProfile.getConnectionStatus(mDevice)).
+ thenReturn(BluetoothProfile.STATE_CONNECTED);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue();
+ }
+
+ @Test
+ public void isConnectedHearingAidDevice_disconnected_returnFalse() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
+ when(mHearingAidProfile.getConnectionStatus(mDevice)).
+ thenReturn(BluetoothProfile.STATE_DISCONNECTED);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedHfpDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getHeadsetProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isHfpDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedA2dpDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getA2dpProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isA2dpDevice()).isFalse();
+ }
+
+ @Test
+ public void isConnectedHearingAidDevice_profileIsNull_returnFalse() {
+ when(mProfileManager.getHearingAidProfile()).thenReturn(null);
+
+ assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse();
+ }
+
+ @Test
+ public void testIsHearingAidDevice_isHearingAidDevice() {
+ mCachedDevice.setHiSyncId(0x1234);
+ assertThat(mCachedDevice.isHearingAidDevice()).isTrue();
+ }
+
+ @Test
+ public void testIsHearingAidDevice_isNotHearingAidDevice() {
+ mCachedDevice.setHiSyncId(BluetoothHearingAid.HI_SYNC_ID_INVALID);
+ assertThat(mCachedDevice.isHearingAidDevice()).isFalse();
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index d342bc8..d7b651b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -52,6 +53,7 @@
@RunWith(RobolectricTestRunner.class)
@Config(resourceDir = "../../res")
public class LocalBluetoothProfileManagerTest {
+ private final static long HI_SYNC_ID = 0x1234;
@Mock
private CachedBluetoothDeviceManager mDeviceManager;
@Mock
@@ -62,6 +64,8 @@
private BluetoothDevice mDevice;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock
+ private CachedBluetoothDevice mHearingAidOtherDevice;
private Context mContext;
private LocalBluetoothProfileManager mProfileManager;
@@ -200,6 +204,32 @@
}
/**
+ * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+ * refresh both sides devices.
+ */
+ @Test
+ public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldRefreshBothSides() {
+ ArrayList<Integer> supportProfiles = new ArrayList<>();
+ supportProfiles.add(BluetoothProfile.HEARING_AID);
+ when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
+ when(mCachedBluetoothDevice.getHiSyncId()).thenReturn(HI_SYNC_ID);
+ when(mDeviceManager.getHearingAidOtherDevice(mCachedBluetoothDevice, HI_SYNC_ID))
+ .thenReturn(mHearingAidOtherDevice);
+
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mCachedBluetoothDevice).refresh();
+ verify(mHearingAidOtherDevice).refresh();
+ }
+
+ /**
* Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to
* profile connection state changed callback
*/
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index aa426d3..78b7385 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -53,12 +53,16 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
+import android.text.TextUtils;
+import android.util.FeatureFlagUtils;
+import android.util.Log;
import android.util.Slog;
import android.util.StatsLog;
@@ -386,6 +390,15 @@
mCallbacks = new RemoteCallbackList<IBluetoothManagerCallback>();
mStateChangeCallbacks = new RemoteCallbackList<IBluetoothStateChangeCallback>();
+ // TODO: We need a more generic way to initialize the persist keys of FeatureFlagUtils
+ boolean isHearingAidEnabled;
+ String value = SystemProperties.get(FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.HEARING_AID_SETTINGS);
+ if (!TextUtils.isEmpty(value)) {
+ isHearingAidEnabled = Boolean.parseBoolean(value);
+ Log.v(TAG, "set feature flag HEARING_AID_SETTINGS to " + isHearingAidEnabled);
+ FeatureFlagUtils.setEnabled(context, FeatureFlagUtils.HEARING_AID_SETTINGS, isHearingAidEnabled);
+ }
+
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_BLUETOOTH_ADDRESS_CHANGED);
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 9bf72fb..d14c1a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -67,6 +67,7 @@
static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration";
static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry";
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
+ static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000;
@@ -95,7 +96,7 @@
private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000;
private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16;
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
-
+ private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -207,6 +208,10 @@
// Indicates if the processes need to be started asynchronously.
public boolean FLAG_PROCESS_START_ASYNC = DEFAULT_PROCESS_START_ASYNC;
+ // Allow app just moving from TOP to FOREGROUND_SERVICE to stay in a higher adj value for
+ // this long.
+ public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
+
// Indicates whether the activity starts logging is enabled.
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
boolean mFlagActivityStartsLoggingEnabled;
@@ -348,6 +353,8 @@
DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY);
FLAG_PROCESS_START_ASYNC = mParser.getBoolean(KEY_PROCESS_START_ASYNC,
DEFAULT_PROCESS_START_ASYNC);
+ TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION,
+ DEFAULT_TOP_TO_FGS_GRACE_DURATION);
updateMaxCachedProcesses();
}
@@ -423,6 +430,8 @@
pw.println(MAX_SERVICE_INACTIVITY);
pw.print(" "); pw.print(KEY_BG_START_TIMEOUT); pw.print("=");
pw.println(BG_START_TIMEOUT);
+ pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("=");
+ pw.println(TOP_TO_FGS_GRACE_DURATION);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 2f1021a..145c1c9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -23390,6 +23390,19 @@
}
}
+ // If the app was recently in the foreground and moved to a foreground service status,
+ // allow it to get a higher rank in memory for some time, compared to other foreground
+ // services so that it can finish performing any persistence/processing of in-memory state.
+ if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+ && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
+ || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
+ adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+ app.adjType = "fg-service-act";
+ if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
+ reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
+ }
+ }
+
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
|| procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
if (app.forcingToImportant != null) {
@@ -23654,6 +23667,10 @@
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
procState = ActivityManager.PROCESS_STATE_PERSISTENT;
}
+ } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
+ && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
+ && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) {
+ newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1;
} else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
&& clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
&& adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -24624,6 +24641,8 @@
// Must be called before updating setProcState
maybeUpdateUsageStatsLocked(app, nowElapsed);
+ maybeUpdateLastTopTime(app, now);
+
app.setProcState = app.curProcState;
if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
app.notCachedSinceIdle = false;
@@ -24848,6 +24867,13 @@
}
}
+ private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
+ if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
+ && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
+ app.lastTopTime = nowUptime;
+ }
+ }
+
private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
if (proc.thread != null) {
if (proc.baseProcessTracker != null) {
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index f9dccea0..aad890b 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -22,6 +22,7 @@
import android.annotation.Nullable;
import android.os.FileUtils;
+import android.os.SystemProperties;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -38,6 +39,10 @@
final class MemoryStatUtil {
private static final String TAG = TAG_WITH_CLASS_NAME ? "MemoryStatUtil" : TAG_AM;
+ /** True if device has per-app memcg */
+ private static final Boolean DEVICE_HAS_PER_APP_MEMCG =
+ SystemProperties.getBoolean("ro.config.per_app_memcg", false);
+
/** Path to check if device has memcg */
private static final String MEMCG_TEST_PATH = "/dev/memcg/apps/memory.stat";
/** Path to memory stat file for logging app start memory state */
@@ -55,15 +60,12 @@
private static final int PGMAJFAULT_INDEX = 11;
private static final int RSS_IN_BYTES_INDEX = 23;
- /** True if device has memcg */
- private static volatile Boolean sDeviceHasMemCg;
-
private MemoryStatUtil() {}
/**
* Reads memory stat for a process.
*
- * Reads from memcg if available on device, else fallback to procfs.
+ * Reads from per-app memcg if available on device, else fallback to procfs.
* Returns null if no stats can be read.
*/
@Nullable
@@ -156,15 +158,10 @@
}
/**
- * Checks if memcg is available on device.
- *
- * Touches the filesystem to do the check.
+ * Returns whether per-app memcg is available on device.
*/
static boolean hasMemcg() {
- if (sDeviceHasMemCg == null) {
- sDeviceHasMemCg = (new File(MEMCG_TEST_PATH)).exists();
- }
- return sDeviceHasMemCg;
+ return DEVICE_HAS_PER_APP_MEMCG;
}
static final class MemoryStat {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 784d62e..3ac7885 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -104,6 +104,11 @@
static final int VISIBLE_APP_ADJ = 100;
static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
+ // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
+ // like a foreground app for a while.
+ // @see TOP_TO_FGS_GRACE_PERIOD
+ static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
+
// This is the process running the current foreground app. We'd really
// rather not kill it!
static final int FOREGROUND_APP_ADJ = 0;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 28ebbb8..e3e839f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -163,6 +163,7 @@
long lastRequestedGc; // When we last asked the app to do a gc
long lastLowMemory; // When we last told the app that memory is low
long lastProviderTime; // The last time someone else was using a provider in this process.
+ long lastTopTime; // The last time the process was in the TOP state or greater.
boolean reportLowMemory; // Set to true when waiting to report low mem
boolean empty; // Is this an empty background process?
boolean cached; // Is this a cached process?
@@ -380,6 +381,11 @@
TimeUtils.formatDuration(lastProviderTime, nowUptime, pw);
pw.println();
}
+ if (lastTopTime > 0) {
+ pw.print(prefix); pw.print("lastTopTime=");
+ TimeUtils.formatDuration(lastTopTime, nowUptime, pw);
+ pw.println();
+ }
if (hasStartedServices) {
pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 415a822..4746e12 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -845,10 +845,16 @@
}
void scheduleStartProfiles() {
- if (!mHandler.hasMessages(START_PROFILES_MSG)) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
- DateUtils.SECOND_IN_MILLIS);
- }
+ // Parent user transition to RUNNING_UNLOCKING happens on FgThread, so it is busy, there is
+ // a chance the profile will reach RUNNING_LOCKED while parent is still locked, so no
+ // attempt will be made to unlock the profile. If we go via FgThread, this will be executed
+ // after the parent had chance to unlock fully.
+ FgThread.getHandler().post(() -> {
+ if (!mHandler.hasMessages(START_PROFILES_MSG)) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
+ DateUtils.SECOND_IN_MILLIS);
+ }
+ });
}
void startProfiles() {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index f7becd5..30fa7fe 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -175,6 +175,10 @@
}
}
+ protected int getBindFlags() {
+ return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT;
+ }
+
protected void onServiceRemovedLocked(ManagedServiceInfo removed) { }
private ManagedServiceInfo newServiceInfo(IInterface service,
@@ -1022,9 +1026,9 @@
}
};
if (!mContext.bindServiceAsUser(intent,
- serviceConnection,
- BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT,
- new UserHandle(userid))) {
+ serviceConnection,
+ getBindFlags(),
+ new UserHandle(userid))) {
mServicesBinding.remove(servicesBindingTag);
Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
return;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 8304e26..b724716 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -33,6 +33,10 @@
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.content.Context.BIND_ADJUST_BELOW_PERCEPTIBLE;
+import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
+import static android.content.Context.BIND_AUTO_CREATE;
+import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -2295,8 +2299,9 @@
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(
String pkg) {
checkCallerIsSystemOrSameApp(pkg);
+
return mRankingHelper.getNotificationChannelGroups(
- pkg, Binder.getCallingUid(), false, false);
+ pkg, Binder.getCallingUid(), false, false, true);
}
@Override
@@ -2372,7 +2377,9 @@
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroupsForPackage(
String pkg, int uid, boolean includeDeleted) {
checkCallerIsSystem();
- return mRankingHelper.getNotificationChannelGroups(pkg, uid, includeDeleted, true);
+
+ return mRankingHelper.getNotificationChannelGroups(
+ pkg, uid, includeDeleted, true, false);
}
@Override
@@ -4251,13 +4258,6 @@
final String pkg = r.sbn.getPackageName();
final int callingUid = r.sbn.getUid();
- final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
- if (isPackageSuspended) {
- Slog.e(TAG, "Suppressing notification from package due to package "
- + "suspended by administrator.");
- usageStats.registerSuspendedByAdmin(r);
- return isPackageSuspended;
- }
final boolean isBlocked =
mRankingHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
|| mRankingHelper.getImportance(pkg, callingUid)
@@ -4266,8 +4266,9 @@
if (isBlocked) {
Slog.e(TAG, "Suppressing notification from package by user request.");
usageStats.registerBlocked(r);
+ return true;
}
- return isBlocked;
+ return false;
}
protected class SnoozeNotificationRunnable implements Runnable {
@@ -4445,7 +4446,11 @@
return;
}
- r.setHidden(isPackageSuspendedLocked(r));
+ final boolean isPackageSuspended = isPackageSuspendedLocked(r);
+ r.setHidden(isPackageSuspended);
+ if (isPackageSuspended) {
+ mUsageStats.registerSuspendedByAdmin(r);
+ }
NotificationRecord old = mNotificationsByKey.get(key);
final StatusBarNotification n = r.sbn;
final Notification notification = n.getNotification();
@@ -6521,6 +6526,16 @@
}
@Override
+ protected int getBindFlags() {
+ // Most of the same flags as the base, but also add BIND_ADJUST_BELOW_PERCEPTIBLE
+ // because too many 3P apps could be kept in memory as notification listeners and
+ // cause extreme memory pressure.
+ // TODO: Change the binding lifecycle of NotificationListeners to avoid this situation.
+ return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE
+ | BIND_ADJUST_BELOW_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT;
+ }
+
+ @Override
protected Config getConfig() {
Config c = new Config();
c.caption = "notification listener";
@@ -6611,7 +6626,6 @@
if (!oldSbnVisible && !sbnVisible) {
continue;
}
-
// If the notification is hidden, don't notifyPosted listeners targeting < P.
// Instead, those listeners will receive notifyPosted when the notification is
// unhidden.
@@ -7045,7 +7059,7 @@
new String[]{pkg});
final String action = suspend ? Intent.ACTION_PACKAGES_SUSPENDED
- : Intent.ACTION_PACKAGES_UNSUSPENDED;
+ : Intent.ACTION_PACKAGES_UNSUSPENDED;
final Intent intent = new Intent(action);
intent.putExtras(extras);
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index af64683..605348b 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -36,7 +36,7 @@
void createNotificationChannelGroup(String pkg, int uid, NotificationChannelGroup group,
boolean fromTargetApp);
ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
- int uid, boolean includeDeleted, boolean includeNonGrouped);
+ int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp, boolean hasDndAccess);
void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 61b5415..c96894b 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -830,7 +830,7 @@
@Override
public ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
- int uid, boolean includeDeleted, boolean includeNonGrouped) {
+ int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty) {
Preconditions.checkNotNull(pkg);
Map<String, NotificationChannelGroup> groups = new ArrayMap<>();
Record r = getRecord(pkg, uid);
@@ -861,6 +861,13 @@
if (includeNonGrouped && nonGrouped.getChannels().size() > 0) {
groups.put(null, nonGrouped);
}
+ if (includeEmpty) {
+ for (NotificationChannelGroup group : r.groups.values()) {
+ if (!groups.containsKey(group.getId())) {
+ groups.put(group.getId(), group);
+ }
+ }
+ }
return new ParceledListSlice<>(new ArrayList<>(groups.values()));
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 670c1af..82ad46f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -12344,8 +12344,7 @@
if (DEBUG_REMOVE) Log.d(TAG, " Activities: " + r);
}
- final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
- mPermissionManager.removeAllPermissions(pkg, allPackageNames, mPermissionCallback, chatty);
+ mPermissionManager.removeAllPermissions(pkg, chatty);
N = pkg.instrumentation.size();
r = null;
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 8202580..1d002ef 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -39,7 +39,6 @@
import com.android.server.pm.DumpState;
import com.android.server.pm.PackageManagerService;
-import com.android.server.pm.PackageSetting;
import com.android.server.pm.PackageSettingBase;
import org.xmlpull.v1.XmlPullParser;
@@ -375,10 +374,8 @@
}
public void enforceDeclaredUsedAndRuntimeOrDevelopment(PackageParser.Package pkg) {
- final PackageSetting pkgSetting = (PackageSetting) pkg.mExtras;
- final PermissionsState permsState = pkgSetting.getPermissionsState();
int index = pkg.requestedPermissions.indexOf(name);
- if (!permsState.hasRequestedPermission(name) && index == -1) {
+ if (index == -1) {
throw new SecurityException("Package " + pkg.packageName
+ " has not requested permission " + name);
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
index c3f23a8..a042fed 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerInternal.java
@@ -115,11 +115,7 @@
*/
public abstract void addAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
public abstract void addAllPermissionGroups(@NonNull PackageParser.Package pkg, boolean chatty);
- public abstract void removeAllPermissions(
- @NonNull PackageParser.Package pkg,
- @NonNull List<String> allPackageNames,
- @Nullable PermissionCallback permissionCallback,
- boolean chatty);
+ public abstract void removeAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
public abstract boolean addDynamicPermission(@NonNull PermissionInfo info, boolean async,
int callingUid, @Nullable PermissionCallback callback);
public abstract void removeDynamicPermission(@NonNull String permName, int callingUid,
@@ -193,4 +189,4 @@
/** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
-}
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 02c9049..c51a724 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -30,7 +30,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
@@ -38,7 +37,6 @@
import android.content.pm.PermissionInfo;
import android.content.pm.PackageParser.Package;
import android.metrics.LogMaker;
-import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -457,9 +455,8 @@
" to " + newPermissionGroupName);
try {
- revokeRuntimePermission(permissionName, packageName,
- mSettings.getPermission(permissionName), false,
- Process.SYSTEM_UID, userId, permissionCallback, false);
+ revokeRuntimePermission(permissionName, packageName, false,
+ Process.SYSTEM_UID, userId, permissionCallback);
} catch (IllegalArgumentException e) {
Slog.e(TAG, "Could not revoke " + permissionName + " from "
+ packageName, e);
@@ -552,59 +549,9 @@
}
- private void revokeAllPermissions(
- @NonNull List<BasePermission> bps,
- @NonNull List<String> allPackageNames,
- @Nullable PermissionCallback permissionCallback) {
- AsyncTask.execute(() -> {
- final int numRemovedPermissions = bps.size();
- for (int permissionNum = 0; permissionNum < numRemovedPermissions; permissionNum++) {
- final int[] userIds = mUserManagerInt.getUserIds();
- final int numUserIds = userIds.length;
-
- final int numPackages = allPackageNames.size();
- for (int packageNum = 0; packageNum < numPackages; packageNum++) {
- final String packageName = allPackageNames.get(packageNum);
- final ApplicationInfo applicationInfo = mPackageManagerInt.getApplicationInfo(
- packageName, 0, Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
- if (applicationInfo != null
- && applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
- continue;
- }
- for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
- final int userId = userIds[userIdNum];
- final String permissionName = bps.get(permissionNum).getName();
- if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
- userId) == PackageManager.PERMISSION_GRANTED) {
- try {
- revokeRuntimePermission(
- permissionName,
- packageName,
- bps.get(permissionNum),
- false,
- Process.SYSTEM_UID,
- userId,
- permissionCallback,
- true);
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Could not revoke " + permissionName + " from "
- + packageName, e);
- }
- }
- }
- }
- }
- });
- }
-
- private void removeAllPermissions(
- @NonNull PackageParser.Package pkg,
- @NonNull List<String> allPackageNames,
- @Nullable PermissionCallback permissionCallback,
- boolean chatty) {
+ private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
synchronized (mLock) {
int N = pkg.permissions.size();
- List<BasePermission> bps = new ArrayList<BasePermission>(N);
StringBuilder r = null;
for (int i=0; i<N; i++) {
PackageParser.Permission p = pkg.permissions.get(i);
@@ -613,9 +560,6 @@
bp = mSettings.mPermissionTrees.get(p.info.name);
}
if (bp != null && bp.isPermission(p)) {
- if ((p.info.getProtection() & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
- bps.add(bp);
- }
bp.setPermission(null);
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -634,7 +578,6 @@
}
}
}
- revokeAllPermissions(bps, allPackageNames, permissionCallback);
if (r != null) {
if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
}
@@ -1547,10 +1490,9 @@
}
}
-
- private void revokeRuntimePermission(String permName, String packageName, BasePermission bp,
- boolean overridePolicy, int callingUid, int userId, PermissionCallback callback,
- boolean permissionRemoved) {
+
+ private void revokeRuntimePermission(String permName, String packageName,
+ boolean overridePolicy, int callingUid, int userId, PermissionCallback callback) {
if (!mUserManagerInt.exists(userId)) {
Log.e(TAG, "No such user:" + userId);
return;
@@ -1575,7 +1517,7 @@
if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
-
+ final BasePermission bp = mSettings.getPermissionLocked(permName);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permName);
}
@@ -2131,10 +2073,8 @@
PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
}
@Override
- public void removeAllPermissions(Package pkg, List<String> allPackageNames,
- PermissionCallback permissionCallback, boolean chatty) {
- PermissionManagerService.this.removeAllPermissions(
- pkg, allPackageNames, permissionCallback, chatty);
+ public void removeAllPermissions(Package pkg, boolean chatty) {
+ PermissionManagerService.this.removeAllPermissions(pkg, chatty);
}
@Override
public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
@@ -2170,8 +2110,7 @@
boolean overridePolicy, int callingUid, int userId,
PermissionCallback callback) {
PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
- mSettings.getPermission(permName), overridePolicy, callingUid, userId,
- callback, false);
+ overridePolicy, callingUid, userId, callback);
}
@Override
public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 5e66bfc3..11df380 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -20,9 +20,9 @@
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
+
import android.util.SparseArray;
import android.util.SparseBooleanArray;
-
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
@@ -291,13 +291,6 @@
}
/**
- * Returns whether the state has any known request for the given permission name,
- * whether or not it has been granted.
- */
- public boolean hasRequestedPermission(String name) {
- return mPermissions != null && (mPermissions.get(name) != null);
- }
- /**
* Gets all permissions for a given device user id regardless if they
* are install time or runtime permissions.
*
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index c3b9841..e8f255f 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -42,6 +42,7 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
+import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
@@ -395,30 +396,11 @@
private String getProviderPkg(Uri uri, int user) {
long ident = Binder.clearCallingIdentity();
try {
- IBinder token = new Binder();
- IActivityManager activityManager = ActivityManager.getService();
- ContentProviderHolder holder = null;
String providerName = getUriWithoutUserId(uri).getAuthority();
- try {
- try {
- holder = activityManager.getContentProviderExternal(
- providerName, getUserIdFromUri(uri, user), token);
- if (holder != null && holder.info != null) {
- return holder.info.packageName;
- } else {
- return null;
- }
- } finally {
- if (holder != null && holder.provider != null) {
- activityManager.removeContentProviderExternal(providerName, token);
- }
- }
- } catch (RemoteException e) {
- // Can't happen.
- throw e.rethrowAsRuntimeException();
- }
+ ProviderInfo provider = mContext.getPackageManager().resolveContentProviderAsUser(
+ providerName, 0, getUserIdFromUri(uri, user));
+ return provider.packageName;
} finally {
- // I know, the double finally seems ugly, but seems safest for the identity.
Binder.restoreCallingIdentity(ident);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2941e93..22ac65d 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -400,6 +400,9 @@
private MagnificationSpec mMagnificationSpec;
+ /** Caches the value whether told display manager that we have content. */
+ private boolean mLastHasContent;
+
private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
WindowStateAnimator winAnimator = w.mWinAnimator;
final AppWindowToken atoken = w.mAppToken;
@@ -2916,8 +2919,9 @@
forAllWindows(mApplySurfaceChangesTransaction, true /* traverseTopToBottom */);
prepareSurfaces();
+ mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
mService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
- mTmpApplySurfaceChangesTransactionState.displayHasContent,
+ mLastHasContent,
mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
mTmpApplySurfaceChangesTransactionState.preferredModeId,
true /* inTraversal, must call performTraversalInTrans... below */);
@@ -4052,4 +4056,11 @@
private boolean canUpdateImeTarget() {
return mDeferUpdateImeTargetCount == 0;
}
+
+ /**
+ * @return Cached value whether we told display manager that we have content.
+ */
+ boolean getLastHasContent() {
+ return mLastHasContent;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1ae680f..087bd6a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -85,6 +85,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
@@ -4248,10 +4249,15 @@
}
if (!mWinAnimator.mLastHidden || wasDeferred) {
mWinAnimator.hide(reason);
+ getDisplayContent().mWallpaperController.mDeferredHideWallpaper = null;
dispatchWallpaperVisibility(false);
final DisplayContent displayContent = getDisplayContent();
if (displayContent != null) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) {
+ mService.mWindowPlacerLocked.debugLayoutRepeats("hideWallpaperWindow " + this,
+ displayContent.pendingLayoutChanges);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index a05e04d..c56c303 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1126,7 +1126,7 @@
setSurfaceBoundariesLocked(recoveringMemory);
- if (mIsWallpaper && !mWin.mWallpaperVisible) {
+ if (mIsWallpaper && !w.mWallpaperVisible) {
// Wallpaper is no longer visible and there is no wp target => hide it.
hide("prepareSurfaceLocked");
} else if (w.isParentWindowHidden() || !w.isOnScreen()) {
@@ -1185,11 +1185,18 @@
if (mIsWallpaper) {
w.dispatchWallpaperVisibility(true);
}
- // This draw means the difference between unique content and mirroring.
- // Run another pass through performLayout to set mHasContent in the
- // LogicalDisplay.
- mAnimator.setPendingLayoutChanges(w.getDisplayId(),
- FINISH_LAYOUT_REDO_ANIM);
+ if (!w.getDisplayContent().getLastHasContent()) {
+ // This draw means the difference between unique content and mirroring.
+ // Run another pass through performLayout to set mHasContent in the
+ // LogicalDisplay.
+ mAnimator.setPendingLayoutChanges(w.getDisplayId(),
+ FINISH_LAYOUT_REDO_ANIM);
+ if (DEBUG_LAYOUT_REPEATS) {
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "showSurfaceRobustlyLocked " + w,
+ mAnimator.getPendingLayoutChanges(w.getDisplayId()));
+ }
+ }
} else {
w.setOrientationChanging(false);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index cdbf3c6..955e247 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -500,8 +500,9 @@
NotificationChannel channel = new NotificationChannel("id", "name",
IMPORTANCE_HIGH);
NotificationRecord r = generateNotificationRecord(channel);
- assertTrue(mService.isBlocked(r, mUsageStats));
- verify(mUsageStats, times(1)).registerSuspendedByAdmin(eq(r));
+
+ // isBlocked is only used for user blocking, not app suspension
+ assertFalse(mService.isBlocked(r, mUsageStats));
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 98c6ec4..a9e713e 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -399,7 +399,7 @@
mHelper.getNotificationChannel(PKG, UID, channel2.getId(), false));
List<NotificationChannelGroup> actualGroups =
- mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
boolean foundNcg = false;
for (NotificationChannelGroup actual : actualGroups) {
if (ncg.getId().equals(actual.getId())) {
@@ -469,7 +469,7 @@
mHelper.getNotificationChannel(PKG, UID, channel3.getId(), false));
List<NotificationChannelGroup> actualGroups =
- mHelper.getNotificationChannelGroups(PKG, UID, false, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, false, true, false).getList();
boolean foundNcg = false;
for (NotificationChannelGroup actual : actualGroups) {
if (ncg.getId().equals(actual.getId())) {
@@ -784,6 +784,31 @@
new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
}
+ @Test
+ public void testGetChannelGroups_includeEmptyGroups() {
+ NotificationChannelGroup ncg = new NotificationChannelGroup("group1", "name1");
+ mHelper.createNotificationChannelGroup(PKG, UID, ncg, true);
+ NotificationChannelGroup ncgEmpty = new NotificationChannelGroup("group2", "name2");
+ mHelper.createNotificationChannelGroup(PKG, UID, ncgEmpty, true);
+
+ NotificationChannel channel1 =
+ new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
+ channel1.setGroup(ncg.getId());
+ mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
+
+ List<NotificationChannelGroup> actual = mHelper.getNotificationChannelGroups(
+ PKG, UID, false, false, true).getList();
+
+ assertEquals(2, actual.size());
+ for (NotificationChannelGroup group : actual) {
+ if (Objects.equals(group.getId(), ncg.getId())) {
+ assertEquals(1, group.getChannels().size());
+ }
+ if (Objects.equals(group.getId(), ncgEmpty.getId())) {
+ assertEquals(0, group.getChannels().size());
+ }
+ }
+ }
@Test
public void testUpdate() throws Exception {
@@ -1421,7 +1446,7 @@
mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG}, new int[]{UID});
assertEquals(0,
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList().size());
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList().size());
}
@Test
@@ -1510,7 +1535,7 @@
mHelper.createNotificationChannel(PKG, UID, channel3, true, false);
List<NotificationChannelGroup> actual =
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
assertEquals(3, actual.size());
for (NotificationChannelGroup group : actual) {
if (group.getId() == null) {
@@ -1542,13 +1567,13 @@
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(ncg.getId());
mHelper.createNotificationChannel(PKG, UID, channel1, true, false);
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
channel1.setImportance(IMPORTANCE_LOW);
mHelper.updateNotificationChannel(PKG, UID, channel1, true);
List<NotificationChannelGroup> actual =
- mHelper.getNotificationChannelGroups(PKG, UID, true, true).getList();
+ mHelper.getNotificationChannelGroups(PKG, UID, true, true, false).getList();
assertEquals(2, actual.size());
for (NotificationChannelGroup group : actual) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 742f059..bae1884 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -110,6 +110,28 @@
"call_barring_visibility_bool";
/**
+ * Flag indicating whether or not changing the call barring password via the "Call Barring"
+ * settings menu is supported. If true, the option will be visible in the "Call
+ * Barring" settings menu. If false, the option will not be visible.
+ *
+ * Enabled by default.
+ * @hide
+ */
+ public static final String KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL =
+ "call_barring_supports_password_change_bool";
+
+ /**
+ * Flag indicating whether or not deactivating all call barring features via the "Call Barring"
+ * settings menu is supported. If true, the option will be visible in the "Call
+ * Barring" settings menu. If false, the option will not be visible.
+ *
+ * Enabled by default.
+ * @hide
+ */
+ public static final String KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL =
+ "call_barring_supports_deactivate_all_bool";
+
+ /**
* Flag indicating whether the Phone app should ignore EVENT_SIM_NETWORK_LOCKED
* events from the Sim.
* If true, this will prevent the IccNetworkDepersonalizationPanel from being shown, and
@@ -1570,11 +1592,21 @@
* When {@code false}, use default title for Enhanced 4G LTE Mode settings.
* When {@code true}, use the variant.
* @hide
+ * @deprecated use {@link #KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT}.
*/
+ @Deprecated
public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL =
"enhanced_4g_lte_title_variant_bool";
/**
+ * The index indicates the carrier specified title string of Enahnce 4G LTE Mode settings.
+ * Default value is 0, which indicates the default title string.
+ * @hide
+ */
+ public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT =
+ "enhanced_4g_lte_title_variant_int";
+
+ /**
* Indicates whether the carrier wants to notify the user when handover of an LTE video call to
* WIFI fails.
* <p>
@@ -2085,6 +2117,8 @@
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
sDefaults.putBoolean(KEY_CALL_BARRING_VISIBILITY_BOOL, false);
+ sDefaults.putBoolean(KEY_CALL_BARRING_SUPPORTS_PASSWORD_CHANGE_BOOL, true);
+ sDefaults.putBoolean(KEY_CALL_BARRING_SUPPORTS_DEACTIVATE_ALL_BOOL, true);
sDefaults.putBoolean(KEY_CALL_FORWARDING_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true);
@@ -2305,6 +2339,7 @@
sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false);
+ sDefaults.putInt(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 6bf22a0..8015b07 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -33,6 +33,7 @@
import com.android.internal.telephony.SmsConstants;
import java.io.UnsupportedEncodingException;
+import java.util.Locale;
/**
* Parses a GSM or UMTS format SMS-CB message into an {@link SmsCbMessage} object. The class is
@@ -44,16 +45,34 @@
* Languages in the 0000xxxx DCS group as defined in 3GPP TS 23.038, section 5.
*/
private static final String[] LANGUAGE_CODES_GROUP_0 = {
- "de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi", "no", "el", "tr", "hu",
- "pl", null
+ Locale.GERMAN.getLanguage(), // German
+ Locale.ENGLISH.getLanguage(), // English
+ Locale.ITALIAN.getLanguage(), // Italian
+ Locale.FRENCH.getLanguage(), // French
+ new Locale("es").getLanguage(), // Spanish
+ new Locale("nl").getLanguage(), // Dutch
+ new Locale("sv").getLanguage(), // Swedish
+ new Locale("da").getLanguage(), // Danish
+ new Locale("pt").getLanguage(), // Portuguese
+ new Locale("fi").getLanguage(), // Finnish
+ new Locale("nb").getLanguage(), // Norwegian
+ new Locale("el").getLanguage(), // Greek
+ new Locale("tr").getLanguage(), // Turkish
+ new Locale("hu").getLanguage(), // Hungarian
+ new Locale("pl").getLanguage(), // Polish
+ null
};
/**
* Languages in the 0010xxxx DCS group as defined in 3GPP TS 23.038, section 5.
*/
private static final String[] LANGUAGE_CODES_GROUP_2 = {
- "cs", "he", "ar", "ru", "is", null, null, null, null, null, null, null, null, null,
- null, null
+ new Locale("cs").getLanguage(), // Czech
+ new Locale("he").getLanguage(), // Hebrew
+ new Locale("ar").getLanguage(), // Arabic
+ new Locale("ru").getLanguage(), // Russian
+ new Locale("is").getLanguage(), // Icelandic
+ null, null, null, null, null, null, null, null, null, null, null
};
private static final char CARRIAGE_RETURN = 0x0d;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
index 0fabc2f..541ca8d 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbConstants.java
@@ -118,71 +118,103 @@
public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE
= 0x111E; // 4382
- /** CMAS Message Identifier for Presidential Level alerts for additional languages
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Presidential Level alerts for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE
= 0x111F; // 4383
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE
= 0x1120; // 4384
- /** CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Immediate, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE
= 0x1121; // 4385
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE
= 0x1122; // 4386
- /** CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Extreme alerts, Urgency=Expected, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE
= 0x1123; // 4387
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE
= 0x1124; // 4388
- /** CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely
- * for additional languages.*/
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Immediate, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE
= 0x1125; // 4389
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Observed
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE
= 0x1126; // 4390
- /** CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely
- * for additional languages.*/
+ /**
+ * CMAS Message Identifier for Severe alerts, Urgency=Expected, Certainty=Likely
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE
= 0x1127; // 4391
- /** CMAS Message Identifier for Child Abduction Emergency (Amber Alert)
- * for additional languages. */
+ /**
+ * CMAS Message Identifier for Child Abduction Emergency (Amber Alert)
+ * for additional languages.
+ */
public static final int MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE
= 0x1128; // 4392
- /** CMAS Message Identifier for the Required Monthly Test
- * for additional languages. */
+ /** CMAS Message Identifier for the Required Monthly Test for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE
= 0x1129; // 4393
- /** CMAS Message Identifier for CMAS Exercise
- * for additional languages. */
+ /** CMAS Message Identifier for CMAS Exercise for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE
= 0x112A; // 4394
- /** CMAS Message Identifier for operator defined use
- * for additional languages. */
+ /** CMAS Message Identifier for operator defined use for additional languages. */
public static final int MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE
= 0x112B; // 4395
+ /** CMAS Message Identifier for CMAS Public Safety Alerts. */
+ public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY
+ = 0x112C; // 4396
+
+ /** CMAS Message Identifier for CMAS Public Safety Alerts for additional languages. */
+ public static final int MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY_LANGUAGE
+ = 0x112D; // 4397
+
+ /** CMAS Message Identifier for CMAS State/Local Test. */
+ public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST
+ = 0x112E; // 4398
+
+ /** CMAS Message Identifier for CMAS State/Local Test for additional languages. */
+ public static final int MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE
+ = 0x112F; // 4399
+
/** End of CMAS Message Identifier range (including future extensions). */
public static final int MESSAGE_ID_CMAS_LAST_IDENTIFIER
= 0x112F; // 4399
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 2918cf6..4a7d703 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -328,9 +328,10 @@
public String preSharedKey;
/**
- * Up to four WEP keys. Either an ASCII string enclosed in double
- * quotation marks (e.g., {@code "abcdef"}) or a string
- * of hex digits (e.g., {@code 0102030405}).
+ * Four WEP keys. For each of the four values, provide either an ASCII
+ * string enclosed in double quotation marks (e.g., {@code "abcdef"}),
+ * a string of hex digits (e.g., {@code 0102030405}), or an empty string
+ * (e.g., {@code ""}).
* <p/>
* When the value of one of these keys is read, the actual key is
* not returned, just a "*" if the key has a value, or the null