diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni
index f48af037caf8..225f330ca8b7 100644
--- a/android/brave_java_sources.gni
+++ b/android/brave_java_sources.gni
@@ -234,6 +234,9 @@ brave_java_sources = [
"../../brave/android/java/org/chromium/chrome/browser/local_database/SavedBandwidthTable.java",
"../../brave/android/java/org/chromium/chrome/browser/local_database/TopSiteTable.java",
"../../brave/android/java/org/chromium/chrome/browser/media/BravePictureInPictureActivity.java",
+ "../../brave/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java",
+ "../../brave/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerServices.java",
+ "../../brave/android/java/org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper.java",
"../../brave/android/java/org/chromium/chrome/browser/misc_metrics/MiscAndroidMetricsConnectionErrorHandler.java",
"../../brave/android/java/org/chromium/chrome/browser/misc_metrics/MiscAndroidMetricsFactory.java",
"../../brave/android/java/org/chromium/chrome/browser/multiwindow/BraveMultiInstanceManagerApi31.java",
diff --git a/android/java/AndroidManifest.xml b/android/java/AndroidManifest.xml
index ed3a34709337..6215fc081050 100644
--- a/android/java/AndroidManifest.xml
+++ b/android/java/AndroidManifest.xml
@@ -215,6 +215,13 @@
+
+
+
+
+
+
diff --git a/android/java/apk_for_test.flags b/android/java/apk_for_test.flags
index eb2b762d244a..6c528aa72d83 100644
--- a/android/java/apk_for_test.flags
+++ b/android/java/apk_for_test.flags
@@ -19,6 +19,13 @@
-keep class org.chromium.components.browser_ui.media.BraveMediaSessionHelper { *; }
-keep class org.chromium.content_public.browser.MediaSessionObserver { *; }
-keep class org.chromium.ui.ViewProvider { *; }
+-keep class org.chromium.components.browser_ui.media.MediaSessionHelper { *; }
+-keep class org.chromium.components.browser_ui.notifications.ForegroundServiceUtils { *; }
+-keep class org.chromium.chrome.browser.media.ui.ChromeMediaNotificationControllerDelegate { *; }
+-keep class org.chromium.chrome.browser.media.ui.MediaSessionTabHelper { *; }
+-keep class org.chromium.components.browser_ui.notifications.BraveForegroundServiceUtils { *; }
+-keep class org.chromium.chrome.browser.media.ui.BraveMediaNotificationControllerDelegate { *; }
+-keep class org.chromium.chrome.browser.media.ui.BraveMediaSessionTabHelper { *; }
-keep class org.chromium.chrome.browser.bookmarks.BookmarkBridge {
*** mNativeBookmarkBridge;
@@ -900,3 +907,11 @@
-keep class org.chromium.chrome.browser.settings.SettingsIntentUtil {
*** createIntent(...);
}
+
+-keep class org.chromium.chrome.browser.media.ui.ChromeMediaNotificationControllerDelegate {
+ *** getContext(...);
+}
+
+-keep class org.chromium.chrome.browser.media.ui.MediaSessionTabHelper {
+ *** mTab;
+}
diff --git a/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java
new file mode 100644
index 000000000000..ad084c3b32ce
--- /dev/null
+++ b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java
@@ -0,0 +1,85 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.media.ui;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+
+import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.notifications.NotificationConstants;
+
+public class BraveMediaNotificationControllerDelegate
+ extends ChromeMediaNotificationControllerDelegate {
+ private static final String TAG = "BraveMediaNotif";
+
+ BraveMediaNotificationControllerDelegate(int id) {
+ super(id);
+ ChromeMediaNotificationControllerDelegate.sMapNotificationIdToOptions.put(
+ PlaybackListenerMicServiceImpl.NOTIFICATION_ID,
+ new NotificationOptions(
+ BraveMediaNotificationControllerServices.PlaybackListenerMicService.class,
+ NotificationConstants.GROUP_MEDIA_PLAYBACK));
+ }
+
+ private static Context getContext() {
+ assert false;
+ return null;
+ }
+
+ /** Service used to run Brave Talk session */
+ public static final class PlaybackListenerMicServiceImpl extends ListenerServiceImpl {
+ static final int NOTIFICATION_ID = R.id.media_playback_mic_notification;
+
+ public PlaybackListenerMicServiceImpl() {
+ super(NOTIFICATION_ID);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ IntentFilter filter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ ContextUtils.registerProtectedBroadcastReceiver(
+ getService(), mAudioBecomingNoisyReceiver, filter);
+ }
+
+ @Override
+ public void onDestroy() {
+ getService().unregisterReceiver(mAudioBecomingNoisyReceiver);
+ super.onDestroy();
+ }
+
+ private BroadcastReceiver mAudioBecomingNoisyReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
+ return;
+ }
+
+ Intent i =
+ new Intent(
+ getContext(),
+ BraveMediaNotificationControllerServices
+ .PlaybackListenerMicService.class);
+ i.setAction(intent.getAction());
+ try {
+ getContext().startService(i);
+ } catch (RuntimeException e) {
+ Log.e(
+ TAG,
+ "Can't start "
+ + "BraveMediaNotificationControllerServices.PlaybackListenerMicService", // presubmit: ignore-long-line
+ e);
+ }
+ }
+ };
+ }
+}
diff --git a/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerServices.java b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerServices.java
new file mode 100644
index 000000000000..476acb42cc37
--- /dev/null
+++ b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerServices.java
@@ -0,0 +1,21 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.media.ui;
+
+import org.chromium.build.annotations.IdentifierNameString;
+import org.chromium.chrome.browser.base.SplitCompatService;
+
+public class BraveMediaNotificationControllerServices {
+ public static class PlaybackListenerMicService extends SplitCompatService {
+ private static @IdentifierNameString String sImplClassName =
+ "org.chromium.chrome.browser.media.ui."
+ + "BraveMediaNotificationControllerDelegate$PlaybackListenerMicServiceImpl";
+
+ public PlaybackListenerMicService() {
+ super(sImplClassName);
+ }
+ }
+}
diff --git a/android/java/org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper.java b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper.java
new file mode 100644
index 000000000000..3126146b18be
--- /dev/null
+++ b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper.java
@@ -0,0 +1,51 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.chrome.browser.media.ui;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.components.browser_ui.media.BraveMediaSessionHelper;
+import org.chromium.components.browser_ui.media.MediaNotificationInfo;
+import org.chromium.components.browser_ui.media.MediaNotificationManager;
+
+public class BraveMediaSessionTabHelper extends MediaSessionTabHelper {
+ /** Will be deleted in bytecode, value from the parent class will be used instead. */
+ private Tab mTab;
+
+ BraveMediaSessionTabHelper(Tab tab) {
+ super(tab);
+ }
+
+ @Override
+ public MediaNotificationInfo.Builder createMediaNotificationInfoBuilder() {
+ if (!BraveMediaSessionHelper.isBraveTalk(mTab.getWebContents())) {
+ return super.createMediaNotificationInfoBuilder();
+ }
+
+ return new MediaNotificationInfo.Builder()
+ .setInstanceId(mTab.getId())
+ .setId(R.id.media_playback_mic_notification);
+ }
+
+ @Override
+ public void hideMediaNotification() {
+ if (!BraveMediaSessionHelper.isBraveTalk(mTab.getWebContents())) {
+ super.hideMediaNotification();
+ return;
+ }
+ MediaNotificationManager.hide(mTab.getId(), R.id.media_playback_mic_notification);
+ }
+
+ @Override
+ public void activateAndroidMediaSession() {
+ if (!BraveMediaSessionHelper.isBraveTalk(mTab.getWebContents())) {
+ super.activateAndroidMediaSession();
+ return;
+ }
+ MediaNotificationManager.activateAndroidMediaSession(
+ mTab.getId(), R.id.media_playback_mic_notification);
+ }
+}
diff --git a/android/java/res/values/brave_ids.xml b/android/java/res/values/brave_ids.xml
index 9d87cfb0251a..472c9a30bb7d 100644
--- a/android/java/res/values/brave_ids.xml
+++ b/android/java/res/values/brave_ids.xml
@@ -27,4 +27,7 @@
+
+
+
diff --git a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
index ffc7f82fc5bf..752628ed885f 100644
--- a/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
+++ b/android/javatests/org/chromium/chrome/browser/BytecodeTest.java
@@ -357,8 +357,17 @@ public void testClassesExist() throws Exception {
"org/chromium/chrome/browser/notifications/NotificationPlatformBridge"));
Assert.assertTrue(classExists("org/chromium/chrome/browser/settings/SettingsIntentUtil"));
+ Assert.assertTrue(classExists("org/chromium/content_public/browser/MediaSessionObserver"));
Assert.assertTrue(
classExists("org/chromium/components/browser_ui/media/MediaSessionHelper"));
+ Assert.assertTrue(
+ classExists(
+ "org/chromium/components/browser_ui/notifications/ForegroundServiceUtils"));
+ Assert.assertTrue(
+ classExists(
+ "org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate")); // presubmit: ignore-long-line
+ Assert.assertTrue(
+ classExists("org/chromium/chrome/browser/media/ui/MediaSessionTabHelper"));
}
@Test
@@ -895,6 +904,13 @@ public void testMethodsExist() throws Exception {
true,
MediaSessionObserver.class,
MediaSession.class));
+ Assert.assertTrue(
+ methodExists(
+ "org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate", // presubmit: ignore-long-line
+ "getContext",
+ MethodModifier.STATIC,
+ true,
+ Context.class));
}
@Test
@@ -1779,6 +1795,24 @@ public void testConstructorsExistAndMatch() throws Exception {
DoubleConsumer.class,
UserEducationHelper.class,
ObservableSupplier.class));
+
+ Assert.assertTrue(
+ constructorsMatch(
+ "org/chromium/components/browser_ui/notifications/ForegroundServiceUtils", // presubmit: ignore-long-line
+ "org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils")); // presubmit: ignore-long-line
+
+ Assert.assertTrue(
+ constructorsMatch(
+ "org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate", // presubmit: ignore-long-line
+ "org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate", // presubmit: ignore-long-line
+ int.class));
+
+ Assert.assertTrue(
+ constructorsMatch(
+ "org/chromium/chrome/browser/media/ui/MediaSessionTabHelper", // presubmit:
+ // ignore-long-line
+ "org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper", // presubmit: ignore-long-line
+ Tab.class));
}
@Test
@@ -2150,6 +2184,8 @@ public void testFieldsExist() throws Exception {
fieldExists(
"org/chromium/components/browser_ui/media/MediaSessionHelper",
"mMediaSessionActions"));
+ Assert.assertTrue(
+ fieldExists("org/chromium/chrome/browser/media/ui/MediaSessionTabHelper", "mTab"));
}
@Test
diff --git a/build/android/bytecode/BUILD.gn b/build/android/bytecode/BUILD.gn
index 11c6a7fbddc0..ff27e4fc1421 100644
--- a/build/android/bytecode/BUILD.gn
+++ b/build/android/bytecode/BUILD.gn
@@ -50,6 +50,7 @@ java_binary("java_bytecode_rewriter") {
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveExternalNavigationHandlerClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFeedSurfaceCoordinatorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFeedSurfaceMediatorClassAdapter.java",
+ "//brave/build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveFreIntentCreatorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveHelpAndFeedbackLauncherImplClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveHomepageManagerClassAdapter.java",
@@ -66,7 +67,9 @@ java_binary("java_bytecode_rewriter") {
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveMainPreferenceBaseClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveManageAccountDevicesLinkViewClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveManageSyncSettingsClassAdapter.java",
+ "//brave/build/android/bytecode/java/org/brave/bytecode/BraveMediaNotificationControllerDelegateAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionHelperClassAdapter.java",
+ "//brave/build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionTabHelperClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveMenuButtonCoordinatorClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveMimeUtilsClassAdapter.java",
"//brave/build/android/bytecode/java/org/brave/bytecode/BraveMostVisitedTilesLayoutBaseClassAdapter.java",
diff --git a/build/android/bytecode/bytecode_rewriter.gni b/build/android/bytecode/bytecode_rewriter.gni
index 8dfbecec80c3..07fb46db65a0 100644
--- a/build/android/bytecode/bytecode_rewriter.gni
+++ b/build/android/bytecode/bytecode_rewriter.gni
@@ -15,6 +15,7 @@ brave_bytecode_jars = [
"obj/brave/browser/ui/android/logo/java.javac.jar",
"obj/brave/browser/ui/android/omnibox/java.javac.jar",
"obj/brave/browser/ui/android/theme/java.javac.jar",
+ "obj/brave/components/browser_ui/notifications/android/java.javac.jar",
"obj/brave/components/browser_ui/media/android/java.javac.jar",
"obj/brave/components/browser_ui/site_settings/android/java.javac.jar",
"obj/brave/components/variations/android/java.javac.jar",
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
index cd7820f14133..fcc9f34c5ae8 100644
--- a/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveClassAdapter.java
@@ -49,6 +49,7 @@ public static ClassVisitor createAdapter(ClassVisitor chain) {
chain = new BraveExternalNavigationHandlerClassAdapter(chain);
chain = new BraveFeedSurfaceCoordinatorClassAdapter(chain);
chain = new BraveFeedSurfaceMediatorClassAdapter(chain);
+ chain = new BraveForegroundServiceUtilsClassAdapter(chain);
chain = new BraveFreIntentCreatorClassAdapter(chain);
chain = new BraveHelpAndFeedbackLauncherImplClassAdapter(chain);
chain = new BraveHomepageManagerClassAdapter(chain);
@@ -65,7 +66,9 @@ public static ClassVisitor createAdapter(ClassVisitor chain) {
chain = new BraveMainPreferenceBaseClassAdapter(chain);
chain = new BraveManageAccountDevicesLinkViewClassAdapter(chain);
chain = new BraveManageSyncSettingsClassAdapter(chain);
+ chain = new BraveMediaNotificationControllerDelegateAdapter(chain);
chain = new BraveMediaSessionHelperClassAdapter(chain);
+ chain = new BraveMediaSessionTabHelperClassAdapter(chain);
chain = new BraveMenuButtonCoordinatorClassAdapter(chain);
chain = new BraveMimeUtilsClassAdapter(chain);
chain = new BraveMostVisitedTilesLayoutBaseClassAdapter(chain);
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java
new file mode 100644
index 000000000000..3bedf120d685
--- /dev/null
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java
@@ -0,0 +1,23 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.brave.bytecode;
+
+import org.objectweb.asm.ClassVisitor;
+
+public class BraveForegroundServiceUtilsClassAdapter extends BraveClassVisitor {
+ static String sForegroundServiceUtilsClassName =
+ "org/chromium/components/browser_ui/notifications/ForegroundServiceUtils";
+
+ static String sBraveForegroundServiceUtilsClassName =
+ "org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils";
+
+ public BraveForegroundServiceUtilsClassAdapter(ClassVisitor visitor) {
+ super(visitor);
+
+ redirectConstructor(
+ sForegroundServiceUtilsClassName, sBraveForegroundServiceUtilsClassName);
+ }
+}
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveMediaNotificationControllerDelegateAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveMediaNotificationControllerDelegateAdapter.java
new file mode 100644
index 000000000000..da36b8a64dbf
--- /dev/null
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveMediaNotificationControllerDelegateAdapter.java
@@ -0,0 +1,25 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.brave.bytecode;
+
+import org.objectweb.asm.ClassVisitor;
+
+public class BraveMediaNotificationControllerDelegateAdapter extends BraveClassVisitor {
+ static String sChromeMediaNotificationControllerDelegate =
+ "org/chromium/chrome/browser/media/ui/ChromeMediaNotificationControllerDelegate";
+ static String sBraveMediaNotificationControllerDelegate =
+ "org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate";
+
+ public BraveMediaNotificationControllerDelegateAdapter(ClassVisitor visitor) {
+ super(visitor);
+
+ redirectConstructor(
+ sChromeMediaNotificationControllerDelegate,
+ sBraveMediaNotificationControllerDelegate);
+ deleteMethod(sBraveMediaNotificationControllerDelegate, "getContext");
+ makePublicMethod(sChromeMediaNotificationControllerDelegate, "getContext");
+ }
+}
diff --git a/build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionTabHelperClassAdapter.java b/build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionTabHelperClassAdapter.java
new file mode 100644
index 000000000000..0faa470f5dfc
--- /dev/null
+++ b/build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionTabHelperClassAdapter.java
@@ -0,0 +1,23 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.brave.bytecode;
+
+import org.objectweb.asm.ClassVisitor;
+
+public class BraveMediaSessionTabHelperClassAdapter extends BraveClassVisitor {
+ static String sMediaSessionTabHelper =
+ "org/chromium/chrome/browser/media/ui/MediaSessionTabHelper";
+ static String sBraveMediaSessionTabHelper =
+ "org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper";
+
+ public BraveMediaSessionTabHelperClassAdapter(ClassVisitor visitor) {
+ super(visitor);
+
+ redirectConstructor(sMediaSessionTabHelper, sBraveMediaSessionTabHelper);
+ deleteField(sBraveMediaSessionTabHelper, "mTab");
+ makeProtectedField(sMediaSessionTabHelper, "mTab");
+ }
+}
diff --git a/build/android/config.gni b/build/android/config.gni
index 7ffc2cf3e250..d7dc2351e519 100644
--- a/build/android/config.gni
+++ b/build/android/config.gni
@@ -37,6 +37,7 @@ brave_chrome_java_deps = [
"//brave/components/brave_vpn/common/mojom:mojom_java",
"//brave/components/brave_wallet/common:mojom_java",
"//brave/components/browser_ui/media/android:java",
+ "//brave/components/browser_ui/notifications/android:java",
"//brave/components/browser_ui/site_settings/android:java",
"//brave/components/misc_metrics/common:mojom_java",
"//brave/components/playlist/common/mojom:mojom_java",
diff --git a/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/BraveMediaSessionHelper.java b/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/BraveMediaSessionHelper.java
index d35aad8293ac..703dfb7957e5 100644
--- a/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/BraveMediaSessionHelper.java
+++ b/components/browser_ui/media/android/java/src/org/chromium/components/browser_ui/media/BraveMediaSessionHelper.java
@@ -29,11 +29,7 @@ public class BraveMediaSessionHelper implements MediaImageCallback {
private static final List sBraveTalkHosts =
Arrays.asList("talk.brave.com", "talk.bravesoftware.com", "talk.brave.software");
- private boolean isBraveTalk() {
- WebContents webContents =
- (WebContents)
- BraveReflectionUtil.getField(
- MediaSessionHelper.class, "mWebContents", this);
+ public static boolean isBraveTalk(WebContents webContents) {
if (webContents == null) {
return false;
}
@@ -47,6 +43,15 @@ private boolean isBraveTalk() {
return false;
}
+ private boolean isBraveTalk() {
+ WebContents webContents =
+ (WebContents)
+ BraveReflectionUtil.getField(
+ MediaSessionHelper.class, "mWebContents", this);
+
+ return isBraveTalk(webContents);
+ }
+
@Override
public void onImageDownloaded(Bitmap image) {}
diff --git a/components/browser_ui/notifications/android/BUILD.gn b/components/browser_ui/notifications/android/BUILD.gn
new file mode 100644
index 000000000000..cbd2d5c44198
--- /dev/null
+++ b/components/browser_ui/notifications/android/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright (c) 2024 The Brave Authors. All rights reserved.
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import("//build/config/android/rules.gni")
+
+android_library("java") {
+ sources = [ "java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.java" ]
+
+ deps = [
+ "//base:base_java",
+ "//components/browser_ui/notifications/android:java",
+ ]
+}
diff --git a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.java b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.java
new file mode 100644
index 000000000000..c1cab6c44018
--- /dev/null
+++ b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.java
@@ -0,0 +1,26 @@
+/* Copyright (c) 2024 The Brave Authors. All rights reserved.
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+package org.chromium.components.browser_ui.notifications;
+
+import android.app.Notification;
+import android.app.Service;
+import android.content.pm.ServiceInfo;
+
+public class BraveForegroundServiceUtils extends ForegroundServiceUtils {
+ private static final String sBraveTalkServiceClassName = "PlaybackListenerMicService";
+
+ @Override
+ public void startForeground(
+ Service service, int id, Notification notification, int foregroundServiceType) {
+ // Check for a service that is dedicated to Brave Talk
+ String serviceSimpleName = service.getClass().getSimpleName();
+ if (serviceSimpleName.equals(sBraveTalkServiceClassName)
+ || serviceSimpleName.endsWith("$" + sBraveTalkServiceClassName)) {
+ foregroundServiceType |= ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE;
+ }
+ super.startForeground(service, id, notification, foregroundServiceType);
+ }
+}
diff --git a/patches/components-browser_ui-notifications-android-java-src-org-chromium-components-browser_ui-notifications-ForegroundServiceUtils.java.patch b/patches/components-browser_ui-notifications-android-java-src-org-chromium-components-browser_ui-notifications-ForegroundServiceUtils.java.patch
new file mode 100644
index 000000000000..3e6197621b9c
--- /dev/null
+++ b/patches/components-browser_ui-notifications-android-java-src-org-chromium-components-browser_ui-notifications-ForegroundServiceUtils.java.patch
@@ -0,0 +1,13 @@
+diff --git a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java
+index e85c68a73c8e624c7e7b1fb782ed7d04c6a33222..f933fe554fe82a5495cddd1d60123466d52a6f03 100644
+--- a/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java
++++ b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/ForegroundServiceUtils.java
+@@ -24,7 +24,7 @@ import org.chromium.base.ResettersForTesting;
+ public class ForegroundServiceUtils {
+ private static final String TAG = "ForegroundService";
+
+- private ForegroundServiceUtils() {}
++ public ForegroundServiceUtils() {}
+
+ /** Gets the singleton instance of ForegroundServiceUtils. */
+ public static ForegroundServiceUtils getInstance() {