diff options
author | wjywbs@gmail.com <wjywbs@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 08:57:41 +0000 |
---|---|---|
committer | wjywbs@gmail.com <wjywbs@gmail.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-04 08:57:41 +0000 |
commit | 7584de288d217916961f4109b1a10f922754ae70 (patch) | |
tree | 34b70ff0344998ad6a3f7f9302bac43b090316e7 | |
parent | ca11059ee2dd9abe0c64b47cda1f58d6c662e855 (diff) | |
download | chromium_src-7584de288d217916961f4109b1a10f922754ae70.zip chromium_src-7584de288d217916961f4109b1a10f922754ae70.tar.gz chromium_src-7584de288d217916961f4109b1a10f922754ae70.tar.bz2 |
Reland: Add generateAppForLink function in chrome.management
This function takes a url and a title as input, generates and
returns a bookmark app.
R=benwells@chromium.org,kalman@chromium.org,calamity@chromium.org
BUG=370350
Review URL: https://codereview.chromium.org/266353006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274732 0039d316-1c4b-4281-b951-d872f2087c98
16 files changed, 363 insertions, 3 deletions
diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc index 189692a..3160c87 100644 --- a/chrome/browser/extensions/api/management/management_api.cc +++ b/chrome/browser/extensions/api/management/management_api.cc @@ -25,6 +25,7 @@ #include "chrome/browser/extensions/extension_ui_util.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/extensions/launch_util.h" +#include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/browser_finder.h" @@ -56,6 +57,7 @@ #include "extensions/common/permissions/permission_set.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/url_pattern.h" +#include "ui/gfx/favicon_size.h" #if !defined(OS_ANDROID) #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h" @@ -852,6 +854,91 @@ bool ManagementSetLaunchTypeFunction::RunSync() { return true; } +ManagementGenerateAppForLinkFunction::ManagementGenerateAppForLinkFunction() { +} + +ManagementGenerateAppForLinkFunction::~ManagementGenerateAppForLinkFunction() { +} + +void ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp( + const extensions::Extension* extension, + const WebApplicationInfo& web_app_info) { + if (extension) { + scoped_ptr<management::ExtensionInfo> info = + CreateExtensionInfo(*extension, ExtensionSystem::Get(GetProfile())); + results_ = management::GenerateAppForLink::Results::Create(*info); + + SendResponse(true); + Release(); + } else { + error_ = keys::kGenerateAppForLinkInstallError; + SendResponse(false); + Release(); + } +} + +void ManagementGenerateAppForLinkFunction::OnFaviconForApp( + const favicon_base::FaviconImageResult& image_result) { + WebApplicationInfo web_app; + web_app.title = base::UTF8ToUTF16(title_); + web_app.app_url = launch_url_; + + if (!image_result.image.IsEmpty()) { + WebApplicationInfo::IconInfo icon; + icon.data = image_result.image.AsBitmap(); + icon.width = icon.data.width(); + icon.height = icon.data.height(); + web_app.icons.push_back(icon); + } + + bookmark_app_helper_.reset(new BookmarkAppHelper(service(), web_app, NULL)); + bookmark_app_helper_->Create(base::Bind( + &ManagementGenerateAppForLinkFunction::FinishCreateBookmarkApp, this)); +} + +bool ManagementGenerateAppForLinkFunction::RunAsync() { + if (!user_gesture()) { + error_ = keys::kGestureNeededForGenerateAppForLinkError; + return false; + } + + scoped_ptr<management::GenerateAppForLink::Params> params( + management::GenerateAppForLink::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + GURL launch_url(params->url); + if (!launch_url.is_valid() || !launch_url.SchemeIsHTTPOrHTTPS()) { + error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidURLError, + params->url); + return false; + } + + if (params->title.empty()) { + error_ = keys::kEmptyTitleError; + return false; + } + + FaviconService* favicon_service = + FaviconServiceFactory::GetForProfile(GetProfile(), + Profile::EXPLICIT_ACCESS); + DCHECK(favicon_service); + + title_ = params->title; + launch_url_ = launch_url; + + favicon_service->GetFaviconImageForURL( + FaviconService::FaviconForURLParams( + launch_url, favicon_base::FAVICON, gfx::kFaviconSize), + base::Bind(&ManagementGenerateAppForLinkFunction::OnFaviconForApp, this), + &cancelable_task_tracker_); + + // Matched with a Release() in OnExtensionLoaded(). + AddRef(); + + // Response is sent async in OnExtensionLoaded(). + return true; +} + ManagementEventRouter::ManagementEventRouter(Profile* profile) : profile_(profile) { int types[] = {chrome::NOTIFICATION_EXTENSION_INSTALLED_DEPRECATED, diff --git a/chrome/browser/extensions/api/management/management_api.h b/chrome/browser/extensions/api/management/management_api.h index 6c98306..264a08f 100644 --- a/chrome/browser/extensions/api/management/management_api.h +++ b/chrome/browser/extensions/api/management/management_api.h @@ -6,9 +6,13 @@ #define CHROME_BROWSER_EXTENSIONS_API_MANAGEMENT_MANAGEMENT_API_H_ #include "base/compiler_specific.h" +#include "base/task/cancelable_task_tracker.h" +#include "chrome/browser/extensions/bookmark_app_helper.h" #include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" +#include "chrome/common/web_application_info.h" +#include "components/favicon_base/favicon_types.h" #include "components/keyed_service/core/keyed_service.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" @@ -200,6 +204,32 @@ class ManagementSetLaunchTypeFunction : public ManagementFunction { virtual bool RunSync() OVERRIDE; }; +class ManagementGenerateAppForLinkFunction : public AsyncManagementFunction { + public: + DECLARE_EXTENSION_FUNCTION("management.generateAppForLink", + MANAGEMENT_GENERATEAPPFORLINK); + + ManagementGenerateAppForLinkFunction(); + + protected: + virtual ~ManagementGenerateAppForLinkFunction(); + + virtual bool RunAsync() OVERRIDE; + + private: + void OnFaviconForApp(const favicon_base::FaviconImageResult& image_result); + void FinishCreateBookmarkApp(const extensions::Extension* extension, + const WebApplicationInfo& web_app_info); + + std::string title_; + GURL launch_url_; + + scoped_ptr<BookmarkAppHelper> bookmark_app_helper_; + + // Used for favicon loading tasks. + base::CancelableTaskTracker cancelable_task_tracker_; +}; + class ManagementEventRouter : public content::NotificationObserver { public: explicit ManagementEventRouter(Profile* profile); diff --git a/chrome/browser/extensions/api/management/management_api_constants.cc b/chrome/browser/extensions/api/management/management_api_constants.cc index 3251084..bb2e0cb 100644 --- a/chrome/browser/extensions/api/management/management_api_constants.cc +++ b/chrome/browser/extensions/api/management/management_api_constants.cc @@ -37,5 +37,11 @@ const char kGestureNeededForSetLaunchTypeError[] = "chrome.management.setLaunchType requires a user gesture."; const char kLaunchTypeNotAvailableError[] = "The launch type is not available for this app."; +const char kGestureNeededForGenerateAppForLinkError[] = + "chrome.management.generateAppForLink requires a user gesture."; +const char kInvalidURLError[] = "The URL \"*\" is invalid."; +const char kEmptyTitleError[] = "The title can not be empty."; +const char kGenerateAppForLinkInstallError[] = + "Failed to install the generated app."; } // namespace extension_management_api_constants diff --git a/chrome/browser/extensions/api/management/management_api_constants.h b/chrome/browser/extensions/api/management/management_api_constants.h index 2c96554..4592231 100644 --- a/chrome/browser/extensions/api/management/management_api_constants.h +++ b/chrome/browser/extensions/api/management/management_api_constants.h @@ -29,6 +29,10 @@ extern const char kCreateOnlyPackagedAppShortcutMac[]; extern const char kCreateShortcutCanceledError[]; extern const char kGestureNeededForSetLaunchTypeError[]; extern const char kLaunchTypeNotAvailableError[]; +extern const char kGestureNeededForGenerateAppForLinkError[]; +extern const char kInvalidURLError[]; +extern const char kEmptyTitleError[]; +extern const char kGenerateAppForLinkInstallError[]; } // namespace extension_management_api_constants diff --git a/chrome/browser/extensions/api/management/management_apitest.cc b/chrome/browser/extensions/api/management/management_apitest.cc index a275eaf0..ee0b508 100644 --- a/chrome/browser/extensions/api/management/management_apitest.cc +++ b/chrome/browser/extensions/api/management/management_apitest.cc @@ -149,6 +149,20 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, "createAppShortcutNotInStable.html")); } +IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, GenerateAppForLink) { + LoadExtensions(); + ASSERT_TRUE(RunExtensionSubtest("management/test", + "generateAppForLink.html")); +} + +IN_PROC_BROWSER_TEST_F(ExtensionManagementApiTest, + GenerateAppForLinkNotInStable) { + extensions::ScopedCurrentChannel channel( + chrome::VersionInfo::CHANNEL_STABLE); + ASSERT_TRUE(RunExtensionSubtest("management/test", + "generateAppForLinkNotInStable.html")); +} + // Fails often on Windows dbg bots. http://crbug.com/177163 #if defined(OS_WIN) #define MAYBE_ManagementPolicyAllowed DISABLED_ManagementPolicyAllowed diff --git a/chrome/browser/extensions/bookmark_app_helper.cc b/chrome/browser/extensions/bookmark_app_helper.cc index 4ef223f..bd5e2df 100644 --- a/chrome/browser/extensions/bookmark_app_helper.cc +++ b/chrome/browser/extensions/bookmark_app_helper.cc @@ -183,6 +183,9 @@ BookmarkAppHelper::BookmarkAppHelper(ExtensionService* service, crx_installer_->set_error_on_unsupported_requirements(true); + if (!contents) + return; + // Add urls from the WebApplicationInfo. std::vector<GURL> web_app_info_icon_urls; for (std::vector<WebApplicationInfo::IconInfo>::const_iterator it = @@ -204,7 +207,11 @@ BookmarkAppHelper::~BookmarkAppHelper() {} void BookmarkAppHelper::Create(const CreateBookmarkAppCallback& callback) { callback_ = callback; - favicon_downloader_->Start(); + + if (favicon_downloader_.get()) + favicon_downloader_->Start(); + else + OnIconsDownloaded(true, std::map<GURL, std::vector<SkBitmap> >()); } void BookmarkAppHelper::OnIconsDownloaded( @@ -239,6 +246,18 @@ void BookmarkAppHelper::OnIconsDownloaded( } } + // Add all existing icons from WebApplicationInfo. + for (std::vector<WebApplicationInfo::IconInfo>::const_iterator it = + web_app_info_.icons.begin(); + it != web_app_info_.icons.end(); + ++it) { + const SkBitmap& icon = it->data; + if (!icon.drawsNothing() && icon.width() == icon.height()) + downloaded_icons.push_back(icon); + } + + web_app_info_.icons.clear(); + // If there are icons that don't match the accepted icon sizes, find the // closest bigger icon to the accepted sizes and resize the icon to it. An // icon will be resized and used for at most one size. diff --git a/chrome/browser/extensions/bookmark_app_helper.h b/chrome/browser/extensions/bookmark_app_helper.h index b0cb661..c9bd9e9 100644 --- a/chrome/browser/extensions/bookmark_app_helper.h +++ b/chrome/browser/extensions/bookmark_app_helper.h @@ -37,7 +37,8 @@ class BookmarkAppHelper : public content::NotificationObserver { // This helper class will create a bookmark app out of |web_app_info| and // install it to |service|. Icons will be downloaded from the URLs in - // |web_app_info.icons| using |contents|. + // |web_app_info.icons| using |contents| if |contents| is not NULL. + // All existing icons from WebApplicationInfo will also be used. BookmarkAppHelper(ExtensionService* service, WebApplicationInfo web_app_info, content::WebContents* contents); diff --git a/chrome/browser/extensions/bookmark_app_helper_unittest.cc b/chrome/browser/extensions/bookmark_app_helper_unittest.cc index dccc06f..b3941fa 100644 --- a/chrome/browser/extensions/bookmark_app_helper_unittest.cc +++ b/chrome/browser/extensions/bookmark_app_helper_unittest.cc @@ -8,6 +8,9 @@ #include "chrome/browser/extensions/extension_service_unittest.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/web_contents_tester.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/constants.h" #include "extensions/common/extension_icon_set.h" @@ -24,7 +27,9 @@ const char kAppTitle[] = "Test title"; const char kAlternativeAppTitle[] = "Different test title"; const char kAppDescription[] = "Test description"; +const int kIconSizeTiny = extension_misc::EXTENSION_ICON_BITTY; const int kIconSizeSmall = extension_misc::EXTENSION_ICON_SMALL; +const int kIconSizeMedium = extension_misc::EXTENSION_ICON_MEDIUM; const int kIconSizeLarge = extension_misc::EXTENSION_ICON_LARGE; #endif @@ -49,6 +54,19 @@ class BookmarkAppHelperExtensionServiceTest : public ExtensionServiceTestBase { EXPECT_EQ(0u, service_->extensions()->size()); } + virtual void TearDown() OVERRIDE { + ExtensionServiceTestBase::TearDown(); + for (content::RenderProcessHost::iterator i( + content::RenderProcessHost::AllHostsIterator()); + !i.IsAtEnd(); + i.Advance()) { + content::RenderProcessHost* host = i.GetCurrentValue(); + if (Profile::FromBrowserContext(host->GetBrowserContext()) == + profile_.get()) + host->Cleanup(); + } + } + private: DISALLOW_COPY_AND_ASSIGN(BookmarkAppHelperExtensionServiceTest); }; @@ -136,7 +154,9 @@ TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkApp) { web_app_info.title = base::UTF8ToUTF16(kAppTitle); web_app_info.description = base::UTF8ToUTF16(kAppDescription); - TestBookmarkAppHelper helper(service_, web_app_info, NULL); + scoped_ptr<content::WebContents> contents( + content::WebContentsTester::CreateTestWebContents(profile_.get(), NULL)); + TestBookmarkAppHelper helper(service_, web_app_info, contents.get()); helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete, base::Unretained(&helper))); @@ -160,6 +180,47 @@ TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkApp) { extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty()); } +TEST_F(BookmarkAppHelperExtensionServiceTest, CreateBookmarkAppNoContents) { + WebApplicationInfo web_app_info; + web_app_info.app_url = GURL(kAppUrl); + web_app_info.title = base::UTF8ToUTF16(kAppTitle); + web_app_info.description = base::UTF8ToUTF16(kAppDescription); + web_app_info.icons.push_back( + CreateIconInfoWithBitmap(kIconSizeTiny, SK_ColorRED)); + + TestBookmarkAppHelper helper(service_, web_app_info, NULL); + helper.Create(base::Bind(&TestBookmarkAppHelper::CreationComplete, + base::Unretained(&helper))); + + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(helper.extension()); + const Extension* extension = + service_->GetInstalledExtension(helper.extension()->id()); + EXPECT_TRUE(extension); + EXPECT_EQ(1u, service_->extensions()->size()); + EXPECT_TRUE(extension->from_bookmark()); + EXPECT_EQ(kAppTitle, extension->name()); + EXPECT_EQ(kAppDescription, extension->description()); + EXPECT_EQ(GURL(kAppUrl), AppLaunchInfo::GetLaunchWebURL(extension)); + EXPECT_FALSE( + IconsInfo::GetIconResource( + extension, kIconSizeTiny, ExtensionIconSet::MATCH_EXACTLY).empty()); + EXPECT_FALSE( + IconsInfo::GetIconResource( + extension, kIconSizeSmall, ExtensionIconSet::MATCH_EXACTLY).empty()); + EXPECT_FALSE( + IconsInfo::GetIconResource(extension, + kIconSizeSmall * 2, + ExtensionIconSet::MATCH_EXACTLY).empty()); + EXPECT_FALSE( + IconsInfo::GetIconResource( + extension, kIconSizeMedium, ExtensionIconSet::MATCH_EXACTLY).empty()); + EXPECT_FALSE( + IconsInfo::GetIconResource(extension, + kIconSizeMedium * 2, + ExtensionIconSet::MATCH_EXACTLY).empty()); +} + TEST_F(BookmarkAppHelperExtensionServiceTest, CreateAndUpdateBookmarkApp) { EXPECT_EQ(0u, registry_->enabled_extensions().size()); WebApplicationInfo web_app_info; diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index 6dc9dc9..186226c 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -542,6 +542,11 @@ "channel": "dev", "contexts": ["blessed_extension"] }, + "management.generateAppForLink": { + "dependencies": ["permission:management"], + "channel": "dev", + "contexts": ["blessed_extension"] + }, // This is not a real API, only here for documentation purposes. // See http://crbug.com/275944 for background. "manifestTypes": { diff --git a/chrome/common/extensions/api/management.json b/chrome/common/extensions/api/management.json index fb0868e..eac94c8 100644 --- a/chrome/common/extensions/api/management.json +++ b/chrome/common/extensions/api/management.json @@ -355,6 +355,33 @@ "parameters": [] } ] + }, + { + "name": "generateAppForLink", + "description": "Generate an app for a URL. Returns the generated bookmark app. Note: This function is only available to Chrome users on the dev channel.", + "parameters": [ + { + "name": "url", + "type": "string", + "description": "The URL of a web page. The scheme of the URL can only be \"http\" or \"https\"." + }, + { + "name": "title", + "type": "string", + "description": "The title of the generated app." + }, + { + "name": "callback", + "type": "function", + "optional": true, + "parameters": [ + { + "name": "result", + "$ref": "ExtensionInfo" + } + ] + } + ] } ], "events": [ diff --git a/chrome/test/data/extensions/api_test/management/test/generateAppForLink.html b/chrome/test/data/extensions/api_test/management/test/generateAppForLink.html new file mode 100644 index 0000000..c44fa6f --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/test/generateAppForLink.html @@ -0,0 +1,7 @@ +<!-- + * Copyright 2014 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<script src="common.js"></script> +<script src="generateAppForLink.js"></script> diff --git a/chrome/test/data/extensions/api_test/management/test/generateAppForLink.js b/chrome/test/data/extensions/api_test/management/test/generateAppForLink.js new file mode 100644 index 0000000..c7eba3b --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/test/generateAppForLink.js @@ -0,0 +1,78 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +function testGenerateAppForLink(url, title, error, func) { + chrome.test.runWithUserGesture(function() { + if (error) + chrome.management.generateAppForLink( + url, title, callback(function(data) {}, error)); + else + chrome.management.generateAppForLink(url, title, callback(func)); + }); +} + +var tests = [ + function generateAppForLinkWithoutUserGesture() { + chrome.management.generateAppForLink( + "http://google.com", "test", callback(function() {}, + "chrome.management.generateAppForLink requires a user gesture.")); + }, + + function generateAppForInvalidLink() { + testGenerateAppForLink("", "test", "The URL \"\" is invalid."); + testGenerateAppForLink("aaaa", "test", "The URL \"aaaa\" is invalid."); + testGenerateAppForLink("http1://google.com", "test", + "The URL \"http1://google.com\" is invalid."); + testGenerateAppForLink("chrome://about", "test", + "The URL \"chrome://about\" is invalid."); + testGenerateAppForLink("chrome-extension://test/test", "test", + "The URL \"chrome-extension://test/test\" is invalid."); + }, + + function generateAppWithEmptyTitle() { + testGenerateAppForLink("http://google.com", "", + "The title can not be empty."); + }, + + function generateAppForLinkWithShortURL() { + var url = "http://google.com", title = "testApp"; + testGenerateAppForLink( + url, title, null, function(data) { + assertEq("http://google.com/", data.appLaunchUrl); + assertEq(title, data.name); + // There is no favicon in the test browser, so only 4 icons will + // be created. + assertEq(4, data.icons.length); + assertEq(32, data.icons[0].size); + assertEq(48, data.icons[1].size); + assertEq(64, data.icons[2].size); + assertEq(96, data.icons[3].size); + + chrome.management.getAll(callback(function(items) { + assertTrue(getItemNamed(items, title) != null); + })); + }); + }, + + function generateAppForLinkWithLongURL() { + var url = "http://google.com/page/page?aa=bb&cc=dd", title = "test App 2"; + testGenerateAppForLink( + url, title, null, function(data) { + assertEq(url, data.appLaunchUrl); + assertEq(title, data.name); + assertEq(4, data.icons.length); + assertEq(32, data.icons[0].size); + assertEq(48, data.icons[1].size); + assertEq(64, data.icons[2].size); + assertEq(96, data.icons[3].size); + + chrome.management.getAll(callback(function(items) { + assertTrue(getItemNamed(items, title) != null); + })); + }); + } +]; + +chrome.test.runTests(tests); + diff --git a/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.html b/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.html new file mode 100644 index 0000000..7edf7b6 --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.html @@ -0,0 +1,7 @@ +<!-- + * Copyright 2014 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<script src="common.js"></script> +<script src="generateAppForLinkNotInStable.js"></script> diff --git a/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.js b/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.js new file mode 100644 index 0000000..3d5eadc --- /dev/null +++ b/chrome/test/data/extensions/api_test/management/test/generateAppForLinkNotInStable.js @@ -0,0 +1,12 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var tests = [ + function generateAppForLinkNotInStable() { + assertEq(chrome.management.generateAppForLink, undefined); + succeed(); + } +]; + +chrome.test.runTests(tests); diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index dbe0581..f0cfd15 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h @@ -843,6 +843,7 @@ enum HistogramValue { FILEBROWSERPRIVATE_OPENINSPECTOR, STREAMSPRIVATE_ABORT, MANAGEMENT_SETLAUNCHTYPE, + MANAGEMENT_GENERATEAPPFORLINK, // Last entry: Add new entries above and ensure to update // tools/metrics/histograms/histograms/histograms.xml. ENUM_BOUNDARY diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4828deb..c2fd7d3 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -35779,6 +35779,7 @@ Therefore, the affected-histogram name has to have at least one dot in it. <int value="782" label="FILEBROWSERPRIVATE_OPENINSPECTOR"/> <int value="783" label="STREAMSPRIVATE_ABORT"/> <int value="784" label="MANAGEMENT_SETLAUNCHTYPE"/> + <int value="785" label="MANAGEMENT_GENERATEAPPFORLINK"/> </enum> <enum name="ExtensionInstallCause" type="int"> |