1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_SHARESHEET_SHARESHEET_SERVICE_H_
#define CHROME_BROWSER_SHARESHEET_SHARESHEET_SERVICE_H_
#include <memory>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "chrome/browser/sharesheet/sharesheet_metrics.h"
#include "chrome/browser/sharesheet/sharesheet_types.h"
#include "chromeos/components/sharesheet/constants.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/services/app_service/public/cpp/icon_types.h"
#include "components/services/app_service/public/cpp/intent.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/gfx/native_widget_types.h"
class Profile;
namespace apps {
class AppServiceProxyAsh;
struct IntentLaunchInfo;
} // namespace apps
namespace views {
class View;
}
namespace content {
class WebContents;
}
namespace gfx {
struct VectorIcon;
}
namespace sharesheet {
class ShareActionCache;
class SharesheetController;
class SharesheetServiceDelegator;
class SharesheetUiDelegate;
// The SharesheetService is the root service that provides a sharesheet for
// Chrome desktop.
class SharesheetService : public KeyedService {
public:
using GetNativeWindowCallback = base::OnceCallback<gfx::NativeWindow()>;
explicit SharesheetService(Profile* profile);
~SharesheetService() override;
SharesheetService(const SharesheetService&) = delete;
SharesheetService& operator=(const SharesheetService&) = delete;
// Displays the dialog (aka bubble) for sharing content (or files) with
// other applications and targets. `intent` contains the list of the
// files/content to be shared. If the files to share contains Google
// Drive hosted document, only drive share action will be shown.
//
// `delivered_callback` is run to signify that the intent has been
// delivered to the target selected by the user (which may then show its own
// separate UI, e.g. for Nearby Sharing). `delivered_callback` must be
// non-null.
// `close_callback` is run to signify that the share flow has finished and the
// dialog has closed (this includes separate UI, e.g. Nearby Sharing).
void ShowBubble(content::WebContents* web_contents,
apps::IntentPtr intent,
LaunchSource source,
DeliveredCallback delivered_callback,
CloseCallback close_callback = base::NullCallback());
void ShowBubble(apps::IntentPtr intent,
LaunchSource source,
GetNativeWindowCallback get_native_window_callback,
DeliveredCallback delivered_callback,
CloseCallback close_callback = base::NullCallback());
// Gets the sharesheet controller for the given |native_window|.
SharesheetController* GetSharesheetController(
gfx::NativeWindow native_window);
#if BUILDFLAG(IS_CHROMEOS)
// Skips the generic Sharesheet bubble and directly displays the
// NearbyShare bubble dialog for ARC.
void ShowNearbyShareBubbleForArc(gfx::NativeWindow native_window,
apps::IntentPtr intent,
LaunchSource source,
DeliveredCallback delivered_callback,
CloseCallback close_callback,
ActionCleanupCallback cleanup_callback);
#endif // BUILDFLAG(IS_CHROMEOS)
// |share_action_type| is set to null when testing, but should otherwise have
// a valid value.
void OnBubbleClosed(gfx::NativeWindow native_window,
const std::optional<ShareActionType>& share_action_type);
// OnTargetSelected is called by both apps and share actions.
// If |type| is kAction, expect |share_action_type| to have a valid
// ShareActionType. If |type| is kArcApp or kWebApp, expect |app_name|
// to contain a valid app name.
void OnTargetSelected(gfx::NativeWindow native_window,
const TargetType type,
const std::optional<ShareActionType>& share_action_type,
const std::optional<std::u16string>& app_name,
apps::IntentPtr intent,
views::View* share_action_view);
// Only share actions, which have a |share_action_type|, call this function.
bool OnAcceleratorPressed(const ui::Accelerator& accelerator,
const ShareActionType share_action_type);
// If the files to share contains a Google Drive hosted document, only the
// drive share action will be shown.
bool HasShareTargets(const apps::IntentPtr& intent);
Profile* GetProfile();
// Only share actions, which have a |share_action_type|, are expected to have
// a vector icon. Return nullptr if |share_action_type| is null.
const gfx::VectorIcon* GetVectorIcon(
const std::optional<ShareActionType>& share_action_type);
// ==========================================================================
// ========================== Testing APIs ==================================
// ==========================================================================
void ShowBubbleForTesting(gfx::NativeWindow native_window,
apps::IntentPtr intent,
LaunchSource source,
DeliveredCallback delivered_callback,
CloseCallback close_callback,
int num_actions_to_add);
SharesheetUiDelegate* GetUiDelegateForTesting(
gfx::NativeWindow native_window);
static void SetSelectedAppForTesting(const std::u16string& target_name);
private:
using SharesheetServiceIconLoaderCallback =
base::OnceCallback<void(std::vector<TargetInfo> targets)>;
void PrepareToShowBubble(apps::IntentPtr intent,
GetNativeWindowCallback get_native_window_callback,
DeliveredCallback delivered_callback,
CloseCallback close_callback);
std::vector<TargetInfo> GetActionsForIntent(const apps::IntentPtr& intent);
void LoadAppIcons(std::vector<apps::IntentLaunchInfo> intent_launch_info,
std::vector<TargetInfo> targets,
size_t index,
SharesheetServiceIconLoaderCallback callback);
void OnIconLoaded(std::vector<apps::IntentLaunchInfo> intent_launch_info,
std::vector<TargetInfo> targets,
size_t index,
SharesheetServiceIconLoaderCallback callback,
apps::IconValuePtr icon_value);
void OnAppIconsLoaded(apps::IntentPtr intent,
GetNativeWindowCallback get_native_window_callback,
DeliveredCallback delivered_callback,
CloseCallback close_callback,
std::vector<TargetInfo> targets);
void OnReadyToShowBubble(gfx::NativeWindow native_window,
apps::IntentPtr intent,
DeliveredCallback delivered_callback,
CloseCallback close_callback,
std::vector<TargetInfo> targets);
void LaunchApp(const std::u16string& target_name, apps::IntentPtr intent);
SharesheetServiceDelegator* GetOrCreateDelegator(
gfx::NativeWindow native_window);
SharesheetServiceDelegator* GetDelegator(gfx::NativeWindow native_window);
void RecordUserActionMetrics(
const std::optional<ShareActionType>& share_action_type,
const std::optional<std::u16string>& app_name);
void RecordTargetCountMetrics(const std::vector<TargetInfo>& targets);
// Makes |intent| related UMA recordings.
void RecordShareDataMetrics(const apps::IntentPtr& intent);
raw_ptr<Profile> profile_;
std::unique_ptr<ShareActionCache> share_action_cache_;
raw_ptr<apps::AppServiceProxyAsh> app_service_proxy_;
// Record of all active SharesheetServiceDelegators. These can be retrieved
// by ShareActions and used as SharesheetControllers to make bubble changes.
std::vector<std::unique_ptr<SharesheetServiceDelegator>> active_delegators_;
base::WeakPtrFactory<SharesheetService> weak_factory_{this};
};
} // namespace sharesheet
#endif // CHROME_BROWSER_SHARESHEET_SHARESHEET_SERVICE_H_
|