mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-25 07:29:24 -05:00
20.0: drop June ASB patches
QPR3 has been merged Signed-off-by: Tad <tad@spotco.us>
This commit is contained in:
parent
0bc93038ac
commit
1e7f10d6b6
@ -1,75 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ray Essick <essick@google.com>
|
||||
Date: Mon, 27 Mar 2023 18:16:46 -0500
|
||||
Subject: [PATCH] Fix NuMediaExtractor::readSampleData buffer Handling
|
||||
|
||||
readSampleData() did not initialize buffer before filling it,
|
||||
leading to OOB memory references. Correct and clarify the book
|
||||
keeping around output buffer management.
|
||||
|
||||
Bug: 275418191
|
||||
Test: CtsMediaExtractorTestCases w/debug messages
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:943fc12219b21d2a98f0ddc070b9b316a6f5d412)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:84c69bca81175feb2fd97ebb22e432ee41572786)
|
||||
Merged-In: Ie744f118526f100d82a312c64f7c6fcf20773b6d
|
||||
Change-Id: Ie744f118526f100d82a312c64f7c6fcf20773b6d
|
||||
---
|
||||
media/libstagefright/NuMediaExtractor.cpp | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
|
||||
index 2b45f2d16d..5b39618ad7 100644
|
||||
--- a/media/libstagefright/NuMediaExtractor.cpp
|
||||
+++ b/media/libstagefright/NuMediaExtractor.cpp
|
||||
@@ -639,9 +639,11 @@ status_t NuMediaExtractor::appendVorbisNumPageSamples(
|
||||
numPageSamples = -1;
|
||||
}
|
||||
|
||||
+ // insert, including accounting for the space used.
|
||||
memcpy((uint8_t *)buffer->data() + mbuf->range_length(),
|
||||
&numPageSamples,
|
||||
sizeof(numPageSamples));
|
||||
+ buffer->setRange(buffer->offset(), buffer->size() + sizeof(numPageSamples));
|
||||
|
||||
uint32_t type;
|
||||
const void *data;
|
||||
@@ -690,6 +692,8 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
|
||||
|
||||
ssize_t minIndex = fetchAllTrackSamples();
|
||||
|
||||
+ buffer->setRange(0, 0); // start with an empty buffer
|
||||
+
|
||||
if (minIndex < 0) {
|
||||
return ERROR_END_OF_STREAM;
|
||||
}
|
||||
@@ -705,25 +709,25 @@ status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
|
||||
sampleSize += sizeof(int32_t);
|
||||
}
|
||||
|
||||
+ // capacity() is ok since we cleared out the buffer
|
||||
if (buffer->capacity() < sampleSize) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ const size_t srclen = it->mBuffer->range_length();
|
||||
const uint8_t *src =
|
||||
(const uint8_t *)it->mBuffer->data()
|
||||
+ it->mBuffer->range_offset();
|
||||
|
||||
- memcpy((uint8_t *)buffer->data(), src, it->mBuffer->range_length());
|
||||
+ memcpy((uint8_t *)buffer->data(), src, srclen);
|
||||
+ buffer->setRange(0, srclen);
|
||||
|
||||
status_t err = OK;
|
||||
if (info->mTrackFlags & kIsVorbis) {
|
||||
+ // adjusts range when it inserts the extra bits
|
||||
err = appendVorbisNumPageSamples(it->mBuffer, buffer);
|
||||
}
|
||||
|
||||
- if (err == OK) {
|
||||
- buffer->setRange(0, sampleSize);
|
||||
- }
|
||||
-
|
||||
return err;
|
||||
}
|
||||
|
@ -1,105 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Renouf <mrenouf@google.com>
|
||||
Date: Wed, 22 Feb 2023 14:48:51 +0000
|
||||
Subject: [PATCH 01/10] Prevent sharesheet from previewing unowned URIs
|
||||
|
||||
Bug: 261036568
|
||||
Test: manually via supplied tool (see bug)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:fa83e125d14e458545086d16f2e7d1051812dabc)
|
||||
Merged-In: Ib3f5839d00c7cf09bca3b01fc0a8a6f0f4960993
|
||||
Change-Id: Ib3f5839d00c7cf09bca3b01fc0a8a6f0f4960993
|
||||
---
|
||||
.../android/internal/app/ChooserActivity.java | 35 +++++++++++++++++--
|
||||
1 file changed, 33 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
|
||||
index bfff93b5f7a4..b68e4f4956d0 100644
|
||||
--- a/core/java/com/android/internal/app/ChooserActivity.java
|
||||
+++ b/core/java/com/android/internal/app/ChooserActivity.java
|
||||
@@ -21,6 +21,7 @@ import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_PERSONAL;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CANT_SHARE_WITH_WORK;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Core.RESOLVER_CROSS_PROFILE_BLOCKED_TITLE;
|
||||
+import static android.content.ContentProvider.getUserIdFromUri;
|
||||
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_PERSONAL;
|
||||
import static android.stats.devicepolicy.DevicePolicyEnums.RESOLVER_EMPTY_STATE_NO_SHARING_TO_WORK;
|
||||
|
||||
@@ -161,6 +162,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
+import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* The Chooser Activity handles intent resolution specifically for sharing intents -
|
||||
@@ -1395,7 +1397,7 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
|
||||
ImageView previewThumbnailView = contentPreviewLayout.findViewById(
|
||||
R.id.content_preview_thumbnail);
|
||||
- if (previewThumbnail == null) {
|
||||
+ if (!validForContentPreview(previewThumbnail)) {
|
||||
previewThumbnailView.setVisibility(View.GONE);
|
||||
} else {
|
||||
mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
|
||||
@@ -1428,6 +1430,10 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
|
||||
if (Intent.ACTION_SEND.equals(action)) {
|
||||
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
+ if (!validForContentPreview(uri)) {
|
||||
+ contentPreviewLayout.setVisibility(View.GONE);
|
||||
+ return contentPreviewLayout;
|
||||
+ }
|
||||
imagePreview.findViewById(R.id.content_preview_image_1_large)
|
||||
.setTransitionName(ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME);
|
||||
mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0);
|
||||
@@ -1437,7 +1443,7 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
List<Uri> imageUris = new ArrayList<>();
|
||||
for (Uri uri : uris) {
|
||||
- if (isImageType(resolver.getType(uri))) {
|
||||
+ if (validForContentPreview(uri) && isImageType(resolver.getType(uri))) {
|
||||
imageUris.add(uri);
|
||||
}
|
||||
}
|
||||
@@ -1547,9 +1553,16 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
String action = targetIntent.getAction();
|
||||
if (Intent.ACTION_SEND.equals(action)) {
|
||||
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
|
||||
+ if (!validForContentPreview(uri)) {
|
||||
+ contentPreviewLayout.setVisibility(View.GONE);
|
||||
+ return contentPreviewLayout;
|
||||
+ }
|
||||
loadFileUriIntoView(uri, contentPreviewLayout);
|
||||
} else {
|
||||
List<Uri> uris = targetIntent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
|
||||
+ uris = uris.stream()
|
||||
+ .filter(ChooserActivity::validForContentPreview)
|
||||
+ .collect(Collectors.toList());
|
||||
int uriCount = uris.size();
|
||||
|
||||
if (uriCount == 0) {
|
||||
@@ -1608,6 +1621,24 @@ public class ChooserActivity extends ResolverActivity implements
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Indicate if the incoming content URI should be allowed.
|
||||
+ *
|
||||
+ * @param uri the uri to test
|
||||
+ * @return true if the URI is allowed for content preview
|
||||
+ */
|
||||
+ private static boolean validForContentPreview(Uri uri) throws SecurityException {
|
||||
+ if (uri == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ int userId = getUserIdFromUri(uri, UserHandle.USER_CURRENT);
|
||||
+ if (userId != UserHandle.USER_CURRENT && userId != UserHandle.myUserId()) {
|
||||
+ Log.e(TAG, "dropped invalid content URI belonging to user " + userId);
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
@VisibleForTesting
|
||||
protected boolean isImageType(String mimeType) {
|
||||
return mimeType != null && mimeType.startsWith("image/");
|
@ -1,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hongwei Wang <hwwang@google.com>
|
||||
Date: Thu, 23 Feb 2023 13:23:37 -0800
|
||||
Subject: [PATCH 02/10] Remove Activity if it enters PiP without window
|
||||
|
||||
This is to prevent malicious app entering PiP without being visible
|
||||
first, like blocking onResume from completion. Which in turn
|
||||
leaves the PiP window in limbo and non-interactable.
|
||||
|
||||
Bug: 265293293
|
||||
Test: atest PinnedStackTests
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4fad1456409b79d6e649a29d5116a4fe3160bd21)
|
||||
Merged-In: I458a9508662e72a1adb9d9818105f2e9d7096d44
|
||||
Change-Id: I458a9508662e72a1adb9d9818105f2e9d7096d44
|
||||
---
|
||||
.../core/java/com/android/server/wm/ActivityRecord.java | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
|
||||
index c1cbdef6b5f5..69e1511da7be 100644
|
||||
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
|
||||
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
|
||||
@@ -1477,6 +1477,12 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
mLastReportedMultiWindowMode = inPictureInPictureMode;
|
||||
ensureActivityConfiguration(0 /* globalChanges */, PRESERVE_WINDOWS,
|
||||
true /* ignoreVisibility */);
|
||||
+ if (inPictureInPictureMode && findMainWindow() == null) {
|
||||
+ // Prevent malicious app entering PiP without valid WindowState, which can in turn
|
||||
+ // result a non-touchable PiP window since the InputConsumer for PiP requires it.
|
||||
+ EventLog.writeEvent(0x534e4554, "265293293", -1, "");
|
||||
+ removeImmediately();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
@ -1,238 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Valentin Iftime <valiiftime@google.com>
|
||||
Date: Wed, 15 Feb 2023 20:39:44 +0100
|
||||
Subject: [PATCH 03/10] Wait for preloading images to complete before inflating
|
||||
notifications
|
||||
|
||||
NotificationContentInflater waits on SysUiBg thread for images to load, with a timeout
|
||||
of 1000ms.
|
||||
|
||||
Test: 1. Build a test app that posts MessagingStyle notifications with a huge image (8k+) set as data Uri.
|
||||
2. SystemUi should not ANR
|
||||
3. adb logcat | grep NotificationInlineImageCache - shows timeout/cancellation logs
|
||||
|
||||
Bug: 252766417
|
||||
Bug: 223859644
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2a2da8935ab70163044c34d7b0d9b9ed4cb91a76)
|
||||
Merged-In: I341db60223214cf2282b5c0270e343e1ce95fa01
|
||||
Change-Id: I341db60223214cf2282b5c0270e343e1ce95fa01
|
||||
---
|
||||
.../row/NotificationContentInflater.java | 15 +++++-
|
||||
.../row/NotificationInlineImageCache.java | 21 ++++++--
|
||||
.../row/NotificationInlineImageResolver.java | 49 +++++++++++++++++--
|
||||
3 files changed, 76 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
|
||||
index c534860d12c6..d2fb0c142cc5 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
|
||||
@@ -439,6 +439,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
CancellationSignal cancellationSignal = new CancellationSignal();
|
||||
cancellationSignal.setOnCancelListener(
|
||||
() -> runningInflations.values().forEach(CancellationSignal::cancel));
|
||||
+
|
||||
return cancellationSignal;
|
||||
}
|
||||
|
||||
@@ -711,6 +712,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
|
||||
implements InflationCallback, InflationTask {
|
||||
|
||||
+ private static final long IMG_PRELOAD_TIMEOUT_MS = 1000L;
|
||||
private final NotificationEntry mEntry;
|
||||
private final Context mContext;
|
||||
private final boolean mInflateSynchronously;
|
||||
@@ -804,7 +806,7 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
recoveredBuilder, mIsLowPriority, mUsesIncreasedHeight,
|
||||
mUsesIncreasedHeadsUpHeight, packageContext);
|
||||
InflatedSmartReplyState previousSmartReplyState = mRow.getExistingSmartReplyState();
|
||||
- return inflateSmartReplyViews(
|
||||
+ InflationProgress result = inflateSmartReplyViews(
|
||||
inflationProgress,
|
||||
mReInflateFlags,
|
||||
mEntry,
|
||||
@@ -812,6 +814,11 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
packageContext,
|
||||
previousSmartReplyState,
|
||||
mSmartRepliesInflater);
|
||||
+
|
||||
+ // wait for image resolver to finish preloading
|
||||
+ mRow.getImageResolver().waitForPreloadedImages(IMG_PRELOAD_TIMEOUT_MS);
|
||||
+
|
||||
+ return result;
|
||||
} catch (Exception e) {
|
||||
mError = e;
|
||||
return null;
|
||||
@@ -846,6 +853,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
mCallback.handleInflationException(mRow.getEntry(),
|
||||
new InflationException("Couldn't inflate contentViews" + e));
|
||||
}
|
||||
+
|
||||
+ // Cancel any image loading tasks, not useful any more
|
||||
+ mRow.getImageResolver().cancelRunningTasks();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -872,6 +882,9 @@ public class NotificationContentInflater implements NotificationRowContentBinder
|
||||
// Notify the resolver that the inflation task has finished,
|
||||
// try to purge unnecessary cached entries.
|
||||
mRow.getImageResolver().purgeCache();
|
||||
+
|
||||
+ // Cancel any image loading tasks that have not completed at this point
|
||||
+ mRow.getImageResolver().cancelRunningTasks();
|
||||
}
|
||||
|
||||
private static class RtlEnabledContext extends ContextWrapper {
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
|
||||
index 41eeada0fcda..fe0b3123eb25 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageCache.java
|
||||
@@ -22,8 +22,11 @@ import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Set;
|
||||
+import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* A cache for inline images of image messages.
|
||||
@@ -56,12 +59,13 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso
|
||||
}
|
||||
|
||||
@Override
|
||||
- public Drawable get(Uri uri) {
|
||||
+ public Drawable get(Uri uri, long timeoutMs) {
|
||||
Drawable result = null;
|
||||
try {
|
||||
- result = mCache.get(uri).get();
|
||||
- } catch (InterruptedException | ExecutionException ex) {
|
||||
- Log.d(TAG, "get: Failed get image from " + uri);
|
||||
+ result = mCache.get(uri).get(timeoutMs, TimeUnit.MILLISECONDS);
|
||||
+ } catch (InterruptedException | ExecutionException
|
||||
+ | TimeoutException | CancellationException ex) {
|
||||
+ Log.d(TAG, "get: Failed get image from " + uri + " " + ex);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -72,6 +76,15 @@ public class NotificationInlineImageCache implements NotificationInlineImageReso
|
||||
mCache.entrySet().removeIf(entry -> !wantedSet.contains(entry.getKey()));
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void cancelRunningTasks() {
|
||||
+ mCache.forEach((key, value) -> {
|
||||
+ if (value.getStatus() != AsyncTask.Status.FINISHED) {
|
||||
+ value.cancel(true);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
private static class PreloadImageTask extends AsyncTask<Uri, Void, Drawable> {
|
||||
private final NotificationInlineImageResolver mResolver;
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
|
||||
index b05e64ab1991..c620f448b3b7 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java
|
||||
@@ -23,6 +23,7 @@ import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
+import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
@@ -45,6 +46,9 @@ import java.util.Set;
|
||||
public class NotificationInlineImageResolver implements ImageResolver {
|
||||
private static final String TAG = NotificationInlineImageResolver.class.getSimpleName();
|
||||
|
||||
+ // Timeout for loading images from ImageCache when calling from UI thread
|
||||
+ private static final long MAX_UI_THREAD_TIMEOUT_MS = 100L;
|
||||
+
|
||||
private final Context mContext;
|
||||
private final ImageCache mImageCache;
|
||||
private Set<Uri> mWantedUriSet;
|
||||
@@ -123,17 +127,25 @@ public class NotificationInlineImageResolver implements ImageResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Loads an image from the Uri.
|
||||
+ * This method is synchronous and is usually called from the Main thread.
|
||||
+ * It will time-out after MAX_UI_THREAD_TIMEOUT_MS.
|
||||
+ *
|
||||
+ * @param uri Uri of the target image.
|
||||
+ * @return drawable of the image, null if loading failed/timeout
|
||||
+ */
|
||||
@Override
|
||||
public Drawable loadImage(Uri uri) {
|
||||
- return hasCache() ? loadImageFromCache(uri) : resolveImage(uri);
|
||||
+ return hasCache() ? loadImageFromCache(uri, MAX_UI_THREAD_TIMEOUT_MS) : resolveImage(uri);
|
||||
}
|
||||
|
||||
- private Drawable loadImageFromCache(Uri uri) {
|
||||
+ private Drawable loadImageFromCache(Uri uri, long timeoutMs) {
|
||||
// if the uri isn't currently cached, try caching it first
|
||||
if (!mImageCache.hasEntry(uri)) {
|
||||
mImageCache.preload((uri));
|
||||
}
|
||||
- return mImageCache.get(uri);
|
||||
+ return mImageCache.get(uri, timeoutMs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,6 +219,30 @@ public class NotificationInlineImageResolver implements ImageResolver {
|
||||
return mWantedUriSet;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Wait for a maximum timeout for images to finish preloading
|
||||
+ * @param timeoutMs total timeout time
|
||||
+ */
|
||||
+ void waitForPreloadedImages(long timeoutMs) {
|
||||
+ if (!hasCache()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ Set<Uri> preloadedUris = getWantedUriSet();
|
||||
+ if (preloadedUris != null) {
|
||||
+ // Decrement remaining timeout after each image check
|
||||
+ long endTimeMs = SystemClock.elapsedRealtime() + timeoutMs;
|
||||
+ preloadedUris.forEach(
|
||||
+ uri -> loadImageFromCache(uri, endTimeMs - SystemClock.elapsedRealtime()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void cancelRunningTasks() {
|
||||
+ if (!hasCache()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ mImageCache.cancelRunningTasks();
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* A interface for internal cache implementation of this resolver.
|
||||
*/
|
||||
@@ -216,7 +252,7 @@ public class NotificationInlineImageResolver implements ImageResolver {
|
||||
* @param uri The uri of the image.
|
||||
* @return Drawable of the image.
|
||||
*/
|
||||
- Drawable get(Uri uri);
|
||||
+ Drawable get(Uri uri, long timeoutMs);
|
||||
|
||||
/**
|
||||
* Set the image resolver that actually resolves image from specified uri.
|
||||
@@ -241,6 +277,11 @@ public class NotificationInlineImageResolver implements ImageResolver {
|
||||
* Purge unnecessary entries in the cache.
|
||||
*/
|
||||
void purge();
|
||||
+
|
||||
+ /**
|
||||
+ * Cancel all unfinished image loading tasks
|
||||
+ */
|
||||
+ void cancelRunningTasks();
|
||||
}
|
||||
|
||||
}
|
@ -1,290 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Valentin Iftime <valiiftime@google.com>
|
||||
Date: Wed, 22 Feb 2023 09:38:55 +0100
|
||||
Subject: [PATCH 04/10] Prevent RemoteViews crashing SystemUi
|
||||
|
||||
Catch canvas drawing exceptions caused by unsuported image sizes.
|
||||
|
||||
Test: 1. Post a custom view notification with a layout
|
||||
containing an ImageView that references a 5k x 5k image
|
||||
2. Add an App Widget to the home screen with that has the
|
||||
layout mentioned above as preview/initial layout.
|
||||
|
||||
Bug: 268193777
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:10752edb540a053e304139894f941fcaef60949b)
|
||||
Merged-In: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||||
Change-Id: Ib3bda769c499b4069b49c566b1b227f98f707a8a
|
||||
---
|
||||
.../android/appwidget/AppWidgetHostView.java | 39 ++++++++++----
|
||||
.../row/ExpandableNotificationRow.java | 7 ++-
|
||||
.../ExpandableNotificationRowController.java | 9 +++-
|
||||
.../row/NotificationContentView.java | 54 ++++++++++++++++++-
|
||||
.../row/NotificationTestHelper.java | 4 +-
|
||||
5 files changed, 97 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
|
||||
index fe10b7f8b3f4..27f6a266597c 100644
|
||||
--- a/core/java/android/appwidget/AppWidgetHostView.java
|
||||
+++ b/core/java/android/appwidget/AppWidgetHostView.java
|
||||
@@ -31,6 +31,7 @@ import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
+import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
@@ -311,19 +312,26 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
} catch (final RuntimeException e) {
|
||||
Log.e(TAG, "Remote provider threw runtime exception, using error view instead.", e);
|
||||
- removeViewInLayout(mView);
|
||||
- View child = getErrorView();
|
||||
- prepareView(child);
|
||||
- addViewInLayout(child, 0, child.getLayoutParams());
|
||||
- measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
|
||||
- MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
|
||||
- child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
|
||||
- child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
|
||||
- mView = child;
|
||||
- mViewMode = VIEW_MODE_ERROR;
|
||||
+ handleViewError();
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Remove bad view and replace with error message view
|
||||
+ */
|
||||
+ private void handleViewError() {
|
||||
+ removeViewInLayout(mView);
|
||||
+ View child = getErrorView();
|
||||
+ prepareView(child);
|
||||
+ addViewInLayout(child, 0, child.getLayoutParams());
|
||||
+ measureChild(child, MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
|
||||
+ MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
|
||||
+ child.layout(0, 0, child.getMeasuredWidth() + mPaddingLeft + mPaddingRight,
|
||||
+ child.getMeasuredHeight() + mPaddingTop + mPaddingBottom);
|
||||
+ mView = child;
|
||||
+ mViewMode = VIEW_MODE_ERROR;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Provide guidance about the size of this widget to the AppWidgetManager. The widths and
|
||||
* heights should correspond to the full area the AppWidgetHostView is given. Padding added by
|
||||
@@ -953,4 +961,15 @@ public class AppWidgetHostView extends FrameLayout implements AppWidgetHost.AppW
|
||||
reapplyLastRemoteViews();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ protected void dispatchDraw(@NonNull Canvas canvas) {
|
||||
+ try {
|
||||
+ super.dispatchDraw(canvas);
|
||||
+ } catch (Exception e) {
|
||||
+ // Catch draw exceptions that may be caused by RemoteViews
|
||||
+ Log.e(TAG, "Drawing view failed: " + e);
|
||||
+ post(this::handleViewError);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
|
||||
index 9f50aef6de11..816ccee604d4 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
|
||||
@@ -73,6 +73,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
+import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.internal.util.ContrastColorUtil;
|
||||
import com.android.internal.widget.CachingIconView;
|
||||
import com.android.internal.widget.CallLayout;
|
||||
@@ -1662,7 +1663,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
NotificationGutsManager gutsManager,
|
||||
MetricsLogger metricsLogger,
|
||||
SmartReplyConstants smartReplyConstants,
|
||||
- SmartReplyController smartReplyController) {
|
||||
+ SmartReplyController smartReplyController,
|
||||
+ IStatusBarService statusBarService) {
|
||||
mEntry = entry;
|
||||
mAppName = appName;
|
||||
if (mMenuRow == null) {
|
||||
@@ -1691,7 +1693,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
|
||||
mPeopleNotificationIdentifier,
|
||||
rivSubcomponentFactory,
|
||||
smartReplyConstants,
|
||||
- smartReplyController);
|
||||
+ smartReplyController,
|
||||
+ statusBarService);
|
||||
}
|
||||
mOnUserInteractionCallback = onUserInteractionCallback;
|
||||
mBubblesManagerOptional = bubblesManagerOptional;
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
|
||||
index d1138608805b..a9bf51fae1fd 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
|
||||
@@ -29,6 +29,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
+import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
@@ -125,6 +126,7 @@ public class ExpandableNotificationRowController implements NotifViewController
|
||||
}
|
||||
};
|
||||
|
||||
+ private final IStatusBarService mStatusBarService;
|
||||
|
||||
@Inject
|
||||
public ExpandableNotificationRowController(
|
||||
@@ -157,7 +159,8 @@ public class ExpandableNotificationRowController implements NotifViewController
|
||||
FeatureFlags featureFlags,
|
||||
PeopleNotificationIdentifier peopleNotificationIdentifier,
|
||||
Optional<BubblesManager> bubblesManagerOptional,
|
||||
- ExpandableNotificationRowDragController dragController) {
|
||||
+ ExpandableNotificationRowDragController dragController,
|
||||
+ IStatusBarService statusBarService) {
|
||||
mView = view;
|
||||
mListContainer = listContainer;
|
||||
mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
|
||||
@@ -189,6 +192,7 @@ public class ExpandableNotificationRowController implements NotifViewController
|
||||
mLogBufferLogger = logBufferLogger;
|
||||
mSmartReplyConstants = smartReplyConstants;
|
||||
mSmartReplyController = smartReplyController;
|
||||
+ mStatusBarService = statusBarService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -219,7 +223,8 @@ public class ExpandableNotificationRowController implements NotifViewController
|
||||
mNotificationGutsManager,
|
||||
mMetricsLogger,
|
||||
mSmartReplyConstants,
|
||||
- mSmartReplyController
|
||||
+ mSmartReplyController,
|
||||
+ mStatusBarService
|
||||
);
|
||||
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
|
||||
if (mAllowLongPress) {
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
|
||||
index e46bf522acff..6b729f240c80 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
|
||||
@@ -21,10 +21,13 @@ import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
+import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
+import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
+import android.service.notification.StatusBarNotification;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
@@ -39,6 +42,7 @@ import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
+import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
|
||||
import com.android.systemui.statusbar.RemoteInputController;
|
||||
@@ -129,6 +133,7 @@ public class NotificationContentView extends FrameLayout implements Notification
|
||||
private Runnable mExpandedVisibleListener;
|
||||
private PeopleNotificationIdentifier mPeopleIdentifier;
|
||||
private RemoteInputViewSubcomponent.Factory mRemoteInputSubcomponentFactory;
|
||||
+ private IStatusBarService mStatusBarService;
|
||||
|
||||
/**
|
||||
* List of listeners for when content views become inactive (i.e. not the showing view).
|
||||
@@ -194,11 +199,13 @@ public class NotificationContentView extends FrameLayout implements Notification
|
||||
PeopleNotificationIdentifier peopleNotificationIdentifier,
|
||||
RemoteInputViewSubcomponent.Factory rivSubcomponentFactory,
|
||||
SmartReplyConstants smartReplyConstants,
|
||||
- SmartReplyController smartReplyController) {
|
||||
+ SmartReplyController smartReplyController,
|
||||
+ IStatusBarService statusBarService) {
|
||||
mPeopleIdentifier = peopleNotificationIdentifier;
|
||||
mRemoteInputSubcomponentFactory = rivSubcomponentFactory;
|
||||
mSmartReplyConstants = smartReplyConstants;
|
||||
mSmartReplyController = smartReplyController;
|
||||
+ mStatusBarService = statusBarService;
|
||||
}
|
||||
|
||||
public void reinflate() {
|
||||
@@ -2133,4 +2140,49 @@ public class NotificationContentView extends FrameLayout implements Notification
|
||||
@Nullable RemoteInputView mView;
|
||||
@Nullable RemoteInputViewController mController;
|
||||
}
|
||||
+
|
||||
+ @VisibleForTesting
|
||||
+ protected void setContractedWrapper(NotificationViewWrapper contractedWrapper) {
|
||||
+ mContractedWrapper = contractedWrapper;
|
||||
+ }
|
||||
+ @VisibleForTesting
|
||||
+ protected void setExpandedWrapper(NotificationViewWrapper expandedWrapper) {
|
||||
+ mExpandedWrapper = expandedWrapper;
|
||||
+ }
|
||||
+ @VisibleForTesting
|
||||
+ protected void setHeadsUpWrapper(NotificationViewWrapper headsUpWrapper) {
|
||||
+ mHeadsUpWrapper = headsUpWrapper;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void dispatchDraw(Canvas canvas) {
|
||||
+ try {
|
||||
+ super.dispatchDraw(canvas);
|
||||
+ } catch (Exception e) {
|
||||
+ // Catch draw exceptions that may be caused by RemoteViews
|
||||
+ Log.e(TAG, "Drawing view failed: " + e);
|
||||
+ cancelNotification(e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private void cancelNotification(Exception exception) {
|
||||
+ try {
|
||||
+ setVisibility(GONE);
|
||||
+ final StatusBarNotification sbn = mNotificationEntry.getSbn();
|
||||
+ if (mStatusBarService != null) {
|
||||
+ // report notification inflation errors back up
|
||||
+ // to notification delegates
|
||||
+ mStatusBarService.onNotificationError(
|
||||
+ sbn.getPackageName(),
|
||||
+ sbn.getTag(),
|
||||
+ sbn.getId(),
|
||||
+ sbn.getUid(),
|
||||
+ sbn.getInitialPid(),
|
||||
+ exception.getMessage(),
|
||||
+ sbn.getUser().getIdentifier());
|
||||
+ }
|
||||
+ } catch (RemoteException ex) {
|
||||
+ Log.e(TAG, "cancelNotification failed: " + ex);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
|
||||
index 728e0265c729..e8aeb18552f8 100644
|
||||
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
|
||||
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
|
||||
@@ -50,6 +50,7 @@ import android.widget.RemoteViews;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
+import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.systemui.TestableDependency;
|
||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
||||
import com.android.systemui.classifier.FalsingManagerFake;
|
||||
@@ -561,7 +562,8 @@ public class NotificationTestHelper {
|
||||
mock(NotificationGutsManager.class),
|
||||
mock(MetricsLogger.class),
|
||||
mock(SmartReplyConstants.class),
|
||||
- mock(SmartReplyController.class));
|
||||
+ mock(SmartReplyController.class),
|
||||
+ mock(IStatusBarService.class));
|
||||
|
||||
row.setAboveShelfChangedListener(aboveShelf -> { });
|
||||
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
|
@ -1,167 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Lee <brnlee@google.com>
|
||||
Date: Fri, 17 Feb 2023 16:05:17 -0800
|
||||
Subject: [PATCH 05/10] Check key intent for selectors and prohibited flags
|
||||
|
||||
Bug: 265015796
|
||||
Test: atest
|
||||
FrameworksServicesTests: com.android.server.accounts.AccountManagerServiceTest
|
||||
(cherry picked from commit e53a96304352e2965176c8d32ac1b504e52ef185)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:64f6c1e13588af3cf4d88a39d9d540c140982043)
|
||||
Merged-In: Ie16f8654337bd75eaad3156817470674b4f0cee3
|
||||
Change-Id: Ie16f8654337bd75eaad3156817470674b4f0cee3
|
||||
---
|
||||
.../accounts/AccountManagerService.java | 18 +++++++---
|
||||
.../accounts/AccountManagerServiceTest.java | 36 +++++++++++++++++++
|
||||
.../AccountManagerServiceTestFixtures.java | 5 ++-
|
||||
.../TestAccountType1Authenticator.java | 5 +--
|
||||
4 files changed, 54 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
index 425158195940..1dc0942ceac5 100644
|
||||
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
|
||||
@@ -4893,10 +4893,6 @@ public class AccountManagerService
|
||||
if (intent.getClipData() == null) {
|
||||
intent.setClipData(ClipData.newPlainText(null, null));
|
||||
}
|
||||
- intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
- | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION));
|
||||
final long bid = Binder.clearCallingIdentity();
|
||||
try {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
@@ -4942,7 +4938,19 @@ public class AccountManagerService
|
||||
if (intent == null) {
|
||||
return (simulateIntent == null);
|
||||
}
|
||||
- return intent.filterEquals(simulateIntent);
|
||||
+ if (!intent.filterEquals(simulateIntent)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (intent.getSelector() != simulateIntent.getSelector()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||
+ return (simulateIntent.getFlags() & prohibitedFlags) == 0;
|
||||
}
|
||||
|
||||
private boolean isExportedSystemActivity(ActivityInfo activityInfo) {
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
index 30ec1632a622..881d1b3d581c 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
|
||||
@@ -18,6 +18,7 @@ package com.android.server.accounts;
|
||||
|
||||
import static android.database.sqlite.SQLiteDatabase.deleteDatabase;
|
||||
|
||||
+import static org.mockito.ArgumentMatchers.contains;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
@@ -707,6 +708,41 @@ public class AccountManagerServiceTest extends AndroidTestCase {
|
||||
assertNotNull(intent.getParcelableExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK));
|
||||
}
|
||||
|
||||
+ @SmallTest
|
||||
+ public void testStartAddAccountSessionWhereAuthenticatorReturnsIntentWithProhibitedFlags()
|
||||
+ throws Exception {
|
||||
+ unlockSystemUser();
|
||||
+ ResolveInfo resolveInfo = new ResolveInfo();
|
||||
+ resolveInfo.activityInfo = new ActivityInfo();
|
||||
+ resolveInfo.activityInfo.applicationInfo = new ApplicationInfo();
|
||||
+ when(mMockPackageManager.resolveActivityAsUser(
|
||||
+ any(Intent.class), anyInt(), anyInt())).thenReturn(resolveInfo);
|
||||
+ when(mMockPackageManager.checkSignatures(
|
||||
+ anyInt(), anyInt())).thenReturn(PackageManager.SIGNATURE_MATCH);
|
||||
+
|
||||
+ final CountDownLatch latch = new CountDownLatch(1);
|
||||
+ Response response = new Response(latch, mMockAccountManagerResponse);
|
||||
+ Bundle options = createOptionsWithAccountName(
|
||||
+ AccountManagerServiceTestFixtures.ACCOUNT_NAME_INTERVENE);
|
||||
+ int prohibitedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
|
||||
+ | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION;
|
||||
+ options.putInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, prohibitedFlags);
|
||||
+
|
||||
+ mAms.startAddAccountSession(
|
||||
+ response, // response
|
||||
+ AccountManagerServiceTestFixtures.ACCOUNT_TYPE_1, // accountType
|
||||
+ "authTokenType",
|
||||
+ null, // requiredFeatures
|
||||
+ true, // expectActivityLaunch
|
||||
+ options); // optionsIn
|
||||
+ waitForLatch(latch);
|
||||
+
|
||||
+ verify(mMockAccountManagerResponse).onError(
|
||||
+ eq(AccountManager.ERROR_CODE_INVALID_RESPONSE), contains("invalid intent"));
|
||||
+ }
|
||||
+
|
||||
@SmallTest
|
||||
public void testStartAddAccountSessionError() throws Exception {
|
||||
unlockSystemUser();
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
index 73f30d9f9e79..b98a6a891d55 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTestFixtures.java
|
||||
@@ -17,9 +17,6 @@ package com.android.server.accounts;
|
||||
|
||||
import android.accounts.Account;
|
||||
|
||||
-import java.util.ArrayList;
|
||||
-import java.util.List;
|
||||
-
|
||||
/**
|
||||
* Constants shared between test AccountAuthenticators and AccountManagerServiceTest.
|
||||
*/
|
||||
@@ -31,6 +28,8 @@ public final class AccountManagerServiceTestFixtures {
|
||||
"account_manager_service_test:account_status_token_key";
|
||||
public static final String KEY_ACCOUNT_PASSWORD =
|
||||
"account_manager_service_test:account_password_key";
|
||||
+ public static final String KEY_INTENT_FLAGS =
|
||||
+ "account_manager_service_test:intent_flags_key";
|
||||
public static final String KEY_OPTIONS_BUNDLE =
|
||||
"account_manager_service_test:option_bundle_key";
|
||||
public static final String ACCOUNT_NAME_SUCCESS = "success_on_return@fixture.com";
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
index 8106364477d9..924443e9d5cf 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/accounts/TestAccountType1Authenticator.java
|
||||
@@ -24,8 +24,6 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
-import com.android.frameworks.servicestests.R;
|
||||
-
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@@ -270,11 +268,13 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
|
||||
String accountName = null;
|
||||
Bundle sessionBundle = null;
|
||||
String password = null;
|
||||
+ int intentFlags = 0;
|
||||
if (options != null) {
|
||||
accountName = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_NAME);
|
||||
sessionBundle = options.getBundle(
|
||||
AccountManagerServiceTestFixtures.KEY_ACCOUNT_SESSION_BUNDLE);
|
||||
password = options.getString(AccountManagerServiceTestFixtures.KEY_ACCOUNT_PASSWORD);
|
||||
+ intentFlags = options.getInt(AccountManagerServiceTestFixtures.KEY_INTENT_FLAGS, 0);
|
||||
}
|
||||
|
||||
Bundle result = new Bundle();
|
||||
@@ -302,6 +302,7 @@ public class TestAccountType1Authenticator extends AbstractAccountAuthenticator
|
||||
intent.putExtra(AccountManagerServiceTestFixtures.KEY_RESULT,
|
||||
eventualActivityResultData);
|
||||
intent.putExtra(AccountManagerServiceTestFixtures.KEY_CALLBACK, response);
|
||||
+ intent.setFlags(intentFlags);
|
||||
|
||||
result.putParcelable(AccountManager.KEY_INTENT, intent);
|
||||
} else {
|
@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Beth Thibodeau <ethibodeau@google.com>
|
||||
Date: Mon, 13 Mar 2023 16:59:33 -0500
|
||||
Subject: [PATCH 06/10] Use PendingIntent for media click action over
|
||||
lockscreen
|
||||
|
||||
The clickIntent is provided by apps as the notification's contentIntent,
|
||||
and it should be sent as is. This fixes the case where the intent called
|
||||
an activity that could show over lockscreen.
|
||||
|
||||
Bug: 271845008
|
||||
Test: atest MediaControlPanelTest
|
||||
Test: manually with test app
|
||||
(cherry picked from commit cb2904c7ff653a87cc98904bcb3bcb9c3b6e06ea)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:223e9c5839308d8cd2e14242315a0e27a5154258)
|
||||
Merged-In: I09d64452c46c4d21b9d958570020b2f5e6c2b23f
|
||||
Change-Id: I09d64452c46c4d21b9d958570020b2f5e6c2b23f
|
||||
---
|
||||
.../media/controls/ui/MediaControlPanel.java | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
index 15c34430f455..5cdfe73ad3aa 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
@@ -495,16 +495,16 @@ public class MediaControlPanel {
|
||||
mLogger.logTapContentView(mUid, mPackageName, mInstanceId);
|
||||
logSmartspaceCardReported(SMARTSPACE_CARD_CLICK_EVENT);
|
||||
|
||||
- // See StatusBarNotificationActivityStarter#onNotificationClicked
|
||||
boolean showOverLockscreen = mKeyguardStateController.isShowing()
|
||||
- && mActivityIntentHelper.wouldShowOverLockscreen(clickIntent.getIntent(),
|
||||
+ && mActivityIntentHelper.wouldPendingShowOverLockscreen(clickIntent,
|
||||
mLockscreenUserManager.getCurrentUserId());
|
||||
|
||||
if (showOverLockscreen) {
|
||||
- mActivityStarter.startActivity(clickIntent.getIntent(),
|
||||
- /* dismissShade */ true,
|
||||
- /* animationController */ null,
|
||||
- /* showOverLockscreenWhenLocked */ true);
|
||||
+ try {
|
||||
+ clickIntent.send();
|
||||
+ } catch (PendingIntent.CanceledException e) {
|
||||
+ Log.e(TAG, "Pending intent for " + key + " was cancelled");
|
||||
+ }
|
||||
} else {
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
|
||||
buildLaunchAnimatorController(mMediaViewHolder.getPlayer()));
|
@ -1,236 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Tue, 7 Mar 2023 15:44:49 -0500
|
||||
Subject: [PATCH 07/10] Allow filtering of services
|
||||
|
||||
Test: ServiceListingTest
|
||||
Bug: 260570119
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ad19ca301191bc709b386bb10f4337cacd895b9e)
|
||||
Merged-In: Ib4740ba401667de62fa1a33334c2c1fbee25b760
|
||||
Change-Id: Ib4740ba401667de62fa1a33334c2c1fbee25b760
|
||||
---
|
||||
.../applications/ServiceListing.java | 17 +++-
|
||||
.../applications/ServiceListingTest.java | 98 ++++++++++++++++++-
|
||||
2 files changed, 111 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
index bd9e760acfda..c8bcabff1094 100644
|
||||
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ServiceListing.java
|
||||
@@ -35,6 +35,7 @@ import android.util.Slog;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Class for managing services matching a given intent and requesting a given permission.
|
||||
@@ -51,12 +52,13 @@ public class ServiceListing {
|
||||
private final HashSet<ComponentName> mEnabledServices = new HashSet<>();
|
||||
private final List<ServiceInfo> mServices = new ArrayList<>();
|
||||
private final List<Callback> mCallbacks = new ArrayList<>();
|
||||
+ private final Predicate mValidator;
|
||||
|
||||
private boolean mListening;
|
||||
|
||||
private ServiceListing(Context context, String tag,
|
||||
String setting, String intentAction, String permission, String noun,
|
||||
- boolean addDeviceLockedFlags) {
|
||||
+ boolean addDeviceLockedFlags, Predicate validator) {
|
||||
mContentResolver = context.getContentResolver();
|
||||
mContext = context;
|
||||
mTag = tag;
|
||||
@@ -65,6 +67,7 @@ public class ServiceListing {
|
||||
mPermission = permission;
|
||||
mNoun = noun;
|
||||
mAddDeviceLockedFlags = addDeviceLockedFlags;
|
||||
+ mValidator = validator;
|
||||
}
|
||||
|
||||
public void addCallback(Callback callback) {
|
||||
@@ -137,7 +140,6 @@ public class ServiceListing {
|
||||
final PackageManager pmWrapper = mContext.getPackageManager();
|
||||
List<ResolveInfo> installedServices = pmWrapper.queryIntentServicesAsUser(
|
||||
new Intent(mIntentAction), flags, user);
|
||||
-
|
||||
for (ResolveInfo resolveInfo : installedServices) {
|
||||
ServiceInfo info = resolveInfo.serviceInfo;
|
||||
|
||||
@@ -148,6 +150,9 @@ public class ServiceListing {
|
||||
+ mPermission);
|
||||
continue;
|
||||
}
|
||||
+ if (mValidator != null && !mValidator.test(info)) {
|
||||
+ continue;
|
||||
+ }
|
||||
mServices.add(info);
|
||||
}
|
||||
for (Callback callback : mCallbacks) {
|
||||
@@ -194,6 +199,7 @@ public class ServiceListing {
|
||||
private String mPermission;
|
||||
private String mNoun;
|
||||
private boolean mAddDeviceLockedFlags = false;
|
||||
+ private Predicate mValidator;
|
||||
|
||||
public Builder(Context context) {
|
||||
mContext = context;
|
||||
@@ -224,6 +230,11 @@ public class ServiceListing {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ public Builder setValidator(Predicate<ServiceInfo> validator) {
|
||||
+ mValidator = validator;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Set to true to add support for both MATCH_DIRECT_BOOT_AWARE and
|
||||
* MATCH_DIRECT_BOOT_UNAWARE flags when querying PackageManager. Required to get results
|
||||
@@ -236,7 +247,7 @@ public class ServiceListing {
|
||||
|
||||
public ServiceListing build() {
|
||||
return new ServiceListing(mContext, mTag, mSetting, mIntentAction, mPermission, mNoun,
|
||||
- mAddDeviceLockedFlags);
|
||||
+ mAddDeviceLockedFlags, mValidator);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
index f7fd25b9fb7d..7ff0988c494d 100644
|
||||
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/ServiceListingTest.java
|
||||
@@ -18,20 +18,35 @@ package com.android.settingslib.applications;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
+import static org.mockito.ArgumentMatchers.any;
|
||||
+import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.Mockito.mock;
|
||||
+import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
+import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
+import android.content.Context;
|
||||
+import android.content.pm.PackageManager;
|
||||
+import android.content.pm.ResolveInfo;
|
||||
+import android.content.pm.ServiceInfo;
|
||||
import android.provider.Settings;
|
||||
|
||||
+import androidx.test.core.app.ApplicationProvider;
|
||||
+
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
+
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
+import org.mockito.ArgumentCaptor;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
+import java.util.List;
|
||||
+
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ServiceListingTest {
|
||||
|
||||
@@ -39,16 +54,97 @@ public class ServiceListingTest {
|
||||
private static final String TEST_INTENT = "com.example.intent";
|
||||
|
||||
private ServiceListing mServiceListing;
|
||||
+ private Context mContext;
|
||||
+ private PackageManager mPm;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
- mServiceListing = new ServiceListing.Builder(RuntimeEnvironment.application)
|
||||
+ mPm = mock(PackageManager.class);
|
||||
+ mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
+ when(mContext.getPackageManager()).thenReturn(mPm);
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
+ .setTag("testTag")
|
||||
+ .setSetting(TEST_SETTING)
|
||||
+ .setNoun("testNoun")
|
||||
+ .setIntentAction(TEST_INTENT)
|
||||
+ .setPermission("testPermission")
|
||||
+ .build();
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testValidator() {
|
||||
+ ServiceInfo s1 = new ServiceInfo();
|
||||
+ s1.permission = "testPermission";
|
||||
+ s1.packageName = "pkg";
|
||||
+ ServiceInfo s2 = new ServiceInfo();
|
||||
+ s2.permission = "testPermission";
|
||||
+ s2.packageName = "pkg2";
|
||||
+ ResolveInfo r1 = new ResolveInfo();
|
||||
+ r1.serviceInfo = s1;
|
||||
+ ResolveInfo r2 = new ResolveInfo();
|
||||
+ r2.serviceInfo = s2;
|
||||
+
|
||||
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
|
||||
+ ImmutableList.of(r1, r2));
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
+ .setTag("testTag")
|
||||
+ .setSetting(TEST_SETTING)
|
||||
+ .setNoun("testNoun")
|
||||
+ .setIntentAction(TEST_INTENT)
|
||||
+ .setValidator(info -> {
|
||||
+ if (info.packageName.equals("pkg")) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ })
|
||||
+ .setPermission("testPermission")
|
||||
+ .build();
|
||||
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
||||
+ mServiceListing.addCallback(callback);
|
||||
+ mServiceListing.reload();
|
||||
+
|
||||
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
|
||||
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
|
||||
+
|
||||
+ assertThat(captor.getValue().size()).isEqualTo(1);
|
||||
+ assertThat(captor.getValue().get(0)).isEqualTo(s1);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testNoValidator() {
|
||||
+ ServiceInfo s1 = new ServiceInfo();
|
||||
+ s1.permission = "testPermission";
|
||||
+ s1.packageName = "pkg";
|
||||
+ ServiceInfo s2 = new ServiceInfo();
|
||||
+ s2.permission = "testPermission";
|
||||
+ s2.packageName = "pkg2";
|
||||
+ ResolveInfo r1 = new ResolveInfo();
|
||||
+ r1.serviceInfo = s1;
|
||||
+ ResolveInfo r2 = new ResolveInfo();
|
||||
+ r2.serviceInfo = s2;
|
||||
+
|
||||
+ when(mPm.queryIntentServicesAsUser(any(), anyInt(), anyInt())).thenReturn(
|
||||
+ ImmutableList.of(r1, r2));
|
||||
+
|
||||
+ mServiceListing = new ServiceListing.Builder(mContext)
|
||||
.setTag("testTag")
|
||||
.setSetting(TEST_SETTING)
|
||||
.setNoun("testNoun")
|
||||
.setIntentAction(TEST_INTENT)
|
||||
.setPermission("testPermission")
|
||||
.build();
|
||||
+ ServiceListing.Callback callback = mock(ServiceListing.Callback.class);
|
||||
+ mServiceListing.addCallback(callback);
|
||||
+ mServiceListing.reload();
|
||||
+
|
||||
+ verify(mPm).queryIntentServicesAsUser(any(), anyInt(), anyInt());
|
||||
+ ArgumentCaptor<List<ServiceInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
+ verify(callback, times(1)).onServicesReloaded(captor.capture());
|
||||
+
|
||||
+ assertThat(captor.getValue().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
@ -1,252 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alex Johnston <acjohnston@google.com>
|
||||
Date: Wed, 8 Mar 2023 22:28:28 +0000
|
||||
Subject: [PATCH 08/10] Enforce
|
||||
DevicePolicyManager.setUserControlDisabledPackages in AppStandbyController
|
||||
|
||||
When deciding an app's standby bucket, check if the
|
||||
app has its user control disabled by an IT admin. If so,
|
||||
the app should be the exempted restricted bucket.
|
||||
|
||||
Bug: 272042183
|
||||
Test: atest AppStandbyControllerTests
|
||||
(cherry picked from commit 269fcb6873dee199dd8023831f882aafff1f6291)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:99b199d1139f50dbecba4f4bdc8066c6d0c28b5b)
|
||||
Merged-In: I4279dc37f0e17aedb1c2a87468478248443a253e
|
||||
Change-Id: I4279dc37f0e17aedb1c2a87468478248443a253e
|
||||
---
|
||||
.../server/usage/AppStandbyInternal.java | 2 +
|
||||
.../server/usage/AppStandbyController.java | 40 +++++++++++++++++++
|
||||
.../app/admin/DevicePolicyManager.java | 3 +-
|
||||
.../app/usage/UsageStatsManagerInternal.java | 10 +++++
|
||||
.../DevicePolicyManagerService.java | 2 +
|
||||
.../usage/AppStandbyControllerTests.java | 38 ++++++++++++++++++
|
||||
.../server/usage/UsageStatsService.java | 5 +++
|
||||
7 files changed, 99 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
|
||||
index 9b64edf53d8c..f50a90248030 100644
|
||||
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
|
||||
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
|
||||
@@ -225,6 +225,8 @@ public interface AppStandbyInternal {
|
||||
|
||||
void setActiveAdminApps(Set<String> adminPkgs, int userId);
|
||||
|
||||
+ void setAdminProtectedPackages(Set<String> packageNames, int userId);
|
||||
+
|
||||
/**
|
||||
* @return {@code true} if the given package is an active device admin app.
|
||||
*/
|
||||
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
|
||||
index a6f47d4e4908..b27ff411dd58 100644
|
||||
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
|
||||
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
|
||||
@@ -264,6 +264,10 @@ public class AppStandbyController
|
||||
@GuardedBy("mActiveAdminApps")
|
||||
private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
|
||||
|
||||
+ /** List of admin protected packages. Can contain {@link android.os.UserHandle#USER_ALL}. */
|
||||
+ @GuardedBy("mAdminProtectedPackages")
|
||||
+ private final SparseArray<Set<String>> mAdminProtectedPackages = new SparseArray<>();
|
||||
+
|
||||
/**
|
||||
* Set of system apps that are headless (don't have any "front door" activities, enabled or
|
||||
* disabled). Presence in this map indicates that the app is a headless system app.
|
||||
@@ -1335,6 +1339,9 @@ public class AppStandbyController
|
||||
synchronized (mActiveAdminApps) {
|
||||
mActiveAdminApps.remove(userId);
|
||||
}
|
||||
+ synchronized (mAdminProtectedPackages) {
|
||||
+ mAdminProtectedPackages.remove(userId);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1424,6 +1431,10 @@ public class AppStandbyController
|
||||
return STANDBY_BUCKET_EXEMPTED;
|
||||
}
|
||||
|
||||
+ if (isAdminProtectedPackages(packageName, userId)) {
|
||||
+ return STANDBY_BUCKET_EXEMPTED;
|
||||
+ }
|
||||
+
|
||||
if (isActiveNetworkScorer(packageName)) {
|
||||
return STANDBY_BUCKET_EXEMPTED;
|
||||
}
|
||||
@@ -1871,6 +1882,17 @@ public class AppStandbyController
|
||||
}
|
||||
}
|
||||
|
||||
+ private boolean isAdminProtectedPackages(String packageName, int userId) {
|
||||
+ synchronized (mAdminProtectedPackages) {
|
||||
+ if (mAdminProtectedPackages.contains(UserHandle.USER_ALL)
|
||||
+ && mAdminProtectedPackages.get(UserHandle.USER_ALL).contains(packageName)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ return mAdminProtectedPackages.contains(userId)
|
||||
+ && mAdminProtectedPackages.get(userId).contains(packageName);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void addActiveDeviceAdmin(String adminPkg, int userId) {
|
||||
synchronized (mActiveAdminApps) {
|
||||
@@ -1894,6 +1916,17 @@ public class AppStandbyController
|
||||
}
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
|
||||
+ synchronized (mAdminProtectedPackages) {
|
||||
+ if (packageNames == null || packageNames.isEmpty()) {
|
||||
+ mAdminProtectedPackages.remove(userId);
|
||||
+ } else {
|
||||
+ mAdminProtectedPackages.put(userId, packageNames);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void onAdminDataAvailable() {
|
||||
mAdminDataAvailableLatch.countDown();
|
||||
@@ -1916,6 +1949,13 @@ public class AppStandbyController
|
||||
}
|
||||
}
|
||||
|
||||
+ @VisibleForTesting
|
||||
+ Set<String> getAdminProtectedPackagesForTest(int userId) {
|
||||
+ synchronized (mAdminProtectedPackages) {
|
||||
+ return mAdminProtectedPackages.get(userId);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
|
||||
* returns {@code false}.
|
||||
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
index f563fdb28953..af42dd3dfc76 100644
|
||||
--- a/core/java/android/app/admin/DevicePolicyManager.java
|
||||
+++ b/core/java/android/app/admin/DevicePolicyManager.java
|
||||
@@ -14625,7 +14625,8 @@ public class DevicePolicyManager {
|
||||
/**
|
||||
* Called by a device owner or a profile owner to disable user control over apps. User will not
|
||||
* be able to clear app data or force-stop packages. When called by a device owner, applies to
|
||||
- * all users on the device.
|
||||
+ * all users on the device. Packages with user control disabled are exempted from
|
||||
+ * App Standby Buckets.
|
||||
*
|
||||
* @param admin which {@link DeviceAdminReceiver} this request is associated with
|
||||
* @param packages The package names for the apps.
|
||||
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
|
||||
index a35aa7c74ee5..ee70e2ff50ce 100644
|
||||
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
|
||||
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
|
||||
@@ -202,6 +202,16 @@ public abstract class UsageStatsManagerInternal {
|
||||
*/
|
||||
public abstract void setActiveAdminApps(Set<String> adminApps, int userId);
|
||||
|
||||
+ /**
|
||||
+ * Called by DevicePolicyManagerService to inform about the protected packages for a user.
|
||||
+ * User control will be disabled for protected packages.
|
||||
+ *
|
||||
+ * @param packageNames the set of protected packages for {@code userId}.
|
||||
+ * @param userId the userId to which the protected packages belong.
|
||||
+ */
|
||||
+ public abstract void setAdminProtectedPackages(@Nullable Set<String> packageNames,
|
||||
+ @UserIdInt int userId);
|
||||
+
|
||||
/**
|
||||
* Called by DevicePolicyManagerService during boot to inform that admin data is loaded and
|
||||
* pushed to UsageStatsService.
|
||||
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
index 515d6dc9cab1..e95f827ff6f1 100644
|
||||
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
|
||||
@@ -3202,6 +3202,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
mInjector.binderWithCleanCallingIdentity(() ->
|
||||
mInjector.getPackageManagerInternal().setOwnerProtectedPackages(
|
||||
targetUserId, protectedPackages));
|
||||
+ mUsageStatsManagerInternal.setAdminProtectedPackages(new ArraySet(protectedPackages),
|
||||
+ targetUserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
|
||||
index 308a4b67de24..e2db7584a2a6 100644
|
||||
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
|
||||
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
|
||||
@@ -158,6 +158,9 @@ public class AppStandbyControllerTests {
|
||||
private static final String ADMIN_PKG2 = "com.android.admin2";
|
||||
private static final String ADMIN_PKG3 = "com.android.admin3";
|
||||
|
||||
+ private static final String ADMIN_PROTECTED_PKG = "com.android.admin.protected";
|
||||
+ private static final String ADMIN_PROTECTED_PKG2 = "com.android.admin.protected2";
|
||||
+
|
||||
private static final long MINUTE_MS = 60 * 1000;
|
||||
private static final long HOUR_MS = 60 * MINUTE_MS;
|
||||
private static final long DAY_MS = 24 * HOUR_MS;
|
||||
@@ -1750,6 +1753,19 @@ public class AppStandbyControllerTests {
|
||||
assertIsNotActiveAdmin(ADMIN_PKG2, USER_ID);
|
||||
}
|
||||
|
||||
+ @Test
|
||||
+ public void testSetAdminProtectedPackages() {
|
||||
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
|
||||
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
|
||||
+
|
||||
+ setAdminProtectedPackages(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
|
||||
+ assertAdminProtectedPackagesForTest(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
|
||||
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
|
||||
+
|
||||
+ setAdminProtectedPackages(USER_ID, (String[]) null);
|
||||
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
@FlakyTest(bugId = 185169504)
|
||||
public void testUserInteraction_CrossProfile() throws Exception {
|
||||
@@ -2144,6 +2160,28 @@ public class AppStandbyControllerTests {
|
||||
mController.setActiveAdminApps(new ArraySet<>(Arrays.asList(admins)), userId);
|
||||
}
|
||||
|
||||
+ private void setAdminProtectedPackages(int userId, String... packageNames) {
|
||||
+ Set<String> adminProtectedPackages = packageNames != null ? new ArraySet<>(
|
||||
+ Arrays.asList(packageNames)) : null;
|
||||
+ mController.setAdminProtectedPackages(adminProtectedPackages, userId);
|
||||
+ }
|
||||
+
|
||||
+ private void assertAdminProtectedPackagesForTest(int userId, String... packageNames) {
|
||||
+ final Set<String> actualAdminProtectedPackages =
|
||||
+ mController.getAdminProtectedPackagesForTest(userId);
|
||||
+ if (packageNames == null) {
|
||||
+ if (actualAdminProtectedPackages != null && !actualAdminProtectedPackages.isEmpty()) {
|
||||
+ fail("Admin protected packages should be null; " + getAdminAppsStr(userId,
|
||||
+ actualAdminProtectedPackages));
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ assertEquals(packageNames.length, actualAdminProtectedPackages.size());
|
||||
+ for (String adminProtectedPackage : packageNames) {
|
||||
+ assertTrue(actualAdminProtectedPackages.contains(adminProtectedPackage));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
private void setAndAssertBucket(String pkg, int user, int bucket, int reason) throws Exception {
|
||||
rearmLatch(pkg);
|
||||
mController.setAppStandbyBucket(pkg, user, bucket, reason);
|
||||
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
|
||||
index ea40100227c4..71644d08e720 100644
|
||||
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
|
||||
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
|
||||
@@ -3086,6 +3086,11 @@ public class UsageStatsService extends SystemService implements
|
||||
mAppStandby.setActiveAdminApps(packageNames, userId);
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
|
||||
+ mAppStandby.setAdminProtectedPackages(packageNames, userId);
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void onAdminDataAvailable() {
|
||||
mAppStandby.onAdminDataAvailable();
|
@ -1,72 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff DeCew <jeffdq@google.com>
|
||||
Date: Fri, 24 Mar 2023 16:15:24 +0000
|
||||
Subject: [PATCH 09/10] Add BubbleMetadata detection to block FSI
|
||||
|
||||
Bug: 274759612
|
||||
Test: atest NotificationInterruptStateProviderImplTest
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e65f0c9643b52e2656ac2da21dfd0fb7395de04c)
|
||||
Merged-In: I40e1aa6377b8a60d91cb2f4189df1e9a4a4578a2
|
||||
Change-Id: I40e1aa6377b8a60d91cb2f4189df1e9a4a4578a2
|
||||
---
|
||||
...otificationInterruptStateProviderImpl.java | 11 ++++++++++
|
||||
...icationInterruptStateProviderImplTest.java | 21 +++++++++++++++++++
|
||||
2 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
|
||||
index d9dacfd0e27c..5956c5473843 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
|
||||
@@ -266,6 +266,17 @@ public class NotificationInterruptStateProviderImpl implements NotificationInter
|
||||
suppressedByDND);
|
||||
}
|
||||
|
||||
+ // If the notification has suppressive BubbleMetadata, block FSI and warn.
|
||||
+ Notification.BubbleMetadata bubbleMetadata = sbn.getNotification().getBubbleMetadata();
|
||||
+ if (bubbleMetadata != null && bubbleMetadata.isNotificationSuppressed()) {
|
||||
+ // b/274759612: Detect and report an event when a notification has both an FSI and a
|
||||
+ // suppressive BubbleMetadata, and now correctly block the FSI from firing.
|
||||
+ final int uid = entry.getSbn().getUid();
|
||||
+ android.util.EventLog.writeEvent(0x534e4554, "274759612", uid, "bubbleMetadata");
|
||||
+ mLogger.logNoFullscreenWarning(entry, "BubbleMetadata may prevent HUN");
|
||||
+ return FullScreenIntentDecision.NO_FULL_SCREEN_INTENT;
|
||||
+ }
|
||||
+
|
||||
// If the screen is off, then launch the FullScreenIntent
|
||||
if (!mPowerManager.isInteractive()) {
|
||||
return getDecisionGivenSuppression(FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE,
|
||||
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
|
||||
index 601771d64046..d2a27b30f36f 100644
|
||||
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
|
||||
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
|
||||
@@ -633,9 +633,30 @@ public class NotificationInterruptStateProviderImplTest extends SysuiTestCase {
|
||||
testShouldFullScreen_notInteractive();
|
||||
}
|
||||
|
||||
+
|
||||
+ @Test
|
||||
+ public void testShouldNotFullScreen_isSuppressedByBubbleMetadata() throws RemoteException {
|
||||
+ NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
|
||||
+ Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
|
||||
+ .setSuppressNotification(true).build();
|
||||
+ entry.getSbn().getNotification().setBubbleMetadata(bubbleMetadata);
|
||||
+ when(mPowerManager.isInteractive()).thenReturn(false);
|
||||
+ when(mDreamManager.isDreaming()).thenReturn(true);
|
||||
+ when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);
|
||||
+
|
||||
+ assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
|
||||
+ .isFalse();
|
||||
+ verify(mLogger, never()).logNoFullscreen(any(), any());
|
||||
+ verify(mLogger).logNoFullscreenWarning(entry, "GroupAlertBehavior will prevent HUN");
|
||||
+ verify(mLogger, never()).logFullscreen(any(), any());
|
||||
+ }
|
||||
+
|
||||
@Test
|
||||
public void testShouldFullScreen_notInteractive() throws RemoteException {
|
||||
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
|
||||
+ Notification.BubbleMetadata bubbleMetadata = new Notification.BubbleMetadata.Builder("foo")
|
||||
+ .setSuppressNotification(false).build();
|
||||
+ entry.getSbn().getNotification().setBubbleMetadata(bubbleMetadata);
|
||||
when(mPowerManager.isInteractive()).thenReturn(false);
|
||||
when(mDreamManager.isDreaming()).thenReturn(false);
|
||||
when(mStatusBarStateController.getState()).thenReturn(SHADE);
|
@ -1,109 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Beth Thibodeau <ethibodeau@google.com>
|
||||
Date: Tue, 14 Mar 2023 22:43:54 -0500
|
||||
Subject: [PATCH 10/10] Fix issues with setRemotePlaybackInfo
|
||||
|
||||
- Check permissions when building DecoratedMediaCustomViewStyle if it includes
|
||||
the extras from this API
|
||||
|
||||
- Send device intent as a regular PendingIntent if it can open over lockscreen
|
||||
|
||||
Bug: 271846393
|
||||
Test: atest NotificationManagerServiceTest MediaControlPanelTest
|
||||
Test: manual using test app
|
||||
(cherry picked from commit 335a3cb7b413fc178f0b190491b870b3327bd7b0)
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3c3056c16970d561175192e7a8909a9de784ae54)
|
||||
Merged-In: Ida43bb4acc34d666e354c16c4344d5c5eb6b333b
|
||||
Change-Id: Ida43bb4acc34d666e354c16c4344d5c5eb6b333b
|
||||
---
|
||||
.../media/controls/ui/MediaControlPanel.java | 11 ++++--
|
||||
.../NotificationManagerService.java | 3 +-
|
||||
.../NotificationManagerServiceTest.java | 37 +++++++++++++++++++
|
||||
3 files changed, 46 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
index 5cdfe73ad3aa..e9d8029a1aad 100644
|
||||
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
|
||||
@@ -620,12 +620,15 @@ public class MediaControlPanel {
|
||||
} else {
|
||||
mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
|
||||
if (device.getIntent() != null) {
|
||||
- if (device.getIntent().isActivity()) {
|
||||
- mActivityStarter.startActivity(
|
||||
- device.getIntent().getIntent(), true);
|
||||
+ PendingIntent deviceIntent = device.getIntent();
|
||||
+ boolean showOverLockscreen = mKeyguardStateController.isShowing()
|
||||
+ && mActivityIntentHelper.wouldPendingShowOverLockscreen(
|
||||
+ deviceIntent, mLockscreenUserManager.getCurrentUserId());
|
||||
+ if (device.getIntent().isActivity() && !showOverLockscreen) {
|
||||
+ mActivityStarter.postStartActivityDismissingKeyguard(deviceIntent);
|
||||
} else {
|
||||
try {
|
||||
- device.getIntent().send();
|
||||
+ deviceIntent.send();
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Log.e(TAG, "Device pending intent was canceled");
|
||||
}
|
||||
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
index d16f856376bf..3999c117d40d 100755
|
||||
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
|
||||
@@ -6747,7 +6747,8 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
// Ensure MediaStyle has correct permissions for remote device extras
|
||||
- if (notification.isStyle(Notification.MediaStyle.class)) {
|
||||
+ if (notification.isStyle(Notification.MediaStyle.class)
|
||||
+ || notification.isStyle(Notification.DecoratedMediaCustomViewStyle.class)) {
|
||||
int hasMediaContentControlPermission = mPackageManager.checkPermission(
|
||||
android.Manifest.permission.MEDIA_CONTENT_CONTROL, pkg, userId);
|
||||
if (hasMediaContentControlPermission != PERMISSION_GRANTED) {
|
||||
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
index 3f3b052931ab..9f0a0b2f7628 100755
|
||||
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
|
||||
@@ -4245,6 +4245,43 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
|
||||
assertFalse(posted.getNotification().extras
|
||||
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
|
||||
+ assertFalse(posted.getNotification().extras
|
||||
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
|
||||
+ assertFalse(posted.getNotification().extras
|
||||
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testCustomMediaStyleRemote_noPermission() throws RemoteException {
|
||||
+ String deviceName = "device";
|
||||
+ when(mPackageManager.checkPermission(
|
||||
+ eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt()))
|
||||
+ .thenReturn(PERMISSION_DENIED);
|
||||
+ Notification.DecoratedMediaCustomViewStyle style =
|
||||
+ new Notification.DecoratedMediaCustomViewStyle();
|
||||
+ style.setRemotePlaybackInfo(deviceName, 0, null);
|
||||
+ Notification.Builder nb = new Notification.Builder(mContext,
|
||||
+ mTestNotificationChannel.getId())
|
||||
+ .setStyle(style);
|
||||
+
|
||||
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
|
||||
+ "testCustomMediaStyleRemoteNoPermission", mUid, 0,
|
||||
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
|
||||
+ NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
|
||||
+
|
||||
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
|
||||
+ nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
|
||||
+ waitForIdle();
|
||||
+
|
||||
+ NotificationRecord posted = mService.findNotificationLocked(
|
||||
+ PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
|
||||
+
|
||||
+ assertFalse(posted.getNotification().extras
|
||||
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
|
||||
+ assertFalse(posted.getNotification().extras
|
||||
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
|
||||
+ assertFalse(posted.getNotification().extras
|
||||
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
|
||||
}
|
||||
|
||||
@Test
|
@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Dementyev <dementyev@google.com>
|
||||
Date: Tue, 7 Mar 2023 10:36:41 -0800
|
||||
Subject: [PATCH 1/2] Convert argument to intent in AddAccountSettings.
|
||||
|
||||
Bug: 265798353
|
||||
Test: manual
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c7e8052b527434ed8660e3babdab718f7f3cd7da)
|
||||
Merged-In: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a
|
||||
Change-Id: I0051e5d5fc9fd3691504cb5fbb959f701e0bce6a
|
||||
---
|
||||
src/com/android/settings/accounts/AddAccountSettings.java | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/com/android/settings/accounts/AddAccountSettings.java b/src/com/android/settings/accounts/AddAccountSettings.java
|
||||
index 81db4df329..85e942b199 100644
|
||||
--- a/src/com/android/settings/accounts/AddAccountSettings.java
|
||||
+++ b/src/com/android/settings/accounts/AddAccountSettings.java
|
||||
@@ -103,7 +103,8 @@ public class AddAccountSettings extends Activity {
|
||||
intent.putExtras(addAccountOptions)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
- startActivityForResultAsUser(intent, ADD_ACCOUNT_REQUEST, mUserHandle);
|
||||
+ startActivityForResultAsUser(
|
||||
+ new Intent(intent), ADD_ACCOUNT_REQUEST, mUserHandle);
|
||||
} else {
|
||||
setResult(RESULT_OK);
|
||||
if (mPendingIntent != null) {
|
@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Julia Reynolds <juliacr@google.com>
|
||||
Date: Tue, 7 Mar 2023 15:44:29 -0500
|
||||
Subject: [PATCH 2/2] Don't show NLSes with excessively long component names
|
||||
|
||||
Test: install test app with long CN
|
||||
Test: ServiceListingTest
|
||||
Bug: 260570119
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:793257967f165970f8cb0f4cebddab9dcd5d8353)
|
||||
Merged-In: I3ffd02f6cf6bf282e7fc264fd070ed3add4d8571
|
||||
Change-Id: I3ffd02f6cf6bf282e7fc264fd070ed3add4d8571
|
||||
---
|
||||
.../settings/notification/NotificationAccessSettings.java | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/src/com/android/settings/notification/NotificationAccessSettings.java b/src/com/android/settings/notification/NotificationAccessSettings.java
|
||||
index 4ec9ccd814..56d3f0e445 100644
|
||||
--- a/src/com/android/settings/notification/NotificationAccessSettings.java
|
||||
+++ b/src/com/android/settings/notification/NotificationAccessSettings.java
|
||||
@@ -65,6 +65,7 @@ public class NotificationAccessSettings extends EmptyTextSettings {
|
||||
private static final String TAG = "NotifAccessSettings";
|
||||
private static final String ALLOWED_KEY = "allowed";
|
||||
private static final String NOT_ALLOWED_KEY = "not_allowed";
|
||||
+ private static final int MAX_CN_LENGTH = 500;
|
||||
|
||||
private static final ManagedServiceSettings.Config CONFIG =
|
||||
new ManagedServiceSettings.Config.Builder()
|
||||
@@ -101,6 +102,12 @@ public class NotificationAccessSettings extends EmptyTextSettings {
|
||||
.setNoun(CONFIG.noun)
|
||||
.setSetting(CONFIG.setting)
|
||||
.setTag(CONFIG.tag)
|
||||
+ .setValidator(info -> {
|
||||
+ if (info.getComponentName().flattenToString().length() > MAX_CN_LENGTH) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ })
|
||||
.build();
|
||||
mServiceListing.addCallback(this::updateList);
|
||||
|
@ -1,290 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Jeon <kevinjeon@google.com>
|
||||
Date: Fri, 17 Feb 2023 20:17:54 +0000
|
||||
Subject: [PATCH 1/2] Update Traceur to check admin user status
|
||||
|
||||
This change updates Traceur to check for admin user privileges wherever
|
||||
a developer options check occurs. This is intended to address the case
|
||||
in which developer options (a global setting not differentiated on
|
||||
current user privileges) being enabled would allow guest users to open
|
||||
Traceur through a 3P app and view its trace files. This would previously
|
||||
be possible even when ADB debugging was disabled by the admin user.
|
||||
|
||||
Traceur now listens for user changes so that its document root
|
||||
(containing traces) is enabled/disabled based on the new user's admin
|
||||
status.
|
||||
|
||||
Test: Using ABTD, apply this on tm-dev+tm-qpr-dev, then check that:
|
||||
- There are no merge conflicts
|
||||
- CtsIntentSignatureTestCases passes (b/270791503)
|
||||
- TraceurUiTests passes
|
||||
Build+flash a local device on tm-dev+tm-qpr-dev and check that:
|
||||
- Traceur cannot be opened through 'am start' on a guest account
|
||||
- Opening Files on a guest account no longer shows a System Traces
|
||||
folder (even if Traceur's onCreate is somehow called)
|
||||
- System tracing no longer appears in settings for guests
|
||||
Bug: 262243665
|
||||
Bug: 262244249
|
||||
Ignore-AOSP-First: Internal-first security fix
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:35b3591dc4e50d51d0d7b54eef6cc0c5c6260898)
|
||||
Merged-In: I1c0c8c9588554378ae39a1a69a35ff44052b93e0
|
||||
Change-Id: I1c0c8c9588554378ae39a1a69a35ff44052b93e0
|
||||
---
|
||||
AndroidManifest.xml | 4 +++
|
||||
src/com/android/traceur/MainActivity.java | 5 +++-
|
||||
src/com/android/traceur/MainTvActivity.java | 5 +++-
|
||||
src/com/android/traceur/Receiver.java | 29 ++++++++++++++-----
|
||||
src/com/android/traceur/SearchProvider.java | 7 +++--
|
||||
src/com/android/traceur/StopTraceService.java | 7 ++++-
|
||||
src/com/android/traceur/StorageProvider.java | 8 +++--
|
||||
src/com/android/traceur/TraceService.java | 7 ++++-
|
||||
8 files changed, 55 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
|
||||
index 6a2544e..f38a71d 100644
|
||||
--- a/AndroidManifest.xml
|
||||
+++ b/AndroidManifest.xml
|
||||
@@ -47,6 +47,9 @@
|
||||
<!-- Used to post file-sending notification. -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
+ <!-- Used to check that the current user is an admin user. -->
|
||||
+ <uses-permission android:name="android.permission.QUERY_USERS" />
|
||||
+
|
||||
<!-- Declare Android TV support. -->
|
||||
<uses-feature android:name="android.software.leanback"
|
||||
android:required="false"/>
|
||||
@@ -113,6 +116,7 @@
|
||||
android:exported="true">
|
||||
<intent-filter android:priority="2147483647">
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED"/>
|
||||
+ <action android:name="android.intent.action.USER_FOREGROUND"/>
|
||||
<action android:name="com.android.internal.intent.action.BUGREPORT_STARTED"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
diff --git a/src/com/android/traceur/MainActivity.java b/src/com/android/traceur/MainActivity.java
|
||||
index 0380dcd..3342652 100644
|
||||
--- a/src/com/android/traceur/MainActivity.java
|
||||
+++ b/src/com/android/traceur/MainActivity.java
|
||||
@@ -17,6 +17,7 @@ package com.android.traceur;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
+import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
|
||||
@@ -34,8 +35,10 @@ public class MainActivity extends CollapsingToolbarBaseActivity {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
+ boolean isAdminUser = getApplicationContext()
|
||||
+ .getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- if (!developerOptionsIsEnabled) {
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
diff --git a/src/com/android/traceur/MainTvActivity.java b/src/com/android/traceur/MainTvActivity.java
|
||||
index 91f67c4..7459b7a 100644
|
||||
--- a/src/com/android/traceur/MainTvActivity.java
|
||||
+++ b/src/com/android/traceur/MainTvActivity.java
|
||||
@@ -17,6 +17,7 @@ package com.android.traceur;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
+import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
|
||||
public class MainTvActivity extends Activity {
|
||||
@@ -32,8 +33,10 @@ public class MainTvActivity extends Activity {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
+ boolean isAdminUser = getApplicationContext()
|
||||
+ .getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- if (!developerOptionsIsEnabled) {
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
diff --git a/src/com/android/traceur/Receiver.java b/src/com/android/traceur/Receiver.java
|
||||
index 0ed5d5d..acadb9a 100644
|
||||
--- a/src/com/android/traceur/Receiver.java
|
||||
+++ b/src/com/android/traceur/Receiver.java
|
||||
@@ -32,6 +32,7 @@ import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
+import android.os.UserManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -85,6 +86,12 @@ public class Receiver extends BroadcastReceiver {
|
||||
// We know that Perfetto won't be tracing already at boot, so pass the
|
||||
// tracingIsOff argument to avoid the Perfetto check.
|
||||
updateTracing(context, /* assumeTracingIsOff= */ true);
|
||||
+ } else if (Intent.ACTION_USER_FOREGROUND.equals(intent.getAction())) {
|
||||
+ boolean developerOptionsEnabled = (1 ==
|
||||
+ Settings.Global.getInt(context.getContentResolver(),
|
||||
+ Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0));
|
||||
+ boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
+ updateStorageProvider(context, developerOptionsEnabled && isAdminUser);
|
||||
} else if (STOP_ACTION.equals(intent.getAction())) {
|
||||
prefs.edit().putBoolean(
|
||||
context.getString(R.string.pref_key_tracing_on), false).commit();
|
||||
@@ -213,14 +220,9 @@ public class Receiver extends BroadcastReceiver {
|
||||
boolean developerOptionsEnabled = (1 ==
|
||||
Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0));
|
||||
-
|
||||
- ComponentName name = new ComponentName(context,
|
||||
- StorageProvider.class);
|
||||
- context.getPackageManager().setComponentEnabledSetting(name,
|
||||
- developerOptionsEnabled
|
||||
- ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
- PackageManager.DONT_KILL_APP);
|
||||
+ boolean isAdminUser = context.getSystemService(UserManager.class)
|
||||
+ .isAdminUser();
|
||||
+ updateStorageProvider(context, developerOptionsEnabled && isAdminUser);
|
||||
|
||||
if (!developerOptionsEnabled) {
|
||||
SharedPreferences prefs =
|
||||
@@ -243,6 +245,17 @@ public class Receiver extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Enables/disables the System Traces storage component. enableProvider should be true iff
|
||||
+ // developer options are enabled and the current user is an admin user.
|
||||
+ static void updateStorageProvider(Context context, boolean enableProvider) {
|
||||
+ ComponentName name = new ComponentName(context, StorageProvider.class);
|
||||
+ context.getPackageManager().setComponentEnabledSetting(name,
|
||||
+ enableProvider
|
||||
+ ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
|
||||
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||
+ PackageManager.DONT_KILL_APP);
|
||||
+ }
|
||||
+
|
||||
private static void postCategoryNotification(Context context, SharedPreferences prefs) {
|
||||
Intent sendIntent = new Intent(context, MainActivity.class);
|
||||
|
||||
diff --git a/src/com/android/traceur/SearchProvider.java b/src/com/android/traceur/SearchProvider.java
|
||||
index 9586bdb..0d76e9f 100644
|
||||
--- a/src/com/android/traceur/SearchProvider.java
|
||||
+++ b/src/com/android/traceur/SearchProvider.java
|
||||
@@ -30,6 +30,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
+import android.os.UserManager;
|
||||
import android.provider.SearchIndexablesProvider;
|
||||
import android.provider.Settings;
|
||||
|
||||
@@ -68,9 +69,11 @@ public class SearchProvider extends SearchIndexablesProvider {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
+ boolean isAdminUser = getContext().getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- // If developer options is not enabled, System Tracing shouldn't be searchable.
|
||||
- if (!developerOptionsIsEnabled) {
|
||||
+ // System Tracing shouldn't be searchable if developer options are not enabled or if the
|
||||
+ // user is not an admin.
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
|
||||
Object[] row = new Object[] {getContext().getString(R.string.system_tracing)};
|
||||
cursor.addRow(row);
|
||||
diff --git a/src/com/android/traceur/StopTraceService.java b/src/com/android/traceur/StopTraceService.java
|
||||
index 20c5f6e..b0c941b 100644
|
||||
--- a/src/com/android/traceur/StopTraceService.java
|
||||
+++ b/src/com/android/traceur/StopTraceService.java
|
||||
@@ -20,6 +20,7 @@ package com.android.traceur;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
+import android.os.UserManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.util.EventLog;
|
||||
@@ -40,7 +41,7 @@ public class StopTraceService extends TraceService {
|
||||
@Override
|
||||
public void onHandleIntent(Intent intent) {
|
||||
Context context = getApplicationContext();
|
||||
- // Checks that developer options are enabled before continuing.
|
||||
+ // Checks that developer options are enabled and the user is an admin before continuing.
|
||||
boolean developerOptionsEnabled =
|
||||
Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
@@ -49,6 +50,10 @@ public class StopTraceService extends TraceService {
|
||||
EventLog.writeEvent(0x534e4554, "204992293", -1, "");
|
||||
return;
|
||||
}
|
||||
+ boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
+ if (!isAdminUser) {
|
||||
+ return;
|
||||
+ }
|
||||
// Ensures that only intents that pertain to stopping a trace and need to be accessed from
|
||||
// outside Traceur are passed to TraceService through StopTraceService.
|
||||
String intentAction = intent.getAction();
|
||||
diff --git a/src/com/android/traceur/StorageProvider.java b/src/com/android/traceur/StorageProvider.java
|
||||
index 3df07d5..a2a6c3a 100644
|
||||
--- a/src/com/android/traceur/StorageProvider.java
|
||||
+++ b/src/com/android/traceur/StorageProvider.java
|
||||
@@ -22,6 +22,7 @@ import android.os.Bundle;
|
||||
import android.os.FileUtils;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
+import android.os.UserManager;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.DocumentsContract.Document;
|
||||
import android.provider.DocumentsContract.Root;
|
||||
@@ -75,10 +76,11 @@ public class StorageProvider extends FileSystemProvider{
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
+ boolean isAdminUser = getContext().getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- // If developer options is not enabled, return an empty root cursor.
|
||||
- // This removes the provider from the list entirely.
|
||||
- if (!developerOptionsIsEnabled) {
|
||||
+ // If developer options is not enabled or the user is not an admin, return an empty root
|
||||
+ // cursor. This removes the provider from the list entirely.
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
return null;
|
||||
}
|
||||
|
||||
diff --git a/src/com/android/traceur/TraceService.java b/src/com/android/traceur/TraceService.java
|
||||
index 96e76a8..0039f6f 100644
|
||||
--- a/src/com/android/traceur/TraceService.java
|
||||
+++ b/src/com/android/traceur/TraceService.java
|
||||
@@ -26,6 +26,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
+import android.os.UserManager;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.format.DateUtils;
|
||||
@@ -108,7 +109,7 @@ public class TraceService extends IntentService {
|
||||
@Override
|
||||
public void onHandleIntent(Intent intent) {
|
||||
Context context = getApplicationContext();
|
||||
- // Checks that developer options are enabled before continuing.
|
||||
+ // Checks that developer options are enabled and the user is an admin before continuing.
|
||||
boolean developerOptionsEnabled =
|
||||
Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
@@ -117,6 +118,10 @@ public class TraceService extends IntentService {
|
||||
EventLog.writeEvent(0x534e4554, "204992293", -1, "");
|
||||
return;
|
||||
}
|
||||
+ boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
+ if (!isAdminUser) {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
if (intent.getAction().equals(INTENT_ACTION_START_TRACING)) {
|
||||
startTracingInternal(intent.getStringArrayListExtra(INTENT_EXTRA_TAGS),
|
@ -1,183 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Jeon <kevinjeon@google.com>
|
||||
Date: Wed, 29 Mar 2023 16:38:23 -0400
|
||||
Subject: [PATCH 2/2] Add DISALLOW_DEBUGGING_FEATURES check
|
||||
|
||||
This change adds a check for the DISALLOW_DEBUGGING_FEATURES restriction
|
||||
wherever a developer options or admin-privileges check exists.
|
||||
|
||||
Test: Apply this change to the relevant branches and verify that Traceur
|
||||
cannot be opened through the researcher-provided APK.
|
||||
Bug: 270050064
|
||||
Bug: 270050191
|
||||
Ignore-AOSP-First: Internal-first security fix.
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:44480ce656dfa33a63bda978b4067bb4e67ee312)
|
||||
Merged-In: I95d308f6e73a19e489f5eb09558275ca6fb3c4aa
|
||||
Change-Id: I95d308f6e73a19e489f5eb09558275ca6fb3c4aa
|
||||
---
|
||||
src/com/android/traceur/MainActivity.java | 10 +++++++---
|
||||
src/com/android/traceur/MainTvActivity.java | 10 +++++++---
|
||||
src/com/android/traceur/Receiver.java | 17 ++++++++++++-----
|
||||
src/com/android/traceur/SearchProvider.java | 7 +++++--
|
||||
src/com/android/traceur/StopTraceService.java | 7 +++++--
|
||||
src/com/android/traceur/StorageProvider.java | 7 +++++--
|
||||
src/com/android/traceur/TraceService.java | 7 +++++--
|
||||
7 files changed, 46 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/com/android/traceur/MainActivity.java b/src/com/android/traceur/MainActivity.java
|
||||
index 3342652..2d48923 100644
|
||||
--- a/src/com/android/traceur/MainActivity.java
|
||||
+++ b/src/com/android/traceur/MainActivity.java
|
||||
@@ -35,10 +35,14 @@ public class MainActivity extends CollapsingToolbarBaseActivity {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
- boolean isAdminUser = getApplicationContext()
|
||||
- .getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
+ UserManager userManager = getApplicationContext()
|
||||
+ .getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser || debuggingDisallowed) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
diff --git a/src/com/android/traceur/MainTvActivity.java b/src/com/android/traceur/MainTvActivity.java
|
||||
index 7459b7a..de8c2bd 100644
|
||||
--- a/src/com/android/traceur/MainTvActivity.java
|
||||
+++ b/src/com/android/traceur/MainTvActivity.java
|
||||
@@ -33,10 +33,14 @@ public class MainTvActivity extends Activity {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getApplicationContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
- boolean isAdminUser = getApplicationContext()
|
||||
- .getSystemService(UserManager.class).isAdminUser();
|
||||
|
||||
- if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
+ UserManager userManager = getApplicationContext()
|
||||
+ .getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser || debuggingDisallowed) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
diff --git a/src/com/android/traceur/Receiver.java b/src/com/android/traceur/Receiver.java
|
||||
index acadb9a..f3c2ae3 100644
|
||||
--- a/src/com/android/traceur/Receiver.java
|
||||
+++ b/src/com/android/traceur/Receiver.java
|
||||
@@ -90,8 +90,12 @@ public class Receiver extends BroadcastReceiver {
|
||||
boolean developerOptionsEnabled = (1 ==
|
||||
Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0));
|
||||
- boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
- updateStorageProvider(context, developerOptionsEnabled && isAdminUser);
|
||||
+ UserManager userManager = context.getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+ updateStorageProvider(context,
|
||||
+ developerOptionsEnabled && isAdminUser && !debuggingDisallowed);
|
||||
} else if (STOP_ACTION.equals(intent.getAction())) {
|
||||
prefs.edit().putBoolean(
|
||||
context.getString(R.string.pref_key_tracing_on), false).commit();
|
||||
@@ -220,9 +224,12 @@ public class Receiver extends BroadcastReceiver {
|
||||
boolean developerOptionsEnabled = (1 ==
|
||||
Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0));
|
||||
- boolean isAdminUser = context.getSystemService(UserManager.class)
|
||||
- .isAdminUser();
|
||||
- updateStorageProvider(context, developerOptionsEnabled && isAdminUser);
|
||||
+ UserManager userManager = context.getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+ updateStorageProvider(context,
|
||||
+ developerOptionsEnabled && isAdminUser && !debuggingDisallowed);
|
||||
|
||||
if (!developerOptionsEnabled) {
|
||||
SharedPreferences prefs =
|
||||
diff --git a/src/com/android/traceur/SearchProvider.java b/src/com/android/traceur/SearchProvider.java
|
||||
index 0d76e9f..8a20331 100644
|
||||
--- a/src/com/android/traceur/SearchProvider.java
|
||||
+++ b/src/com/android/traceur/SearchProvider.java
|
||||
@@ -69,11 +69,14 @@ public class SearchProvider extends SearchIndexablesProvider {
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
- boolean isAdminUser = getContext().getSystemService(UserManager.class).isAdminUser();
|
||||
+ UserManager userManager = getContext().getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
|
||||
// System Tracing shouldn't be searchable if developer options are not enabled or if the
|
||||
// user is not an admin.
|
||||
- if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser || debuggingDisallowed) {
|
||||
MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
|
||||
Object[] row = new Object[] {getContext().getString(R.string.system_tracing)};
|
||||
cursor.addRow(row);
|
||||
diff --git a/src/com/android/traceur/StopTraceService.java b/src/com/android/traceur/StopTraceService.java
|
||||
index b0c941b..0e754ac 100644
|
||||
--- a/src/com/android/traceur/StopTraceService.java
|
||||
+++ b/src/com/android/traceur/StopTraceService.java
|
||||
@@ -50,8 +50,11 @@ public class StopTraceService extends TraceService {
|
||||
EventLog.writeEvent(0x534e4554, "204992293", -1, "");
|
||||
return;
|
||||
}
|
||||
- boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
- if (!isAdminUser) {
|
||||
+ UserManager userManager = context.getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+ if (!isAdminUser || debuggingDisallowed) {
|
||||
return;
|
||||
}
|
||||
// Ensures that only intents that pertain to stopping a trace and need to be accessed from
|
||||
diff --git a/src/com/android/traceur/StorageProvider.java b/src/com/android/traceur/StorageProvider.java
|
||||
index a2a6c3a..0044a81 100644
|
||||
--- a/src/com/android/traceur/StorageProvider.java
|
||||
+++ b/src/com/android/traceur/StorageProvider.java
|
||||
@@ -76,11 +76,14 @@ public class StorageProvider extends FileSystemProvider{
|
||||
boolean developerOptionsIsEnabled =
|
||||
Settings.Global.getInt(getContext().getContentResolver(),
|
||||
Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
|
||||
- boolean isAdminUser = getContext().getSystemService(UserManager.class).isAdminUser();
|
||||
+ UserManager userManager = getContext().getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
|
||||
// If developer options is not enabled or the user is not an admin, return an empty root
|
||||
// cursor. This removes the provider from the list entirely.
|
||||
- if (!developerOptionsIsEnabled || !isAdminUser) {
|
||||
+ if (!developerOptionsIsEnabled || !isAdminUser || debuggingDisallowed) {
|
||||
return null;
|
||||
}
|
||||
|
||||
diff --git a/src/com/android/traceur/TraceService.java b/src/com/android/traceur/TraceService.java
|
||||
index 0039f6f..9b6f69d 100644
|
||||
--- a/src/com/android/traceur/TraceService.java
|
||||
+++ b/src/com/android/traceur/TraceService.java
|
||||
@@ -118,8 +118,11 @@ public class TraceService extends IntentService {
|
||||
EventLog.writeEvent(0x534e4554, "204992293", -1, "");
|
||||
return;
|
||||
}
|
||||
- boolean isAdminUser = context.getSystemService(UserManager.class).isAdminUser();
|
||||
- if (!isAdminUser) {
|
||||
+ UserManager userManager = context.getSystemService(UserManager.class);
|
||||
+ boolean isAdminUser = userManager.isAdminUser();
|
||||
+ boolean debuggingDisallowed = userManager.hasUserRestriction(
|
||||
+ UserManager.DISALLOW_DEBUGGING_FEATURES);
|
||||
+ if (!isAdminUser || debuggingDisallowed) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Delwiche <delwiche@google.com>
|
||||
Date: Wed, 29 Mar 2023 22:52:06 +0000
|
||||
Subject: [PATCH 1/2] Fix OOB read in btm_ble_periodic_av_sync_lost
|
||||
|
||||
btm_ble_periodic_av_sync_lost internally calls the function
|
||||
btm_ble_get_psync_index_from_handle, which polls the internal periodic
|
||||
sync buffer and returns a matching index if one exists. If no matching
|
||||
handle is found, it returns MAX_SYNC_TRANSACTION.
|
||||
|
||||
However, here the calling function lacks the check for this case present
|
||||
in similar functions. If no handle is matched, it will attempt to index
|
||||
the buffer with MAX_SYNC_TRANSACTION, which will overrun it by a single
|
||||
width and lead to OOB access.
|
||||
|
||||
Add handling for this case.
|
||||
|
||||
Bug: 273502002
|
||||
Test: atest bluetooth_test_gd_unit, atest net_test_stack_btm, validated
|
||||
against researcher POC
|
||||
Tag: #security
|
||||
Ignore-AOSP-First: Security
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c077ffbe609c33adc212b73cd3018b174f0c8f89)
|
||||
Merged-In: I2e1e95b277f81b2668f721a7693df50841968ec5
|
||||
Change-Id: I2e1e95b277f81b2668f721a7693df50841968ec5
|
||||
---
|
||||
system/stack/btm/btm_ble_gap.cc | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/system/stack/btm/btm_ble_gap.cc b/system/stack/btm/btm_ble_gap.cc
|
||||
index f8a8940d98..af7da7f70c 100644
|
||||
--- a/system/stack/btm/btm_ble_gap.cc
|
||||
+++ b/system/stack/btm/btm_ble_gap.cc
|
||||
@@ -1180,6 +1180,10 @@ void btm_ble_periodic_adv_sync_lost(uint16_t sync_handle) {
|
||||
LOG_DEBUG("[PSync]: sync_handle = %d", sync_handle);
|
||||
|
||||
int index = btm_ble_get_psync_index_from_handle(sync_handle);
|
||||
+ if (index == MAX_SYNC_TRANSACTION) {
|
||||
+ LOG_ERROR("[PSync]: index not found for handle %u", sync_handle);
|
||||
+ return;
|
||||
+ }
|
||||
tBTM_BLE_PERIODIC_SYNC* ps = &btm_ble_pa_sync_cb.p_sync[index];
|
||||
ps->sync_lost_cb.Run(sync_handle);
|
||||
|
@ -1,128 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Delwiche <delwiche@google.com>
|
||||
Date: Tue, 21 Mar 2023 22:34:41 +0000
|
||||
Subject: [PATCH 2/2] Revert "Revert "Validate buffer length in
|
||||
sdpu_build_uuid_seq""
|
||||
|
||||
This reverts commit e6cf2700522cf639d8115b025833edc24702c7e9.
|
||||
|
||||
Reason for revert: Reinstate original change for QPR
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4a33fbcfdb10a16760ef208f1f12a71c1be2d084)
|
||||
Merged-In: I3e039f1b8f8ffbcc4875b663d417462451fb76a0
|
||||
Change-Id: I3e039f1b8f8ffbcc4875b663d417462451fb76a0
|
||||
---
|
||||
system/stack/sdp/sdp_discovery.cc | 58 ++++++++++++++++++++++++++++---
|
||||
1 file changed, 53 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/system/stack/sdp/sdp_discovery.cc b/system/stack/sdp/sdp_discovery.cc
|
||||
index 22d6e7caf4..654f899a89 100644
|
||||
--- a/system/stack/sdp/sdp_discovery.cc
|
||||
+++ b/system/stack/sdp/sdp_discovery.cc
|
||||
@@ -70,10 +70,15 @@ static uint8_t* add_attr(uint8_t* p, uint8_t* p_end, tSDP_DISCOVERY_DB* p_db,
|
||||
*
|
||||
******************************************************************************/
|
||||
static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
|
||||
- Uuid* p_uuid_list) {
|
||||
+ Uuid* p_uuid_list, uint16_t& bytes_left) {
|
||||
uint16_t xx;
|
||||
uint8_t* p_len;
|
||||
|
||||
+ if (bytes_left < 2) {
|
||||
+ DCHECK(0) << "SDP: No space for data element header";
|
||||
+ return (p_out);
|
||||
+ }
|
||||
+
|
||||
/* First thing is the data element header */
|
||||
UINT8_TO_BE_STREAM(p_out, (DATA_ELE_SEQ_DESC_TYPE << 3) | SIZE_IN_NEXT_BYTE);
|
||||
|
||||
@@ -81,9 +86,20 @@ static uint8_t* sdpu_build_uuid_seq(uint8_t* p_out, uint16_t num_uuids,
|
||||
p_len = p_out;
|
||||
p_out += 1;
|
||||
|
||||
+ /* Account for data element header and length */
|
||||
+ bytes_left -= 2;
|
||||
+
|
||||
/* Now, loop through and put in all the UUID(s) */
|
||||
for (xx = 0; xx < num_uuids; xx++, p_uuid_list++) {
|
||||
int len = p_uuid_list->GetShortestRepresentationSize();
|
||||
+
|
||||
+ if (len + 1 > bytes_left) {
|
||||
+ DCHECK(0) << "SDP: Too many UUIDs for internal buffer";
|
||||
+ break;
|
||||
+ } else {
|
||||
+ bytes_left -= (len + 1);
|
||||
+ }
|
||||
+
|
||||
if (len == Uuid::kNumBytes16) {
|
||||
UINT8_TO_BE_STREAM(p_out, (UUID_DESC_TYPE << 3) | SIZE_TWO_BYTES);
|
||||
UINT16_TO_BE_STREAM(p_out, p_uuid_list->As16Bit());
|
||||
@@ -120,6 +136,7 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
|
||||
uint8_t *p, *p_start, *p_param_len;
|
||||
BT_HDR* p_cmd = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
|
||||
uint16_t param_len;
|
||||
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
|
||||
|
||||
/* Prepare the buffer for sending the packet to L2CAP */
|
||||
p_cmd->offset = L2CAP_MIN_OFFSET;
|
||||
@@ -134,9 +151,24 @@ static void sdp_snd_service_search_req(tCONN_CB* p_ccb, uint8_t cont_len,
|
||||
p_param_len = p;
|
||||
p += 2;
|
||||
|
||||
-/* Build the UID sequence. */
|
||||
+ /* Account for header size, max service record count and
|
||||
+ * continuation state */
|
||||
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
|
||||
+ 3u + /* service search request header */
|
||||
+ 2u + /* param len */
|
||||
+ 3u + ((p_cont) ? cont_len : 0));
|
||||
+
|
||||
+ if (base_bytes > bytes_left) {
|
||||
+ DCHECK(0) << "SDP: Overran SDP data buffer";
|
||||
+ osi_free(p_cmd);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bytes_left -= base_bytes;
|
||||
+
|
||||
+ /* Build the UID sequence. */
|
||||
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
|
||||
- p_ccb->p_db->uuid_filters);
|
||||
+ p_ccb->p_db->uuid_filters, bytes_left);
|
||||
|
||||
/* Set max service record count */
|
||||
UINT16_TO_BE_STREAM(p, sdp_cb.max_recs_per_search);
|
||||
@@ -562,6 +594,7 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
|
||||
if ((cont_request_needed) || (!p_reply)) {
|
||||
BT_HDR* p_msg = (BT_HDR*)osi_malloc(SDP_DATA_BUF_SIZE);
|
||||
uint8_t* p;
|
||||
+ uint16_t bytes_left = SDP_DATA_BUF_SIZE;
|
||||
|
||||
p_msg->offset = L2CAP_MIN_OFFSET;
|
||||
p = p_start = (uint8_t*)(p_msg + 1) + L2CAP_MIN_OFFSET;
|
||||
@@ -575,9 +608,24 @@ static void process_service_search_attr_rsp(tCONN_CB* p_ccb, uint8_t* p_reply,
|
||||
p_param_len = p;
|
||||
p += 2;
|
||||
|
||||
-/* Build the UID sequence. */
|
||||
+ /* Account for header size, max service record count and
|
||||
+ * continuation state */
|
||||
+ const uint16_t base_bytes = (sizeof(BT_HDR) + L2CAP_MIN_OFFSET +
|
||||
+ 3u + /* service search request header */
|
||||
+ 2u + /* param len */
|
||||
+ 3u + /* max service record count */
|
||||
+ ((p_reply) ? (*p_reply) : 0));
|
||||
+
|
||||
+ if (base_bytes > bytes_left) {
|
||||
+ sdp_disconnect(p_ccb, SDP_INVALID_CONT_STATE);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bytes_left -= base_bytes;
|
||||
+
|
||||
+ /* Build the UID sequence. */
|
||||
p = sdpu_build_uuid_seq(p, p_ccb->p_db->num_uuid_filters,
|
||||
- p_ccb->p_db->uuid_filters);
|
||||
+ p_ccb->p_db->uuid_filters, bytes_left);
|
||||
|
||||
/* Max attribute byte count */
|
||||
UINT16_TO_BE_STREAM(p, sdp_cb.max_attr_list_size);
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,79 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pranav Madapurmath <pmadapurmath@google.com>
|
||||
Date: Tue, 21 Mar 2023 23:28:56 +0000
|
||||
Subject: [PATCH] Call Redirection: unbind service when onBind returns null
|
||||
|
||||
The call redirection service does not handle the corner case of
|
||||
onNullBinding (occurs when onBind returns null). This vulnerability
|
||||
would give the app that has the call redirection role unintentional
|
||||
access to launch background activities outside the scope of a call
|
||||
lifecycle.
|
||||
|
||||
Fixes: 273260090
|
||||
Test: Unit test to ensure we unbind the service on null onBind
|
||||
Test: CTS for similar assertion
|
||||
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9b753a1d0d1e563b3363ecd49f7f9d0100200cab)
|
||||
Merged-In: Ib9d44d239833131eb055e83801cb635e8efe0b81
|
||||
Change-Id: Ib9d44d239833131eb055e83801cb635e8efe0b81
|
||||
---
|
||||
.../CallRedirectionProcessor.java | 13 ++++++++++
|
||||
.../tests/CallRedirectionProcessorTest.java | 24 +++++++++++++++++++
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
|
||||
index adeb3113d..226382bde 100644
|
||||
--- a/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
|
||||
+++ b/src/com/android/server/telecom/callredirection/CallRedirectionProcessor.java
|
||||
@@ -162,6 +162,19 @@ public class CallRedirectionProcessor implements CallRedirectionCallback {
|
||||
Log.endSession();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void onNullBinding(ComponentName componentName) {
|
||||
+ // Make sure we unbind the service if onBind returns null
|
||||
+ Log.startSession("CRSC.oNB");
|
||||
+ try {
|
||||
+ synchronized (mTelecomLock) {
|
||||
+ finishCallRedirection();
|
||||
+ }
|
||||
+ } finally {
|
||||
+ Log.endSession();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
private class CallRedirectionAdapter extends ICallRedirectionAdapter.Stub {
|
||||
diff --git a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
|
||||
index 0a896a8ce..f2fe045ef 100644
|
||||
--- a/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
|
||||
+++ b/tests/src/com/android/server/telecom/tests/CallRedirectionProcessorTest.java
|
||||
@@ -352,4 +352,28 @@ public class CallRedirectionProcessorTest extends TelecomTestCase {
|
||||
assertEquals(REDIRECTED_GATEWAY_NUMBER_WITH_POST_DIAL,
|
||||
gatewayInfoArgumentCaptor.getValue().getGatewayAddress());
|
||||
}
|
||||
+
|
||||
+ @Test
|
||||
+ public void testUnbindOnNullBind() throws Exception {
|
||||
+ startProcessWithNoGateWayInfo();
|
||||
+ // To make sure tests are not flaky, clean all the previous handler messages
|
||||
+ waitForHandlerAction(mProcessor.getHandler(), HANDLER_TIMEOUT_DELAY);
|
||||
+ enableUserDefinedCallRedirectionService();
|
||||
+ disableCarrierCallRedirectionService();
|
||||
+
|
||||
+ mProcessor.performCallRedirection();
|
||||
+
|
||||
+ // Capture the binder
|
||||
+ ArgumentCaptor<ServiceConnection> serviceConnectionCaptor = ArgumentCaptor.forClass(
|
||||
+ ServiceConnection.class);
|
||||
+ // Verify binding occurred
|
||||
+ verify(mContext, times(1)).bindServiceAsUser(any(Intent.class),
|
||||
+ serviceConnectionCaptor.capture(), anyInt(), eq(UserHandle.CURRENT));
|
||||
+ // Simulate null return from onBind
|
||||
+ serviceConnectionCaptor.getValue().onNullBinding(USER_DEFINED_SERVICE_TEST_COMPONENT_NAME);
|
||||
+
|
||||
+ // Verify service was unbound
|
||||
+ verify(mContext, times(1)).
|
||||
+ unbindService(any(ServiceConnection.class));
|
||||
+ }
|
||||
}
|
@ -97,7 +97,6 @@ applyPatch "$DOS_PATCHES/android_build/0004-Selective_APEX.patch"; #Only enable
|
||||
sed -i '75i$(my_res_package): PRIVATE_AAPT_FLAGS += --auto-add-overlay' core/aapt2.mk; #Enable auto-add-overlay for packages, this allows the vendor overlay to easily work across all branches.
|
||||
sed -i 's/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 23/PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION := 28/' core/version_util.mk; #Set the minimum supported target SDK to Pie (GrapheneOS)
|
||||
#sed -i 's/PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := true/PRODUCT_OTA_ENFORCE_VINTF_KERNEL_REQUIREMENTS := false/' core/product_config.mk; #broken by hardenDefconfig
|
||||
sed -i 's/2023-05-05/2023-06-01/' core/version_defaults.mk; #Bump Security String #T_asb_2023-06 #XXX
|
||||
fi;
|
||||
|
||||
if enterAndClear "build/soong"; then
|
||||
@ -123,12 +122,7 @@ sed -i 's/34359738368/2147483648/' Android.bp; #revert 48-bit address space requ
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if enterAndClear "frameworks/av"; then
|
||||
git am $DOS_PATCHES/android_frameworks_av/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
fi;
|
||||
|
||||
if enterAndClear "frameworks/base"; then
|
||||
git am $DOS_PATCHES/android_frameworks_base/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
git revert --no-edit d36faad3267522c6d3ff91ba9dcca8f6274bccd1; #Reverts "JobScheduler: Respect allow-in-power-save perm" in favor of below patch
|
||||
git revert --no-edit 90d6826548189ca850d91692e71fcc1be426f453; #Reverts "Remove sensitive info from SUPL requests" in favor of below patch
|
||||
applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS)
|
||||
@ -291,7 +285,6 @@ if [ "$DOS_GRAPHENE_CONSTIFY" = true ]; then applyPatch "$DOS_PATCHES/android_pa
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/apps/Settings"; then
|
||||
git am $DOS_PATCHES/android_packages_apps_Settings/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
git revert --no-edit 41b4ed345a91da1dd46c00ee11a151c2b5ff4f43;
|
||||
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch)
|
||||
applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0005-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS)
|
||||
@ -316,10 +309,6 @@ if enterAndClear "packages/apps/ThemePicker"; then
|
||||
git revert --no-edit fcf658d2005dc557a95d5a7fb89cb90d06b31d33; #grant permission by default, to prevent crashes, missing previews, and confusion
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/apps/Traceur"; then
|
||||
git am $DOS_PATCHES/android_packages_apps_Traceur/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/apps/Trebuchet"; then
|
||||
cp $DOS_BUILD_BASE/vendor/divested/overlay/common/packages/apps/Trebuchet/res/xml/default_workspace_*.xml res/xml/; #XXX: Likely no longer needed
|
||||
fi;
|
||||
@ -336,10 +325,6 @@ applyPatch "$DOS_PATCHES_COMMON/android_packages_inputmethods_LatinIME/0001-Voic
|
||||
applyPatch "$DOS_PATCHES_COMMON/android_packages_inputmethods_LatinIME/0002-Disable_Personalization.patch"; #Disable personalization dictionary by default (GrapheneOS)
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/modules/Bluetooth"; then
|
||||
git am $DOS_PATCHES/android_packages_modules_Bluetooth/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/modules/Connectivity"; then
|
||||
applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-1.patch"; #Skip reportNetworkConnectivity() when permission is revoked (GrapheneOS)
|
||||
applyPatch "$DOS_PATCHES/android_packages_modules_Connectivity/0001-Network_Permission-2.patch"; #Enforce INTERNET permission per-uid instead of per-appId (GrapheneOS)
|
||||
@ -365,7 +350,6 @@ applyPatch "$DOS_PATCHES/android_packages_modules_Permission/0006-Location_Indic
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/modules/Wifi"; then
|
||||
git am $DOS_PATCHES/android_packages_modules_Wifi/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/344228.patch"; #wifi: resurrect mWifiLinkLayerStatsSupported counter (sassmann)
|
||||
applyPatch "$DOS_PATCHES/android_packages_modules_Wifi/0001-Random_MAC.patch"; #Add support for always generating new random MAC (GrapheneOS)
|
||||
fi;
|
||||
@ -374,10 +358,6 @@ if enterAndClear "packages/providers/DownloadProvider"; then
|
||||
applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Network_Permission.patch"; #Expose the NETWORK permission (GrapheneOS)
|
||||
fi;
|
||||
|
||||
if enterAndClear "packages/services/Telecomm"; then
|
||||
git am $DOS_PATCHES/android_packages_services_Telecomm/ASB-2023-06/*.patch; #T_asb_2023-06
|
||||
fi;
|
||||
|
||||
#if enterAndClear "packages/providers/TelephonyProvider"; then
|
||||
#cp $DOS_PATCHES_COMMON/android_packages_providers_TelephonyProvider/carrier_list.* assets/latest_carrier_id/;
|
||||
#fi;
|
||||
|
Loading…
Reference in New Issue
Block a user