Merge branch 'q' of https://github.com/BlissRoms/platform_frameworks_base into pixel
Change-Id: Iee47bdd51304f04a359ed69d0ad166868e491c89
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index a15caa0..44842c6 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -2082,6 +2082,7 @@
/**
* Get the value set in {@link SessionParams#setOriginatingUri(Uri)}.
+ * Note: This value will only be non-null for the owner of the session.
*/
public @Nullable Uri getOriginatingUri() {
return originatingUri;
@@ -2096,6 +2097,7 @@
/**
* Get the value set in {@link SessionParams#setReferrerUri(Uri)}
+ * Note: This value will only be non-null for the owner of the session.
*/
public @Nullable Uri getReferrerUri() {
return referrerUri;
diff --git a/core/res/res/values/bliss_config.xml b/core/res/res/values/bliss_config.xml
index 71d8f69..0ad0ad9 100644
--- a/core/res/res/values/bliss_config.xml
+++ b/core/res/res/values/bliss_config.xml
@@ -176,4 +176,7 @@
<!-- Default fod pressed icon -->
<integer name="config_pressed_fod_icon">0</integer>
+ <!-- Whether device uses linear screen brightness slider -->
+ <bool name="config_linearBrightnessSlider">false</bool>
+
</resources>
diff --git a/core/res/res/values/bliss_symbols.xml b/core/res/res/values/bliss_symbols.xml
index a6befd1..6e4cbc8 100644
--- a/core/res/res/values/bliss_symbols.xml
+++ b/core/res/res/values/bliss_symbols.xml
@@ -241,4 +241,6 @@
<!-- Default fod pressed icon -->
<java-symbol type="integer" name="config_pressed_fod_icon" />
+ <!-- Whether device uses linear screen brightness slider -->
+ <java-symbol type="bool" name="config_linearBrightnessSlider" />
</resources>
diff --git a/core/tests/bugreports/src/android/server/bugreports/BugreportManagerTest.java b/core/tests/bugreports/src/android/server/bugreports/BugreportManagerTest.java
index c72707db..1533377 100644
--- a/core/tests/bugreports/src/android/server/bugreports/BugreportManagerTest.java
+++ b/core/tests/bugreports/src/android/server/bugreports/BugreportManagerTest.java
@@ -58,6 +58,8 @@
private Handler mHandler;
private Executor mExecutor;
private BugreportManager mBrm;
+ private File mBugreportFile;
+ private File mScreenshotFile;
private ParcelFileDescriptor mBugreportFd;
private ParcelFileDescriptor mScreenshotFd;
@@ -73,8 +75,10 @@
};
mBrm = getBugreportManager();
- mBugreportFd = parcelFd("bugreport_" + name.getMethodName(), ".zip");
- mScreenshotFd = parcelFd("screenshot_" + name.getMethodName(), ".png");
+ mBugreportFile = createTempFile("bugreport_" + name.getMethodName(), ".zip");
+ mScreenshotFile = createTempFile("screenshot_" + name.getMethodName(), ".png");
+ mBugreportFd = parcelFd(mBugreportFile);
+ mScreenshotFd = parcelFd(mScreenshotFile);
getPermissions();
}
@@ -121,6 +125,21 @@
}
@Test
+ public void normalFlow_full() throws Exception {
+ BugreportCallbackImpl callback = new BugreportCallbackImpl();
+ mBrm.startBugreport(mBugreportFd, mScreenshotFd, full(), mExecutor, callback);
+
+ waitTillDoneOrTimeout(callback);
+ assertThat(callback.isDone()).isTrue();
+ assertThat(callback.getErrorCode()).isEqualTo(
+ BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
+ // bugreport and screenshot files should be empty when user consent timed out.
+ assertThat(mBugreportFile.length()).isEqualTo(0);
+ assertThat(mScreenshotFile.length()).isEqualTo(0);
+ assertFdsAreClosed(mBugreportFd, mScreenshotFd);
+ }
+
+ @Test
public void simultaneousBugreportsNotAllowed() throws Exception {
// Start bugreport #1
BugreportCallbackImpl callback = new BugreportCallbackImpl();
@@ -129,9 +148,10 @@
// Before #1 is done, try to start #2.
assertThat(callback.isDone()).isFalse();
BugreportCallbackImpl callback2 = new BugreportCallbackImpl();
- ParcelFileDescriptor bugreportFd2 = parcelFd("bugreport_2_" + name.getMethodName(), ".zip");
- ParcelFileDescriptor screenshotFd2 =
- parcelFd("screenshot_2_" + name.getMethodName(), ".png");
+ File bugreportFile2 = createTempFile("bugreport_2_" + name.getMethodName(), ".zip");
+ File screenshotFile2 = createTempFile("screenshot_2_" + name.getMethodName(), ".png");
+ ParcelFileDescriptor bugreportFd2 = parcelFd(bugreportFile2);
+ ParcelFileDescriptor screenshotFd2 = parcelFd(screenshotFile2);
mBrm.startBugreport(bugreportFd2, screenshotFd2, wifi(), mExecutor, callback2);
Thread.sleep(500 /* .5s */);
@@ -271,12 +291,16 @@
return bm;
}
- private static ParcelFileDescriptor parcelFd(String prefix, String extension) throws Exception {
- File f = File.createTempFile(prefix, extension);
+ private static File createTempFile(String prefix, String extension) throws Exception {
+ final File f = File.createTempFile(prefix, extension);
f.setReadable(true, true);
f.setWritable(true, true);
+ f.deleteOnExit();
+ return f;
+ }
- return ParcelFileDescriptor.open(f,
+ private static ParcelFileDescriptor parcelFd(File file) throws Exception {
+ return ParcelFileDescriptor.open(file,
ParcelFileDescriptor.MODE_WRITE_ONLY | ParcelFileDescriptor.MODE_APPEND);
}
@@ -342,4 +366,13 @@
private static BugreportParams interactive() {
return new BugreportParams(BugreportParams.BUGREPORT_MODE_INTERACTIVE);
}
+
+ /*
+ * Returns a {@link BugreportParams} for full bugreport that includes a screenshot.
+ *
+ * <p> This can take on the order of minutes to finish
+ */
+ private static BugreportParams full() {
+ return new BugreportParams(BugreportParams.BUGREPORT_MODE_FULL);
+ }
}
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 325eb17..a6f3006 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -18,7 +18,6 @@
import android.app.Notification;
import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -392,13 +391,9 @@
mNiNotificationBuilder.setDefaults(0);
}
- // if not to popup dialog immediately, pending intent will open the dialog
- Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
- PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
mNiNotificationBuilder.setTicker(getNotifTicker(notif, mContext))
.setContentTitle(title)
- .setContentText(message)
- .setContentIntent(pi);
+ .setContentText(message);
notificationManager.notifyAsUser(null, notif.notificationId, mNiNotificationBuilder.build(),
UserHandle.ALL);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 1b6acc1..511367a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -226,7 +226,7 @@
@Nullable
private TouchAnimator createFooterAnimator() {
- if (isQsSettingsEnabled()) {
+ if (isSettingsDisabled() == 2) {
return new TouchAnimator.Builder()
.addFloat(mActionsContainer, "alpha", 1, 1) // contains mRunningServicesButton
.addFloat(mEditContainer, "alpha", 0, 1)
@@ -352,15 +352,25 @@
private void updateClickabilities() {
mMultiUserSwitch.setClickable(mMultiUserSwitch.getVisibility() == View.VISIBLE);
mEdit.setClickable(mEdit.getVisibility() == View.VISIBLE);
- mSettingsButton.setClickable(mSettingsButton.getVisibility() == View.VISIBLE);
+ if (isSettingsDisabled() == 0) {
+ mSettingsButton.setClickable(false);
+ } else if (isSettingsDisabled() == 1) {
+ if (mExpanded) {
+ mSettingsButton.setClickable(true);
+ } else {
+ mSettingsButton.setClickable(false);
+ }
+ } else if (isSettingsDisabled() == 2) {
+ mSettingsButton.setClickable(true);
+ }
}
private void updateVisibilities() {
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
- mSettingsContainer.setVisibility(isSettingsDisabled() || mQsDisabled ? View.GONE : View.VISIBLE);
- mSettingsButton.setVisibility(isSettingsDisabled() ? View.GONE : (isDemo || !mExpanded ? View.VISIBLE : View.VISIBLE));
+ mSettingsContainer.setVisibility(isSettingsDisabled() == 0 || mQsDisabled ? View.GONE : View.VISIBLE);
+ mSettingsButton.setVisibility(isSettingsDisabled() == 0 ? View.GONE : (isDemo || !mExpanded ? (isSettingsDisabled() == 1 ? View.GONE: View.VISIBLE) : View.VISIBLE));
mRunningServicesButton.setVisibility(isServicesEnabled() ? (isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE) : View.GONE);
mMultiUserSwitch.setVisibility(isUserEnabled() ? (showUserSwitcher() ? View.VISIBLE : View.INVISIBLE) : View.GONE);
mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
@@ -391,9 +401,9 @@
}
}
- public boolean isSettingsDisabled() {
+ public int isSettingsDisabled() {
return Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.QS_FOOTER_SHOW_SETTINGS, 1) == 0;
+ Settings.System.QS_FOOTER_SHOW_SETTINGS, 1);
}
public boolean isQsSettingsEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index 52a6c4e..d2f8196 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -543,7 +543,7 @@
this,
REQUEST_CODE,
viewIntent,
- Intent.FLAG_GRANT_READ_URI_PERMISSION))
+ PendingIntent.FLAG_IMMUTABLE))
.addAction(shareAction)
.addAction(deleteAction)
.setAutoCancel(true);
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
index fc1f655..cf24044 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java
@@ -73,6 +73,7 @@
private final ImageView mIcon;
private final ToggleSlider mControl;
private final boolean mAutomaticAvailable;
+ private final boolean mLinearBrightnessSlider;
private final DisplayManager mDisplayManager;
private final CurrentUserTracker mUserTracker;
private final IVrManager mVrManager;
@@ -291,6 +292,8 @@
mAutomaticAvailable = context.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available);
+ mLinearBrightnessSlider = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_linearBrightnessSlider);
mDisplayManager = context.getSystemService(DisplayManager.class);
mVrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
Context.VR_SERVICE));
@@ -398,7 +401,12 @@
setting = Settings.System.SCREEN_BRIGHTNESS;
}
- final int val = convertGammaToLinear(value, min, max);
+ final int val;
+ if (!mLinearBrightnessSlider) {
+ val = convertGammaToLinear(value, min, max);
+ } else {
+ val = (value < min) ? min : value;
+ }
if (stopTracking) {
MetricsLogger.action(mContext, metric, val);
@@ -466,16 +474,22 @@
min = mMinimumBacklight;
max = mMaximumBacklight;
}
- if (val == convertGammaToLinear(mControl.getValue(), min, max)) {
- // If we have more resolution on the slider than we do in the actual setting, then
- // multiple slider positions will map to the same setting value. Thus, if we see a
- // setting value here that maps to the current slider position, we don't bother to
- // calculate the new slider position since it may differ and look like a brightness
- // change to the user even though it isn't one.
- return;
+ if (!mLinearBrightnessSlider) {
+ if (val == convertGammaToLinear(mControl.getValue(), min, max)) {
+ // If we have more resolution on the slider than we do in the actual setting, then
+ // multiple slider positions will map to the same setting value. Thus, if we see a
+ // setting value here that maps to the current slider position, we don't bother to
+ // calculate the new slider position since it may differ and look like a brightness
+ // change to the user even though it isn't one.
+ return;
+ }
+ final int sliderVal = convertLinearToGamma(val, min, max);
+ mControl.setMax(GAMMA_SPACE_MAX);
+ animateSliderTo(sliderVal);
+ } else {
+ mControl.setMax(max - min);
+ animateSliderTo(val - min);
}
- final int sliderVal = convertLinearToGamma(val, min, max);
- animateSliderTo(sliderVal);
}
private void animateSliderTo(int target) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
index b25df5f..5e72808 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/LeakReporter.java
@@ -104,9 +104,13 @@
.setContentText(String.format(
"SystemUI has detected %d leaked objects. Tap to send", garbageCount))
.setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
- .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
+ .setContentIntent(PendingIntent.getActivityAsUser(
+ mContext,
+ 0,
getIntent(hprofFile, dumpFile),
- PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT));
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
+ null,
+ UserHandle.CURRENT));
notiMan.notify(TAG, 0, builder.build());
} catch (IOException e) {
Log.e(TAG, "Couldn't dump heap for leak", e);
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 067becb..a434733 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -316,12 +316,14 @@
.toString());
long identity = Binder.clearCallingIdentity();
try {
- return PendingIntent.getActivity(getContext(),
+ return PendingIntent.getActivityAsUser(getContext(),
0 /* request code */,
NotificationAccessConfirmationActivityContract.launcherIntent(
userId, component, packageTitle),
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT
- | PendingIntent.FLAG_CANCEL_CURRENT);
+ | PendingIntent.FLAG_CANCEL_CURRENT,
+ null /* options */,
+ new UserHandle(userId));
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f979661..27d66f8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3219,6 +3219,10 @@
@Override
public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
throws RemoteException {
+ if (!isCallerShell()) {
+ EventLog.writeEvent(0x534e4554, 160390416, Binder.getCallingUid(), "");
+ throw new SecurityException("Only shell can call it");
+ }
synchronized (this) {
final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
if (app == null) {
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index 4a9ccde..13a2c19 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -217,6 +217,9 @@
}
}
result = lockoutMode != LOCKOUT_NONE; // in a lockout mode
+ if(result) { // lockde out
+ mAlreadyDone = true;
+ }
}
} catch (RemoteException e) {
Slog.e(getLogTag(), "Remote exception", e);
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index d056763..262ecc4 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -967,6 +967,7 @@
if (!client.onError(getHalDeviceId(), errorCode, 0 /* vendorCode */)) {
Slog.w(getTag(), "Cannot send permanent lockout message to client");
}
+
return;
}
startClient(client, true /* initiatedByClient */);
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index 6631345..f9d89d6 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -235,6 +235,10 @@
@Override
public void binderDied() {
+ if (isAlreadyDone()) {
+ Slog.w(getLogTag(), "Binder died but client is finished, ignoring");
+ return;
+ }
// If the current client dies we should cancel the current operation.
Slog.e(getLogTag(), "Binder died, cancelling client");
stop(false /* initiatedByClient */);
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index dd522b9..0f38473 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -21,7 +21,6 @@
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
-import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -645,7 +644,6 @@
.setTicker(accessibilityServicesText)
.setContentTitle(firstLineText)
.setContentText(secondLineText)
- .setContentIntent(PendingIntent.getBroadcast(context, 0, new Intent(), 0))
.build();
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8227e58..ba83762 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -770,26 +770,30 @@
public SessionInfo getSessionInfo(int sessionId) {
synchronized (mSessions) {
final PackageInstallerSession session = mSessions.get(sessionId);
- return session != null ? session.generateInfo() : null;
+
+ return session != null
+ ? session.generateInfoForCaller(true /*withIcon*/, Binder.getCallingUid())
+ : null;
}
}
@Override
public ParceledListSlice<SessionInfo> getStagedSessions() {
- return mStagingManager.getSessions();
+ return mStagingManager.getSessions(Binder.getCallingUid());
}
@Override
public ParceledListSlice<SessionInfo> getAllSessions(int userId) {
+ final int callingUid = Binder.getCallingUid();
mPermissionManager.enforceCrossUserPermission(
- Binder.getCallingUid(), userId, true, false, "getAllSessions");
+ callingUid, userId, true, false, "getAllSessions");
final List<SessionInfo> result = new ArrayList<>();
synchronized (mSessions) {
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
if (session.userId == userId && !session.hasParentSessionId()) {
- result.add(session.generateInfo(false));
+ result.add(session.generateInfoForCaller(false, callingUid));
}
}
}
@@ -807,7 +811,8 @@
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
- SessionInfo info = session.generateInfo(false);
+ SessionInfo info =
+ session.generateInfoForCaller(false /*withIcon*/, Process.SYSTEM_UID);
if (Objects.equals(info.getInstallerPackageName(), installerPackageName)
&& session.userId == userId && !session.hasParentSessionId()) {
result.add(info);
@@ -1251,7 +1256,10 @@
session.markUpdated();
writeSessionsAsync();
if (mOkToSendBroadcasts) {
- mPm.sendSessionUpdatedBroadcast(session.generateInfo(false),
+ // we don't scrub the data here as this is sent only to the installer several
+ // privileged system packages
+ mPm.sendSessionUpdatedBroadcast(
+ session.generateInfoForCaller(false/*icon*/, Process.SYSTEM_UID),
session.userId);
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index b661a85..1976ffd 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -457,11 +457,41 @@
stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
}
- public SessionInfo generateInfo() {
- return generateInfo(true);
+ /**
+ * Returns {@code true} if the {@link SessionInfo} object should be produced with potentially
+ * sensitive data scrubbed from its fields.
+ *
+ * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may
+ * need to be scrubbed
+ */
+ private boolean shouldScrubData(int callingUid) {
+ return !(callingUid < Process.FIRST_APPLICATION_UID || getInstallerUid() == callingUid);
}
- public SessionInfo generateInfo(boolean includeIcon) {
+ /**
+ * Generates a {@link SessionInfo} object for the provided uid. This may result in some fields
+ * that may contain sensitive info being filtered.
+ *
+ * @param includeIcon true if the icon should be included in the object
+ * @param callingUid the uid of the caller; the recipient of the {@link SessionInfo} that may
+ * need to be scrubbed
+ * @see #shouldScrubData(int)
+ */
+ public SessionInfo generateInfoForCaller(boolean includeIcon, int callingUid) {
+ return generateInfoInternal(includeIcon, shouldScrubData(callingUid));
+ }
+
+ /**
+ * Generates a {@link SessionInfo} object to ensure proper hiding of sensitive fields.
+ *
+ * @param includeIcon true if the icon should be included in the object
+ * @see #generateInfoForCaller(boolean, int)
+ */
+ public SessionInfo generateInfoScrubbed(boolean includeIcon) {
+ return generateInfoInternal(includeIcon, true /*scrubData*/);
+ }
+
+ private SessionInfo generateInfoInternal(boolean includeIcon, boolean scrubData) {
final SessionInfo info = new SessionInfo();
synchronized (mLock) {
info.sessionId = sessionId;
@@ -484,9 +514,13 @@
info.appLabel = params.appLabel;
info.installLocation = params.installLocation;
- info.originatingUri = params.originatingUri;
+ if (!scrubData) {
+ info.originatingUri = params.originatingUri;
+ }
info.originatingUid = params.originatingUid;
- info.referrerUri = params.referrerUri;
+ if (!scrubData) {
+ info.referrerUri = params.referrerUri;
+ }
info.grantedRuntimePermissions = params.grantedRuntimePermissions;
info.whitelistedRestrictedPermissions = params.whitelistedRestrictedPermissions;
info.installFlags = params.installFlags;
@@ -2190,7 +2224,7 @@
final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
if (success && isNewInstall && mPm.mInstallerService.okToSendBroadcasts()
&& (params.installFlags & PackageManager.INSTALL_DRY_RUN) == 0) {
- mPm.sendSessionCommitBroadcast(generateInfo(), userId);
+ mPm.sendSessionCommitBroadcast(generateInfoScrubbed(true /*icon*/), userId);
}
mCallback.onSessionFinished(this, success);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 8ba32ea..68b6b51 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1143,13 +1143,6 @@
int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
boolean needUpdate = false;
- if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG,
- "Updating IntentFilterVerificationInfo for package " + packageName
- + " verificationId:" + verificationId
- + " verified=" + verified);
- }
-
// In a success case, we promote from undefined or ASK to ALWAYS. This
// supports a flow where the app fails validation but then ships an updated
// APK that passes, and therefore deserves to be in ALWAYS.
@@ -11774,6 +11767,8 @@
~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
pkg.applicationInfo.privateFlags &=
~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
+ // clear protected broadcasts
+ pkg.protectedBroadcasts = null;
// cap permission priorities
if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
@@ -11782,8 +11777,6 @@
}
}
if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
- // clear protected broadcasts
- pkg.protectedBroadcasts = null;
// ignore export request for single user receivers
if (pkg.receivers != null) {
for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
@@ -14689,19 +14682,32 @@
// Verify: if target already has an installer package, it must
// be signed with the same cert as the caller.
- if (targetPackageSetting.installerPackageName != null) {
- PackageSetting setting = mSettings.mPackages.get(
- targetPackageSetting.installerPackageName);
- // If the currently set package isn't valid, then it's always
- // okay to change it.
- if (setting != null) {
- if (compareSignatures(callerSignature,
- setting.signatures.mSigningDetails.signatures)
- != PackageManager.SIGNATURE_MATCH) {
- throw new SecurityException(
- "Caller does not have same cert as old installer package "
- + targetPackageSetting.installerPackageName);
- }
+ String targetInstallerPackageName =
+ targetPackageSetting.installerPackageName;
+ PackageSetting targetInstallerPkgSetting = targetInstallerPackageName == null ? null :
+ mSettings.mPackages.get(targetInstallerPackageName);
+
+ if (targetInstallerPkgSetting != null) {
+ if (compareSignatures(callerSignature,
+ targetInstallerPkgSetting.signatures.mSigningDetails.signatures)
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as old installer package "
+ + targetInstallerPackageName);
+ }
+ } else if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED) {
+ // This is probably an attempt to exploit vulnerability b/150857253 of taking
+ // privileged installer permissions when the installer has been uninstalled or
+ // was never set.
+ EventLog.writeEvent(0x534e4554, "150857253", callingUid, "");
+
+ if (getUidTargetSdkVersionLockedLPr(callingUid) > Build.VERSION_CODES.Q) {
+ throw new SecurityException("Neither user " + callingUid
+ + " nor current process has " + Manifest.permission.INSTALL_PACKAGES);
+ } else {
+ // If not targeting >Q, fail silently for backwards compatibility
+ return;
}
}
@@ -18271,16 +18277,18 @@
int count = 0;
final String packageName = pkg.packageName;
-
boolean handlesWebUris = false;
- final boolean alreadyVerified;
+ ArraySet<String> domains = new ArraySet<>();
+ final boolean previouslyVerified;
+ boolean hostSetExpanded = false;
+ boolean needToRunVerify = false;
synchronized (mPackages) {
// If this is a new install and we see that we've already run verification for this
// package, we have nothing to do: it means the state was restored from backup.
- final IntentFilterVerificationInfo ivi =
+ IntentFilterVerificationInfo ivi =
mSettings.getIntentFilterVerificationLPr(packageName);
- alreadyVerified = (ivi != null);
- if (!replacing && alreadyVerified) {
+ previouslyVerified = (ivi != null);
+ if (!replacing && previouslyVerified) {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.i(TAG, "Package " + packageName + " already verified: status="
+ ivi.getStatusString());
@@ -18288,77 +18296,107 @@
return;
}
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, " Previous verified hosts: "
+ + (ivi == null ? "[none]" : ivi.getDomainsString()));
+ }
+
// If any filters need to be verified, then all need to be. In addition, we need to
// know whether an updating app has any web navigation intent filters, to re-
// examine handling policy even if not re-verifying.
- boolean needToVerify = false;
+ final boolean needsVerification = needsNetworkVerificationLPr(packageName);
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
if (filter.handlesWebUris(true)) {
handlesWebUris = true;
}
- if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
+ if (needsVerification && filter.needsVerification()) {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG,
- "Intent filter needs verification, so processing all filters");
+ Slog.d(TAG, "autoVerify requested, processing all filters");
}
- needToVerify = true;
+ needToRunVerify = true;
// It's safe to break out here because filter.needsVerification()
- // can only be true if filter.handlesWebUris(true) returns true, so
+ // can only be true if filter.handlesWebUris(true) returned true, so
// we've already noted that.
break;
}
}
}
- // Note whether this app publishes any web navigation handling support at all,
- // and whether there are any web-nav filters that fit the profile for running
- // a verification pass now.
- if (needToVerify) {
+ // Compare the new set of recognized hosts if the app is either requesting
+ // autoVerify or has previously used autoVerify but no longer does.
+ if (needToRunVerify || previouslyVerified) {
final int verificationId = mIntentFilterVerificationToken++;
for (PackageParser.Activity a : pkg.activities) {
for (ActivityIntentInfo filter : a.intents) {
// Run verification against hosts mentioned in any web-nav intent filter,
// even if the filter matches non-web schemes as well
- if (filter.handlesWebUris(false) && needsNetworkVerificationLPr(filter)) {
+ if (filter.handlesWebUris(false /*onlyWebSchemes*/)) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Verification needed for IntentFilter:" + filter.toString());
mIntentFilterVerifier.addOneIntentFilterVerification(
verifierUid, userId, verificationId, filter, packageName);
+ domains.addAll(filter.getHostsList());
count++;
}
}
}
}
+
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, " Update published hosts: " + domains.toString());
+ }
+
+ // If we've previously verified this same host set (or a subset), we can trust that
+ // a current ALWAYS policy is still applicable. If this is the case, we're done.
+ // (If we aren't in ALWAYS, we want to reverify to allow for apps that had failing
+ // hosts in their intent filters, then pushed a new apk that removed them and now
+ // passes.)
+ //
+ // Cases:
+ // + still autoVerify (needToRunVerify):
+ // - preserve current state if all of: unexpanded, in always
+ // - otherwise rerun as usual (fall through)
+ // + no longer autoVerify (alreadyVerified && !needToRunVerify)
+ // - wipe verification history always
+ // - preserve current state if all of: unexpanded, in always
+ hostSetExpanded = !previouslyVerified
+ || (ivi != null && !ivi.getDomains().containsAll(domains));
+ final int currentPolicy =
+ mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
+ final boolean keepCurState = !hostSetExpanded
+ && currentPolicy == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+
+ if (needToRunVerify && keepCurState) {
+ if (DEBUG_DOMAIN_VERIFICATION) {
+ Slog.i(TAG, "Host set not expanding + ALWAYS -> no need to reverify");
+ }
+ ivi.setDomains(domains);
+ scheduleWriteSettingsLocked();
+ return;
+ } else if (previouslyVerified && !needToRunVerify) {
+ // Prior autoVerify state but not requesting it now. Clear autoVerify history,
+ // and preserve the always policy iff the host set is not expanding.
+ clearIntentFilterVerificationsLPw(packageName, userId, !keepCurState);
+ return;
+ }
}
- if (count > 0) {
- // count > 0 means that we're running a full verification pass
+ if (needToRunVerify && count > 0) {
+ // app requested autoVerify and has at least one matching intent filter
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
+ " IntentFilter verification" + (count > 1 ? "s" : "")
+ " for userId:" + userId);
mIntentFilterVerifier.startVerifications(userId);
- } else if (alreadyVerified && handlesWebUris) {
- // App used autoVerify in the past, no longer does, but still handles web
- // navigation starts.
- if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG, "App changed web filters but no longer verifying - resetting policy");
- }
- synchronized (mPackages) {
- clearIntentFilterVerificationsLPw(packageName, userId);
- }
} else {
if (DEBUG_DOMAIN_VERIFICATION) {
- Slog.d(TAG, "No web filters or no prior verify policy for " + packageName);
+ Slog.d(TAG, "No web filters or no new host policy for " + packageName);
}
}
}
@GuardedBy("mPackages")
- private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
- final ComponentName cn = filter.activity.getComponentName();
- final String packageName = cn.getPackageName();
-
+ private boolean needsNetworkVerificationLPr(String packageName) {
IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
packageName);
if (ivi == null) {
@@ -19104,7 +19142,7 @@
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
final SparseBooleanArray changedUsers = new SparseBooleanArray();
synchronized (mPackages) {
- clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
+ clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL, true);
clearDefaultBrowserIfNeeded(packageName);
mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
removedAppId = mSettings.removePackageLPw(packageName);
@@ -20609,13 +20647,14 @@
final int packageCount = mPackages.size();
for (int i = 0; i < packageCount; i++) {
PackageParser.Package pkg = mPackages.valueAt(i);
- clearIntentFilterVerificationsLPw(pkg.packageName, userId);
+ clearIntentFilterVerificationsLPw(pkg.packageName, userId, true);
}
}
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
@GuardedBy("mPackages")
- void clearIntentFilterVerificationsLPw(String packageName, int userId) {
+ void clearIntentFilterVerificationsLPw(String packageName, int userId,
+ boolean alsoResetStatus) {
if (userId == UserHandle.USER_ALL) {
if (mSettings.removeIntentFilterVerificationLPw(packageName,
sUserManager.getUserIds())) {
@@ -20624,7 +20663,8 @@
}
}
} else {
- if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
+ if (mSettings.removeIntentFilterVerificationLPw(packageName, userId,
+ alsoResetStatus)) {
scheduleWritePackageRestrictionsLocked(userId);
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index d449db3..53ff627 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -1243,7 +1243,8 @@
return result;
}
- boolean removeIntentFilterVerificationLPw(String packageName, int userId) {
+ boolean removeIntentFilterVerificationLPw(String packageName, int userId,
+ boolean alsoResetStatus) {
PackageSetting ps = mPackages.get(packageName);
if (ps == null) {
if (DEBUG_DOMAIN_VERIFICATION) {
@@ -1251,7 +1252,9 @@
}
return false;
}
- ps.clearDomainVerificationStatusForUser(userId);
+ if (alsoResetStatus) {
+ ps.clearDomainVerificationStatusForUser(userId);
+ }
ps.setIntentFilterVerificationInfo(null);
return true;
}
@@ -1259,7 +1262,7 @@
boolean removeIntentFilterVerificationLPw(String packageName, int[] userIds) {
boolean result = false;
for (int userId : userIds) {
- result |= removeIntentFilterVerificationLPw(packageName, userId);
+ result |= removeIntentFilterVerificationLPw(packageName, userId, true);
}
return result;
}
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 895d2c5..dd71331 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -95,11 +95,12 @@
}
}
- ParceledListSlice<PackageInstaller.SessionInfo> getSessions() {
+ ParceledListSlice<PackageInstaller.SessionInfo> getSessions(int callingUid) {
final List<PackageInstaller.SessionInfo> result = new ArrayList<>();
synchronized (mStagedSessions) {
for (int i = 0; i < mStagedSessions.size(); i++) {
- result.add(mStagedSessions.valueAt(i).generateInfo(false));
+ final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
+ result.add(stagedSession.generateInfoForCaller(false /*icon*/, callingUid));
}
}
return new ParceledListSlice<>(result);
diff --git a/services/core/java/com/android/server/policy/pocket/PocketLock.java b/services/core/java/com/android/server/policy/pocket/PocketLock.java
index a432d7c..2fa207e 100644
--- a/services/core/java/com/android/server/policy/pocket/PocketLock.java
+++ b/services/core/java/com/android/server/policy/pocket/PocketLock.java
@@ -93,10 +93,12 @@
@Override
public void run() {
mView.setAlpha(0.0f);
+ mView.setVisibility(View.VISIBLE);
addView();
}
}).start();
} else {
+ mView.setVisibility(View.VISIBLE);
mView.setAlpha(1.0f);
addView();
}
@@ -128,6 +130,7 @@
@Override
public void onAnimationEnd(Animator animator) {
+ mView.setVisibility(View.GONE);
mView.setLayerType(View.LAYER_TYPE_NONE, null);
mAnimating = false;
removeView();
@@ -142,8 +145,9 @@
}
}).start();
} else {
- removeView();
+ mView.setVisibility(View.GONE);
mView.setAlpha(0.0f);
+ removeView();
}
}
};