diff --git a/android/brave_java_resources.gni b/android/brave_java_resources.gni index abd381e8bbd..0b80a438d19 100644 --- a/android/brave_java_resources.gni +++ b/android/brave_java_resources.gni @@ -790,6 +790,7 @@ brave_java_resources = [ "java/res/layout/activity_account_detail.xml", "java/res/layout/activity_account_details_with_qr.xml", "java/res/layout/activity_account_private_key.xml", + "java/res/layout/activity_account_selector.xml", "java/res/layout/activity_add_account.xml", "java/res/layout/activity_advance_tx_setting.xml", "java/res/layout/activity_asset_detail.xml", @@ -954,6 +955,7 @@ brave_java_resources = [ "java/res/layout/wallet_coin_list_item.xml", "java/res/layout/web_notification_icon_frame_brave.xml", "java/res/menu/exit_settings_menu.xml", + "java/res/menu/menu_account_selector.xml", "java/res/menu/menu_brave_vpn.xml", "java/res/menu/menu_dapps_panel.xml", "java/res/menu/monthly_contribution_popup_menu.xml", diff --git a/android/brave_java_sources.gni b/android/brave_java_sources.gni index 80667d718d9..cfc03e74107 100644 --- a/android/brave_java_sources.gni +++ b/android/brave_java_sources.gni @@ -44,7 +44,9 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/app/appmenu/AppMenuIconRowFooter.java", "../../brave/android/java/org/chromium/chrome/browser/app/appmenu/BraveAppMenuPropertiesDelegateImpl.java", "../../brave/android/java/org/chromium/chrome/browser/app/domain/CryptoModel.java", + "../../brave/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedData.java", "../../brave/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java", + "../../brave/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java", "../../brave/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java", "../../brave/android/java/org/chromium/chrome/browser/appmenu/BraveTabbedAppMenuPropertiesDelegate.java", "../../brave/android/java/org/chromium/chrome/browser/autofill/BraveAutofillPopupBridge.java", @@ -70,6 +72,7 @@ brave_java_sources = [ "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailActivity.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountDetailsWithQrActivity.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountPrivateKeyActivity.java", + "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountSelectorActivity.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AddAccountActivity.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AdvanceTxSettingActivity.java", "../../brave/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AssetDetailActivity.java", diff --git a/android/java/AndroidManifest.xml b/android/java/AndroidManifest.xml index 1d13a9e45b2..4d871c8021f 100644 --- a/android/java/AndroidManifest.xml +++ b/android/java/AndroidManifest.xml @@ -84,6 +84,11 @@ android:screenOrientation="sensorPortrait" tools:ignore="LockedOrientationActivity"/> + + > mPendingTransactions; - // Todo: create a models for network and portfolio + private BlockchainRegistry mBlockchainRegistry; + private JsonRpcService mJsonRpcService; + private EthTxManagerProxy mEthTxManagerProxy; + private SolanaTxManagerProxy mSolanaTxManagerProxy; + private BraveWalletService mBraveWalletService; + private AssetRatioService mAssetRatioService; + private CryptoSharedData mSharedData; + private final MutableLiveData _mCoinTypeMutableLiveData = + new MutableLiveData<>(CoinType.ETH); + public final LiveData mCoinTypeMutableLiveData = _mCoinTypeMutableLiveData; + + private NetworkModel mNetworkModel; + // Todo: create a models for portfolio // Todo: create method to create and return new models for Asset, Account, // TransactionConfirmation - public CryptoModel(TxService txService, KeyringService keyringService) { - this.mTxService = txService; - this.mKeyringService = keyringService; + public CryptoModel(TxService mTxService, KeyringService mKeyringService, + BlockchainRegistry mBlockchainRegistry, JsonRpcService mJsonRpcService, + EthTxManagerProxy mEthTxManagerProxy, SolanaTxManagerProxy mSolanaTxManagerProxy, + BraveWalletService mBraveWalletService, AssetRatioService mAssetRatioService) { + this.mTxService = mTxService; + this.mKeyringService = mKeyringService; + this.mBlockchainRegistry = mBlockchainRegistry; + this.mJsonRpcService = mJsonRpcService; + this.mEthTxManagerProxy = mEthTxManagerProxy; + this.mSolanaTxManagerProxy = mSolanaTxManagerProxy; + this.mBraveWalletService = mBraveWalletService; + this.mAssetRatioService = mAssetRatioService; + mSharedData = new CryptoSharedDataImpl(); mPendingTxHelper = new PendingTxHelper(mTxService, new AccountInfo[0], true, null, true); + mNetworkModel = new NetworkModel(mJsonRpcService, mSharedData); + } + + public void resetServices(TxService mTxService, KeyringService mKeyringService, + BlockchainRegistry mBlockchainRegistry, JsonRpcService mJsonRpcService, + EthTxManagerProxy mEthTxManagerProxy, SolanaTxManagerProxy mSolanaTxManagerProxy, + BraveWalletService mBraveWalletService, AssetRatioService mAssetRatioService) { + this.mTxService = mTxService; + this.mKeyringService = mKeyringService; + this.mBlockchainRegistry = mBlockchainRegistry; + this.mJsonRpcService = mJsonRpcService; + this.mEthTxManagerProxy = mEthTxManagerProxy; + this.mSolanaTxManagerProxy = mSolanaTxManagerProxy; + this.mBraveWalletService = mBraveWalletService; + this.mAssetRatioService = mAssetRatioService; + mPendingTxHelper.setTxService(mTxService); init(); } - public void resetServices(TxService txService, KeyringService keyringService) { - mTxService = txService; - mKeyringService = keyringService; - mPendingTxHelper.setTxService(txService); - init(); - } - - private void init() { + public void init() { getPendingTxHelper().fetchTransactions(null); mKeyringService.getKeyringInfo(BraveWalletConstants.DEFAULT_KEYRING_ID, keyringInfo -> { mPendingTxHelper.setAccountInfos(keyringInfo.accountInfos); }); + + // filter out a separate list of unapproved transactions mPendingTransactions = Transformations.map(mPendingTxHelper.mTransactionInfoLd, transactionInfos -> { List pendingTransactionInfo = new ArrayList<>(); @@ -56,6 +97,7 @@ public class CryptoModel { } return pendingTransactionInfo; }); + mNetworkModel.init(); } public void refreshTransactions() { @@ -77,4 +119,30 @@ public class CryptoModel { public PendingTxHelper getPendingTxHelper() { return mPendingTxHelper; } + + public CryptoSharedData getSharedData() { + return mSharedData; + } + + /* + * A container class to share the required data throughout the domain model classes. + * Note: It should only be used/accessed within the domain package + */ + class CryptoSharedDataImpl implements CryptoSharedData { + @Override + public int getCoinType() { + if (mCoinTypeMutableLiveData.getValue() == null) { + return CoinType.ETH; + } + return mCoinTypeMutableLiveData.getValue(); + } + + @Override + public String getChainId() { + if (mNetworkModel.mChainId == null) { + return BraveWalletConstants.MAINNET_CHAIN_ID; + } + return mNetworkModel.mChainId.getValue(); + } + } } diff --git a/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedData.java b/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedData.java new file mode 100644 index 00000000000..672fc881c5d --- /dev/null +++ b/android/java/org/chromium/chrome/browser/app/domain/CryptoSharedData.java @@ -0,0 +1,6 @@ +package org.chromium.chrome.browser.app.domain; + +public interface CryptoSharedData { + int getCoinType(); + String getChainId(); +} \ No newline at end of file diff --git a/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java b/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java index 71c8c26c68d..da2807ff8de 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/KeyringModel.java @@ -8,6 +8,7 @@ package org.chromium.chrome.browser.app.domain; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; +import org.chromium.brave_wallet.mojom.AccountInfo; import org.chromium.brave_wallet.mojom.BraveWalletConstants; import org.chromium.brave_wallet.mojom.KeyringInfo; import org.chromium.brave_wallet.mojom.KeyringService; @@ -18,29 +19,55 @@ public class KeyringModel implements KeyringServiceObserver { private KeyringService mKeyringService; private MutableLiveData _mKeyringInfoLiveData; public LiveData mKeyringInfoLiveData; + private final MutableLiveData _mSelectedAccount; + public LiveData mSelectedAccount; + private CryptoSharedData mSharedData; // Todo: create method to interact with keyring - public KeyringModel(KeyringService mKeyringService) { + public KeyringModel(KeyringService mKeyringService, CryptoSharedData sharedData) { this.mKeyringService = mKeyringService; + mSharedData = sharedData; _mKeyringInfoLiveData = new MutableLiveData<>(null); mKeyringInfoLiveData = _mKeyringInfoLiveData; - init(); + _mSelectedAccount = new MutableLiveData<>(); + mSelectedAccount = _mSelectedAccount; } - private void init() { + public void init() { mKeyringService.addObserver(this); } private void update() { - mKeyringService.getKeyringInfo(BraveWalletConstants.DEFAULT_KEYRING_ID, - keyringInfo -> { _mKeyringInfoLiveData.postValue(keyringInfo); }); + mKeyringService.getKeyringInfo(BraveWalletConstants.DEFAULT_KEYRING_ID, keyringInfo -> { + _mKeyringInfoLiveData.postValue(keyringInfo); + Integer coinType = mSharedData.getCoinType(); + mKeyringService.getSelectedAccount(coinType, accountAddress -> { + if (keyringInfo.accountInfos.length > 0) { + AccountInfo selectedAccount = keyringInfo.accountInfos[0]; + for (AccountInfo accountInfo : keyringInfo.accountInfos) { + if (accountInfo.address.equals(accountAddress)) { + selectedAccount = accountInfo; + break; + } + } + _mSelectedAccount.postValue(selectedAccount); + } + }); + }); + } + + public void setSelectedAccount(String accountAddress, int coin) { + mKeyringService.setSelectedAccount(accountAddress, coin, isAccountSelected -> {}); } public KeyringInfo getKeyringInfo() { return _mKeyringInfoLiveData.getValue(); } - public void setKeyringService(KeyringService keyringService) { + public void resetService(KeyringService keyringService) { + if (mKeyringService == keyringService) { + return; + } this.mKeyringService = keyringService; init(); } diff --git a/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java new file mode 100644 index 00000000000..35a72143007 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/app/domain/NetworkModel.java @@ -0,0 +1,53 @@ +package org.chromium.chrome.browser.app.domain; + +import android.text.TextUtils; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.MutableLiveData; + +import org.chromium.brave_wallet.mojom.BraveWalletConstants; +import org.chromium.brave_wallet.mojom.JsonRpcService; +import org.chromium.brave_wallet.mojom.JsonRpcServiceObserver; +import org.chromium.mojo.system.MojoException; + +public class NetworkModel implements JsonRpcServiceObserver { + private final JsonRpcService mJsonRpcService; + private final MutableLiveData _mChainId; + public LiveData mChainId; + private final CryptoSharedData mSharedData; + + public NetworkModel(JsonRpcService jsonRpcService, CryptoSharedData sharedData) { + mJsonRpcService = jsonRpcService; + mSharedData = sharedData; + _mChainId = new MutableLiveData<>(BraveWalletConstants.MAINNET_CHAIN_ID); + mChainId = _mChainId; + jsonRpcService.addObserver(this); + } + + public void init() { + mJsonRpcService.getChainId(mSharedData.getCoinType(), chainId -> { + String id = + TextUtils.isEmpty(chainId) ? BraveWalletConstants.MAINNET_CHAIN_ID : chainId; + _mChainId.postValue(id); + mJsonRpcService.setNetwork(id, mSharedData.getCoinType(), hasSetNetwork -> {}); + }); + } + + @Override + public void chainChangedEvent(String chainId, int coin) { + _mChainId.postValue(chainId); + } + + @Override + public void onAddEthereumChainRequestCompleted(String chainId, String error) {} + + @Override + public void onIsEip1559Changed(String chainId, boolean isEip1559) {} + + @Override + public void onConnectionError(MojoException e) {} + + @Override + public void close() {} +} diff --git a/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java b/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java index f4c6bf52764..d3540b43df1 100644 --- a/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java +++ b/android/java/org/chromium/chrome/browser/app/domain/WalletModel.java @@ -13,7 +13,6 @@ import org.chromium.brave_wallet.mojom.JsonRpcService; import org.chromium.brave_wallet.mojom.KeyringService; import org.chromium.brave_wallet.mojom.SolanaTxManagerProxy; import org.chromium.brave_wallet.mojom.TxService; -import org.chromium.chrome.browser.app.domain.CryptoModel; // Under development, some parts not tested so use with caution // A container for all the native services and APIs @@ -41,8 +40,11 @@ public class WalletModel { mSolanaTxManagerProxy = solanaTxManagerProxy; mAssetRatioService = assetRatioService; mBraveWalletService = braveWalletService; - mCryptoModel = new CryptoModel(mTxService, mKeyringService); - mKeyringModel = new KeyringModel(keyringService); + mCryptoModel = new CryptoModel(mTxService, mKeyringService, mBlockchainRegistry, + mJsonRpcService, mEthTxManagerProxy, mSolanaTxManagerProxy, mBraveWalletService, + mAssetRatioService); + mKeyringModel = new KeyringModel(keyringService, mCryptoModel.getSharedData()); + init(); } public void resetServices(KeyringService keyringService, BlockchainRegistry blockchainRegistry, @@ -57,8 +59,19 @@ public class WalletModel { setSolanaTxManagerProxy(solanaTxManagerProxy); setAssetRatioService(assetRatioService); setBraveWalletService(braveWalletService); - mCryptoModel.resetServices(mTxService, mKeyringService); - mKeyringModel.setKeyringService(mKeyringService); + mCryptoModel.resetServices(mTxService, mKeyringService, mBlockchainRegistry, + mJsonRpcService, mEthTxManagerProxy, mSolanaTxManagerProxy, mBraveWalletService, + mAssetRatioService); + mKeyringModel.resetService(mKeyringService); + init(); + } + + /* + * Explicit method to ensure the sage initialisation to start the required data process + */ + private void init() { + mCryptoModel.init(); + mKeyringModel.init(); } public KeyringModel getKeyringModel() { diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountSelectorActivity.java b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountSelectorActivity.java new file mode 100644 index 00000000000..312e18cc3b0 --- /dev/null +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/activities/AccountSelectorActivity.java @@ -0,0 +1,100 @@ +/* Copyright (c) 2021 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 http://mozilla.org/MPL/2.0/. */ + +package org.chromium.chrome.browser.crypto_wallet.activities; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.view.MenuItem; + +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.MaterialToolbar; + +import org.chromium.brave_wallet.mojom.AccountInfo; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.app.BraveActivity; +import org.chromium.chrome.browser.app.domain.KeyringModel; +import org.chromium.chrome.browser.crypto_wallet.adapters.WalletCoinAdapter; +import org.chromium.chrome.browser.crypto_wallet.fragments.AccountsFragment; +import org.chromium.chrome.browser.crypto_wallet.listeners.OnWalletListItemClick; +import org.chromium.chrome.browser.crypto_wallet.model.WalletListItemModel; +import org.chromium.chrome.browser.crypto_wallet.util.Utils; + +import java.util.ArrayList; +import java.util.List; + +public class AccountSelectorActivity + extends BraveWalletBaseActivity implements OnWalletListItemClick { + private KeyringModel mKeyringModel; + private RecyclerView mRVNetworkSelector; + private WalletCoinAdapter mWalletCoinAdapter; + private AccountInfo[] mAccountInfos; + + @Override + protected void triggerLayoutInflation() { + setContentView(R.layout.activity_account_selector); + BraveActivity activity = BraveActivity.getBraveActivity(); + if (activity != null) { + mKeyringModel = activity.getWalletModel().getKeyringModel(); + } + assert mKeyringModel != null; + init(); + onInitialLayoutInflationComplete(); + } + + @SuppressLint("NotifyDataSetChanged") + private void init() { + mRVNetworkSelector = findViewById(R.id.rv_account_selector_activity); + mWalletCoinAdapter = + new WalletCoinAdapter(WalletCoinAdapter.AdapterType.SELECT_ACCOUNTS_LIST); + mRVNetworkSelector.setAdapter(mWalletCoinAdapter); + mWalletCoinAdapter.setOnWalletListItemClick(this); + mWalletCoinAdapter.setOnWalletListItemClick(this); + mKeyringModel.mKeyringInfoLiveData.observe(this, keyringInfo -> { + if (keyringInfo != null) { + mAccountInfos = keyringInfo.accountInfos; + List walletListItemModelList = new ArrayList<>(); + for (AccountInfo accountInfo : mAccountInfos) { + if (!accountInfo.isImported) { + walletListItemModelList.add( + new WalletListItemModel(R.drawable.ic_eth, accountInfo.name, + accountInfo.address, null, null, accountInfo.isImported)); + } + } + + mWalletCoinAdapter.setWalletListItemModelList(walletListItemModelList); + mWalletCoinAdapter.notifyDataSetChanged(); + } + }); + + mKeyringModel.mSelectedAccount.observe(this, selectedAccountInfo -> { + if (selectedAccountInfo != null) { + mWalletCoinAdapter.updateSelectedNetwork( + selectedAccountInfo.name, selectedAccountInfo.address); + } + }); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + toolbar.setOnMenuItemClickListener(item -> { + Intent intent = new Intent(this, AddAccountActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); + startActivity(intent); + return true; + }); + } + + @Override + public void onAccountClick(WalletListItemModel walletListItemModel) { + for (AccountInfo accountInfo : mAccountInfos) { + if (walletListItemModel.getTitle().equals(accountInfo.name) + && walletListItemModel.getSubTitle().equals(accountInfo.address)) { + mKeyringModel.setSelectedAccount(accountInfo.address, accountInfo.coin); + finish(); + } + } + } +} diff --git a/android/java/org/chromium/chrome/browser/crypto_wallet/adapters/WalletCoinAdapter.java b/android/java/org/chromium/chrome/browser/crypto_wallet/adapters/WalletCoinAdapter.java index bcfa4991454..291d3a8c820 100644 --- a/android/java/org/chromium/chrome/browser/crypto_wallet/adapters/WalletCoinAdapter.java +++ b/android/java/org/chromium/chrome/browser/crypto_wallet/adapters/WalletCoinAdapter.java @@ -40,6 +40,7 @@ public class WalletCoinAdapter extends RecyclerView.Adapter { onWalletListItemClick.onTrashIconClick(walletListItemModel); }); } } - } else if (mType == AdapterType.ACCOUNTS_LIST) { + } else if (mType == AdapterType.ACCOUNTS_LIST + || mType == AdapterType.SELECT_ACCOUNTS_LIST) { Utils.setBlockiesBitmapResource( mExecutor, mHandler, holder.iconImg, walletListItemModel.getSubTitle(), true); holder.itemView.setOnLongClickListener(v -> { @@ -196,6 +202,10 @@ public class WalletCoinAdapter extends RecyclerView.Adapter { + PopupMenu menu = new PopupMenu(mOptionsImage.getContext(), (View) mOptionsImage); + menu.getMenuInflater().inflate(R.menu.menu_dapps_panel, menu.getMenu()); + menu.setOnMenuItemClickListener(item -> { if (item.getItemId() == R.id.action_lock_wallet) { mBraveWalletPanelServices.getKeyringService().lock(); dismiss(); @@ -335,8 +331,8 @@ public class BraveWalletPanel implements DialogInterface { activity.openBraveWallet(false); } }); - mOptionsImage = mPopupView.findViewById(R.id.iv_dapp_panel_menu); - mOptionsImage.setOnClickListener(v -> { showPopupMenu(); }); + mOptionsImage = mPopupView.findViewById(R.id.iv_dapp_panel_menu); + mOptionsImage.setOnClickListener(v -> { showPopupMenu(); }); mBtnSelectedNetwork = mPopupView.findViewById(R.id.btn_dapps_panel_networks); mBtnSelectedNetwork.setOnClickListener(v -> { @@ -357,6 +353,13 @@ public class BraveWalletPanel implements DialogInterface { mAccountAddress = mPopupView.findViewById(R.id.tv_dapps_panel_account_address); mAmountAsset = mPopupView.findViewById(R.id.tv_dapps_panel_amount_asset); mAmountFiat = mPopupView.findViewById(R.id.tv_dapps_panel_amount_fiat); + mAccountChangeAnchor = mPopupView.findViewById(R.id.iv_dapps_panel_down_arrow_anchor); + mAccountChangeAnchor.setOnClickListener(v -> { + BraveActivity activity = BraveActivity.getBraveActivity(); + if (activity != null) { + activity.startActivity(new Intent(activity, AccountSelectorActivity.class)); + } + }); updateState(); updateStatus(); } diff --git a/android/java/res/drawable/ic_menu.xml b/android/java/res/drawable/ic_menu.xml index 55daf83cda3..2dd03095528 100644 --- a/android/java/res/drawable/ic_menu.xml +++ b/android/java/res/drawable/ic_menu.xml @@ -8,4 +8,3 @@ android:fillColor="#ffffff" android:fillType="evenOdd"/> - diff --git a/android/java/res/layout/activity_account_selector.xml b/android/java/res/layout/activity_account_selector.xml new file mode 100644 index 00000000000..deac73259fb --- /dev/null +++ b/android/java/res/layout/activity_account_selector.xml @@ -0,0 +1,35 @@ + + + + + + + + + diff --git a/android/java/res/layout/brave_wallet_panel_layout.xml b/android/java/res/layout/brave_wallet_panel_layout.xml index f945253c844..e932896ee5d 100644 --- a/android/java/res/layout/brave_wallet_panel_layout.xml +++ b/android/java/res/layout/brave_wallet_panel_layout.xml @@ -29,7 +29,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" android:orientation="vertical"> - + + + diff --git a/android/java/res/menu/menu_account_selector.xml b/android/java/res/menu/menu_account_selector.xml new file mode 100644 index 00000000000..4be5c6501d9 --- /dev/null +++ b/android/java/res/menu/menu_account_selector.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/android/java/res/values-night/brave_colors.xml b/android/java/res/values-night/brave_colors.xml index 55aca6a80af..6b68a6c15c3 100644 --- a/android/java/res/values-night/brave_colors.xml +++ b/android/java/res/values-night/brave_colors.xml @@ -30,7 +30,7 @@ @android:color/white - @android:color/white + #C2C4CF #84889C diff --git a/browser/ui/android/strings/android_brave_strings.grd b/browser/ui/android/strings/android_brave_strings.grd index 8a8fa19c4eb..798ab538a06 100644 --- a/browser/ui/android/strings/android_brave_strings.grd +++ b/browser/ui/android/strings/android_brave_strings.grd @@ -3037,6 +3037,9 @@ If you don't accept this request, VPN will not reconnect and your internet conne Notification channel for Brave Browser + + Select Account +