From 42c5569d1eecf6f5af57d5867806730384500d91 Mon Sep 17 00:00:00 2001 From: Serg Date: Fri, 13 Dec 2024 11:51:47 -0500 Subject: [PATCH] Allows to use a microphone for Brave Talk in the background on Android --- android/brave_java_sources.gni | 3 + android/java/AndroidManifest.xml | 7 ++ .../java/AndroidManifest_user_permissions.xml | 1 + android/java/apk_for_test.flags | 15 ++++ ...veMediaNotificationControllerDelegate.java | 77 +++++++++++++++++++ ...veMediaNotificationControllerServices.java | 21 +++++ .../media/ui/BraveMediaSessionTabHelper.java | 51 ++++++++++++ android/java/res/values/brave_ids.xml | 3 + .../chromium/chrome/browser/BytecodeTest.java | 36 +++++++++ build/android/bytecode/BUILD.gn | 3 + build/android/bytecode/bytecode_rewriter.gni | 1 + .../org/brave/bytecode/BraveClassAdapter.java | 3 + ...aveForegroundServiceUtilsClassAdapter.java | 23 ++++++ ...NotificationControllerDelegateAdapter.java | 25 ++++++ ...raveMediaSessionTabHelperClassAdapter.java | 23 ++++++ build/android/config.gni | 1 + .../media/BraveMediaSessionHelper.java | 15 ++-- .../browser_ui/notifications/android/BUILD.gn | 15 ++++ .../BraveForegroundServiceUtils.java | 25 ++++++ ...ications-ForegroundServiceUtils.java.patch | 13 ++++ 20 files changed, 356 insertions(+), 5 deletions(-) create mode 100644 android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java create mode 100644 android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerServices.java create mode 100644 android/java/org/chromium/chrome/browser/media/ui/BraveMediaSessionTabHelper.java create mode 100644 build/android/bytecode/java/org/brave/bytecode/BraveForegroundServiceUtilsClassAdapter.java create mode 100644 build/android/bytecode/java/org/brave/bytecode/BraveMediaNotificationControllerDelegateAdapter.java create mode 100644 build/android/bytecode/java/org/brave/bytecode/BraveMediaSessionTabHelperClassAdapter.java create mode 100644 components/browser_ui/notifications/android/BUILD.gn create mode 100644 components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.java create mode 100644 patches/components-browser_ui-notifications-android-java-src-org-chromium-components-browser_ui-notifications-ForegroundServiceUtils.java.patch 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..06e1b0ae2c24 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/media/ui/BraveMediaNotificationControllerDelegate.java @@ -0,0 +1,77 @@ +/* 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.chrome.R; +import org.chromium.chrome.browser.notifications.NotificationConstants; + +public class BraveMediaNotificationControllerDelegate + extends ChromeMediaNotificationControllerDelegate { + 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) { + } + } + }; + } +} 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..7f69c0cdb394 --- /dev/null +++ b/components/browser_ui/notifications/android/java/src/org/chromium/components/browser_ui/notifications/BraveForegroundServiceUtils.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.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 + if (service.getClass().getSimpleName().equals(sBraveTalkServiceClassName) + || service.getClass().getSimpleName().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() {