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
|
// Copyright 2012 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_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
#include "chrome/browser/extensions/api/developer_private/developer_private_event_router.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/pref_types.h"
#include "ui/base/clipboard/file_info.h"
class Profile;
namespace extensions {
// Key that indicates whether the safety check warning for this
// extension has been acknowledged because the user has chosen to keep
// it in a past review.
inline constexpr PrefMap kPrefAcknowledgeSafetyCheckWarningReason = {
"ack_safety_check_warning_reason", PrefType::kInteger,
PrefScope::kExtensionSpecific};
class EventRouter;
// The profile-keyed service that manages the DeveloperPrivate API.
class DeveloperPrivateAPI : public BrowserContextKeyedAPI,
public EventRouter::Observer {
public:
using UnpackedRetryId = std::string;
static BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>*
GetFactoryInstance();
// Convenience method to get the DeveloperPrivateAPI for a profile.
static DeveloperPrivateAPI* Get(content::BrowserContext* context);
explicit DeveloperPrivateAPI(content::BrowserContext* context);
DeveloperPrivateAPI(const DeveloperPrivateAPI&) = delete;
DeveloperPrivateAPI& operator=(const DeveloperPrivateAPI&) = delete;
~DeveloperPrivateAPI() override;
// Adds a path to the list of allowed unpacked paths for the given
// `web_contents`. Returns a unique identifier to retry that path. Safe to
// call multiple times for the same <web_contents, path> pair; each call will
// return the same identifier.
UnpackedRetryId AddUnpackedPath(content::WebContents* web_contents,
const base::FilePath& path);
// Returns the FilePath associated with the given `id` and `web_contents`, if
// one exists.
base::FilePath GetUnpackedPath(content::WebContents* web_contents,
const UnpackedRetryId& id) const;
// Sets the dragged file for the given `web_contents`.
void SetDraggedFile(content::WebContents* web_contents,
const ui::FileInfo& file);
// Returns the dragged file for the given `web_contents`, if one exists.
ui::FileInfo GetDraggedFile(content::WebContents* web_contents) const;
// KeyedService implementation
void Shutdown() override;
// EventRouter::Observer implementation.
void OnListenerAdded(const EventListenerInfo& details) override;
void OnListenerRemoved(const EventListenerInfo& details) override;
DeveloperPrivateEventRouter* developer_private_event_router() {
return developer_private_event_router_.get();
}
const base::FilePath& last_unpacked_directory() const {
return last_unpacked_directory_;
}
private:
class WebContentsTracker;
using IdToPathMap = std::map<UnpackedRetryId, base::FilePath>;
// Data specific to a given WebContents.
struct WebContentsData {
WebContentsData();
WebContentsData(const WebContentsData&) = delete;
WebContentsData& operator=(const WebContentsData&) = delete;
~WebContentsData();
WebContentsData(WebContentsData&& other);
// A set of unpacked paths that we are allowed to load for different
// WebContents. For security reasons, we don't let JavaScript arbitrarily
// pass us a path and load the extension at that location; instead, the user
// has to explicitly select the path through a native dialog first, and then
// we will allow JavaScript to request we reload that same selected path.
// Additionally, these are segmented by WebContents; this is primarily to
// allow collection (removing old paths when the WebContents closes) but has
// the effect that WebContents A cannot retry a path selected in
// WebContents B.
IdToPathMap allowed_unpacked_paths;
// The last dragged file for the WebContents.
ui::FileInfo dragged_file;
};
friend class BrowserContextKeyedAPIFactory<DeveloperPrivateAPI>;
// BrowserContextKeyedAPI implementation.
static const char* service_name() { return "DeveloperPrivateAPI"; }
static const bool kServiceRedirectedInIncognito = true;
static const bool kServiceIsNULLWhileTesting = true;
void RegisterNotifications();
const WebContentsData* GetWebContentsData(
content::WebContents* web_contents) const;
WebContentsData* GetOrCreateWebContentsData(
content::WebContents* web_contents);
raw_ptr<Profile> profile_;
// Used to start the load `load_extension_dialog_` in the last directory that
// was loaded.
base::FilePath last_unpacked_directory_;
std::map<content::WebContents*, WebContentsData> web_contents_data_;
// Created lazily upon OnListenerAdded.
std::unique_ptr<DeveloperPrivateEventRouter> developer_private_event_router_;
base::WeakPtrFactory<DeveloperPrivateAPI> weak_factory_{this};
};
template <>
void BrowserContextKeyedAPIFactory<
DeveloperPrivateAPI>::DeclareFactoryDependencies();
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_DEVELOPER_PRIVATE_DEVELOPER_PRIVATE_API_H_
|