From cdbfb0f453c26359e0f91721c6dc57d2b9c99239 Mon Sep 17 00:00:00 2001
From: Shinru Han
Date: Tue, 10 Aug 2021 18:27:25 +0800
Subject: [PATCH 01/26] Allow negative value for
CorrelationVector#samplingStartM
Bug: 195934893
Test: atest ctsLocationPrivilegedTestCases
Change-Id: I255e118cabf274811b57e88a35faf8c9e697d8ae
(cherry picked from commit e19a11cf6fdafd9e9a75bc65f6c3a498a4ff687e)
---
location/java/android/location/CorrelationVector.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/location/java/android/location/CorrelationVector.java b/location/java/android/location/CorrelationVector.java
index 718977ff42966..5493e2579225f 100644
--- a/location/java/android/location/CorrelationVector.java
+++ b/location/java/android/location/CorrelationVector.java
@@ -94,8 +94,6 @@ public final class CorrelationVector implements Parcelable {
"FrequencyOffsetMetersPerSecond must be non-negative (greater than or equal to 0)");
Preconditions.checkArgument(builder.mSamplingWidthMeters > 0.0,
"SamplingWidthMeters must be positive (greater than 0)");
- Preconditions.checkArgument(builder.mSamplingStartMeters >= 0.0,
- "SamplingStartMeters must be non-negative (greater than or equal to 0)");
mMagnitude = builder.mMagnitude;
mFrequencyOffsetMetersPerSecond = builder.mFrequencyOffsetMetersPerSecond;
mSamplingWidthMeters = builder.mSamplingWidthMeters;
From 54b1606727b74029c601a5eca4eccf7a5083020b Mon Sep 17 00:00:00 2001
From: Evan Severson
Date: Wed, 11 Aug 2021 13:25:21 -0700
Subject: [PATCH 02/26] Fix boot loop when upgrading sensor privacy file
Also add new testcase for sensor privacy service boot.
Test: atest SensorPrivacyServiceMockingTest CtsSensorPrivacyTestCases
Manually test booting with old file version
Fixes: 195913883
Change-Id: I9d8791e5f27c881afd9e23f94fb5fb9dc891fda4
(cherry picked from commit 4fa06df1b8fbb252f1d6ce2412e8a42ea5d8271e)
---
.../android/server/SensorPrivacyService.java | 20 +++++++++++++------
.../persisted_file6.xml | 3 +++
.../SensorPrivacyServiceMockingTest.java | 4 ++++
3 files changed, 21 insertions(+), 6 deletions(-)
create mode 100644 services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml
diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java
index 422e8ae148621..91b2440f71fec 100644
--- a/services/core/java/com/android/server/SensorPrivacyService.java
+++ b/services/core/java/com/android/server/SensorPrivacyService.java
@@ -1021,7 +1021,15 @@ public final class SensorPrivacyService extends SystemService {
}
}
- return upgradeAndInit(version, map);
+ try {
+ return upgradeAndInit(version, map);
+ } catch (Exception e) {
+ Log.wtf(TAG, "Failed to upgrade and set sensor privacy state,"
+ + " resetting to default.", e);
+ mEnabled = new SparseBooleanArray();
+ mIndividualEnabled = new SparseArray<>();
+ return true;
+ }
}
private boolean upgradeAndInit(int version, SparseArray map) {
@@ -1037,22 +1045,22 @@ public final class SensorPrivacyService extends SystemService {
final int[] users = getLocalService(UserManagerInternal.class).getUserIds();
if (version == 0) {
final boolean enabled = (boolean) map.get(VER0_ENABLED);
- final SparseBooleanArray individualEnabled =
- (SparseBooleanArray) map.get(VER0_INDIVIDUAL_ENABLED);
+ final SparseArray individualEnabled =
+ (SparseArray) map.get(VER0_INDIVIDUAL_ENABLED);
final SparseBooleanArray perUserEnabled = new SparseBooleanArray();
- final SparseArray perUserIndividualEnabled =
+ final SparseArray> perUserIndividualEnabled =
new SparseArray<>();
// Copy global state to each user
for (int i = 0; i < users.length; i++) {
int user = users[i];
perUserEnabled.put(user, enabled);
- SparseBooleanArray userIndividualSensorEnabled = new SparseBooleanArray();
+ SparseArray userIndividualSensorEnabled = new SparseArray<>();
perUserIndividualEnabled.put(user, userIndividualSensorEnabled);
for (int j = 0; j < individualEnabled.size(); j++) {
final int sensor = individualEnabled.keyAt(j);
- final boolean isSensorEnabled = individualEnabled.valueAt(j);
+ final SensorState isSensorEnabled = individualEnabled.valueAt(j);
userIndividualSensorEnabled.put(sensor, isSensorEnabled);
}
}
diff --git a/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml b/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml
new file mode 100644
index 0000000000000..b3c142285c8ae
--- /dev/null
+++ b/services/tests/mockingservicestests/assets/SensorPrivacyServiceMockingTest/persisted_file6.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java
index 844687f34555f..ba79a764b6729 100644
--- a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/SensorPrivacyServiceMockingTest.java
@@ -60,6 +60,8 @@ public class SensorPrivacyServiceMockingTest {
String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 4);
public static final String PERSISTENCE_FILE5 =
String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 5);
+ public static final String PERSISTENCE_FILE6 =
+ String.format(PERSISTENCE_FILE_PATHS_TEMPLATE, 6);
private Context mContext;
@Mock
@@ -111,6 +113,7 @@ public class SensorPrivacyServiceMockingTest {
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE3);
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE4);
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE5);
+ initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE6);
// Try all files with two known users
doReturn(new int[]{0, 10}).when(mMockedUserManagerInternal).getUserIds();
@@ -124,6 +127,7 @@ public class SensorPrivacyServiceMockingTest {
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE3);
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE4);
initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE5);
+ initServiceWithPersistenceFile(onDeviceFile, PERSISTENCE_FILE6);
} finally {
mockitoSession.finishMocking();
From af54bb321c064db9976c9a464e8df090b10631c4 Mon Sep 17 00:00:00 2001
From: Hui Yu
Date: Thu, 5 Aug 2021 12:26:38 -0700
Subject: [PATCH 03/26] Reduce background FGS start WTF log messages.
In ActivityManagerConstants, add key "fgs_start_allowed_log_sample_rate"
for the "allowed" WTF log sample rate, default sample rate is 25%; add key
"fgs_start_denied_log_sample_rate" for the "denied" WTF log sample rate, default sample rate
is 100%.
In ActiveServices.java, use these two sample rates for the FGS start WTF
log messages.
Bug: 195672687
Test: build and run.
Change-Id: I21cd83552b2988f7e5233094d93f93ba1b6af04a
(cherry picked from commit d4db713dccc0fffd1934a81bdc6a57303f5c3ec9)
---
.../com/android/server/am/ActiveServices.java | 9 +++-
.../server/am/ActivityManagerConstants.java | 42 +++++++++++++++++++
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index f41036cde4338..a2fec2753340d 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -6314,10 +6314,17 @@ public final class ActiveServices {
final String msg = "Background started FGS: "
+ ((r.mAllowStartForeground != REASON_DENIED) ? "Allowed " : "Disallowed ")
+ r.mInfoAllowStartForeground;
- Slog.wtfQuiet(TAG, msg);
if (r.mAllowStartForeground != REASON_DENIED) {
+ if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName,
+ mAm.mConstants.mFgsStartAllowedLogSampleRate)) {
+ Slog.wtfQuiet(TAG, msg);
+ }
Slog.i(TAG, msg);
} else {
+ if (ActivityManagerUtils.shouldSamplePackageForAtom(r.packageName,
+ mAm.mConstants.mFgsStartDeniedLogSampleRate)) {
+ Slog.wtfQuiet(TAG, msg);
+ }
Slog.w(TAG, msg);
}
r.mLoggedInfoAllowStartForeground = true;
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index ac0a1985ac896..eeb41a3df969f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -108,6 +108,8 @@ final class ActivityManagerConstants extends ContentObserver {
static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration";
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate";
+ static final String KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE = "fgs_start_allowed_log_sample_rate";
+ static final String KEY_FGS_START_DENIED_LOG_SAMPLE_RATE = "fgs_start_denied_log_sample_rate";
static final String KEY_FGS_ALLOW_OPT_OUT = "fgs_allow_opt_out";
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
@@ -152,6 +154,8 @@ final class ActivityManagerConstants extends ContentObserver {
private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 %
+ private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25%
+ private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100%
/**
* Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
*/
@@ -495,6 +499,20 @@ final class ActivityManagerConstants extends ContentObserver {
*/
volatile float mFgsAtomSampleRate = DEFAULT_FGS_ATOM_SAMPLE_RATE;
+ /**
+ * Sample rate for the allowed FGS start WTF logs.
+ *
+ * If the value is 0.1, 10% of the logs would be sampled.
+ */
+ volatile float mFgsStartAllowedLogSampleRate = DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE;
+
+ /**
+ * Sample rate for the denied FGS start WTF logs.
+ *
+ * If the value is 0.1, 10% of the logs would be sampled.
+ */
+ volatile float mFgsStartDeniedLogSampleRate = DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE;
+
/**
* Whether to allow "opt-out" from the foreground service restrictions.
* (https://developer.android.com/about/versions/12/foreground-services)
@@ -711,6 +729,12 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_FGS_ATOM_SAMPLE_RATE:
updateFgsAtomSamplePercent();
break;
+ case KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE:
+ updateFgsStartAllowedLogSamplePercent();
+ break;
+ case KEY_FGS_START_DENIED_LOG_SAMPLE_RATE:
+ updateFgsStartDeniedLogSamplePercent();
+ break;
case KEY_FGS_ALLOW_OPT_OUT:
updateFgsAllowOptOut();
break;
@@ -1057,6 +1081,20 @@ final class ActivityManagerConstants extends ContentObserver {
DEFAULT_FGS_ATOM_SAMPLE_RATE);
}
+ private void updateFgsStartAllowedLogSamplePercent() {
+ mFgsStartAllowedLogSampleRate = DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE,
+ DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE);
+ }
+
+ private void updateFgsStartDeniedLogSamplePercent() {
+ mFgsStartDeniedLogSampleRate = DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_FGS_START_DENIED_LOG_SAMPLE_RATE,
+ DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE);
+ }
+
private void updateFgsAllowOptOut() {
mFgsAllowOptOut = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1285,6 +1323,10 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mFgsStartRestrictionCheckCallerTargetSdk);
pw.print(" "); pw.print(KEY_FGS_ATOM_SAMPLE_RATE);
pw.print("="); pw.println(mFgsAtomSampleRate);
+ pw.print(" "); pw.print(KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE);
+ pw.print("="); pw.println(mFgsStartAllowedLogSampleRate);
+ pw.print(" "); pw.print(KEY_FGS_START_DENIED_LOG_SAMPLE_RATE);
+ pw.print("="); pw.println(mFgsStartDeniedLogSampleRate);
pw.print(" "); pw.print(KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR);
pw.print("="); pw.println(mPushMessagingOverQuotaBehavior);
pw.print(" "); pw.print(KEY_FGS_ALLOW_OPT_OUT);
From 65cedbaa32e50955e48a3694770ad236d27ac12f Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Tue, 10 Aug 2021 16:50:52 -0600
Subject: [PATCH 04/26] Register IBluetoothManagerCallback per-process.
As part of introducing AttributionSource across the Bluetooth stack
earlier this year, each BluetoothAdapter instance is now associated
with a specific AttributionSource, and several instances of shared
static code were made BluetoothAdapter-specific so they could be
augmented with the relevant AttributionSource.
However, processes that create many BluetoothAdapter instances can
overload the system, since a IBluetoothManagerCallback was registered
for each instance. This change mitigates this by only registering a
single IBluetoothManagerCallback for the entire process, and it
then reuses the existing sProxyServiceStateCallbacks list for
dispatching events to all active adapters within the process.
Since it's so late in the release, we keep both mService and
sService intact to minimize the size of this CL; future work should
refactor to a more robust design, such as Supplier.
Bug: 195286998, 172022978
Test: atest BluetoothInstrumentationTests
Change-Id: I012f3f65e61eaf55e40436486806e56506c928ee
(cherry picked from commit f0fa7f9b4aaee876053486d988909df9dc64e990)
---
.../android/bluetooth/BluetoothAdapter.java | 184 ++++++++++++------
.../android/bluetooth/BluetoothSocket.java | 6 +-
2 files changed, 127 insertions(+), 63 deletions(-)
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 8398be1af49a6..5094498dbee55 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -64,6 +64,8 @@ import android.os.SystemProperties;
import android.util.Log;
import android.util.Pair;
+import com.android.internal.annotations.GuardedBy;
+
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -78,6 +80,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
+import java.util.WeakHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -715,10 +718,21 @@ public final class BluetoothAdapter {
private final IBluetoothManager mManagerService;
private final AttributionSource mAttributionSource;
+ // Yeah, keeping both mService and sService isn't pretty, but it's too late
+ // in the current release for a major refactoring, so we leave them both
+ // intact until this can be cleaned up in a future release
+
@UnsupportedAppUsage
+ @GuardedBy("mServiceLock")
private IBluetooth mService;
private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
+ @GuardedBy("sServiceLock")
+ private static boolean sServiceRegistered;
+ @GuardedBy("sServiceLock")
+ private static IBluetooth sService;
+ private static final Object sServiceLock = new Object();
+
private final Object mLock = new Object();
private final Map mLeScanClients;
private final Map>>
@@ -792,19 +806,11 @@ public final class BluetoothAdapter {
* Use {@link #getDefaultAdapter} to get the BluetoothAdapter instance.
*/
BluetoothAdapter(IBluetoothManager managerService, AttributionSource attributionSource) {
- if (managerService == null) {
- throw new IllegalArgumentException("bluetooth manager service is null");
- }
- try {
- mServiceLock.writeLock().lock();
- mService = managerService.registerAdapter(mManagerCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- } finally {
- mServiceLock.writeLock().unlock();
- }
mManagerService = Objects.requireNonNull(managerService);
mAttributionSource = Objects.requireNonNull(attributionSource);
+ synchronized (mServiceLock.writeLock()) {
+ mService = getBluetoothService(mManagerCallback);
+ }
mLeScanClients = new HashMap();
mToken = new Binder(DESCRIPTOR);
}
@@ -3154,21 +3160,16 @@ public final class BluetoothAdapter {
}
}
- @SuppressLint("AndroidFrameworkBluetoothPermission")
- private final IBluetoothManagerCallback mManagerCallback =
+ private static final IBluetoothManagerCallback sManagerCallback =
new IBluetoothManagerCallback.Stub() {
- @SuppressLint("AndroidFrameworkRequiresPermission")
public void onBluetoothServiceUp(IBluetooth bluetoothService) {
if (DBG) {
Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
}
- mServiceLock.writeLock().lock();
- mService = bluetoothService;
- mServiceLock.writeLock().unlock();
-
- synchronized (mProxyServiceStateCallbacks) {
- for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
+ synchronized (sServiceLock) {
+ sService = bluetoothService;
+ for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
try {
if (cb != null) {
cb.onBluetoothServiceUp(bluetoothService);
@@ -3180,6 +3181,56 @@ public final class BluetoothAdapter {
}
}
}
+ }
+
+ public void onBluetoothServiceDown() {
+ if (DBG) {
+ Log.d(TAG, "onBluetoothServiceDown");
+ }
+
+ synchronized (sServiceLock) {
+ sService = null;
+ for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
+ try {
+ if (cb != null) {
+ cb.onBluetoothServiceDown();
+ } else {
+ Log.d(TAG, "onBluetoothServiceDown: cb is null!");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "", e);
+ }
+ }
+ }
+ }
+
+ public void onBrEdrDown() {
+ if (VDBG) {
+ Log.i(TAG, "onBrEdrDown");
+ }
+
+ synchronized (sServiceLock) {
+ for (IBluetoothManagerCallback cb : sProxyServiceStateCallbacks.keySet()) {
+ try {
+ if (cb != null) {
+ cb.onBrEdrDown();
+ } else {
+ Log.d(TAG, "onBrEdrDown: cb is null!");
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "", e);
+ }
+ }
+ }
+ }
+ };
+
+ private final IBluetoothManagerCallback mManagerCallback =
+ new IBluetoothManagerCallback.Stub() {
+ public void onBluetoothServiceUp(IBluetooth bluetoothService) {
+ synchronized (mServiceLock.writeLock()) {
+ mService = bluetoothService;
+ }
synchronized (mMetadataListeners) {
mMetadataListeners.forEach((device, pair) -> {
try {
@@ -3204,12 +3255,7 @@ public final class BluetoothAdapter {
}
public void onBluetoothServiceDown() {
- if (DBG) {
- Log.d(TAG, "onBluetoothServiceDown: " + mService);
- }
-
- try {
- mServiceLock.writeLock().lock();
+ synchronized (mServiceLock.writeLock()) {
mService = null;
if (mLeScanClients != null) {
mLeScanClients.clear();
@@ -3220,29 +3266,10 @@ public final class BluetoothAdapter {
if (mBluetoothLeScanner != null) {
mBluetoothLeScanner.cleanup();
}
- } finally {
- mServiceLock.writeLock().unlock();
- }
-
- synchronized (mProxyServiceStateCallbacks) {
- for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks) {
- try {
- if (cb != null) {
- cb.onBluetoothServiceDown();
- } else {
- Log.d(TAG, "onBluetoothServiceDown: cb is null!");
- }
- } catch (Exception e) {
- Log.e(TAG, "", e);
- }
- }
}
}
public void onBrEdrDown() {
- if (VDBG) {
- Log.i(TAG, "onBrEdrDown: " + mService);
- }
}
};
@@ -3477,15 +3504,12 @@ public final class BluetoothAdapter {
protected void finalize() throws Throwable {
try {
- mManagerService.unregisterAdapter(mManagerCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
+ removeServiceStateCallback(mManagerCallback);
} finally {
super.finalize();
}
}
-
/**
* Validate a String Bluetooth address, such as "00:43:A8:23:10:F0"
* Alphabetic characters must be uppercase to be valid.
@@ -3549,24 +3573,64 @@ public final class BluetoothAdapter {
return mAttributionSource;
}
- private final ArrayList mProxyServiceStateCallbacks =
- new ArrayList();
+ @GuardedBy("sServiceLock")
+ private static final WeakHashMap sProxyServiceStateCallbacks =
+ new WeakHashMap<>();
+
+ /*package*/ IBluetooth getBluetoothService() {
+ synchronized (sServiceLock) {
+ if (sProxyServiceStateCallbacks.isEmpty()) {
+ throw new IllegalStateException(
+ "Anonymous service access requires at least one lifecycle in process");
+ }
+ return sService;
+ }
+ }
@UnsupportedAppUsage
/*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
- synchronized (mProxyServiceStateCallbacks) {
- if (cb == null) {
- Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback");
- } else if (!mProxyServiceStateCallbacks.contains(cb)) {
- mProxyServiceStateCallbacks.add(cb);
- }
+ Objects.requireNonNull(cb);
+ synchronized (sServiceLock) {
+ sProxyServiceStateCallbacks.put(cb, null);
+ registerOrUnregisterAdapterLocked();
+ return sService;
}
- return mService;
}
/*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
- synchronized (mProxyServiceStateCallbacks) {
- mProxyServiceStateCallbacks.remove(cb);
+ Objects.requireNonNull(cb);
+ synchronized (sServiceLock) {
+ sProxyServiceStateCallbacks.remove(cb);
+ registerOrUnregisterAdapterLocked();
+ }
+ }
+
+ /**
+ * Handle registering (or unregistering) a single process-wide
+ * {@link IBluetoothManagerCallback} based on the presence of local
+ * {@link #sProxyServiceStateCallbacks} clients.
+ */
+ @GuardedBy("sServiceLock")
+ private void registerOrUnregisterAdapterLocked() {
+ final boolean isRegistered = sServiceRegistered;
+ final boolean wantRegistered = !sProxyServiceStateCallbacks.isEmpty();
+
+ if (isRegistered != wantRegistered) {
+ if (wantRegistered) {
+ try {
+ sService = mManagerService.registerAdapter(sManagerCallback);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ } else {
+ try {
+ mManagerService.unregisterAdapter(sManagerCallback);
+ sService = null;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ sServiceRegistered = wantRegistered;
}
}
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index bb409d5360f91..1655b62bbfec1 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -399,7 +399,7 @@ public final class BluetoothSocket implements Closeable {
try {
if (mSocketState == SocketState.CLOSED) throw new IOException("socket closed");
IBluetooth bluetoothProxy =
- BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+ BluetoothAdapter.getDefaultAdapter().getBluetoothService();
if (bluetoothProxy == null) throw new IOException("Bluetooth is off");
mPfd = bluetoothProxy.getSocketManager().connectSocket(mDevice, mType,
mUuid, mPort, getSecurityFlags());
@@ -438,7 +438,7 @@ public final class BluetoothSocket implements Closeable {
/*package*/ int bindListen() {
int ret;
if (mSocketState == SocketState.CLOSED) return EBADFD;
- IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+ IBluetooth bluetoothProxy = BluetoothAdapter.getDefaultAdapter().getBluetoothService();
if (bluetoothProxy == null) {
Log.e(TAG, "bindListen fail, reason: bluetooth is off");
return -1;
@@ -706,7 +706,7 @@ public final class BluetoothSocket implements Closeable {
throw new IOException("socket closed");
}
IBluetooth bluetoothProxy =
- BluetoothAdapter.getDefaultAdapter().getBluetoothService(null);
+ BluetoothAdapter.getDefaultAdapter().getBluetoothService();
if (bluetoothProxy == null) {
throw new IOException("Bluetooth is off");
}
From 268425437440ca3e108bd76057053f59dc0ffb50 Mon Sep 17 00:00:00 2001
From: Philip Junker
Date: Thu, 15 Jul 2021 18:01:11 +0200
Subject: [PATCH 05/26] Disallow usb access to camera and mic devices if global
privacy toggle is active
Note that this will not prevent currently running apps from accessing
usb devies to which a connection has already been established.
Removed isCameraDevicePresent() as this has been implemented as well in
UsbDevice#getHasVideoCapture().
Bug: 189915399
Test: Install nExt Camera - USB app, verify that camera is not accessible when camera privacy toggle is disabled.
Change-Id: Ie60adfe9fc667d883ad4a6b8d7582a4bc17d1549
Merged-In: Ie60adfe9fc667d883ad4a6b8d7582a4bc17d1549
(cherry picked from commit f063780d433c6e429a14dd4d98d67764d7760908)
(cherry picked from commit 79023f08d310bf1c5405ca70c563938bd51756cc)
---
.../server/usb/UsbUserPermissionManager.java | 58 +++++++++----------
1 file changed, 27 insertions(+), 31 deletions(-)
diff --git a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
index 5874b4b9fd3e5..7b6ccd31adccc 100644
--- a/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
+++ b/services/usb/java/com/android/server/usb/UsbUserPermissionManager.java
@@ -25,12 +25,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.hardware.SensorPrivacyManager.Sensors;
+import android.hardware.SensorPrivacyManagerInternal;
import android.hardware.usb.AccessoryFilter;
import android.hardware.usb.DeviceFilter;
import android.hardware.usb.UsbAccessory;
-import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Binder;
@@ -52,9 +52,9 @@ import android.util.TypedXmlSerializer;
import android.util.Xml;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.dump.DualDumpOutputStream;
+import com.android.server.LocalServices;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -64,7 +64,6 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
/**
* UsbUserPermissionManager manages usb device or accessory access permissions.
@@ -110,19 +109,20 @@ class UsbUserPermissionManager {
*/
@GuardedBy("mLock")
private boolean mIsCopyPermissionsScheduled;
+ private final SensorPrivacyManagerInternal mSensorPrivacyMgrInternal;
UsbUserPermissionManager(@NonNull Context context,
@NonNull UsbUserSettingsManager usbUserSettingsManager) {
mContext = context;
mUser = context.getUser();
mUsbUserSettingsManager = usbUserSettingsManager;
+ mSensorPrivacyMgrInternal = LocalServices.getService(SensorPrivacyManagerInternal.class);
mDisablePermissionDialogs = context.getResources().getBoolean(
com.android.internal.R.bool.config_disableUsbPermissionDialogs);
mPermissionsFile = new AtomicFile(new File(
Environment.getUserSystemDirectory(mUser.getIdentifier()),
"usb_permissions.xml"), "usb-permissions");
-
synchronized (mLock) {
readPermissionsLocked();
}
@@ -195,11 +195,27 @@ class UsbUserPermissionManager {
*/
boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName, int pid,
int uid) {
- if (isCameraDevicePresent(device)) {
- if (!isCameraPermissionGranted(packageName, pid, uid)) {
+ if (device.getHasVideoCapture()) {
+ boolean isCameraPrivacyEnabled = mSensorPrivacyMgrInternal.isSensorPrivacyEnabled(
+ UserHandle.getUserId(uid), Sensors.CAMERA);
+ if (DEBUG) {
+ Slog.d(TAG, "isCameraPrivacyEnabled: " + isCameraPrivacyEnabled);
+ }
+ if (isCameraPrivacyEnabled || !isCameraPermissionGranted(packageName, pid, uid)) {
return false;
}
}
+ // Only check for microphone privacy and not RECORD_AUDIO permission, because access to usb
+ // camera device with audio recording capabilities may still be granted with a warning
+ if (device.getHasAudioCapture() && mSensorPrivacyMgrInternal.isSensorPrivacyEnabled(
+ UserHandle.getUserId(uid), Sensors.MICROPHONE)) {
+ if (DEBUG) {
+ Slog.d(TAG,
+ "Access to device with audio recording capabilities denied because "
+ + "microphone privacy is enabled.");
+ }
+ return false;
+ }
synchronized (mLock) {
if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
return true;
@@ -698,7 +714,10 @@ class UsbUserPermissionManager {
}
return;
}
- if (isCameraDevicePresent(device)) {
+ // If the app doesn't have camera permission do not request permission to the USB device.
+ // Note that if the USB camera also has a microphone, a warning will be shown to the user if
+ // the app doesn't have RECORD_AUDIO permission.
+ if (device.getHasVideoCapture()) {
if (!isCameraPermissionGranted(packageName, pid, uid)) {
intent.putExtra(UsbManager.EXTRA_DEVICE, device);
intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false);
@@ -733,27 +752,4 @@ class UsbUserPermissionManager {
requestPermissionDialog(null, accessory,
mUsbUserSettingsManager.canBeDefault(accessory, packageName), packageName, pi, uid);
}
-
- /**
- * Check whether a particular device or any of its interfaces
- * is of class VIDEO.
- *
- * @param device The device that needs to get scanned
- * @return True in case a VIDEO device or interface is present,
- * False otherwise.
- */
- private boolean isCameraDevicePresent(UsbDevice device) {
- if (device.getDeviceClass() == UsbConstants.USB_CLASS_VIDEO) {
- return true;
- }
-
- for (int i = 0; i < device.getInterfaceCount(); i++) {
- UsbInterface iface = device.getInterface(i);
- if (iface.getInterfaceClass() == UsbConstants.USB_CLASS_VIDEO) {
- return true;
- }
- }
-
- return false;
- }
}
From 2c3fcd7fd8ae1238068435f36eba3897e1005886 Mon Sep 17 00:00:00 2001
From: Matt Pietal
Date: Thu, 12 Aug 2021 18:26:15 -0400
Subject: [PATCH 06/26] Limit keyguard views on alt displays
When casting or on other displays, the keyguard has always limited the
information shown when locked. Don't show the smartspace and icons on
these alternate displays
Fixes: 196175396
Test: manual (cast to nest display device)
Change-Id: Ied1ecff9103d8539f075785409d2951a1be21ab2
(cherry picked from commit 893286a5d4c8bac3a332b5f38a553900488ee6b1)
---
.../KeyguardClockSwitchController.java | 19 +++++++++++++++++++
.../keyguard/KeyguardDisplayManager.java | 1 +
2 files changed, 20 insertions(+)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 632919ae51e47..f4a3fb236ffa1 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -97,6 +97,8 @@ public class KeyguardClockSwitchController extends ViewController
Date: Tue, 10 Aug 2021 14:27:42 -0700
Subject: [PATCH 07/26] Rename android.media.MediaTranscodeManager ->
MediaTranscodingManager
renamed to avoid conflict with existing copy in the R framework.jar.
The framework.jar copy was removed during S development
Bug: 195608856
Test: build
Test: cts-tradefed run cts -m CtsMediaTranscodingTestCases
Change-Id: I40ab066cd61be8d278f21cc788016f2edd6bb86e
(cherry picked from commit 1168d9d014cfc0e007c311db92ff2d69cc30df18)
---
apex/media/framework/Android.bp | 2 +-
apex/media/framework/api/system-current.txt | 38 +++++++++----------
.../media/MediaFrameworkInitializer.java | 4 +-
...ager.java => MediaTranscodingManager.java} | 22 +++++------
core/java/android/content/Context.java | 4 +-
5 files changed, 35 insertions(+), 35 deletions(-)
rename apex/media/framework/java/android/media/{MediaTranscodeManager.java => MediaTranscodingManager.java} (99%)
diff --git a/apex/media/framework/Android.bp b/apex/media/framework/Android.bp
index 1bf732ba33f27..d963e68d80ecb 100644
--- a/apex/media/framework/Android.bp
+++ b/apex/media/framework/Android.bp
@@ -120,7 +120,7 @@ filegroup {
srcs: [
"java/android/media/ApplicationMediaCapabilities.java",
"java/android/media/MediaFeature.java",
- "java/android/media/MediaTranscodeManager.java",
+ "java/android/media/MediaTranscodingManager.java",
],
path: "java",
}
diff --git a/apex/media/framework/api/system-current.txt b/apex/media/framework/api/system-current.txt
index ce68447df051b..6eea769d9f57c 100644
--- a/apex/media/framework/api/system-current.txt
+++ b/apex/media/framework/api/system-current.txt
@@ -1,15 +1,15 @@
// Signature format: 2.0
package android.media {
- public final class MediaTranscodeManager {
- method @Nullable public android.media.MediaTranscodeManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodeManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodeManager.OnTranscodingFinishedListener);
+ public final class MediaTranscodingManager {
+ method @Nullable public android.media.MediaTranscodingManager.TranscodingSession enqueueRequest(@NonNull android.media.MediaTranscodingManager.TranscodingRequest, @NonNull java.util.concurrent.Executor, @NonNull android.media.MediaTranscodingManager.OnTranscodingFinishedListener);
}
- @java.lang.FunctionalInterface public static interface MediaTranscodeManager.OnTranscodingFinishedListener {
- method public void onTranscodingFinished(@NonNull android.media.MediaTranscodeManager.TranscodingSession);
+ @java.lang.FunctionalInterface public static interface MediaTranscodingManager.OnTranscodingFinishedListener {
+ method public void onTranscodingFinished(@NonNull android.media.MediaTranscodingManager.TranscodingSession);
}
- public abstract static class MediaTranscodeManager.TranscodingRequest {
+ public abstract static class MediaTranscodingManager.TranscodingRequest {
method public int getClientPid();
method public int getClientUid();
method @Nullable public android.os.ParcelFileDescriptor getDestinationFileDescriptor();
@@ -18,13 +18,13 @@ package android.media {
method @NonNull public android.net.Uri getSourceUri();
}
- public static class MediaTranscodeManager.TranscodingRequest.VideoFormatResolver {
- ctor public MediaTranscodeManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat);
+ public static class MediaTranscodingManager.TranscodingRequest.VideoFormatResolver {
+ ctor public MediaTranscodingManager.TranscodingRequest.VideoFormatResolver(@NonNull android.media.ApplicationMediaCapabilities, @NonNull android.media.MediaFormat);
method @Nullable public android.media.MediaFormat resolveVideoFormat();
method public boolean shouldTranscode();
}
- public static final class MediaTranscodeManager.TranscodingSession {
+ public static final class MediaTranscodingManager.TranscodingSession {
method public boolean addClientUid(int);
method public void cancel();
method @NonNull public java.util.List getClientUids();
@@ -33,7 +33,7 @@ package android.media {
method public int getResult();
method public int getSessionId();
method public int getStatus();
- method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener);
+ method public void setOnProgressUpdateListener(@NonNull java.util.concurrent.Executor, @Nullable android.media.MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener);
field public static final int ERROR_DROPPED_BY_SERVICE = 1; // 0x1
field public static final int ERROR_NONE = 0; // 0x0
field public static final int ERROR_SERVICE_DIED = 2; // 0x2
@@ -47,21 +47,21 @@ package android.media {
field public static final int STATUS_RUNNING = 2; // 0x2
}
- @java.lang.FunctionalInterface public static interface MediaTranscodeManager.TranscodingSession.OnProgressUpdateListener {
- method public void onProgressUpdate(@NonNull android.media.MediaTranscodeManager.TranscodingSession, @IntRange(from=0, to=100) int);
+ @java.lang.FunctionalInterface public static interface MediaTranscodingManager.TranscodingSession.OnProgressUpdateListener {
+ method public void onProgressUpdate(@NonNull android.media.MediaTranscodingManager.TranscodingSession, @IntRange(from=0, to=100) int);
}
- public static final class MediaTranscodeManager.VideoTranscodingRequest extends android.media.MediaTranscodeManager.TranscodingRequest {
+ public static final class MediaTranscodingManager.VideoTranscodingRequest extends android.media.MediaTranscodingManager.TranscodingRequest {
method @NonNull public android.media.MediaFormat getVideoTrackFormat();
}
- public static final class MediaTranscodeManager.VideoTranscodingRequest.Builder {
- ctor public MediaTranscodeManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat);
- method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest build();
- method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientPid(int);
- method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setClientUid(int);
- method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
- method @NonNull public android.media.MediaTranscodeManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
+ public static final class MediaTranscodingManager.VideoTranscodingRequest.Builder {
+ ctor public MediaTranscodingManager.VideoTranscodingRequest.Builder(@NonNull android.net.Uri, @NonNull android.net.Uri, @NonNull android.media.MediaFormat);
+ method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest build();
+ method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientPid(int);
+ method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setClientUid(int);
+ method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setDestinationFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
+ method @NonNull public android.media.MediaTranscodingManager.VideoTranscodingRequest.Builder setSourceFileDescriptor(@NonNull android.os.ParcelFileDescriptor);
}
}
diff --git a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
index de2924e160b66..75a56b7231d9a 100644
--- a/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
+++ b/apex/media/framework/java/android/media/MediaFrameworkInitializer.java
@@ -75,8 +75,8 @@ public class MediaFrameworkInitializer {
public static void registerServiceWrappers() {
SystemServiceRegistry.registerContextAwareService(
Context.MEDIA_TRANSCODING_SERVICE,
- MediaTranscodeManager.class,
- context -> new MediaTranscodeManager(context)
+ MediaTranscodingManager.class,
+ context -> new MediaTranscodingManager(context)
);
if (SdkLevel.isAtLeastS()) {
SystemServiceRegistry.registerContextAwareService(
diff --git a/apex/media/framework/java/android/media/MediaTranscodeManager.java b/apex/media/framework/java/android/media/MediaTranscodingManager.java
similarity index 99%
rename from apex/media/framework/java/android/media/MediaTranscodeManager.java
rename to apex/media/framework/java/android/media/MediaTranscodingManager.java
index 5742d43f83b7b..93d58d07f81af 100644
--- a/apex/media/framework/java/android/media/MediaTranscodeManager.java
+++ b/apex/media/framework/java/android/media/MediaTranscodingManager.java
@@ -54,7 +54,7 @@ import java.util.concurrent.Executors;
/**
Android 12 introduces Compatible media transcoding feature. See
- Compatible media transcoding. MediaTranscodeManager provides an interface to the system's media
+ Compatible media transcoding. MediaTranscodingManager provides an interface to the system's media
transcoding service and can be used to transcode media files, e.g. transcoding a video from HEVC to
AVC.
@@ -69,7 +69,7 @@ import java.util.concurrent.Executors;
To transcode a media file, first create a {@link TranscodingRequest} through its builder class
{@link VideoTranscodingRequest.Builder}. Transcode requests are then enqueue to the manager through
- {@link MediaTranscodeManager#enqueueRequest(
+ {@link MediaTranscodingManager#enqueueRequest(
TranscodingRequest, Executor, OnTranscodingFinishedListener)}
TranscodeRequest are processed based on client process's priority and request priority. When a
transcode operation is completed the caller is notified via its
@@ -87,8 +87,8 @@ import java.util.concurrent.Executors;
*/
@MinSdk(Build.VERSION_CODES.S)
@SystemApi
-public final class MediaTranscodeManager {
- private static final String TAG = "MediaTranscodeManager";
+public final class MediaTranscodingManager {
+ private static final String TAG = "MediaTranscodingManager";
/** Maximum number of retry to connect to the service. */
private static final int CONNECT_SERVICE_RETRY_COUNT = 100;
@@ -127,7 +127,7 @@ public final class MediaTranscodeManager {
private final Object mLock = new Object();
@GuardedBy("mLock")
@NonNull private ITranscodingClient mTranscodingClient = null;
- private static MediaTranscodeManager sMediaTranscodeManager;
+ private static MediaTranscodingManager sMediaTranscodingManager;
private void handleTranscodingFinished(int sessionId, TranscodingResultParcel result) {
synchronized (mPendingTranscodingSessions) {
@@ -306,7 +306,7 @@ public final class MediaTranscodeManager {
}
try {
- // Do not set hasRetried for retry initiated by MediaTranscodeManager.
+ // Do not set hasRetried for retry initiated by MediaTranscodingManager.
session.retryInternal(false /*setHasRetried*/);
} catch (Exception re) {
// TODO(hkuang): Return correct error code to the client.
@@ -423,7 +423,7 @@ public final class MediaTranscodeManager {
/**
* @hide
*/
- public MediaTranscodeManager(@NonNull Context context) {
+ public MediaTranscodingManager(@NonNull Context context) {
mContext = context;
mContentResolver = mContext.getContentResolver();
mPackageName = mContext.getPackageName();
@@ -1348,7 +1348,7 @@ public final class MediaTranscodeManager {
@IntRange(from = 0, to = 100) int progress);
}
- private final MediaTranscodeManager mManager;
+ private final MediaTranscodingManager mManager;
private Executor mListenerExecutor;
private OnTranscodingFinishedListener mListener;
private int mSessionId = -1;
@@ -1374,7 +1374,7 @@ public final class MediaTranscodeManager {
private final TranscodingRequest mRequest;
private TranscodingSession(
- @NonNull MediaTranscodeManager manager,
+ @NonNull MediaTranscodingManager manager,
@NonNull TranscodingRequest request,
@NonNull TranscodingSessionParcel parcel,
@NonNull @CallbackExecutor Executor executor,
@@ -1675,10 +1675,10 @@ public final class MediaTranscodeManager {
/**
* Enqueues a TranscodingRequest for execution.
- *
Upon successfully accepting the request, MediaTranscodeManager will return a
+ *
Upon successfully accepting the request, MediaTranscodingManager will return a
* {@link TranscodingSession} to the client. Client should use {@link TranscodingSession} to
* track the progress and get the result.
- *
MediaTranscodeManager will return null if fails to accept the request due to service
+ *
MediaTranscodingManager will return null if fails to accept the request due to service
* rebooting. Client could retry again after receiving null.
*
* @param transcodingRequest The TranscodingRequest to enqueue.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index c02dcfd3d6815..27027721109df 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4464,11 +4464,11 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a {@link
- * android.media.MediaTranscodeManager} for transcoding media.
+ * android.media.MediaTranscodingManager} for transcoding media.
*
* @hide
* @see #getSystemService(String)
- * @see android.media.MediaTranscodeManager
+ * @see android.media.MediaTranscodingManager
*/
@SystemApi
public static final String MEDIA_TRANSCODING_SERVICE = "media_transcoding";
From 76926b0c629e64890415ae0586e0031675f6a6f8 Mon Sep 17 00:00:00 2001
From: Joe Bolinger
Date: Tue, 10 Aug 2021 14:20:12 -0700
Subject: [PATCH 08/26] Remove new task flag when launching unicorn enrollment.
Bug: 196103931
Test: manual (enroll via settings)
Change-Id: I35aae96e4ebb0c13bc567bb926f2e7a549f554ba
(cherry picked from commit 6c582e973d2bb8eb03edf974dd3ce2222837aaf1)
---
.../enterprise/BiometricActionDisabledByAdminController.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
index e0339dacf5ac9..d205eaab66565 100644
--- a/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/enterprise/BiometricActionDisabledByAdminController.java
@@ -65,7 +65,6 @@ public class BiometricActionDisabledByAdminController extends BaseActionDisabled
Log.d(TAG, "Positive button clicked, component: " + enforcedAdmin.component);
final Intent intent = new Intent(ACTION_LEARN_MORE)
.putExtra(EXTRA_SETTING_KEY, EXTRA_SETTING_VALUE)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.setPackage(enforcedAdmin.component.getPackageName());
context.startActivity(intent);
};
From 455f98831b18c6b4280959da5824b2b3086b3ad4 Mon Sep 17 00:00:00 2001
From: Jayant Chowdhary
Date: Mon, 9 Aug 2021 23:34:04 +0000
Subject: [PATCH 09/26] camera2: Documentation updates for ultra high
resolution sensors.
Bug: 195987968
1) Document mininum pixel array size restriction for ultra high resolution sensors.
2) Add docs explaining mandatory stream combinations for ultra high resolution sensors.
Change-Id: Ic630259a57906c475210465588eda1a5cc3f68ec
Signed-off-by: Jayant Chowdhary
(cherry picked from commit 1f3071d540fcefca6ca941568b7486657cd9198a)
---
.../hardware/camera2/CameraDevice.java | 27 +++++++++++++++++++
.../hardware/camera2/CameraMetadata.java | 6 ++++-
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index af48b71f99621..3c1ec3e629a9c 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -807,6 +807,23 @@ public abstract class CameraDevice implements AutoCloseable {
* The same logic applies to other hardware levels and capabilities.
*
*
+ * Devices with the ULTRA_HIGH_RESOLUTION_SENSOR capability have some additional guarantees
+ * which clients can take advantage of :
+ *
+ * | Additional guaranteed combinations for ULTRA_HIGH_RESOLUTION sensors |
+ * | Target 1 | Target 2 | Target 3 | Sample use case(s) |
+ * | Type | SC Map | Max size | Type | SC Map | Max size | Type | SC Map | Max size |
+ * | {@code YUV / JPEG / RAW} | {@code MAX_RES} | {@code MAX} | {@code PRIV / YUV} | {@code DEFAULT} | {@code PREVIEW} | | Ultra high res still image capture with preview |
+ * | {@code YUV / JPEG / RAW} | {@code MAX_RES} | {@code MAX} | {@code PRIV} | {@code DEFAULT} | {@code PREVIEW} | {@code PRIV / YUV} | {@code DEFAULT} | {@code RECORD} | Ultra high res still capture with preview + app based RECORD size analysis |
+ * | {@code YUV / JPEG / RAW} | {@code MAX_RES} | {@code MAX} | {@code PRIV} | {@code DEFAULT} | {@code PREVIEW} | {@code JPEG / YUV / RAW} | {@code DEFAULT} | {@code MAX} | Ultra high res still image capture with preview + default sensor pixel mode analysis stream |
+ *
+ *
+ * Here, SC Map, refers to the {@link StreamConfigurationMap}, the target stream sizes must
+ * be chosen from. {@code DEFAULT} refers to the default sensor pixel mode {@link
+ * StreamConfigurationMap} and {@code MAX_RES} refers to the maximum resolution {@link
+ * StreamConfigurationMap}. The same capture request must not mix targets from
+ * {@link StreamConfigurationMap}s corresponding to different sensor pixel modes.
+ *
*
Since the capabilities of camera devices vary greatly, a given camera device may support
* target combinations with sizes outside of these guarantees, but this can only be tested for
* by calling {@link #isSessionConfigurationSupported} or attempting to create a session with
@@ -989,6 +1006,16 @@ public abstract class CameraDevice implements AutoCloseable {
*
| {@code PRIV} | {@code MULTI_RES} | {@code PRIV} | {@code MULTI_RES} | {@code YUV} | {@code PREVIEW} | {@code YUV} | {@code MULTI_RES} | | | Maximum-resolution two-input ZSL in-app processing. |
* | {@code PRIV}/{@code YUV} | {@code MULTI_RES} | Same as input | {@code MULTI_RES} | {@code PRIV} | {@code PREVIEW} | {@code YUV} | {@code PREVIEW} | {@code JPEG} | {@code MULTI_RES} | ZSL still capture and in-app processing. |
*
+ * Devices with the ULTRA_HIGH_RESOLUTION_SENSOR capability have some additional guarantees
+ * which clients can take advantage of :
+ *
+ * | Additional guaranteed combinations for ULTRA_HIGH_RESOLUTION sensors (YUV / PRIV inputs are guaranteed only if YUV / PRIVATE reprocessing are supported) |
+ * | Input | Target 1 | Target 2 | Target 3 | Sample use case(s) |
+ * | Type | SC Map | Max size | Type | SC Map | Max size | Type | SC Map | Max size | Type | SC Map | Max size |
+ * | {@code RAW} | {@code MAX_RES} | {@code MAX} | {@code RAW} | {@code MAX_RES} | {@code MAX} | {@code PRIV / YUV} | {@code DEFAULT} | {@code PREVIEW} | | RAW remosaic reprocessing with seperate preview |
+ * | {@code RAW} | {@code MAX_RES} | {@code MAX} | {@code RAW} | {@code MAX_RES} | {@code MAX} | {@code PRIV / YUV} | {@code DEFAULT} | {@code PREVIEW} | {@code JPEG / YUV} | {@code MAX_RES} | {@code MAX} | Ultra high res RAW -> JPEG / YUV with seperate preview |
+ * | {@code YUV / PRIV} | {@code MAX_RES} | {@code MAX} | {@code YUV / PRIV} | {@code MAX_RES} | {@code MAX} | {@code YUV / PRIV} | {@code DEFAULT} | {@code PREVIEW} | {@code JPEG } | {@code MAX_RES} | {@code MAX} | Ultra high res PRIV / YUV -> YUV / JPEG reprocessing with seperate preview |
+ *
* No additional mandatory stream combinations for RAW capability and LEVEL-3 hardware level.
*
*
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index d9fa56e1cbaac..4b35294826dbb 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1138,10 +1138,14 @@ public abstract class CameraMetadata {
* {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP android.scaler.streamConfigurationMap} describes the streams supported in 'default'
* mode.
* The stream configurations supported in 'max resolution' mode are described by
- * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}.
+ * {@link CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION android.scaler.streamConfigurationMapMaximumResolution}.
+ * The maximum resolution mode pixel array size of a camera device
+ * ({@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}) with this capability,
+ * will be at least 24 megapixels.
*
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP
* @see CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP_MAXIMUM_RESOLUTION
+ * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_ULTRA_HIGH_RESOLUTION_SENSOR = 16;
From 842915025f1842ef397e2fa855a4866004ad813e Mon Sep 17 00:00:00 2001
From: Emilian Peev
Date: Tue, 10 Aug 2021 17:07:17 -0700
Subject: [PATCH 10/26] Camera: Initialize the forward processor along with the
repeating pipeline
Some preview extensions of the image processor type expect to recevive
'onOutputSurface' calls before the session is enabled by 'onEnableSession'.
Bug: 187341271
Test: atest -c
cts/tests/camera/src/android/hardware/camera2/cts/CameraExtensionSessionTest.java
Change-Id: I67147ec24553cf87d23e33c63692fa7e59c57e5f
(cherry picked from commit a0ced2aa9ec636417d085696c9274d6cd17713a0)
---
.../hardware/camera2/impl/CameraExtensionSessionImpl.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index ecd24914c566c..71047af69b87a 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -251,6 +251,7 @@ public final class CameraExtensionSessionImpl extends CameraExtensionSession {
CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT);
mPreviewImageProcessor.onResolutionUpdate(new Size(repeatingSurfaceInfo.mWidth,
repeatingSurfaceInfo.mHeight));
+ mPreviewImageProcessor.onOutputSurface(null, -1);
mRepeatingRequestImageReader = ImageReader.newInstance(repeatingSurfaceInfo.mWidth,
repeatingSurfaceInfo.mHeight,
CameraExtensionCharacteristics.PROCESSING_INPUT_FORMAT, PREVIEW_QUEUE_SIZE,
From cbe8bc36eb6f180dbdfb764679105612c5d0b363 Mon Sep 17 00:00:00 2001
From: Ahaan Ugale
Date: Thu, 12 Aug 2021 14:08:52 -0700
Subject: [PATCH 11/26] Fix OOB crash in ContentCapture for translated views
When a view is partially visible on the screen, ContentCapture reports
only the visible portion (+ a few additional lines). The offsets
calculated for this can be out of bounds if the view's displayed text
is longer from the original text.
Fix: 196414491
Test: manual - translate app to lang with more characters and trigger
a relayout (by scrolling for an app with ListView)
Test: atest CtsContentCaptureServiceTestCases
Change-Id: Iae98133c48cc67a0b00f1b0ab8b93e5adb293423
(cherry picked from commit 273a0eabc8faa46349c63a6836ae4004709aeb0b)
---
core/java/android/widget/TextView.java | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index ca6e735f86b42..f5c1bcf2de42e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -11857,6 +11857,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (text != null) {
if (expandedTopChar > 0 || expandedBottomChar < text.length()) {
+ // Cap the offsets to avoid an OOB exception. That can happen if the
+ // displayed/layout text, on which these offsets are calculated, is longer
+ // than the original text (such as when the view is translated by the
+ // platform intelligence).
+ // TODO(b/196433694): Figure out how to better handle the offset
+ // calculations for this case (so we don't unnecessarily cutoff the original
+ // text, for example).
+ expandedTopChar = Math.min(expandedTopChar, text.length());
+ expandedBottomChar = Math.min(expandedBottomChar, text.length());
text = text.subSequence(expandedTopChar, expandedBottomChar);
}
From 580ce0ec16ac83bcb18e9b450be882f58d2ccca2 Mon Sep 17 00:00:00 2001
From: Fabian Kozynski
Date: Fri, 13 Aug 2021 15:50:51 -0400
Subject: [PATCH 12/26] Remove managed profile icon from QSBH
This adds it to the ignored icons in QuickStatusBarHeaderController
iconContainer.
Test: manual, create managed profile, icon doesn't show.
Fixes: 196243622
Change-Id: Ib97b9d947318b09d289076c63995327d356cb5fc
(cherry picked from commit 1c785319223566f162e75abb67498337a450aab7)
---
.../com/android/systemui/qs/QuickStatusBarHeaderController.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index b8b7f42455bba..da75c9e45c541 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -178,6 +178,8 @@ class QuickStatusBarHeaderController extends ViewController
Date: Thu, 12 Aug 2021 14:11:25 +0800
Subject: [PATCH 13/26] Don't create one-handed-background-panel after rotation
From code flow, when onConfigurationChanged() by rotating
OneHandedBackgroundPanelOrganizer#showBackgroundPanelLayer()
will be invoked and then create one-handed-background-panel
even though OHM is not activated.
Besides, this could introduce overhead on SF.
Test: manual rotate and dumpsys check HWC layers
Test: atest WMShellUnitTests
Bug: 196306312
Change-Id: Ia766078d5c76b08ab5b24e0ce965ad1d085e4686
(cherry picked from commit 27da5b04d44e76e884f8148684eb36311923c651)
---
.../OneHandedBackgroundPanelOrganizer.java | 17 ++++++++++++++++-
.../shell/onehanded/OneHandedController.java | 1 +
...OneHandedBackgroundPanelOrganizerTest.java | 19 +++++++++++++++++++
3 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
index 97461e607e667..d3274706631b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
@@ -16,6 +16,8 @@
package com.android.wm.shell.onehanded;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
+
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Color;
@@ -46,7 +48,7 @@ import java.util.concurrent.Executor;
* the screen has entered one handed mode.
*/
public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
- implements OneHandedAnimationCallback {
+ implements OneHandedAnimationCallback, OneHandedState.OnStateChangedListener {
private static final String TAG = "OneHandedBackgroundPanelOrganizer";
private static final int THEME_COLOR_OFFSET = 10;
private static final int ALPHA_ANIMATION_DURATION = 200;
@@ -56,6 +58,7 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
private final OneHandedSurfaceTransactionHelper.SurfaceControlTransactionFactory
mTransactionFactory;
+ private @OneHandedState.State int mCurrentState;
private ValueAnimator mAlphaAnimator;
private float mTranslationFraction;
@@ -180,6 +183,9 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
* Called when transition finished.
*/
public void onStopFinished() {
+ if (mAlphaAnimator == null) {
+ return;
+ }
mAlphaAnimator.start();
}
@@ -224,6 +230,10 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
*/
public void onConfigurationChanged() {
updateThemeColors();
+
+ if (mCurrentState != STATE_ACTIVE) {
+ return;
+ }
showBackgroundPanelLayer();
}
@@ -242,6 +252,11 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
return Math.max(origColor - THEME_COLOR_OFFSET, 0) / 255.0f;
}
+ @Override
+ public void onStateChanged(int newState) {
+ mCurrentState = newState;
+ }
+
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
pw.println(TAG);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index b0fe856df7c8c..954ca14b49601 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -307,6 +307,7 @@ public class OneHandedController implements RemoteCallable
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityStateChangeListener);
+ mState.addSListeners(mBackgroundPanelOrganizer);
mState.addSListeners(mTutorialHandler);
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
index 99c610765c046..7b9553c5ef9b2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizerTest.java
@@ -19,6 +19,9 @@ package com.android.wm.shell.onehanded;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.window.DisplayAreaOrganizer.FEATURE_ONE_HANDED_BACKGROUND_PANEL;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE;
+import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -109,4 +112,20 @@ public class OneHandedBackgroundPanelOrganizerTest extends OneHandedTestCase {
assertThat(mSpiedBackgroundPanelOrganizer.mBackgroundSurface).isNull();
}
+
+ @Test
+ public void testStateNone_onConfigurationChanged() {
+ mSpiedBackgroundPanelOrganizer.onStateChanged(STATE_NONE);
+ mSpiedBackgroundPanelOrganizer.onConfigurationChanged();
+
+ verify(mSpiedBackgroundPanelOrganizer, never()).showBackgroundPanelLayer();
+ }
+
+ @Test
+ public void testStateActivate_onConfigurationChanged() {
+ mSpiedBackgroundPanelOrganizer.onStateChanged(STATE_ACTIVE);
+ mSpiedBackgroundPanelOrganizer.onConfigurationChanged();
+
+ verify(mSpiedBackgroundPanelOrganizer).showBackgroundPanelLayer();
+ }
}
From 773d4f36fcec4a5db1057dc4ff00cb3ffde0a304 Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Tue, 10 Aug 2021 12:11:18 -0600
Subject: [PATCH 14/26] Preserve certain "Nearby devices" implicit grants.
We're willing to preserve an implicit "Nearby devices" permission
grant if this app was already able to interact with nearby devices
via background location access.
If the app doesn't have background location access, then the implicit
"Nearby devices" grant will be revoked as normal. If the "Nearby
devices" permission had already been revoked through some other
means, it will remain revoked.
Bug: 195931693
Test: atest CtsPermission2TestCases CtsPermission3TestCases
Change-Id: I7d8df91954525da6473f70cb1759d9507e6a5606
(cherry picked from commit e2e6e67bf7e57cb5b2d1e530af9e79711f04f8de)
---
.../permission/PermissionManagerService.java | 24 ++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
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 08a67d7f4bb5e..1133faabcf691 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -217,6 +217,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
/** All storage permissions */
private static final List STORAGE_PERMISSIONS = new ArrayList<>();
+ /** All nearby devices permissions */
+ private static final List NEARBY_DEVICES_PERMISSIONS = new ArrayList<>();
/** If the permission of the value is granted, so is the key */
private static final Map FULLER_PERMISSION_MAP = new HashMap<>();
@@ -233,6 +235,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
STORAGE_PERMISSIONS.add(Manifest.permission.ACCESS_MEDIA_LOCATION);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_ADVERTISE);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
}
/** Set of source package names for Privileged Permission Allowlist */
@@ -3076,13 +3081,26 @@ public class PermissionManagerService extends IPermissionManager.Stub {
Permission bp = mRegistry.getPermission(permission);
if (bp != null && bp.isRuntime()) {
int flags = ps.getPermissionFlags(permission);
-
if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
-
int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
+ // We're willing to preserve an implicit "Nearby devices"
+ // permission grant if this app was already able to interact
+ // with nearby devices via background location access
+ boolean preserveGrant = false;
+ if (ArrayUtils.contains(NEARBY_DEVICES_PERMISSIONS, permission)
+ && ps.isPermissionGranted(
+ android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
+ && (ps.getPermissionFlags(
+ android.Manifest.permission.ACCESS_BACKGROUND_LOCATION)
+ & (FLAG_PERMISSION_REVOKE_WHEN_REQUESTED
+ | FLAG_PERMISSION_REVOKED_COMPAT)) == 0) {
+ preserveGrant = true;
+ }
+
if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
- && supportsRuntimePermissions) {
+ && supportsRuntimePermissions
+ && !preserveGrant) {
if (ps.revokePermission(bp)) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Revoking runtime permission "
From 991fe9a310898868e671cb758f4b0fbea77c5a7c Mon Sep 17 00:00:00 2001
From: Evan Laird
Date: Fri, 13 Aug 2021 16:39:20 -0400
Subject: [PATCH 15/26] DO NOT MERGE: Register NetworkController to DumpManager
It seems that enough Dependency.get() calls were removed for
NetworkController that the dumpsys stopped including NetworkController
in it. This CL manually registers NetworkController so we can have those
logs back.
Test: `adb shell dumpsys activity service com.android.systemui/.SystemUIService | grep NetworkController`
Fixes: 196486687
Change-Id: Id8865dd2159a6e3d85ebe80a3d0c4e05d0c16491
(cherry picked from commit 2b79873e29155f680efb6dafb968340f45d346a0)
---
.../statusbar/policy/NetworkControllerImpl.java | 14 +++++++++++---
.../policy/NetworkControllerBaseTest.java | 8 ++++++--
.../policy/NetworkControllerDataTest.java | 3 ++-
.../policy/NetworkControllerSignalTest.java | 10 +++++++---
4 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index fa6111589bff7..c49de7ab0e5de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -70,6 +70,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -126,6 +127,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
private Config mConfig;
private final CarrierConfigTracker mCarrierConfigTracker;
private final FeatureFlags mFeatureFlags;
+ private final DumpManager mDumpManager;
private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
@@ -218,7 +220,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
AccessPointControllerImpl accessPointController,
DemoModeController demoModeController,
CarrierConfigTracker carrierConfigTracker,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ DumpManager dumpManager) {
this(context, connectivityManager,
telephonyManager,
telephonyListenerManager,
@@ -236,7 +239,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
broadcastDispatcher,
demoModeController,
carrierConfigTracker,
- featureFlags);
+ featureFlags,
+ dumpManager);
mReceiverHandler.post(mRegisterListeners);
}
@@ -256,7 +260,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
BroadcastDispatcher broadcastDispatcher,
DemoModeController demoModeController,
CarrierConfigTracker carrierConfigTracker,
- FeatureFlags featureFlags
+ FeatureFlags featureFlags,
+ DumpManager dumpManager
) {
mContext = context;
mTelephonyListenerManager = telephonyListenerManager;
@@ -275,6 +280,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mDemoModeController = demoModeController;
mCarrierConfigTracker = carrierConfigTracker;
mFeatureFlags = featureFlags;
+ mDumpManager = dumpManager;
// telephony
mPhone = telephonyManager;
@@ -425,6 +431,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
mDemoModeController.addCallback(this);
mProviderModelBehavior = mFeatureFlags.isCombinedStatusBarSignalIconsEnabled();
mProviderModelSetting = mFeatureFlags.isProviderModelSettingEnabled();
+
+ mDumpManager.registerDumpable(TAG, this);
}
private final Runnable mClearForceValidated = () -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index f2de26c29805d..6c4ec223969ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -70,6 +70,7 @@ import com.android.settingslib.net.DataUsageController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.FeatureFlags;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
@@ -241,7 +242,9 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
mMockBd,
mDemoModeController,
mCarrierConfigTracker,
- mFeatureFlags);
+ mFeatureFlags,
+ mock(DumpManager.class)
+ );
setupNetworkController();
// Trigger blank callbacks to always get the current state (some tests don't trigger
@@ -309,7 +312,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
- mCarrierConfigTracker, mFeatureFlags);
+ mCarrierConfigTracker, mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index bc4c2b69e3f04..3433a14f54e7a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -21,6 +21,7 @@ import android.testing.TestableLooper.RunWithLooper;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
@@ -113,7 +114,7 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
mock(AccessPointControllerImpl.class),
mock(DataUsageController.class), mMockSubDefaults,
mock(DeviceProvisionedController.class), mMockBd, mDemoModeController,
- mock(CarrierConfigTracker.class), mFeatureFlags);
+ mock(CarrierConfigTracker.class), mFeatureFlags, mock(DumpManager.class));
setupNetworkController();
setupDefaultSignal();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 5090b0dbc2a63..4ff13011567b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -41,6 +41,7 @@ import com.android.settingslib.graph.SignalDrawable;
import com.android.settingslib.mobile.TelephonyIcons;
import com.android.settingslib.net.DataUsageController;
import com.android.systemui.R;
+import com.android.systemui.dump.DumpManager;
import com.android.systemui.util.CarrierConfigTracker;
import org.junit.Test;
@@ -67,7 +68,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
verifyLastMobileDataIndicators(false, -1, 0);
@@ -87,7 +89,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
mNetworkController.registerListeners();
// Wait for the main looper to execute the previous command
@@ -155,7 +158,8 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
Looper.getMainLooper(), mFakeExecutor, mCallbackHandler,
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
- mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags);
+ mDemoModeController, mock(CarrierConfigTracker.class), mFeatureFlags,
+ mock(DumpManager.class));
setupNetworkController();
// No Subscriptions.
From 436f041ed91aaa604c3f8e30c8ff59dc7088dbc8 Mon Sep 17 00:00:00 2001
From: Joe Bolinger
Date: Fri, 13 Aug 2021 15:36:56 -0700
Subject: [PATCH 16/26] Add a generic error message for missing vendor error
strings.
The message is empty, instead of null, to prevent apps from crashing but it will be changed to a more meaninful string in a future change.
Fix: 196176475
Test: N/A
Change-Id: I7823084238a87cb1b8892b8550c472cd8b40f556
(cherry picked from commit 5d5d9eb8122b33705a864a1946da479af2bd10db)
---
core/java/android/hardware/face/FaceManager.java | 5 +++++
.../android/hardware/fingerprint/FingerprintManager.java | 7 ++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 3c3ba595f3fb9..385ad2d3577fe 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -790,6 +790,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
}
}
+
+ // This is used as a last resort in case a vendor string is missing
+ // It should not happen for anything other than FACE_ERROR_VENDOR, but
+ // warn and use the default if all else fails.
+ // TODO(b/196639965): update string
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
return "";
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index dc1a50fa66161..87d45b9de745b 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1386,8 +1386,13 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
}
}
}
+
+ // This is used as a last resort in case a vendor string is missing
+ // It should not happen for anything other than FINGERPRINT_ERROR_VENDOR, but
+ // warn and use the default if all else fails.
+ // TODO(b/196639965): update string
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
- return null;
+ return "";
}
/**
From 85b1919f458aacfc1931468a68d5feb838afe814 Mon Sep 17 00:00:00 2001
From: Ryan Mitchell
Date: Thu, 12 Aug 2021 09:36:53 -0700
Subject: [PATCH 17/26] Guard against null info when applying widget RROs
Add null checks to applyResourceOverlaysToWidgetsLocked to protect
against a widget provider component info being null.
Fixes: 196231621
Fixes: 196331791
Test: none
Change-Id: Ia762694523404ac508eb49600306048037f13658
(cherry picked from commit 8c86f395be220c16434b3c1b1d657d1d6795dda8)
---
.../com/android/server/appwidget/AppWidgetServiceImpl.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index a56b1db1494c8..c32543ae5c13d 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -3306,11 +3306,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
Slog.w(TAG, "Failed to retrieve app info for " + packageName
+ " userId=" + userId, e);
}
- if (newAppInfo == null) {
+ if (newAppInfo == null || provider.info == null
+ || provider.info.providerInfo == null) {
continue;
}
ApplicationInfo oldAppInfo = provider.info.providerInfo.applicationInfo;
- if (!newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) {
+ if (oldAppInfo == null || !newAppInfo.sourceDir.equals(oldAppInfo.sourceDir)) {
// Overlay paths are generated against a particular version of an application.
// The overlays paths of a newly upgraded application are incompatible with the
// old version of the application.
From 2cf61babf8de1e5e3a45770632fa067556021291 Mon Sep 17 00:00:00 2001
From: Winson Chiu
Date: Fri, 13 Aug 2021 20:54:40 +0000
Subject: [PATCH 18/26] Revert "Use StorageManager#isUserKeyUnlocked to
determine CE storage in PMS"
This reverts commit 76e6f9d221567f5a3b3726e7a67d3551198356f3.
Reason for revert: b/196030595
Bug: 196030595
Change-Id: Idf42eee3277ceace275aad3e11c7ee692f1171a6
(cherry picked from commit 864538dd29bb6d470be5ee11f54b398a681f735c)
---
.../java/com/android/server/pm/PackageManagerService.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 904a1f0d6f4fc..c4775463ee75f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -22528,7 +22528,7 @@ public class PackageManagerService extends IPackageManager.Stub
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
final int flags;
- if (StorageManager.isUserKeyUnlocked(userId)) {
+ if (umInternal.isUserUnlockingOrUnlocked(userId)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(userId)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25395,7 +25395,7 @@ public class PackageManagerService extends IPackageManager.Stub
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
final int flags;
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25735,7 +25735,7 @@ public class PackageManagerService extends IPackageManager.Stub
StorageManagerInternal smInternal = mInjector.getLocalService(StorageManagerInternal.class);
for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
final int flags;
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
} else if (umInternal.isUserRunning(user.id)) {
flags = StorageManager.FLAG_STORAGE_DE;
@@ -25749,7 +25749,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Note: this code block is executed with the Installer lock
// already held, since it's invoked as a side-effect of
// executeBatchLI()
- if (StorageManager.isUserKeyUnlocked(user.id)) {
+ if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
// Prepare app data on external storage; currently this is used to
// setup any OBB dirs that were created by the installer correctly.
int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
From fb0db2652a8ec3d631c439b47075f52a4dc15de1 Mon Sep 17 00:00:00 2001
From: Edgar Wang
Date: Fri, 2 Jul 2021 17:05:03 +0800
Subject: [PATCH 19/26] Fix lint error for those module used in mainline module
Bug: 187861723
Test: rebuild
Change-Id: I3a8c9e00f164d0f0dd381b188ecfd0c4a758a277
Merged-In: I3a8c9e00f164d0f0dd381b188ecfd0c4a758a277
(cherry picked from commit d56251bae4a305f5668adce8bfbfa1b31b8dc5e3)
---
.../SettingsLib/ActionBarShadow/Android.bp | 2 +-
.../ActionBarShadow/lint-baseline.xml | 37 ---------
.../ActionButtonsPreference/lint-baseline.xml | 81 -------------------
.../res/drawable/half_rounded_left_bk.xml | 2 +
.../res/drawable/half_rounded_right_bk.xml | 28 ++++---
.../res/drawable/rounded_bk.xml | 28 ++++---
.../res/values/styles.xml | 4 +-
.../SettingsLib/BarChartPreference/Android.bp | 2 +-
.../BarChartPreference/lint-baseline.xml | 15 ----
.../BarChartPreference/res/values/styles.xml | 4 +-
.../SettingsLib/HelpUtils/lint-baseline.xml | 15 ----
.../com/android/settingslib/HelpUtils.java | 28 ++++++-
.../SettingsLib/ProgressBar/lint-baseline.xml | 15 ----
.../res/layout/progress_header.xml | 2 +
.../RestrictedLockUtils/lint-baseline.xml | 26 ------
.../settingslib/RestrictedLockUtils.java | 15 ++++
.../SettingsSpinner/lint-baseline.xml | 15 ----
.../settingsspinner/SettingsSpinner.java | 4 +
18 files changed, 88 insertions(+), 235 deletions(-)
delete mode 100644 packages/SettingsLib/ActionBarShadow/lint-baseline.xml
delete mode 100644 packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
delete mode 100644 packages/SettingsLib/BarChartPreference/lint-baseline.xml
delete mode 100644 packages/SettingsLib/HelpUtils/lint-baseline.xml
delete mode 100644 packages/SettingsLib/ProgressBar/lint-baseline.xml
delete mode 100644 packages/SettingsLib/RestrictedLockUtils/lint-baseline.xml
delete mode 100644 packages/SettingsLib/SettingsSpinner/lint-baseline.xml
diff --git a/packages/SettingsLib/ActionBarShadow/Android.bp b/packages/SettingsLib/ActionBarShadow/Android.bp
index 800ab671cedba..4a07d49fcde51 100644
--- a/packages/SettingsLib/ActionBarShadow/Android.bp
+++ b/packages/SettingsLib/ActionBarShadow/Android.bp
@@ -19,5 +19,5 @@ android_library {
],
sdk_version: "system_current",
- min_sdk_version: "21",
+ min_sdk_version: "28",
}
diff --git a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml b/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
deleted file mode 100644
index 4d5de5f46894f..0000000000000
--- a/packages/SettingsLib/ActionBarShadow/lint-baseline.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml b/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
deleted file mode 100644
index 95b7e3b8033d7..0000000000000
--- a/packages/SettingsLib/ActionButtonsPreference/lint-baseline.xml
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
index 16a85d694bf81..8a25726ecd174 100644
--- a/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
+++ b/packages/SettingsLib/ActionButtonsPreference/res/drawable/half_rounded_left_bk.xml
@@ -17,6 +17,8 @@
-
+