Adds mojo interface to interact with AI credential manager from Java
This commit is contained in:
@@ -77,6 +77,7 @@ brave_java_sources = [
|
||||
"../../brave/android/java/org/chromium/chrome/browser/bookmarks/BraveBookmarkToolbarCoordinator.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/bookmarks/BraveBookmarkUtils.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoActivity.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoCMHelper.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoSettingsLauncherHelper.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/brave_news/BraveNewsAdapterFeedCard.java",
|
||||
"../../brave/android/java/org/chromium/chrome/browser/brave_news/BraveNewsBottomSheetDialogFragment.java",
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* Copyright (c) 2023 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.brave_leo;
|
||||
|
||||
import org.chromium.ai_chat.mojom.CredentialManagerHelper;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.base.annotations.NativeMethods;
|
||||
import org.chromium.content_public.browser.BrowserContextHandle;
|
||||
import org.chromium.mojo.bindings.ConnectionErrorHandler;
|
||||
import org.chromium.mojo.bindings.Interface;
|
||||
import org.chromium.mojo.bindings.Interface.Proxy.Handler;
|
||||
import org.chromium.mojo.system.MessagePipeHandle;
|
||||
import org.chromium.mojo.system.MojoException;
|
||||
import org.chromium.mojo.system.impl.CoreImpl;
|
||||
|
||||
/** Helper to interact with ai_chat_credential_manager. */
|
||||
@JNINamespace("ai_chat")
|
||||
public class BraveLeoCMHelper implements ConnectionErrorHandler {
|
||||
private long mNativeAIChatCMHelperAndroid;
|
||||
CredentialManagerHelper mCredentialManagerHelper;
|
||||
|
||||
private static final Object sLock = new Object();
|
||||
private static BraveLeoCMHelper sInstance;
|
||||
|
||||
public static BraveLeoCMHelper getInstance(BrowserContextHandle browserContextHandle) {
|
||||
synchronized (sLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new BraveLeoCMHelper(browserContextHandle);
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
private BraveLeoCMHelper(BrowserContextHandle browserContextHandle) {
|
||||
mNativeAIChatCMHelperAndroid = BraveLeoCMHelperJni.get().init(browserContextHandle);
|
||||
long nativeHandle =
|
||||
BraveLeoCMHelperJni.get()
|
||||
.getInterfaceToCredentialManagerHelper(mNativeAIChatCMHelperAndroid);
|
||||
MessagePipeHandle handle =
|
||||
CoreImpl.getInstance().acquireNativeHandle(nativeHandle).toMessagePipeHandle();
|
||||
mCredentialManagerHelper = CredentialManagerHelper.MANAGER.attachProxy(handle, 0);
|
||||
Handler handler = ((Interface.Proxy) mCredentialManagerHelper).getProxyHandler();
|
||||
handler.setErrorHandler(this);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
synchronized (sLock) {
|
||||
sInstance = null;
|
||||
if (mNativeAIChatCMHelperAndroid == 0 && mCredentialManagerHelper == null) {
|
||||
return;
|
||||
}
|
||||
mCredentialManagerHelper.close();
|
||||
mCredentialManagerHelper = null;
|
||||
BraveLeoCMHelperJni.get().destroy(mNativeAIChatCMHelperAndroid);
|
||||
mNativeAIChatCMHelperAndroid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void getPremiumStatus(CredentialManagerHelper.GetPremiumStatus_Response callback) {
|
||||
if (mCredentialManagerHelper == null) {
|
||||
return;
|
||||
}
|
||||
mCredentialManagerHelper.getPremiumStatus(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionError(MojoException e) {
|
||||
destroy();
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
public interface Natives {
|
||||
long init(BrowserContextHandle browserContextHandle);
|
||||
|
||||
void destroy(long nativeAIChatCMHelperAndroid);
|
||||
|
||||
long getInterfaceToCredentialManagerHelper(long nativeAIChatCMHelperAndroid);
|
||||
}
|
||||
}
|
||||
@@ -7,14 +7,61 @@ package org.chromium.chrome.browser.settings;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.chromium.ai_chat.mojom.PremiumStatus;
|
||||
import org.chromium.base.Log;
|
||||
import org.chromium.chrome.R;
|
||||
import org.chromium.chrome.browser.app.BraveActivity;
|
||||
import org.chromium.chrome.browser.brave_leo.BraveLeoCMHelper;
|
||||
import org.chromium.chrome.browser.util.TabUtils;
|
||||
import org.chromium.components.browser_ui.settings.ChromeBasePreference;
|
||||
import org.chromium.components.browser_ui.settings.SettingsUtils;
|
||||
|
||||
public class BraveLeoPreferences extends BravePreferenceFragment {
|
||||
private static final String TAG = "BraveLeoPreferences";
|
||||
private static final String PREF_LINK_SUBSCRIPTION = "link_subscription";
|
||||
private static final String LINK_SUBSCRIPTION_URL = "https://account.brave.com";
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
requireActivity().setTitle(R.string.menu_brave_leo);
|
||||
SettingsUtils.addPreferencesFromResource(this, R.xml.brave_leo_preferences);
|
||||
|
||||
BraveLeoCMHelper.getInstance(getProfile())
|
||||
.getPremiumStatus(
|
||||
status -> {
|
||||
if (status != PremiumStatus.ACTIVE) {
|
||||
ChromeBasePreference link_subscription =
|
||||
findPreference(PREF_LINK_SUBSCRIPTION);
|
||||
if (link_subscription == null) {
|
||||
Log.e(TAG, "Subscription pref is null");
|
||||
return;
|
||||
}
|
||||
link_subscription.setVisible(true);
|
||||
link_subscription.setOnPreferenceClickListener(
|
||||
preference -> {
|
||||
try {
|
||||
BraveActivity.getBraveActivity()
|
||||
.openNewOrSelectExistingTab(
|
||||
LINK_SUBSCRIPTION_URL, true);
|
||||
TabUtils.bringChromeTabbedActivityToTheTop(
|
||||
getActivity());
|
||||
} catch (
|
||||
BraveActivity.BraveActivityNotFoundException
|
||||
e) {
|
||||
Log.e(
|
||||
TAG,
|
||||
"Error while opening subscription tab.",
|
||||
e);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
BraveLeoCMHelper.getInstance(getProfile()).destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,21 @@
|
||||
* 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/. -->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<org.chromium.chrome.browser.settings.BraveLeoDescriptionPreference
|
||||
android:key="leo_summary"
|
||||
android:summary="@string/leo_summary" />
|
||||
|
||||
<org.chromium.components.browser_ui.settings.ChromeBasePreference
|
||||
android:key="link_subscription"
|
||||
android:title="@string/link_subscription_title_leo"
|
||||
android:summary="@string/link_subscription_summary_leo"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<org.chromium.components.browser_ui.settings.ChromeBasePreference
|
||||
android:key="subscription_manage"
|
||||
android:title="@string/manage_subscription_leo"
|
||||
app:isPreferenceVisible="false"/>
|
||||
<org.chromium.chrome.browser.settings.BraveLeoResetPreference
|
||||
android:key="reset_data"
|
||||
android:title="@string/leo_reset_data"/>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2023 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/. */
|
||||
|
||||
#include "brave/browser/ai_chat/android/ai_chat_cm_helper_android.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "brave/browser/skus/skus_service_factory.h"
|
||||
#include "brave/build/android/jni_headers/BraveLeoCMHelper_jni.h"
|
||||
#include "chrome/browser/browser_process.h"
|
||||
#include "content/public/browser/android/browser_context_handle.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
|
||||
namespace ai_chat {
|
||||
|
||||
static jlong JNI_BraveLeoCMHelper_Init(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& jbrowser_context_handle) {
|
||||
AIChatCMHelperAndroid* cm_helper =
|
||||
new AIChatCMHelperAndroid(jbrowser_context_handle);
|
||||
return reinterpret_cast<intptr_t>(cm_helper);
|
||||
}
|
||||
|
||||
AIChatCMHelperAndroid::AIChatCMHelperAndroid(
|
||||
const base::android::JavaParamRef<jobject>& jbrowser_context_handle) {
|
||||
content::BrowserContext* context =
|
||||
content::BrowserContextFromJavaHandle(jbrowser_context_handle);
|
||||
auto skus_service_getter = base::BindRepeating(
|
||||
[](content::BrowserContext* context) {
|
||||
return skus::SkusServiceFactory::GetForContext(context);
|
||||
},
|
||||
context);
|
||||
credential_manager_ = std::make_unique<ai_chat::AIChatCredentialManager>(
|
||||
skus_service_getter, g_browser_process->local_state());
|
||||
}
|
||||
|
||||
AIChatCMHelperAndroid::~AIChatCMHelperAndroid() = default;
|
||||
|
||||
void AIChatCMHelperAndroid::Destroy(JNIEnv* env) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
jlong AIChatCMHelperAndroid::GetInterfaceToCredentialManagerHelper(
|
||||
JNIEnv* env) {
|
||||
mojo::PendingRemote<mojom::CredentialManagerHelper> remote;
|
||||
receivers_.Add(this, remote.InitWithNewPipeAndPassReceiver());
|
||||
|
||||
return static_cast<jlong>(remote.PassPipe().release().value());
|
||||
}
|
||||
|
||||
void AIChatCMHelperAndroid::GetPremiumStatus(
|
||||
GetPremiumStatusCallback callback) {
|
||||
credential_manager_->GetPremiumStatus(
|
||||
base::BindOnce(&AIChatCMHelperAndroid::OnPremiumStatusReceived,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
|
||||
}
|
||||
|
||||
void AIChatCMHelperAndroid::OnPremiumStatusReceived(
|
||||
mojom::PageHandler::GetPremiumStatusCallback parent_callback,
|
||||
mojom::PremiumStatus premium_status) {
|
||||
std::move(parent_callback).Run(premium_status);
|
||||
}
|
||||
|
||||
} // namespace ai_chat
|
||||
@@ -0,0 +1,42 @@
|
||||
/* Copyright (c) 2023 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/. */
|
||||
|
||||
#ifndef BRAVE_BROWSER_AI_CHAT_ANDROID_AI_CHAT_CM_HELPER_ANDROID_H_
|
||||
#define BRAVE_BROWSER_AI_CHAT_ANDROID_AI_CHAT_CM_HELPER_ANDROID_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/android/jni_android.h"
|
||||
#include "base/android/scoped_java_ref.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "brave/components/ai_chat/core/browser/ai_chat_credential_manager.h"
|
||||
#include "brave/components/ai_chat/core/common/mojom/ai_chat.mojom.h"
|
||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||
|
||||
namespace ai_chat {
|
||||
|
||||
class AIChatCMHelperAndroid : public mojom::CredentialManagerHelper {
|
||||
public:
|
||||
AIChatCMHelperAndroid(
|
||||
const base::android::JavaParamRef<jobject>& jbrowser_context_handle);
|
||||
~AIChatCMHelperAndroid() override;
|
||||
|
||||
void Destroy(JNIEnv* env);
|
||||
|
||||
void GetPremiumStatus(GetPremiumStatusCallback callback) override;
|
||||
jlong GetInterfaceToCredentialManagerHelper(JNIEnv* env);
|
||||
|
||||
private:
|
||||
void OnPremiumStatusReceived(
|
||||
mojom::PageHandler::GetPremiumStatusCallback parent_callback,
|
||||
mojom::PremiumStatus premium_status);
|
||||
std::unique_ptr<AIChatCredentialManager> credential_manager_;
|
||||
mojo::ReceiverSet<mojom::CredentialManagerHelper> receivers_;
|
||||
base::WeakPtrFactory<AIChatCMHelperAndroid> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace ai_chat
|
||||
|
||||
#endif // BRAVE_BROWSER_AI_CHAT_ANDROID_AI_CHAT_CM_HELPER_ANDROID_H_
|
||||
@@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2023 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/.
|
||||
|
||||
brave_browser_ai_chat_android_sources = [
|
||||
"//brave/browser/ai_chat/android/ai_chat_cm_helper_android.cc",
|
||||
"//brave/browser/ai_chat/android/ai_chat_cm_helper_android.h",
|
||||
]
|
||||
|
||||
brave_browser_ai_chat_android_deps = [
|
||||
"//brave/components/ai_chat/core/browser",
|
||||
"//brave/components/ai_chat/core/common/mojom",
|
||||
]
|
||||
@@ -3,6 +3,7 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import("//brave/browser/ai_chat/android/sources.gni")
|
||||
import("//brave/browser/autocomplete/sources.gni")
|
||||
import("//brave/browser/brave_adaptive_captcha/sources.gni")
|
||||
import("//brave/browser/brave_ads/sources.gni")
|
||||
@@ -292,6 +293,11 @@ if (enable_ai_chat) {
|
||||
"//brave/components/ai_chat/core/common",
|
||||
"//brave/components/ai_chat/core/common/mojom",
|
||||
]
|
||||
|
||||
if (is_android) {
|
||||
brave_chrome_browser_sources += brave_browser_ai_chat_android_sources
|
||||
brave_chrome_browser_deps += brave_browser_ai_chat_android_deps
|
||||
}
|
||||
}
|
||||
|
||||
if (enable_brave_vpn) {
|
||||
|
||||
@@ -4100,6 +4100,15 @@ If you don't accept this request, VPN will not reconnect and your internet conne
|
||||
<message name="IDS_ELLIPSIS_TEXT" desc="Generic ellipsis text" translateable="false">
|
||||
...
|
||||
</message>
|
||||
<message name="IDS_LINK_SUBSCRIPTION_TITLE_LEO" desc="Brave Leo link subscription settings title text">
|
||||
Link purchase to your Brave account
|
||||
</message>
|
||||
<message name="IDS_LINK_SUBSCRIPTION_SUMMARY_LEO" desc="Brave Leo link subscription settings summary">
|
||||
Link your Play Store purchase to your Brave account to use Brave Leo on other devices.
|
||||
</message>
|
||||
<message name="IDS_MANAGE_SUBSCRIPTION_LEO" desc="Brave Leo settings section text">
|
||||
Manage Subscription
|
||||
</message>
|
||||
</messages>
|
||||
</release>
|
||||
</grit>
|
||||
|
||||
@@ -212,6 +212,7 @@ generate_jni("jni_headers") {
|
||||
"//brave/android/java/org/chromium/chrome/browser/BraveSyncWorker.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/app/BraveActivity.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/bookmarks/BraveBookmarkBridge.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoCMHelper.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoSettingsLauncherHelper.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/brave_news/BraveNewsControllerFactory.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/crypto_wallet/AssetRatioServiceFactory.java",
|
||||
|
||||
@@ -30,6 +30,7 @@ brave_chrome_java_deps = [
|
||||
"//brave/browser/ui/android/logo:java",
|
||||
"//brave/browser/ui/android/omnibox:java",
|
||||
"//brave/browser/ui/android/theme:java",
|
||||
"//brave/components/ai_chat/core/common/mojom:mojom_java",
|
||||
"//brave/components/brave_news/common:mojom_java",
|
||||
"//brave/components/brave_rewards/common/mojom:mojom_java",
|
||||
"//brave/components/brave_shields/common:mojom_java",
|
||||
@@ -110,6 +111,7 @@ brave_jni_headers_sources = [
|
||||
"//brave/android/java/org/chromium/chrome/browser/BraveSyncWorker.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/app/BraveActivity.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/bookmarks/BraveBookmarkBridge.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/brave_leo/BraveLeoCMHelper.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/brave_news/BraveNewsControllerFactory.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/crypto_wallet/AssetRatioServiceFactory.java",
|
||||
"//brave/android/java/org/chromium/chrome/browser/crypto_wallet/BlockchainRegistryFactory.java",
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import("//mojo/public/tools/bindings/mojom.gni")
|
||||
|
||||
mojom("mojom") {
|
||||
generate_java = true
|
||||
sources = [
|
||||
"ai_chat.mojom",
|
||||
"page_content_extractor.mojom",
|
||||
|
||||
@@ -159,3 +159,7 @@ interface ChatUIPage {
|
||||
// This reports if there are any pending entries to be sent to the remote LLM.
|
||||
OnConversationEntryPending();
|
||||
};
|
||||
|
||||
interface CredentialManagerHelper {
|
||||
GetPremiumStatus() => (PremiumStatus result);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user