#ifndef CHROME_APP_SHIM_APP_SHIM_CONTROLLER_H_
#define CHROME_APP_SHIM_APP_SHIM_CONTROLLER_H_
#include <vector>
#import <AppKit/AppKit.h>
#include "base/files/file_path.h"
#include "chrome/common/mac/app_shim.mojom.h"
#include "chrome/services/mac_notifications/public/mojom/mac_notifications.mojom.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/system/isolated_connection.h"
#include "url/gurl.h"
namespace apps {
class MachBootstrapAcceptorTest;
}
namespace display {
class ScopedNativeScreen;
}
namespace mac_notifications {
class MacNotificationServiceUN;
}
@class AppShimDelegate;
@class ProfileMenuTarget;
@class ApplicationDockMenuTarget;
@protocol RenderWidgetHostViewMacDelegate;
class AppShimController
: public chrome::mojom::AppShim,
public mac_notifications::mojom::MacNotificationProvider {
public:
class TestDelegate {
public:
virtual ~TestDelegate() = default;
virtual void PopulateChromeCommandLine(base::CommandLine& command_line) = 0;
};
static void SetDelegateForTesting(TestDelegate* delegate);
struct Params {
Params();
Params(const Params& other);
~Params();
base::FilePath user_data_dir;
base::FilePath profile_dir;
std::string app_id;
std::u16string app_name;
GURL app_url;
scoped_refptr<base::SequencedTaskRunner> io_thread_runner;
};
explicit AppShimController(const Params& params);
AppShimController(const AppShimController&) = delete;
AppShimController& operator=(const AppShimController&) = delete;
~AppShimController() override;
static void PreInitFeatureState(const base::CommandLine& command_line);
static void FinalizeFeatureState(
const variations::VariationsCommandLine& feature_state,
const scoped_refptr<base::SequencedTaskRunner>& io_thread_runner);
chrome::mojom::AppShimHost* host() const { return host_.get(); }
void OnAppFinishedLaunching(bool launched_by_notification_action);
void OpenFiles(const std::vector<base::FilePath>& files);
void ProfileMenuItemSelected(uint32_t index);
void CommandFromDock(uint32_t index);
void CommandDispatch(int command_id);
void OpenUrls(const std::vector<GURL>& urls);
NSMenu* GetApplicationDockMenu();
void ApplicationWillTerminate();
mac_notifications::MacNotificationServiceUN* notification_service_un();
private:
friend class TestShimClient;
friend class apps::MachBootstrapAcceptorTest;
enum class InitState {
kWaitingForAppToFinishLaunch,
kWaitingForChromeReady,
kHasSentOnShimConnected,
kHasReceivedOnShimConnectedResponse,
};
bool FindOrLaunchChrome();
void PollForChromeReady(const base::TimeDelta& time_until_timeout);
void SendBootstrapOnShimConnected(mojo::PlatformChannelEndpoint endpoint);
void OnShimConnectedResponse(
chrome::mojom::AppShimLaunchResult result,
variations::VariationsCommandLine feature_state,
mojo::PendingReceiver<chrome::mojom::AppShim> app_shim_receiver);
void SetUpMenu();
void ChannelError(uint32_t custom_reason, const std::string& description);
void BootstrapChannelError(uint32_t custom_reason,
const std::string& description);
void CreateRemoteCocoaApplication(
mojo::PendingAssociatedReceiver<remote_cocoa::mojom::Application>
receiver) override;
void CreateCommandDispatcherForWidget(uint64_t widget_id) override;
void SetBadgeLabel(const std::string& badge_label) override;
void SetUserAttention(
chrome::mojom::AppShimAttentionType attention_type) override;
void UpdateProfileMenu(std::vector<chrome::mojom::ProfileMenuItemPtr>
profile_menu_items) override;
void UpdateApplicationDockMenu(
std::vector<chrome::mojom::ApplicationDockMenuItemPtr> dock_menu_items)
override;
void BindNotificationProvider(
mojo::PendingReceiver<mac_notifications::mojom::MacNotificationProvider>
provider) override;
void RequestNotificationPermission(
RequestNotificationPermissionCallback callback) override;
void BindChildHistogramFetcherFactory(
mojo::PendingReceiver<metrics::mojom::ChildHistogramFetcherFactory>
receiver) override;
void BindNotificationService(
mojo::PendingReceiver<mac_notifications::mojom::MacNotificationService>
service,
mojo::PendingRemote<
mac_notifications::mojom::MacNotificationActionHandler> handler)
override;
void NotificationPermissionStatusChanged(
mac_notifications::mojom::PermissionStatus status);
bool WebAppIsAdHocSigned() const;
static mojo::PlatformChannelEndpoint ConnectToBrowser(
const mojo::NamedPlatformChannel::ServerName& server_name);
static NSRunningApplication* FindChromeFromSingletonLock(
const base::FilePath& user_data_dir);
static void CreateRenderWidgetHostNSView(
uint64_t view_id,
mojo::ScopedInterfaceEndpointHandle host_handle,
mojo::ScopedInterfaceEndpointHandle view_request_handle);
static NSObject<RenderWidgetHostViewMacDelegate>* GetDelegateForHost(
uint64_t view_id);
const Params params_;
std::vector<base::FilePath> launch_files_;
std::vector<GURL> launch_urls_;
bool launched_by_notification_action_ = false;
NSRunningApplication* __strong chrome_to_connect_to_;
NSRunningApplication* __strong chrome_launched_by_app_;
mojo::IsolatedConnection bootstrap_mojo_connection_;
mojo::Remote<chrome::mojom::AppShimHostBootstrap> host_bootstrap_;
mojo::Receiver<chrome::mojom::AppShim> shim_receiver_{this};
mojo::Remote<chrome::mojom::AppShimHost> host_;
mojo::PendingReceiver<chrome::mojom::AppShimHost> host_receiver_;
mojo::Receiver<mac_notifications::mojom::MacNotificationProvider>
notifications_receiver_{this};
AppShimDelegate* __strong delegate_;
InitState init_state_ = InitState::kWaitingForAppToFinishLaunch;
ProfileMenuTarget* __strong profile_menu_target_;
ApplicationDockMenuTarget* __strong application_dock_menu_target_;
std::unique_ptr<display::ScopedNativeScreen> screen_;
std::vector<chrome::mojom::ProfileMenuItemPtr> profile_menu_items_;
std::vector<chrome::mojom::ApplicationDockMenuItemPtr> dock_menu_items_;
std::unique_ptr<mac_notifications::mojom::MacNotificationService>
notification_service_;
mojo::PendingRemote<mac_notifications::mojom::MacNotificationActionHandler>
notification_action_handler_remote_;
mojo::PendingReceiver<mac_notifications::mojom::MacNotificationActionHandler>
notification_action_handler_receiver_ =
notification_action_handler_remote_.InitWithNewPipeAndPassReceiver();
NSInteger attention_request_id_ = 0;
};
#endif