diff --git a/Manifests/Manifest_LAOS-14.1.xml b/Manifests/Manifest_LAOS-14.1.xml index 28381063..15f6fe4e 100644 --- a/Manifests/Manifest_LAOS-14.1.xml +++ b/Manifests/Manifest_LAOS-14.1.xml @@ -81,7 +81,7 @@ - + diff --git a/Patches/LineageOS-16.0/android_frameworks_av/373949.patch b/Patches/LineageOS-16.0/android_frameworks_av/373949.patch deleted file mode 100644 index bcde2adf..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_av/373949.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shruti Bihani -Date: Mon, 10 Jul 2023 08:53:42 +0000 -Subject: [PATCH] Fix for heap buffer overflow issue flagged by fuzzer test. - -OOB write occurs when a value is assigned to a buffer index which is greater than the buffer size. Adding a check on buffer bounds fixes the issue. - -Similar checks have been added wherever applicable on other such methods of the class. - -Bug: 243463593 -Test: Build mtp_packet_fuzzer and run on the target device -(cherry picked from commit a669e34bb8e6f0f7b5d7a35144bd342271a24712) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1401a723899766632363129265b30d433ac69c44) -Merged-In: Icd0f2307803a1a35e655bc08d9d4cca5e2b58a9b -Change-Id: Icd0f2307803a1a35e655bc08d9d4cca5e2b58a9b ---- - media/mtp/MtpPacket.cpp | 40 +++++++++++++++++++++++++++++++--------- - 1 file changed, 31 insertions(+), 9 deletions(-) - -diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp -index 3dd4248e4c..917967cf17 100644 ---- a/media/mtp/MtpPacket.cpp -+++ b/media/mtp/MtpPacket.cpp -@@ -92,24 +92,46 @@ void MtpPacket::copyFrom(const MtpPacket& src) { - } - - uint16_t MtpPacket::getUInt16(int offset) const { -- return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; -+ if ((unsigned long)(offset+2) <= mBufferSize) { -+ return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset]; -+ } -+ else { -+ ALOGE("offset for buffer read is greater than buffer size!"); -+ abort(); -+ } - } - - uint32_t MtpPacket::getUInt32(int offset) const { -- return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | -- ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; -+ if ((unsigned long)(offset+4) <= mBufferSize) { -+ return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) | -+ ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset]; -+ } -+ else { -+ ALOGE("offset for buffer read is greater than buffer size!"); -+ abort(); -+ } - } - - void MtpPacket::putUInt16(int offset, uint16_t value) { -- mBuffer[offset++] = (uint8_t)(value & 0xFF); -- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); -+ if ((unsigned long)(offset+2) <= mBufferSize) { -+ mBuffer[offset++] = (uint8_t)(value & 0xFF); -+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); -+ } -+ else { -+ ALOGE("offset for buffer write is greater than buffer size!"); -+ } - } - - void MtpPacket::putUInt32(int offset, uint32_t value) { -- mBuffer[offset++] = (uint8_t)(value & 0xFF); -- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); -- mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); -- mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); -+ if ((unsigned long)(offset+4) <= mBufferSize) { -+ mBuffer[offset++] = (uint8_t)(value & 0xFF); -+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF); -+ mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF); -+ mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF); -+ } -+ else { -+ ALOGE("offset for buffer write is greater than buffer size!"); -+ } - } - - uint16_t MtpPacket::getContainerCode() const { diff --git a/Patches/LineageOS-16.0/android_frameworks_av/373950.patch b/Patches/LineageOS-16.0/android_frameworks_av/373950.patch deleted file mode 100644 index 03d599d5..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_av/373950.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Shruti Bihani -Date: Thu, 13 Jul 2023 09:19:08 +0000 -Subject: [PATCH] Fix heap-use-after-free issue flagged by fuzzer test. - -A data member of class MtpFfsHandle is being accessed after the class object has been freed in the fuzzer. The method accessing the data member is running in a separate thread that gets detached from its parent. Using a conditional variable with an atomic int predicate in the close() function to ensure the detached thread's execution has completed before freeing the object fixes the issue without blocking the processing mid-way. - -Bug: 243381410 -Test: Build mtp_handle_fuzzer and run on the target device -(cherry picked from commit 50bf46a3f62136386548a9187a749936bda3ee8f) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:73d89318a658ece5f337c5f9c1ec1149c52eb722) -Merged-In: I41dde165a5eba151c958b81417d9e1065af1b411 -Change-Id: I41dde165a5eba151c958b81417d9e1065af1b411 ---- - media/mtp/MtpFfsHandle.cpp | 14 ++++++++++++++ - media/mtp/MtpFfsHandle.h | 4 ++++ - 2 files changed, 18 insertions(+) - -diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp -index f25fc71752..60af36457b 100644 ---- a/media/mtp/MtpFfsHandle.cpp -+++ b/media/mtp/MtpFfsHandle.cpp -@@ -294,6 +294,10 @@ int MtpFfsHandle::start(bool ptp) { - } - - void MtpFfsHandle::close() { -+ auto timeout = std::chrono::seconds(2); -+ std::unique_lock lk(m); -+ cv.wait_for(lk, timeout ,[this]{return child_threads==0;}); -+ - io_destroy(mCtx); - closeEndpoints(); - closeConfig(); -@@ -660,6 +664,11 @@ int MtpFfsHandle::sendEvent(mtp_event me) { - char *temp = new char[me.length]; - memcpy(temp, me.data, me.length); - me.data = temp; -+ -+ std::unique_lock lk(m); -+ child_threads++; -+ lk.unlock(); -+ - std::thread t([this, me]() { return this->doSendEvent(me); }); - t.detach(); - return 0; -@@ -671,6 +680,11 @@ void MtpFfsHandle::doSendEvent(mtp_event me) { - if (static_cast(ret) != length) - PLOG(ERROR) << "Mtp error sending event thread!"; - delete[] reinterpret_cast(me.data); -+ -+ std::unique_lock lk(m); -+ child_threads--; -+ lk.unlock(); -+ cv.notify_one(); - } - - } // namespace android -diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h -index fe343f74f6..ae78db2877 100644 ---- a/media/mtp/MtpFfsHandle.h -+++ b/media/mtp/MtpFfsHandle.h -@@ -58,6 +58,10 @@ protected: - - bool mCanceled; - -+ std::mutex m; -+ std::condition_variable cv; -+ std::atomic child_threads{0}; -+ - android::base::unique_fd mControl; - // "in" from the host's perspective => sink for mtp server - android::base::unique_fd mBulkIn; diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368055.patch b/Patches/LineageOS-16.0/android_frameworks_base/368055.patch deleted file mode 100644 index cb42760d..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368055.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jean-Michel Trivi -Date: Wed, 7 Dec 2022 04:36:46 +0000 -Subject: [PATCH] RingtoneManager: verify default ringtone is audio - -When a ringtone picker tries to set a ringtone through -RingtoneManager.setActualDefaultRingtoneUri (also -called by com.android.settings.DefaultRingtonePreference), -verify the mimeType can be obtained (not found when caller -doesn't have access to it) and it is an audio resource. - -Bug: 205837340 -Test: atest android.media.audio.cts.RingtoneManagerTest -(cherry picked from commit 38618f9fb16d3b5617e2289354d47abe5af17dad) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:377144b64325dadad102f5233ecb50a4446b205b) -Merged-In: I3f2c487ded405c0c1a83ef0a2fe99cff7cc9328e -Change-Id: I3f2c487ded405c0c1a83ef0a2fe99cff7cc9328e ---- - media/java/android/media/RingtoneManager.java | 19 +++++++++++++++++-- - 1 file changed, 17 insertions(+), 2 deletions(-) - -diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java -index fefa1ede849e..0e03bfb2502a 100644 ---- a/media/java/android/media/RingtoneManager.java -+++ b/media/java/android/media/RingtoneManager.java -@@ -819,10 +819,10 @@ public class RingtoneManager { - - return ringtoneUri; - } -- -+ - /** - * Sets the {@link Uri} of the default sound for a given sound type. -- * -+ * - * @param context A context used for querying. - * @param type The type whose default sound should be set. One of - * {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or -@@ -843,6 +843,21 @@ public class RingtoneManager { - if(!isInternalRingtoneUri(ringtoneUri)) { - ringtoneUri = ContentProvider.maybeAddUserId(ringtoneUri, context.getUserId()); - } -+ -+ if (ringtoneUri != null) { -+ final String mimeType = resolver.getType(ringtoneUri); -+ if (mimeType == null) { -+ Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri -+ + " ignored: failure to find mimeType (no access from this context?)"); -+ return; -+ } -+ if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) { -+ Log.e(TAG, "setActualDefaultRingtoneUri for URI:" + ringtoneUri -+ + " ignored: associated mimeType:" + mimeType + " is not an audio type"); -+ return; -+ } -+ } -+ - Settings.System.putStringForUser(resolver, setting, - ringtoneUri != null ? ringtoneUri.toString() : null, context.getUserId()); - diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368059.patch b/Patches/LineageOS-16.0/android_frameworks_base/368059.patch deleted file mode 100644 index de7a0236..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368059.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josep del Rio -Date: Mon, 26 Jun 2023 11:16:37 +0000 -Subject: [PATCH] Do not share key mappings with JNI object - -The key mapping information between the native key mappings and -the KeyCharacterMap object available in Java is currently shared, -which means that a read can be attempted while it's being modified. - -Because the code changed between R and S, this CL fixes it just -for R; the patch for versions S+ is ag/23785419 - -Bug: 274058082 -Test: Presubmit -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4b3c4620166071561ec44961fb08a56676b4fd6c) -Merged-In: I3be94534dcda365da473f82347ae2e3f57bb1b42 -Change-Id: I3be94534dcda365da473f82347ae2e3f57bb1b42 ---- - core/jni/android_view_InputDevice.cpp | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp -index 494fad7900ef..806a88f8f50e 100644 ---- a/core/jni/android_view_InputDevice.cpp -+++ b/core/jni/android_view_InputDevice.cpp -@@ -14,6 +14,7 @@ - * limitations under the License. - */ - -+#include - #include - - #include -@@ -48,9 +49,16 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi - return NULL; - } - -+ sp map = deviceInfo.getKeyCharacterMap(); -+ if (map != nullptr) { -+ Parcel parcel; -+ map->writeToParcel(&parcel); -+ map = map->readFromParcel(&parcel); -+ } -+ - ScopedLocalRef kcmObj(env, -- android_view_KeyCharacterMap_create(env, deviceInfo.getId(), -- deviceInfo.getKeyCharacterMap())); -+ android_view_KeyCharacterMap_create(env, deviceInfo.getId(), -+ map)); - if (!kcmObj.get()) { - return NULL; - } diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368060-backport.patch b/Patches/LineageOS-16.0/android_frameworks_base/368060-backport.patch deleted file mode 100644 index 2d9eaadd..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368060-backport.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tim Yu -Date: Tue, 20 Jun 2023 21:24:36 +0000 -Subject: [PATCH] Verify URI Permissions in Autofill RemoteViews - -Check permissions of URI inside of FillResponse's RemoteViews. If the -current user does not have the required permissions to view the URI, the -RemoteView is dropped from displaying. - -This fixes a security spill in which a user can view content of another -user through a malicious Autofill provider. - -Bug: 283137865 -Fixes: b/283264674 b/281666022 b/281665050 b/281848557 b/281533566 -b/281534749 b/283101289 -Test: Verified by POC app attached in bugs -Test: atest CtsAutoFillServiceTestCases (added new tests) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:26beceb9a252a50374d056b162fa7e8ea55051b3) -Merged-In: I6f4d2a35e89bbed7bd9e07bf5cd3e2d68b20af9a -Change-Id: I6f4d2a35e89bbed7bd9e07bf5cd3e2d68b20af9a ---- - .../com/android/server/autofill/Helper.java | 43 +++++++++++++++++++ - .../android/server/autofill/ui/FillUi.java | 11 +++-- - .../android/server/autofill/ui/SaveUi.java | 2 +- - 3 files changed, 52 insertions(+), 4 deletions(-) - -diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java -index f14c8f1aa7f6..a50d87ac81e4 100644 ---- a/services/autofill/java/com/android/server/autofill/Helper.java -+++ b/services/autofill/java/com/android/server/autofill/Helper.java -@@ -18,6 +18,8 @@ package com.android.server.autofill; - - import android.annotation.NonNull; - import android.annotation.Nullable; -+import android.annotation.UserIdInt; -+import android.app.ActivityManager; - import android.app.assist.AssistStructure; - import android.app.assist.AssistStructure.ViewNode; - import android.content.ComponentName; -@@ -29,13 +31,16 @@ import android.util.Slog; - import android.view.WindowManager; - import android.view.autofill.AutofillId; - import android.view.autofill.AutofillValue; -+import android.widget.RemoteViews; - - import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - import com.android.internal.util.ArrayUtils; - - import java.io.PrintWriter; -+import java.util.Arrays; - import java.util.ArrayList; - import java.util.LinkedList; -+import java.util.concurrent.atomic.AtomicBoolean; - - public final class Helper { - -@@ -79,6 +84,44 @@ public final class Helper { - throw new UnsupportedOperationException("contains static members only"); - } - -+ private static boolean checkRemoteViewUriPermissions( -+ @UserIdInt int userId, @NonNull RemoteViews rView) { -+ final AtomicBoolean permissionsOk = new AtomicBoolean(true); -+ -+ rView.visitUris(uri -> { -+ int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri); -+ boolean allowed = uriOwnerId == userId; -+ permissionsOk.set(allowed && permissionsOk.get()); -+ }); -+ -+ return permissionsOk.get(); -+ } -+ -+ /** -+ * Checks the URI permissions of the remote view, -+ * to see if the current userId is able to access it. -+ * -+ * Returns the RemoteView that is passed if user is able, null otherwise. -+ * -+ * TODO: instead of returning a null remoteview when -+ * the current userId cannot access an URI, -+ * return a new RemoteView with the URI removed. -+ */ -+ public static @Nullable RemoteViews sanitizeRemoteView(RemoteViews rView) { -+ if (rView == null) return null; -+ -+ int userId = ActivityManager.getCurrentUser(); -+ -+ boolean ok = checkRemoteViewUriPermissions(userId, rView); -+ if (!ok) { -+ Slog.w(TAG, -+ "sanitizeRemoteView() user: " + userId -+ + " tried accessing resource that does not belong to them"); -+ } -+ return (ok ? rView : null); -+ } -+ -+ - @Nullable - static AutofillId[] toArray(@Nullable ArraySet set) { - if (set == null) return null; -diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java -index 8119054f4196..cacfcdff686f 100644 ---- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java -+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java -@@ -137,8 +137,9 @@ final class FillUi { - mContext = new ContextThemeWrapper(context, THEME_ID); - final LayoutInflater inflater = LayoutInflater.from(mContext); - -- final RemoteViews headerPresentation = response.getHeader(); -- final RemoteViews footerPresentation = response.getFooter(); -+ final RemoteViews headerPresentation = Helper.sanitizeRemoteView(response.getHeader()); -+ final RemoteViews footerPresentation = Helper.sanitizeRemoteView(response.getFooter()); -+ - final ViewGroup decor; - if (mFullScreen) { - decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null); -@@ -219,6 +220,9 @@ final class FillUi { - ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker); - final View content; - try { -+ if (Helper.sanitizeRemoteView(response.getPresentation()) == null) { -+ throw new RuntimeException("Permission error accessing RemoteView"); -+ } - response.getPresentation().setApplyTheme(THEME_ID); - content = response.getPresentation().apply(mContext, decor, interceptionHandler); - container.addView(content); -@@ -296,7 +300,8 @@ final class FillUi { - final Dataset dataset = response.getDatasets().get(i); - final int index = dataset.getFieldIds().indexOf(focusedViewId); - if (index >= 0) { -- final RemoteViews presentation = dataset.getFieldPresentation(index); -+ final RemoteViews presentation = Helper.sanitizeRemoteView( -+ dataset.getFieldPresentation(index)); - if (presentation == null) { - Slog.w(TAG, "not displaying UI on field " + focusedViewId + " because " - + "service didn't provide a presentation for it on " + dataset); -diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -index 58823036212d..695171e82773 100644 ---- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -@@ -269,7 +269,7 @@ final class SaveUi { - final int type = info.getType(); - writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_DESCRIPTION, type); - -- final RemoteViews template = customDescription.getPresentation(); -+ final RemoteViews template = Helper.sanitizeRemoteView(customDescription.getPresentation()); - if (template == null) { - Slog.w(TAG, "No remote view on custom description"); - return false; diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368061.patch b/Patches/LineageOS-16.0/android_frameworks_base/368061.patch deleted file mode 100644 index fb16b368..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368061.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josep del Rio -Date: Wed, 12 Jul 2023 16:32:05 +0000 -Subject: [PATCH] Fix KCM key mapping cloning - -ag/23792288 tried to fix a security issue by cloning the key -mappings, but unfortunately the parcel was not being rewinded. - -Bug: 274058082 -Test: Confirmed change works in newer Android versions -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:aaaba6cf190d976efdc5db6c78997dbdc9214c15) -Merged-In: I6f75b9202e20d82ebf81a35a2916e653ee1b8372 -Change-Id: I6f75b9202e20d82ebf81a35a2916e653ee1b8372 ---- - core/jni/android_view_InputDevice.cpp | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/core/jni/android_view_InputDevice.cpp b/core/jni/android_view_InputDevice.cpp -index 806a88f8f50e..f36300ada64e 100644 ---- a/core/jni/android_view_InputDevice.cpp -+++ b/core/jni/android_view_InputDevice.cpp -@@ -53,6 +53,7 @@ jobject android_view_InputDevice_create(JNIEnv* env, const InputDeviceInfo& devi - if (map != nullptr) { - Parcel parcel; - map->writeToParcel(&parcel); -+ parcel.setDataPosition(0); - map = map->readFromParcel(&parcel); - } - diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368062-backport.patch b/Patches/LineageOS-16.0/android_frameworks_base/368062-backport.patch deleted file mode 100644 index b67adf35..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368062-backport.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hongwei Wang -Date: Wed, 24 May 2023 19:35:44 -0700 -Subject: [PATCH] Disallow loading icon from content URI to PipMenu - -Bug: 278246904 -Test: manually, with the PoC app attached to the bug -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5f5a87d8a0dc9190327ba0e6113d5b80ee96abae) -Merged-In: Iecfc1fb962de611cbe3c51a44ba4fded53925a7d -Change-Id: Iecfc1fb962de611cbe3c51a44ba4fded53925a7d ---- - .../systemui/pip/phone/PipMenuActivity.java | 17 ++++++++++++----- - 1 file changed, 12 insertions(+), 5 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java -index 615b29f93269..214c58a80727 100644 ---- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java -+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java -@@ -51,6 +51,7 @@ import android.graphics.PointF; - import android.graphics.Rect; - import android.graphics.drawable.ColorDrawable; - import android.graphics.drawable.Drawable; -+import android.graphics.drawable.Icon; - import android.net.Uri; - import android.os.Bundle; - import android.os.Handler; -@@ -508,11 +509,17 @@ public class PipMenuActivity extends Activity { - final RemoteAction action = mActions.get(i); - final ImageView actionView = (ImageView) mActionsGroup.getChildAt(i); - -- // TODO: Check if the action drawable has changed before we reload it -- action.getIcon().loadDrawableAsync(this, d -> { -- d.setTint(Color.WHITE); -- actionView.setImageDrawable(d); -- }, mHandler); -+ final int iconType = action.getIcon().getType(); -+ if (iconType == Icon.TYPE_URI /* || iconType == Icon.TYPE_URI_ADAPTIVE_BITMAP*/) { -+ // Disallow loading icon from content URI -+ actionView.setImageDrawable(null); -+ } else { -+ // TODO: Check if the action drawable has changed before we reload it -+ action.getIcon().loadDrawableAsync(this, d -> { -+ d.setTint(Color.WHITE); -+ actionView.setImageDrawable(d); -+ }, mHandler); -+ } - actionView.setContentDescription(action.getContentDescription()); - if (action.isEnabled()) { - actionView.setOnClickListener(v -> { diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368063.patch b/Patches/LineageOS-16.0/android_frameworks_base/368063.patch deleted file mode 100644 index 79631de4..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368063.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kunal Malhotra -Date: Fri, 2 Jun 2023 23:32:02 +0000 -Subject: [PATCH] Fixing DatabaseUtils to detect malformed UTF-16 strings - -Test: tested with POC in bug, also using atest -Bug: 224771621 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:fb4a72e3943d166088407e61aa4439ac349f3f12) -Merged-In: Ide65205b83063801971c5778af3154bcf3f0e530 -Change-Id: Ide65205b83063801971c5778af3154bcf3f0e530 ---- - core/java/android/database/DatabaseUtils.java | 32 +++++++++++++------ - 1 file changed, 23 insertions(+), 9 deletions(-) - -diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java -index 3d019f07cb84..d3ebfea947db 100644 ---- a/core/java/android/database/DatabaseUtils.java -+++ b/core/java/android/database/DatabaseUtils.java -@@ -337,17 +337,31 @@ public class DatabaseUtils { - */ - public static void appendEscapedSQLString(StringBuilder sb, String sqlString) { - sb.append('\''); -- if (sqlString.indexOf('\'') != -1) { -- int length = sqlString.length(); -- for (int i = 0; i < length; i++) { -- char c = sqlString.charAt(i); -- if (c == '\'') { -- sb.append('\''); -+ int length = sqlString.length(); -+ for (int i = 0; i < length; i++) { -+ char c = sqlString.charAt(i); -+ if (Character.isHighSurrogate(c)) { -+ if (i == length - 1) { -+ continue; -+ } -+ if (Character.isLowSurrogate(sqlString.charAt(i + 1))) { -+ // add them both -+ sb.append(c); -+ sb.append(sqlString.charAt(i + 1)); -+ continue; -+ } else { -+ // this is a lone surrogate, skip it -+ continue; - } -- sb.append(c); - } -- } else -- sb.append(sqlString); -+ if (Character.isLowSurrogate(c)) { -+ continue; -+ } -+ if (c == '\'') { -+ sb.append('\''); -+ } -+ sb.append(c); -+ } - sb.append('\''); - } - diff --git a/Patches/LineageOS-16.0/android_frameworks_base/368067-backport.patch b/Patches/LineageOS-16.0/android_frameworks_base/368067-backport.patch deleted file mode 100644 index 5da69ce1..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/368067-backport.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tad -Date: Mon, 9 Oct 2023 20:41:21 -0400 -Subject: [PATCH] Revert "DO NOT MERGE Dismiss keyguard when simpin auth'd - and..." - -This reverts commit 9137c0f90ae0fc93afa873e8bf6e1565ac46b9ba. ---- - .../src/com/android/keyguard/KeyguardSecurityContainer.java | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java -index bb205956e932..6a71cf84759c 100644 ---- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java -+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java -@@ -351,7 +351,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe - case SimPuk: - // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home - SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); -- if (securityMode == SecurityMode.None || mLockPatternUtils.isLockScreenDisabled( -+ if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled( - KeyguardUpdateMonitor.getCurrentUser())) { - finish = true; - } else { diff --git a/Patches/LineageOS-16.0/android_frameworks_base/373951-backport.patch b/Patches/LineageOS-16.0/android_frameworks_base/373951-backport.patch deleted file mode 100644 index 7cd01f22..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/373951-backport.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nan Wu -Date: Fri, 16 Jun 2023 14:42:24 +0000 -Subject: [PATCH] DO NOT MERGE Fix BAL via notification.publicVersion - -We stripped the token that allows app to retrieve their own notification -and fire their own PI to launch activities from background. But we -forgot to strip the token from notification.publicVersion - -Bug: 278558814 -Test: NotificationManagerTest#testActivityStartFromRetrievedNotification_isBlocked -(cherry picked from commit cf851d81a954f0a6dd0c2fd7defa93932539e7f9) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1896c2e7068c9ec1ab8355d863d7e8107d5d5706) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:75fcbb37617246c43c2af34b12c9ae4b4043f9ac) -Merged-In: I8f25d7a5e47890a0496af023149717e1df482f98 -Change-Id: I8f25d7a5e47890a0496af023149717e1df482f98 ---- - core/java/android/app/Notification.java | 7 +++++-- - .../server/notification/NotificationManagerService.java | 2 +- - 2 files changed, 6 insertions(+), 3 deletions(-) - -diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java -index b2daecc659cc..d456e3d57039 100644 ---- a/core/java/android/app/Notification.java -+++ b/core/java/android/app/Notification.java -@@ -2860,8 +2860,11 @@ public class Notification implements Parcelable - * - * @hide - */ -- public void setAllowlistToken(@Nullable IBinder token) { -- mWhitelistToken = token; -+ public void clearAllowlistToken() { -+ mWhitelistToken = null; -+ if (publicVersion != null) { -+ publicVersion.clearAllowlistToken(); -+ } - } - - /** -diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index ca0ec012fb60..a1e8cd15fd7e 100755 ---- a/services/core/java/com/android/server/notification/NotificationManagerService.java -+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java -@@ -2702,7 +2702,7 @@ public class NotificationManagerService extends SystemService { - // Remove background token before returning notification to untrusted app, this - // ensures the app isn't able to perform background operations that are - // associated with notification interactions. -- notification.setAllowlistToken(null); -+ notification.clearAllowlistToken(); - return new StatusBarNotification( - sbn.getPackageName(), - sbn.getOpPkg(), diff --git a/Patches/LineageOS-16.0/android_frameworks_base/373953.patch b/Patches/LineageOS-16.0/android_frameworks_base/373953.patch deleted file mode 100644 index fa11b7b7..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/373953.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: kumarashishg -Date: Thu, 3 Aug 2023 12:01:29 +0000 -Subject: [PATCH] Use type safe API of readParcelableArray - -Bug: 291299076 -Test: Build and flash the device and check if it throws exception for -non UsbInterface object -Test: atest CtsUsbManagerTestCases -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:85d7e6712a9eeeed3bdd68ea3c3862c7e88bfe70) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:60bfbde79f2ffb012abced55d358fdf6380c0bae) -Merged-In: I2917c8331b6d56caaa9a6479bcd9a2d089f5f503 -Change-Id: I2917c8331b6d56caaa9a6479bcd9a2d089f5f503 ---- - core/java/android/hardware/usb/UsbConfiguration.java | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java -index 6ce420191ed3..34f5c9d0602f 100644 ---- a/core/java/android/hardware/usb/UsbConfiguration.java -+++ b/core/java/android/hardware/usb/UsbConfiguration.java -@@ -172,7 +172,8 @@ public class UsbConfiguration implements Parcelable { - String name = in.readString(); - int attributes = in.readInt(); - int maxPower = in.readInt(); -- Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader()); -+ Parcelable[] interfaces = in.readParcelableArray( -+ UsbInterface.class.getClassLoader(), UsbInterface.class); - UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower); - configuration.setInterfaces(interfaces); - return configuration; diff --git a/Patches/LineageOS-16.0/android_frameworks_base/373955.patch b/Patches/LineageOS-16.0/android_frameworks_base/373955.patch deleted file mode 100644 index d0201dc4..00000000 --- a/Patches/LineageOS-16.0/android_frameworks_base/373955.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Songchun Fan -Date: Mon, 14 Aug 2023 15:24:11 -0700 -Subject: [PATCH] verify ringtone URI before setting - -Similar to ag/24422287, but the same URI verification should be done in -SettingsProvider as well, which can be called by apps via -Settings.System API or ContentProvider APIs without using -RingtoneManager. - -BUG: 227201030 -Test: manual with a test app. Will add a CTS test. -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1b234678ec122994ccbfc52ac48aafdad7fdb1ed) -Merged-In: Ic0ffa1db14b5660d02880b632a7f2ad9e6e5d84b -Change-Id: Ic0ffa1db14b5660d02880b632a7f2ad9e6e5d84b ---- - .../providers/settings/SettingsProvider.java | 31 +++++++++++++++++++ - 1 file changed, 31 insertions(+) - -diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java -index 8e8ee46b8488..b65b612ecad5 100644 ---- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java -+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java -@@ -1497,6 +1497,9 @@ public class SettingsProvider extends ContentProvider { - cacheName = Settings.System.ALARM_ALERT_CACHE; - } - if (cacheName != null) { -+ if (!isValidAudioUri(name, value)) { -+ return false; -+ } - final File cacheFile = new File( - getRingtoneCacheDir(owningUserId), cacheName); - cacheFile.delete(); -@@ -1529,6 +1532,34 @@ public class SettingsProvider extends ContentProvider { - } - } - -+ private boolean isValidAudioUri(String name, String uri) { -+ if (uri != null) { -+ Uri audioUri = Uri.parse(uri); -+ if (Settings.AUTHORITY.equals( -+ ContentProvider.getAuthorityWithoutUserId(audioUri.getAuthority()))) { -+ // Don't accept setting the default uri to self-referential URIs like -+ // Settings.System.DEFAULT_RINGTONE_URI, which is an alias to the value of this -+ // setting. -+ return false; -+ } -+ final String mimeType = getContext().getContentResolver().getType(audioUri); -+ if (mimeType == null) { -+ Slog.e(LOG_TAG, -+ "mutateSystemSetting for setting: " + name + " URI: " + audioUri -+ + " ignored: failure to find mimeType (no access from this context?)"); -+ return false; -+ } -+ if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") -+ || mimeType.equals("application/x-flac"))) { -+ Slog.e(LOG_TAG, -+ "mutateSystemSetting for setting: " + name + " URI: " + audioUri -+ + " ignored: associated mimeType: " + mimeType + " is not an audio type"); -+ return false; -+ } -+ } -+ return true; -+ } -+ - private boolean hasWriteSecureSettingsPermission() { - // Write secure settings is a more protected permission. If caller has it we are good. - if (getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) diff --git a/Patches/LineageOS-16.0/android_packages_apps_Settings/368069-backport.patch b/Patches/LineageOS-16.0/android_packages_apps_Settings/368069-backport.patch deleted file mode 100644 index b5eb3bea..00000000 --- a/Patches/LineageOS-16.0/android_packages_apps_Settings/368069-backport.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Weng Su -Date: Fri, 7 Jul 2023 19:52:04 +0800 -Subject: [PATCH] Restrict ApnEditor settings - -- Finish ApnEditor settings if user is not an admin - -- Finish ApnEditor settings if user has DISALLOW_CONFIG_MOBILE_NETWORKS restriction - -Bug: 279902472 -Test: manual test -make RunSettingsRoboTests ROBOTEST_FILTER=ApnEditorTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5c2d727b8f9198bf758a4896eda7c9e5385435ff) -Merged-In: Iecdbbff7e21dfb11e3ba385858747a220cfd3e04 -Change-Id: Iecdbbff7e21dfb11e3ba385858747a220cfd3e04 ---- - .../android/settings/network/ApnEditor.java | 23 ++++++++++++++ - .../settings/network/ApnEditorTest.java | 31 ++++++++++++++++++- - 2 files changed, 53 insertions(+), 1 deletion(-) - -diff --git a/src/com/android/settings/network/ApnEditor.java b/src/com/android/settings/network/ApnEditor.java -index cceb31d29e7..74a7fed07fc 100644 ---- a/src/com/android/settings/network/ApnEditor.java -+++ b/src/com/android/settings/network/ApnEditor.java -@@ -27,6 +27,7 @@ import android.database.Cursor; - import android.net.Uri; - import android.os.Bundle; - import android.os.PersistableBundle; -+import android.os.UserManager; - import android.provider.Telephony; - import android.support.annotation.VisibleForTesting; - import android.support.v14.preference.MultiSelectListPreference; -@@ -203,6 +204,11 @@ public class ApnEditor extends SettingsPreferenceFragment - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); -+ if (isUserRestricted()) { -+ Log.e(TAG, "This setting isn't available due to user restriction."); -+ finish(); -+ return; -+ } - - addPreferencesFromResource(R.xml.apn_editor); - -@@ -1166,6 +1172,23 @@ public class ApnEditor extends SettingsPreferenceFragment - return userEnteredApnType; - } - -+ @VisibleForTesting -+ boolean isUserRestricted() { -+ UserManager userManager = getContext().getSystemService(UserManager.class); -+ if (userManager == null) { -+ return false; -+ } -+ if (!userManager.isAdminUser()) { -+ Log.e(TAG, "User is not an admin"); -+ return true; -+ } -+ if (userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) { -+ Log.e(TAG, "User is not allowed to configure mobile network"); -+ return true; -+ } -+ return false; -+ } -+ - public static class ErrorDialog extends InstrumentedDialogFragment { - - public static void showError(ApnEditor editor) { -diff --git a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java -index 35f68a06698..ed82b59be5b 100644 ---- a/tests/robotests/src/com/android/settings/network/ApnEditorTest.java -+++ b/tests/robotests/src/com/android/settings/network/ApnEditorTest.java -@@ -32,6 +32,7 @@ import android.content.Context; - import android.content.res.Resources; - import android.database.Cursor; - import android.net.Uri; -+import android.os.UserManager; - import android.support.v14.preference.MultiSelectListPreference; - import android.support.v14.preference.SwitchPreference; - import android.support.v7.preference.EditTextPreference; -@@ -97,6 +98,8 @@ public class ApnEditorTest { - - private ApnEditor mApnEditorUT; - private Activity mActivity; -+ @Mock -+ private UserManager mUserManager; - private Resources mResources; - - @Before -@@ -111,6 +114,11 @@ public class ApnEditorTest { - doNothing().when(mApnEditorUT).finish(); - doNothing().when(mApnEditorUT).showError(); - -+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class); -+ doReturn(true).when(mUserManager).isAdminUser(); -+ doReturn(false).when(mUserManager) -+ .hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); -+ - setMockPreference(mActivity); - mApnEditorUT.mApnData = new FakeApnData(APN_DATA); - mApnEditorUT.sNotSet = "Not Set"; -@@ -447,6 +455,27 @@ public class ApnEditorTest { - assertThat(ApnEditor.formatInteger("not an int")).isEqualTo("not an int"); - } - -+ @Test -+ @Config(shadows = ShadowFragment.class) -+ public void onCreate_notAdminUser_shouldFinish() { -+ doReturn(false).when(mUserManager).isAdminUser(); -+ -+ mApnEditorUT.onCreate(null); -+ -+ verify(mApnEditorUT).finish(); -+ } -+ -+ @Test -+ @Config(shadows = ShadowFragment.class) -+ public void onCreate_hasUserRestriction_shouldFinish() { -+ doReturn(true).when(mUserManager) -+ .hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); -+ -+ mApnEditorUT.onCreate(null); -+ -+ verify(mApnEditorUT).finish(); -+ } -+ - private void initCursor() { - doReturn(2).when(mCursor).getColumnCount(); - doReturn(Integer.valueOf(2)).when(mCursor).getInt(CURSOR_INTEGER_INDEX); -@@ -489,4 +518,4 @@ public class ApnEditorTest { - mUri = uri; - } - } --} -\ No newline at end of file -+} diff --git a/Patches/LineageOS-16.0/android_packages_providers_TelephonyProvider/373957-backport.patch b/Patches/LineageOS-16.0/android_packages_providers_TelephonyProvider/373957-backport.patch deleted file mode 100644 index 5b5a0b48..00000000 --- a/Patches/LineageOS-16.0/android_packages_providers_TelephonyProvider/373957-backport.patch +++ /dev/null @@ -1,817 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aishwarya Mallampati -Date: Wed, 23 Aug 2023 18:30:46 +0000 -Subject: [PATCH] DO NOT MERGE Block access to sms/mms db from work profile. - -Bug: 289242655 -Test: Manually verified work profile cannot access personal sms by -following steps mentioned in b/289242655#comment26 -- atest SmsProviderTest -- atest MmsProviderTest -- atest SmsBackupRestoreTest -- QA performed regression testing and confirmed fix is working as intended here: b/294459052#comment30 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:950a7e5a4bf1b38e846fe00642105479efded57d) -Merged-In: Ib1c9ec75f77e8412b53df50f5414caa0e5aaa277 -Change-Id: Ib1c9ec75f77e8412b53df50f5414caa0e5aaa277 ---- - .../providers/telephony/MmsProvider.java | 41 ++++- - .../telephony/MmsSmsDatabaseHelper.java | 156 +++++++++------- - .../providers/telephony/MmsSmsProvider.java | 36 ++++ - .../providers/telephony/SmsProvider.java | 35 ++++ - .../providers/telephony/MmsProviderTest.java | 173 ++++++++++++++++++ - .../telephony/MmsProviderTestable.java | 77 ++++++++ - .../providers/telephony/SmsProviderTest.java | 55 ++++++ - 7 files changed, 503 insertions(+), 70 deletions(-) - create mode 100644 tests/src/com/android/providers/telephony/MmsProviderTest.java - create mode 100644 tests/src/com/android/providers/telephony/MmsProviderTestable.java - -diff --git a/src/com/android/providers/telephony/MmsProvider.java b/src/com/android/providers/telephony/MmsProvider.java -index 7546c246..9f58fc33 100644 ---- a/src/com/android/providers/telephony/MmsProvider.java -+++ b/src/com/android/providers/telephony/MmsProvider.java -@@ -25,6 +25,7 @@ import android.content.Context; - import android.content.Intent; - import android.content.UriMatcher; - import android.database.Cursor; -+import android.database.MatrixCursor; - import android.database.sqlite.SQLiteDatabase; - import android.database.sqlite.SQLiteException; - import android.database.sqlite.SQLiteOpenHelper; -@@ -34,6 +35,7 @@ import android.os.Binder; - import android.os.FileUtils; - import android.os.ParcelFileDescriptor; - import android.os.UserHandle; -+import android.os.UserManager; - import android.provider.BaseColumns; - import android.provider.Telephony; - import android.provider.Telephony.CanonicalAddressesColumns; -@@ -50,6 +52,8 @@ import android.text.TextUtils; - import android.util.EventLog; - import android.util.Log; - -+import com.android.internal.annotations.VisibleForTesting; -+ - import com.google.android.mms.pdu.PduHeaders; - import com.google.android.mms.util.DownloadDrmHelper; - -@@ -94,6 +98,16 @@ public class MmsProvider extends ContentProvider { - @Override - public Cursor query(Uri uri, String[] projection, - String selection, String[] selectionArgs, String sortOrder) { -+ Cursor emptyCursor = new MatrixCursor((projection == null) ? -+ (new String[] {}) : projection); -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to query mms, return empty cursor. -+ Log.e(TAG, "Managed profile is not allowed to query MMS."); -+ return emptyCursor; -+ } -+ - // First check if a restricted view of the "pdu" table should be used based on the - // caller's identity. Only system, phone or the default sms app can have full access - // of mms data. For other apps, we present a restricted view which only contains sent -@@ -307,6 +321,14 @@ public class MmsProvider extends ContentProvider { - - @Override - public Uri insert(Uri uri, ContentValues values) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to insert mms, return null. -+ Log.e(TAG, "Managed profile is not allowed to insert MMS."); -+ return null; -+ } -+ - final int callerUid = Binder.getCallingUid(); - final String callerPkg = getCallingPackage(); - int msgBox = Mms.MESSAGE_BOX_ALL; -@@ -622,6 +644,14 @@ public class MmsProvider extends ContentProvider { - @Override - public int delete(Uri uri, String selection, - String[] selectionArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to delete mms, return 0. -+ Log.e(TAG, "Managed profile is not allowed to delete MMS."); -+ return 0; -+ } -+ - int match = sURLMatcher.match(uri); - if (LOCAL_LOGV) { - Log.v(TAG, "Delete uri=" + uri + ", match=" + match); -@@ -774,6 +804,14 @@ public class MmsProvider extends ContentProvider { - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to update mms, return 0. -+ Log.e(TAG, "Managed profile is not allowed to update MMS."); -+ return 0; -+ } -+ - // The _data column is filled internally in MmsProvider, so this check is just to avoid - // it from being inadvertently set. This is not supposed to be a protection against - // malicious attack, since sql injection could still be attempted to bypass the check. On -@@ -1062,7 +1100,8 @@ public class MmsProvider extends ContentProvider { - sURLMatcher.addURI("mms", "resetFilePerm/*", MMS_PART_RESET_FILE_PERMISSION); - } - -- private SQLiteOpenHelper mOpenHelper; -+ @VisibleForTesting -+ public SQLiteOpenHelper mOpenHelper; - - private static String concatSelections(String selection1, String selection2) { - if (TextUtils.isEmpty(selection1)) { -diff --git a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java -index 738963ed..3d765333 100644 ---- a/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java -+++ b/src/com/android/providers/telephony/MmsSmsDatabaseHelper.java -@@ -708,78 +708,96 @@ public class MmsSmsDatabaseHelper extends SQLiteOpenHelper { - } - } - -+ @VisibleForTesting -+ public static String CREATE_ADDR_TABLE_STR = -+ "CREATE TABLE " + MmsProvider.TABLE_ADDR + " (" + -+ Addr._ID + " INTEGER PRIMARY KEY," + -+ Addr.MSG_ID + " INTEGER," + -+ Addr.CONTACT_ID + " INTEGER," + -+ Addr.ADDRESS + " TEXT," + -+ Addr.TYPE + " INTEGER," + -+ Addr.CHARSET + " INTEGER);"; -+ -+ @VisibleForTesting -+ public static String CREATE_PART_TABLE_STR = -+ "CREATE TABLE " + MmsProvider.TABLE_PART + " (" + -+ Part._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + -+ Part.MSG_ID + " INTEGER," + -+ Part.SEQ + " INTEGER DEFAULT 0," + -+ Part.CONTENT_TYPE + " TEXT," + -+ Part.NAME + " TEXT," + -+ Part.CHARSET + " INTEGER," + -+ Part.CONTENT_DISPOSITION + " TEXT," + -+ Part.FILENAME + " TEXT," + -+ Part.CONTENT_ID + " TEXT," + -+ Part.CONTENT_LOCATION + " TEXT," + -+ Part.CT_START + " INTEGER," + -+ Part.CT_TYPE + " TEXT," + -+ Part._DATA + " TEXT," + -+ Part.TEXT + " TEXT);"; -+ -+ public static String CREATE_PDU_TABLE_STR = -+ "CREATE TABLE " + MmsProvider.TABLE_PDU + " (" + -+ Mms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + -+ Mms.THREAD_ID + " INTEGER," + -+ Mms.DATE + " INTEGER," + -+ Mms.DATE_SENT + " INTEGER DEFAULT 0," + -+ Mms.MESSAGE_BOX + " INTEGER," + -+ Mms.READ + " INTEGER DEFAULT 0," + -+ Mms.MESSAGE_ID + " TEXT," + -+ Mms.SUBJECT + " TEXT," + -+ Mms.SUBJECT_CHARSET + " INTEGER," + -+ Mms.CONTENT_TYPE + " TEXT," + -+ Mms.CONTENT_LOCATION + " TEXT," + -+ Mms.EXPIRY + " INTEGER," + -+ Mms.MESSAGE_CLASS + " TEXT," + -+ Mms.MESSAGE_TYPE + " INTEGER," + -+ Mms.MMS_VERSION + " INTEGER," + -+ Mms.MESSAGE_SIZE + " INTEGER," + -+ Mms.PRIORITY + " INTEGER," + -+ Mms.READ_REPORT + " INTEGER," + -+ Mms.REPORT_ALLOWED + " INTEGER," + -+ Mms.RESPONSE_STATUS + " INTEGER," + -+ Mms.STATUS + " INTEGER," + -+ Mms.TRANSACTION_ID + " TEXT," + -+ Mms.RETRIEVE_STATUS + " INTEGER," + -+ Mms.RETRIEVE_TEXT + " TEXT," + -+ Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," + -+ Mms.READ_STATUS + " INTEGER," + -+ Mms.CONTENT_CLASS + " INTEGER," + -+ Mms.RESPONSE_TEXT + " TEXT," + -+ Mms.DELIVERY_TIME + " INTEGER," + -+ Mms.DELIVERY_REPORT + " INTEGER," + -+ Mms.LOCKED + " INTEGER DEFAULT 0," + -+ Mms.SUBSCRIPTION_ID + " INTEGER DEFAULT " -+ + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " + -+ Mms.SEEN + " INTEGER DEFAULT 0," + -+ Mms.CREATOR + " TEXT," + -+ Mms.TEXT_ONLY + " INTEGER DEFAULT 0);"; -+ -+ @VisibleForTesting -+ public static String CREATE_RATE_TABLE_STR = -+ "CREATE TABLE " + MmsProvider.TABLE_RATE + " (" + -+ Rate.SENT_TIME + " INTEGER);"; -+ -+ @VisibleForTesting -+ public static String CREATE_DRM_TABLE_STR = -+ "CREATE TABLE " + MmsProvider.TABLE_DRM + " (" + -+ BaseColumns._ID + " INTEGER PRIMARY KEY," + -+ "_data TEXT);"; -+ - private void createMmsTables(SQLiteDatabase db) { - // N.B.: Whenever the columns here are changed, the columns in - // {@ref MmsSmsProvider} must be changed to match. -- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PDU + " (" + -- Mms._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + -- Mms.THREAD_ID + " INTEGER," + -- Mms.DATE + " INTEGER," + -- Mms.DATE_SENT + " INTEGER DEFAULT 0," + -- Mms.MESSAGE_BOX + " INTEGER," + -- Mms.READ + " INTEGER DEFAULT 0," + -- Mms.MESSAGE_ID + " TEXT," + -- Mms.SUBJECT + " TEXT," + -- Mms.SUBJECT_CHARSET + " INTEGER," + -- Mms.CONTENT_TYPE + " TEXT," + -- Mms.CONTENT_LOCATION + " TEXT," + -- Mms.EXPIRY + " INTEGER," + -- Mms.MESSAGE_CLASS + " TEXT," + -- Mms.MESSAGE_TYPE + " INTEGER," + -- Mms.MMS_VERSION + " INTEGER," + -- Mms.MESSAGE_SIZE + " INTEGER," + -- Mms.PRIORITY + " INTEGER," + -- Mms.READ_REPORT + " INTEGER," + -- Mms.REPORT_ALLOWED + " INTEGER," + -- Mms.RESPONSE_STATUS + " INTEGER," + -- Mms.STATUS + " INTEGER," + -- Mms.TRANSACTION_ID + " TEXT," + -- Mms.RETRIEVE_STATUS + " INTEGER," + -- Mms.RETRIEVE_TEXT + " TEXT," + -- Mms.RETRIEVE_TEXT_CHARSET + " INTEGER," + -- Mms.READ_STATUS + " INTEGER," + -- Mms.CONTENT_CLASS + " INTEGER," + -- Mms.RESPONSE_TEXT + " TEXT," + -- Mms.DELIVERY_TIME + " INTEGER," + -- Mms.DELIVERY_REPORT + " INTEGER," + -- Mms.LOCKED + " INTEGER DEFAULT 0," + -- Mms.SUBSCRIPTION_ID + " INTEGER DEFAULT " -- + SubscriptionManager.INVALID_SUBSCRIPTION_ID + ", " + -- Mms.SEEN + " INTEGER DEFAULT 0," + -- Mms.CREATOR + " TEXT," + -- Mms.TEXT_ONLY + " INTEGER DEFAULT 0" + -- ");"); -- -- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_ADDR + " (" + -- Addr._ID + " INTEGER PRIMARY KEY," + -- Addr.MSG_ID + " INTEGER," + -- Addr.CONTACT_ID + " INTEGER," + -- Addr.ADDRESS + " TEXT," + -- Addr.TYPE + " INTEGER," + -- Addr.CHARSET + " INTEGER);"); -- -- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_PART + " (" + -- Part._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + -- Part.MSG_ID + " INTEGER," + -- Part.SEQ + " INTEGER DEFAULT 0," + -- Part.CONTENT_TYPE + " TEXT," + -- Part.NAME + " TEXT," + -- Part.CHARSET + " INTEGER," + -- Part.CONTENT_DISPOSITION + " TEXT," + -- Part.FILENAME + " TEXT," + -- Part.CONTENT_ID + " TEXT," + -- Part.CONTENT_LOCATION + " TEXT," + -- Part.CT_START + " INTEGER," + -- Part.CT_TYPE + " TEXT," + -- Part._DATA + " TEXT," + -- Part.TEXT + " TEXT);"); -- -- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_RATE + " (" + -- Rate.SENT_TIME + " INTEGER);"); -- -- db.execSQL("CREATE TABLE " + MmsProvider.TABLE_DRM + " (" + -- BaseColumns._ID + " INTEGER PRIMARY KEY," + -- "_data TEXT);"); -+ db.execSQL(CREATE_PDU_TABLE_STR); -+ -+ db.execSQL(CREATE_ADDR_TABLE_STR); -+ -+ db.execSQL(CREATE_PART_TABLE_STR); -+ -+ db.execSQL(CREATE_RATE_TABLE_STR); -+ -+ db.execSQL(CREATE_DRM_TABLE_STR); - - // Restricted view of pdu table, only sent/received messages without wap pushes - db.execSQL("CREATE VIEW " + MmsProvider.VIEW_PDU_RESTRICTED + " AS " + -diff --git a/src/com/android/providers/telephony/MmsSmsProvider.java b/src/com/android/providers/telephony/MmsSmsProvider.java -index 1653cd98..ce83d679 100644 ---- a/src/com/android/providers/telephony/MmsSmsProvider.java -+++ b/src/com/android/providers/telephony/MmsSmsProvider.java -@@ -23,6 +23,7 @@ import android.content.Context; - import android.content.UriMatcher; - import android.database.Cursor; - import android.database.DatabaseUtils; -+import android.database.MatrixCursor; - import android.database.sqlite.SQLiteDatabase; - import android.database.sqlite.SQLiteOpenHelper; - import android.database.sqlite.SQLiteQueryBuilder; -@@ -30,6 +31,7 @@ import android.net.Uri; - import android.os.Binder; - import android.os.Bundle; - import android.os.UserHandle; -+import android.os.UserManager; - import android.provider.BaseColumns; - import android.provider.Telephony; - import android.provider.Telephony.CanonicalAddressesColumns; -@@ -323,6 +325,16 @@ public class MmsSmsProvider extends ContentProvider { - @Override - public Cursor query(Uri uri, String[] projection, - String selection, String[] selectionArgs, String sortOrder) { -+ Cursor emptyCursor = new MatrixCursor((projection == null) ? -+ (new String[] {}) : projection); -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to query mms/sms, return empty cursor. -+ Log.e(LOG_TAG, "Managed profile is not allowed to query MMS/SMS."); -+ return emptyCursor; -+ } -+ - // First check if restricted views of the "sms" and "pdu" tables should be used based on the - // caller's identity. Only system, phone or the default sms app can have full access - // of sms/mms data. For other apps, we present a restricted view which only contains sent -@@ -1216,6 +1228,14 @@ public class MmsSmsProvider extends ContentProvider { - @Override - public int delete(Uri uri, String selection, - String[] selectionArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to delete mms/sms, return 0. -+ Log.e(LOG_TAG, "Managed profile is not allowed to delete MMS/SMS."); -+ return 0; -+ } -+ - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - Context context = getContext(); - int affectedRows = 0; -@@ -1272,6 +1292,14 @@ public class MmsSmsProvider extends ContentProvider { - - @Override - public Uri insert(Uri uri, ContentValues values) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to insert mms/sms, return null. -+ Log.e(LOG_TAG, "Managed profile is not allowed to insert MMS/SMS."); -+ return null; -+ } -+ - if (URI_MATCHER.match(uri) == URI_PENDING_MSG) { - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); - long rowId = db.insert(TABLE_PENDING_MSG, null, values); -@@ -1283,6 +1311,14 @@ public class MmsSmsProvider extends ContentProvider { - @Override - public int update(Uri uri, ContentValues values, - String selection, String[] selectionArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to update mms/sms, return 0. -+ Log.e(LOG_TAG, "Managed profile is not allowed to update MMS/SMS."); -+ return 0; -+ } -+ - final int callerUid = Binder.getCallingUid(); - final String callerPkg = getCallingPackage(); - SQLiteDatabase db = mOpenHelper.getWritableDatabase(); -diff --git a/src/com/android/providers/telephony/SmsProvider.java b/src/com/android/providers/telephony/SmsProvider.java -index 2b40d7eb..986c93a1 100644 ---- a/src/com/android/providers/telephony/SmsProvider.java -+++ b/src/com/android/providers/telephony/SmsProvider.java -@@ -32,6 +32,7 @@ import android.database.sqlite.SQLiteQueryBuilder; - import android.net.Uri; - import android.os.Binder; - import android.os.UserHandle; -+import android.os.UserManager; - import android.provider.Contacts; - import android.provider.Telephony; - import android.provider.Telephony.MmsSms; -@@ -113,6 +114,16 @@ public class SmsProvider extends ContentProvider { - @Override - public Cursor query(Uri url, String[] projectionIn, String selection, - String[] selectionArgs, String sort) { -+ Cursor emptyCursor = new MatrixCursor((projectionIn == null) ? -+ (new String[] {}) : projectionIn); -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to query sms, return empty cursor. -+ Log.e(TAG, "Managed profile is not allowed to query SMS."); -+ return emptyCursor; -+ } -+ - // First check if a restricted view of the "sms" table should be used based on the - // caller's identity. Only system, phone or the default sms app can have full access - // of sms data. For other apps, we present a restricted view which only contains sent -@@ -458,6 +469,14 @@ public class SmsProvider extends ContentProvider { - } - - private Uri insertInner(Uri url, ContentValues initialValues, int callerUid, String callerPkg) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to insert sms, return null. -+ Log.e(TAG, "Managed profile is not allowed to insert SMS."); -+ return null; -+ } -+ - ContentValues values; - long rowID; - int type = Sms.MESSAGE_TYPE_ALL; -@@ -651,6 +670,14 @@ public class SmsProvider extends ContentProvider { - - @Override - public int delete(Uri url, String where, String[] whereArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to delete sms, return 0. -+ Log.e(TAG, "Managed profile is not allowed to delete SMS."); -+ return 0; -+ } -+ - int count; - int match = sURLMatcher.match(url); - SQLiteDatabase db = getWritableDatabase(match); -@@ -753,6 +780,14 @@ public class SmsProvider extends ContentProvider { - - @Override - public int update(Uri url, ContentValues values, String where, String[] whereArgs) { -+ UserManager userManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); -+ if ((userManager != null) && (userManager.isManagedProfile( -+ Binder.getCallingUserHandle().getIdentifier()))) { -+ // If work profile is trying to update sms, return 0. -+ Log.e(TAG, "Managed profile is not allowed to update SMS."); -+ return 0; -+ } -+ - final int callerUid = Binder.getCallingUid(); - final String callerPkg = getCallingPackage(); - int count = 0; -diff --git a/tests/src/com/android/providers/telephony/MmsProviderTest.java b/tests/src/com/android/providers/telephony/MmsProviderTest.java -new file mode 100644 -index 00000000..e1010e01 ---- /dev/null -+++ b/tests/src/com/android/providers/telephony/MmsProviderTest.java -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2023 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package com.android.providers.telephony; -+ -+import static org.mockito.ArgumentMatchers.anyInt; -+import static org.mockito.ArgumentMatchers.anyString; -+import static org.mockito.ArgumentMatchers.eq; -+import static org.mockito.Mockito.mock; -+import static org.mockito.Mockito.when; -+ -+import android.app.AppOpsManager; -+import android.content.ContentValues; -+import android.content.Context; -+import android.content.pm.PackageManager; -+import android.content.pm.ProviderInfo; -+import android.database.ContentObserver; -+import android.database.Cursor; -+import android.net.Uri; -+import android.os.UserManager; -+import android.provider.Telephony; -+import android.telephony.TelephonyManager; -+import android.test.mock.MockContentResolver; -+import android.util.Log; -+ -+import junit.framework.TestCase; -+ -+import org.junit.Test; -+import org.mockito.Mock; -+import org.mockito.MockitoAnnotations; -+ -+public class MmsProviderTest extends TestCase { -+ private static final String TAG = "MmsProviderTest"; -+ -+ @Mock private Context mContext; -+ private MockContentResolver mContentResolver; -+ private MmsProviderTestable mMmsProviderTestable; -+ @Mock private PackageManager mPackageManager; -+ -+ private int notifyChangeCount; -+ private UserManager mUserManager; -+ -+ @Override -+ protected void setUp() throws Exception { -+ super.setUp(); -+ MockitoAnnotations.initMocks(this); -+ mMmsProviderTestable = new MmsProviderTestable(); -+ mUserManager = mock(UserManager.class); -+ -+ // setup mocks -+ when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))) -+ .thenReturn(mock(AppOpsManager.class)); -+ when(mContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) -+ .thenReturn(mock(TelephonyManager.class)); -+ when(mContext.getSystemService(eq(Context.USER_SERVICE))) -+ .thenReturn(mUserManager); -+ -+ when(mContext.checkCallingOrSelfPermission(anyString())) -+ .thenReturn(PackageManager.PERMISSION_GRANTED); -+ when(mContext.getUserId()).thenReturn(0); -+ when(mContext.getPackageManager()).thenReturn(mPackageManager); -+ -+ /** -+ * This is used to give the MmsProviderTest a mocked context which takes a -+ * SmsProvider and attaches it to the ContentResolver with telephony authority. -+ * The mocked context also gives WRITE_APN_SETTINGS permissions -+ */ -+ mContentResolver = new MockContentResolver() { -+ @Override -+ public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, -+ int userHandle) { -+ notifyChangeCount++; -+ } -+ }; -+ when(mContext.getContentResolver()).thenReturn(mContentResolver); -+ -+ // Add authority="mms" to given mmsProvider -+ ProviderInfo providerInfo = new ProviderInfo(); -+ providerInfo.authority = "mms"; -+ -+ // Add context to given mmsProvider -+ mMmsProviderTestable.attachInfoForTesting(mContext, providerInfo); -+ Log.d(TAG, "MockContextWithProvider: mmsProvider.getContext(): " -+ + mMmsProviderTestable.getContext()); -+ -+ // Add given MmsProvider to mResolver with authority="mms" so that -+ // mResolver can send queries to mMmsProvider -+ mContentResolver.addProvider("mms", mMmsProviderTestable); -+ Log.d(TAG, "MockContextWithProvider: Add MmsProvider to mResolver"); -+ notifyChangeCount = 0; -+ } -+ -+ @Override -+ protected void tearDown() throws Exception { -+ super.tearDown(); -+ mMmsProviderTestable.closeDatabase(); -+ } -+ -+ @Test -+ public void testInsertMms() { -+ final ContentValues values = new ContentValues(); -+ values.put(Telephony.Mms.READ, 1); -+ values.put(Telephony.Mms.SEEN, 1); -+ values.put(Telephony.Mms.SUBSCRIPTION_ID, 1); -+ values.put(Telephony.Mms.MESSAGE_BOX, Telephony.Mms.MESSAGE_BOX_ALL); -+ values.put(Telephony.Mms.TEXT_ONLY, 1); -+ values.put(Telephony.Mms.THREAD_ID, 1); -+ -+ Uri expected = Uri.parse("content://mms/1"); -+ Uri actual = mContentResolver.insert(Telephony.Mms.CONTENT_URI, values); -+ -+ assertEquals(expected, actual); -+ assertEquals(1, notifyChangeCount); -+ } -+ -+ @Test -+ public void testInsertUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertNull(mContentResolver.insert(Telephony.Mms.CONTENT_URI, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Error inserting mms: " + e); -+ } -+ } -+ -+ @Test -+ public void testQueryUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try (Cursor cursor = mContentResolver.query(Telephony.Mms.CONTENT_URI, -+ null, null, null, null)) { -+ assertEquals(0, cursor.getCount()); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in getting count: " + e); -+ } -+ } -+ -+ @Test -+ public void testUpdateUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertEquals(0, mContentResolver.update(Telephony.Mms.CONTENT_URI, null, null, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in updating mms: " + e); -+ } -+ } -+ -+ @Test -+ public void testDeleteUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertEquals(0, mContentResolver.delete(Telephony.Mms.CONTENT_URI, null, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in deleting mms: " + e); -+ } -+ } -+} -diff --git a/tests/src/com/android/providers/telephony/MmsProviderTestable.java b/tests/src/com/android/providers/telephony/MmsProviderTestable.java -new file mode 100644 -index 00000000..cea411be ---- /dev/null -+++ b/tests/src/com/android/providers/telephony/MmsProviderTestable.java -@@ -0,0 +1,77 @@ -+/* -+ * Copyright (C) 2023 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+package com.android.providers.telephony; -+ -+import static com.android.providers.telephony.MmsSmsDatabaseHelper.CREATE_ADDR_TABLE_STR; -+import static com.android.providers.telephony.MmsSmsDatabaseHelper.CREATE_DRM_TABLE_STR; -+import static com.android.providers.telephony.MmsSmsDatabaseHelper.CREATE_PART_TABLE_STR; -+import static com.android.providers.telephony.MmsSmsDatabaseHelper.CREATE_PDU_TABLE_STR; -+import static com.android.providers.telephony.MmsSmsDatabaseHelper.CREATE_RATE_TABLE_STR; -+ -+import android.database.sqlite.SQLiteDatabase; -+import android.database.sqlite.SQLiteOpenHelper; -+import android.util.Log; -+ -+/** -+ * A subclass of MmsProvider used for testing on an in-memory database -+ */ -+public class MmsProviderTestable extends MmsProvider { -+ private static final String TAG = "MmsProviderTestable"; -+ -+ @Override -+ public boolean onCreate() { -+ Log.d(TAG, "onCreate called: mDbHelper = new InMemoryMmsProviderDbHelper()"); -+ mOpenHelper = new InMemoryMmsProviderDbHelper(); -+ return true; -+ } -+ -+ // close mDbHelper database object -+ protected void closeDatabase() { -+ mOpenHelper.close(); -+ } -+ -+ /** -+ * An in memory DB for MmsProviderTestable to use -+ */ -+ public static class InMemoryMmsProviderDbHelper extends SQLiteOpenHelper { -+ -+ -+ public InMemoryMmsProviderDbHelper() { -+ super(null, // no context is needed for in-memory db -+ null, // db file name is null for in-memory db -+ null, // CursorFactory is null by default -+ 1); // db version is no-op for tests -+ Log.d(TAG, "InMemoryMmsProviderDbHelper creating in-memory database"); -+ } -+ -+ @Override -+ public void onCreate(SQLiteDatabase db) { -+ // Set up the mms tables -+ Log.d(TAG, "InMemoryMmsProviderDbHelper onCreate creating the mms tables"); -+ db.execSQL(CREATE_PDU_TABLE_STR); -+ db.execSQL(CREATE_ADDR_TABLE_STR); -+ db.execSQL(CREATE_PART_TABLE_STR); -+ db.execSQL(CREATE_RATE_TABLE_STR); -+ db.execSQL(CREATE_DRM_TABLE_STR); -+ } -+ -+ @Override -+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { -+ Log.d(TAG, "InMemorySmsProviderDbHelper onUpgrade doing nothing"); -+ } -+ } -+} -diff --git a/tests/src/com/android/providers/telephony/SmsProviderTest.java b/tests/src/com/android/providers/telephony/SmsProviderTest.java -index ba632039..13d9ae98 100644 ---- a/tests/src/com/android/providers/telephony/SmsProviderTest.java -+++ b/tests/src/com/android/providers/telephony/SmsProviderTest.java -@@ -16,6 +16,10 @@ - - package com.android.providers.telephony; - -+ -+import static org.mockito.ArgumentMatchers.anyInt; -+import static org.mockito.Mockito.when; -+ - import android.app.AppOpsManager; - import android.content.ContentResolver; - import android.content.ContentValues; -@@ -26,6 +30,7 @@ import android.content.res.Resources; - import android.database.ContentObserver; - import android.database.Cursor; - import android.net.Uri; -+import android.os.UserManager; - import android.provider.Telephony; - import android.telephony.TelephonyManager; - import android.test.mock.MockContentResolver; -@@ -57,6 +62,7 @@ public class SmsProviderTest extends TestCase { - private MockContextWithProvider mContext; - private MockContentResolver mContentResolver; - private SmsProviderTestable mSmsProviderTestable; -+ private UserManager mUserManager; - - private int notifyChangeCount; - -@@ -115,6 +121,8 @@ public class SmsProviderTest extends TestCase { - return Mockito.mock(AppOpsManager.class); - case Context.TELEPHONY_SERVICE: - return Mockito.mock(TelephonyManager.class); -+ case Context.USER_SERVICE: -+ return mUserManager; - default: - return null; - } -@@ -148,6 +156,8 @@ public class SmsProviderTest extends TestCase { - mSmsProviderTestable = new SmsProviderTestable(); - mContext = new MockContextWithProvider(mSmsProviderTestable); - mContentResolver = mContext.getContentResolver(); -+ mUserManager = Mockito.mock(UserManager.class); -+ - notifyChangeCount = 0; - } - -@@ -254,6 +264,51 @@ public class SmsProviderTest extends TestCase { - cursor.close(); - } - -+ @Test -+ public void testInsertUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertNull(mContentResolver.insert(Telephony.Sms.CONTENT_URI, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Error inserting sms: " + e); -+ } -+ } -+ -+ @Test -+ public void testQueryUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try (Cursor cursor = mContentResolver.query(Telephony.Sms.CONTENT_URI, -+ null, null, null, null)) { -+ assertEquals(0, cursor.getCount()); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in getting count: " + e); -+ } -+ } -+ -+ @Test -+ public void testUpdateUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertEquals(0, mContentResolver.update(Telephony.Sms.CONTENT_URI, null, null, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in updating sms: " + e); -+ } -+ } -+ -+ @Test -+ public void testDeleteUsingManagedProfile() { -+ when(mUserManager.isManagedProfile(anyInt())).thenReturn(true); -+ -+ try { -+ assertEquals(0, mContentResolver.delete(Telephony.Sms.CONTENT_URI, null, null)); -+ } catch (Exception e) { -+ Log.d(TAG, "Exception in deleting sms: " + e); -+ } -+ } -+ - private ContentValues getFakeRawValue() { - ContentValues values = new ContentValues(); - values.put("pdu", mFakePdu); diff --git a/Scripts/LineageOS-16.0/Functions.sh b/Scripts/LineageOS-16.0/Functions.sh index f05fded7..b0fdcef7 100644 --- a/Scripts/LineageOS-16.0/Functions.sh +++ b/Scripts/LineageOS-16.0/Functions.sh @@ -93,6 +93,8 @@ patchWorkspaceReal() { repopick -fit P_asb_2023-07 -e 361282; repopick -fit P_asb_2023-08 -e 365327,365328,364605; repopick -fit P_asb_2023-09; + repopick -fit P_asb_2023-10 -e 370704; + repopick -fit P_asb_2023-11 -e 374916; sh "$DOS_SCRIPTS/Patch.sh"; sh "$DOS_SCRIPTS_COMMON/Enable_Verity.sh"; diff --git a/Scripts/LineageOS-16.0/Patch.sh b/Scripts/LineageOS-16.0/Patch.sh index 2af46cc3..af891dab 100644 --- a/Scripts/LineageOS-16.0/Patch.sh +++ b/Scripts/LineageOS-16.0/Patch.sh @@ -165,22 +165,10 @@ awk -i inplace '!/deletePackage/' pico/src/com/svox/pico/LangPackUninstaller.jav fi; if enterAndClear "frameworks/av"; then -applyPatch "$DOS_PATCHES/android_frameworks_av/373949.patch"; #R_asb_2023-11 Fix for heap buffer overflow issue flagged by fuzzer test. -#applyPatch "$DOS_PATCHES/android_frameworks_av/373950.patch"; #R_asb_2023-11 Fix heap-use-after-free issue flagged by fuzzer test. #XXX: error: use of class template 'std::unique_lock' requires template arguments if [ "$DOS_GRAPHENE_MALLOC" = true ]; then applyPatch "$DOS_PATCHES/android_frameworks_av/0001-HM-No_RLIMIT_AS.patch"; fi; #(GrapheneOS) fi; if enterAndClear "frameworks/base"; then -applyPatch "$DOS_PATCHES/android_frameworks_base/368055.patch"; #R_asb_2023-10 RingtoneManager: verify default ringtone is audio -applyPatch "$DOS_PATCHES/android_frameworks_base/368059.patch"; #R_asb_2023-10 Do not share key mappings with JNI object -applyPatch "$DOS_PATCHES/android_frameworks_base/368060-backport.patch"; #R_asb_2023-10 Verify URI Permissions in Autofill RemoteViews -applyPatch "$DOS_PATCHES/android_frameworks_base/368061.patch"; #R_asb_2023-10 Fix KCM key mapping cloning -applyPatch "$DOS_PATCHES/android_frameworks_base/368062-backport.patch"; #R_asb_2023-10 Disallow loading icon from content URI to PipMenu -applyPatch "$DOS_PATCHES/android_frameworks_base/368063.patch"; #R_asb_2023-10 Fixing DatabaseUtils to detect malformed UTF-16 strings -applyPatch "$DOS_PATCHES/android_frameworks_base/368067-backport.patch"; #R_asb_2023-10 Revert "DO NOT MERGE Dismiss keyguard when simpin auth'd and..." -applyPatch "$DOS_PATCHES/android_frameworks_base/373951-backport.patch"; #R_asb_2023-11 Fix BAL via notification.publicVersion -applyPatch "$DOS_PATCHES/android_frameworks_base/373953.patch"; #R_asb_2023-11 Use type safe API of readParcelableArray -applyPatch "$DOS_PATCHES/android_frameworks_base/373955.patch"; #R_asb_2023-11 [SettingsProvider] verify ringtone URI before setting applyPatch "$DOS_PATCHES/android_frameworks_base/0007-Always_Restict_Serial.patch"; #Always restrict access to Build.SERIAL (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0008-Browser_No_Location.patch"; #Don't grant location permission to system browsers (GrapheneOS) applyPatch "$DOS_PATCHES/android_frameworks_base/0009-SystemUI_No_Permission_Review.patch"; #Allow SystemUI to directly manage Bluetooth/WiFi (GrapheneOS) @@ -332,7 +320,6 @@ fi; if enterAndClear "packages/apps/Settings"; then git revert --no-edit c240992b4c86c7f226290807a2f41f2619e7e5e8; #Don't hide OEM unlock -applyPatch "$DOS_PATCHES/android_packages_apps_Settings/368069-backport.patch"; #R_asb_2023-10 Restrict ApnEditor settings applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0001-Captive_Portal_Toggle.patch"; #Add option to disable captive portal checks (MSe1969) #applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0004-Private_DNS.patch"; #More 'Private DNS' options (heavily based off of a CalyxOS patch) #TODO: Needs work #applyPatch "$DOS_PATCHES/android_packages_apps_Settings/0005-Automatic_Reboot.patch"; #Timeout for reboot (GrapheneOS) @@ -370,7 +357,6 @@ applyPatch "$DOS_PATCHES/android_packages_providers_DownloadProvider/0001-Networ fi; if enterAndClear "packages/providers/TelephonyProvider"; then -applyPatch "$DOS_PATCHES/android_packages_providers_TelephonyProvider/373957-backport.patch"; #R_asb_2023-11 Block access to sms/mms db from work profile. #cp $DOS_PATCHES_COMMON/android_packages_providers_TelephonyProvider/carrier_list.* assets/; fi;