Commit 1e26fb86 authored by wutao's avatar wutao Committed by Commit Bot

cros: Add Settings to launcher apps grid.

This patch adds the Settings to launcher apps grid.
1. Added class InternalAppItem.
2. Added class InternalAppModelBuilder.

Bug: 824437
Test: InternalAppModelBuilderTest.Build
Change-Id: I0dd06e767527b73e7ed14ca4dbab3e26d5c6e075
Reviewed-on: https://chromium-review.googlesource.com/1007496Reviewed-by: default avatarNicolas Zea <zea@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Tao Wu <wutao@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550679}
parent 2ef7b374
......@@ -14,13 +14,12 @@
#include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h"
#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
#include "components/browser_sync/profile_sync_service.h"
#include "extensions/browser/extension_system.h"
namespace {
const size_t kNumDefaultApps = 2;
bool AllProfilesHaveSameAppList() {
return SyncAppListHelper::GetInstance()->AllProfilesHaveSameAppList();
}
......@@ -124,6 +123,11 @@ IN_PROC_BROWSER_TEST_F(SingleClientAppListSyncTest, AppListSomeApps) {
app_list::AppListSyncableService* service =
app_list::AppListSyncableServiceFactory::GetForProfile(verifier());
// Default apps: chrome + web store + internal apps.
const size_t kNumDefaultApps =
2u + app_list::GetNumberOfInternalAppsShowInLauncherForTest(
/*apps_name=*/nullptr);
ASSERT_EQ(kNumApps + kNumDefaultApps, service->GetNumSyncItemsForTest());
ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait());
......
......@@ -3637,8 +3637,12 @@ split_static_library("ui") {
"app_list/crostini/crostini_installer_view.h",
"app_list/crostini/crostini_util.cc",
"app_list/crostini/crostini_util.h",
"app_list/internal_app/internal_app_item.cc",
"app_list/internal_app/internal_app_item.h",
"app_list/internal_app/internal_app_metadata.cc",
"app_list/internal_app/internal_app_metadata.h",
"app_list/internal_app/internal_app_model_builder.cc",
"app_list/internal_app/internal_app_model_builder.h",
"app_list/search/arc_app_result.cc",
"app_list/search/arc_app_result.h",
"app_list/search/internal_app_result.cc",
......
......@@ -30,6 +30,7 @@
#include "chrome/browser/ui/app_list/crostini/crostini_util.h"
#include "chrome/browser/ui/app_list/extension_app_item.h"
#include "chrome/browser/ui/app_list/extension_app_model_builder.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_model_builder.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/pref_names.h"
......@@ -399,15 +400,16 @@ void AppListSyncableService::BuildModel() {
arc_apps_builder_.reset(new ArcAppModelBuilder(controller));
if (IsExperimentalCrostiniUIAvailable())
crostini_apps_builder_.reset(new CrostiniAppModelBuilder(controller));
internal_apps_builder_.reset(new InternalAppModelBuilder(controller));
DCHECK(profile_);
SyncStarted();
apps_builder_->Initialize(this, profile_, model_updater_.get());
if (arc_apps_builder_.get())
arc_apps_builder_->Initialize(this, profile_, model_updater_.get());
if (crostini_apps_builder_.get())
crostini_apps_builder_->Initialize(this, profile_, model_updater_.get());
internal_apps_builder_->Initialize(this, profile_, model_updater_.get());
HandleUpdateFinished();
}
......
......@@ -31,6 +31,7 @@ class ArcAppModelBuilder;
class ChromeAppListItem;
class CrostiniAppModelBuilder;
class ExtensionAppModelBuilder;
class InternalAppModelBuilder;
class Profile;
namespace extensions {
......@@ -274,6 +275,7 @@ class AppListSyncableService : public syncer::SyncableService,
std::unique_ptr<ExtensionAppModelBuilder> apps_builder_;
std::unique_ptr<ArcAppModelBuilder> arc_apps_builder_;
std::unique_ptr<CrostiniAppModelBuilder> crostini_apps_builder_;
std::unique_ptr<InternalAppModelBuilder> internal_apps_builder_;
std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_;
std::unique_ptr<syncer::SyncErrorFactory> sync_error_handler_;
SyncItemMap sync_items_;
......
// Copyright 2018 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.
#include "chrome/browser/ui/app_list/internal_app/internal_app_item.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
#include "ui/base/l10n/l10n_util.h"
// static
const char InternalAppItem::kItemType[] = "InternalAppItem";
InternalAppItem::InternalAppItem(
Profile* profile,
const app_list::AppListSyncableService::SyncItem* sync_item,
const app_list::InternalApp& internal_app)
: ChromeAppListItem(profile, internal_app.app_id) {
SetIcon(app_list::GetIconForResourceId(internal_app.icon_resource_id));
SetName(l10n_util::GetStringUTF8(internal_app.name_string_resource_id));
if (sync_item && sync_item->item_ordinal.IsValid())
UpdateFromSync(sync_item);
else
SetDefaultPositionIfApplicable();
}
const char* InternalAppItem::GetItemType() const {
return InternalAppItem::kItemType;
}
void InternalAppItem::Activate(int event_flags) {
app_list::OpenInternalApp(id(), profile());
}
// Copyright 2018 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_ITEM_H_
#define CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_ITEM_H_
#include "base/macros.h"
#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
namespace app_list {
struct InternalApp;
}
class InternalAppItem : public ChromeAppListItem {
public:
static const char kItemType[];
InternalAppItem(Profile* profile,
const app_list::AppListSyncableService::SyncItem* sync_item,
const app_list::InternalApp& internal_app);
~InternalAppItem() override = default;
private:
// ChromeAppListItem:
void Activate(int event_flags) override;
const char* GetItemType() const override;
DISALLOW_COPY_AND_ASSIGN(InternalAppItem);
};
#endif // CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_ITEM_H_
......@@ -8,7 +8,15 @@
#include "ash/resources/grit/ash_resources.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/strings/string_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/grit/generated_resources.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia_operations.h"
namespace app_list {
......@@ -18,11 +26,13 @@ const std::vector<InternalApp>& GetInternalAppList() {
IDS_INTERNAL_APP_KEYBOARD_SHORTCUT_VIEWER,
IDR_KEYBOARD_SHORTCUT_VIEWER_LOGO_192,
/*recommendable=*/false,
/*show_in_launcher=*/false,
IDS_LAUNCHER_SEARCHABLE_KEYBOARD_SHORTCUT_VIEWER},
{kInternalAppIdSettings, IDS_INTERNAL_APP_SETTINGS,
IDR_SETTINGS_LOGO_192,
/*recommendable=*/true,
/*show_in_launcher=*/true,
/*searchable_string_resource_id=*/0}});
return *internal_app_list;
}
......@@ -35,4 +45,40 @@ int GetIconResourceIdByAppId(const std::string& app_id) {
return 0;
}
void OpenInternalApp(const std::string& app_id, Profile* profile) {
if (app_id == kInternalAppIdKeyboardShortcutViewer) {
keyboard_shortcut_viewer_util::ShowKeyboardShortcutViewer();
} else if (app_id == kInternalAppIdSettings) {
chrome::ShowSettingsSubPageForProfile(profile, std::string());
}
}
gfx::ImageSkia GetIconForResourceId(int resource_id) {
if (resource_id == 0)
return gfx::ImageSkia();
gfx::ImageSkia* source =
ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
return gfx::ImageSkiaOperations::CreateResizedImage(
*source, skia::ImageOperations::RESIZE_BEST,
gfx::Size(kTileIconSize, kTileIconSize));
}
size_t GetNumberOfInternalAppsShowInLauncherForTest(std::string* apps_name) {
size_t num_of_internal_apps_show_in_launcher = 0u;
std::vector<std::string> internal_apps_name;
for (const auto& app : GetInternalAppList()) {
if (app.show_in_launcher) {
++num_of_internal_apps_show_in_launcher;
if (apps_name) {
internal_apps_name.emplace_back(
l10n_util::GetStringUTF8(app.name_string_resource_id));
}
}
}
if (apps_name)
*apps_name = base::JoinString(internal_apps_name, ",");
return num_of_internal_apps_show_in_launcher;
}
} // namespace app_list
......@@ -8,6 +8,10 @@
#include <string>
#include <vector>
#include "ui/gfx/image/image_skia.h"
class Profile;
namespace app_list {
// Metadata about an internal app.
......@@ -24,6 +28,9 @@ struct InternalApp {
// Can show as a suggested app.
bool recommendable;
// Can show in launcher apps grid.
bool show_in_launcher;
// The string used for search query in addition to the name.
int searchable_string_resource_id = 0;
};
......@@ -35,6 +42,18 @@ const std::vector<InternalApp>& GetInternalAppList();
// Returns 0 if |app_id| is invalid.
int GetIconResourceIdByAppId(const std::string& app_id);
// Helper function to open internal apps.
void OpenInternalApp(const std::string& app_id, Profile* profile);
// Returns icon associated with the |resource_id|.
// Returns empty ImageSkia if |resource_id| is 0;
gfx::ImageSkia GetIconForResourceId(int resource_id);
// Returns the number of internal apps which can show in launcher.
// If |apps_name| is not nullptr, it will be the concatenated string of these
// internal apps' name.
size_t GetNumberOfInternalAppsShowInLauncherForTest(std::string* apps_name);
} // namespace app_list
#endif // CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_METADATA_H_
// Copyright 2018 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.
#include "chrome/browser/ui/app_list/internal_app/internal_app_model_builder.h"
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_item.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
InternalAppModelBuilder::InternalAppModelBuilder(
AppListControllerDelegate* controller)
: AppListModelBuilder(controller, InternalAppItem::kItemType) {}
InternalAppModelBuilder::~InternalAppModelBuilder() = default;
void InternalAppModelBuilder::BuildModel() {
for (const auto& internal_app : app_list::GetInternalAppList()) {
if (!internal_app.show_in_launcher)
continue;
InsertApp(std::make_unique<InternalAppItem>(
profile(), GetSyncItem(internal_app.app_id), internal_app));
}
}
// Copyright 2018 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.
#ifndef CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_MODEL_BUILDER_H_
#define CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_MODEL_BUILDER_H_
#include "base/macros.h"
#include "chrome/browser/ui/app_list/app_list_model_builder.h"
class AppListControllerDelegate;
// This class populates and maintains Crostini apps.
class InternalAppModelBuilder : public AppListModelBuilder {
public:
explicit InternalAppModelBuilder(AppListControllerDelegate* controller);
~InternalAppModelBuilder() override;
private:
// AppListModelBuilder:
void BuildModel() override;
DISALLOW_COPY_AND_ASSIGN(InternalAppModelBuilder);
};
#endif // CHROME_BROWSER_UI_APP_LIST_INTERNAL_APP_INTERNAL_APP_MODEL_BUILDER_H_
// Copyright 2018 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.
#include "chrome/browser/ui/app_list/internal_app/internal_app_model_builder.h"
#include "base/macros.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ui/app_list/app_list_test_util.h"
#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
#include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h"
#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
// Get a set of all apps in |model|.
std::string GetModelContent(AppListModelUpdater* model_updater) {
std::vector<std::string> app_names;
for (size_t i = 0; i < model_updater->ItemCount(); ++i)
app_names.emplace_back(model_updater->ItemAtForTest(i)->name());
return base::JoinString(app_names, ",");
}
} // namespace
class InternalAppModelBuilderTest : public AppListTestBase {
public:
InternalAppModelBuilderTest() {}
~InternalAppModelBuilderTest() override {}
// AppListTestBase:
void SetUp() override {
AppListTestBase::SetUp();
CreateBuilder();
}
void TearDown() override {
ResetBuilder();
AppListTestBase::TearDown();
}
protected:
std::unique_ptr<FakeAppListModelUpdater> model_updater_;
private:
// Creates a new builder, destroying any existing one.
void CreateBuilder() {
ResetBuilder(); // Destroy any existing builder in the correct order.
model_updater_ = std::make_unique<FakeAppListModelUpdater>();
controller_ = std::make_unique<test::TestAppListControllerDelegate>();
builder_ = std::make_unique<InternalAppModelBuilder>(controller_.get());
builder_->Initialize(nullptr, profile(), model_updater_.get());
}
void ResetBuilder() {
builder_.reset();
controller_.reset();
model_updater_.reset();
}
std::unique_ptr<test::TestAppListControllerDelegate> controller_;
std::unique_ptr<InternalAppModelBuilder> builder_;
DISALLOW_COPY_AND_ASSIGN(InternalAppModelBuilderTest);
};
TEST_F(InternalAppModelBuilderTest, Build) {
// The internal apps list is provided by GetInternalAppList() in
// internal_app_metadata.cc. Only count the apps can display in launcher.
std::string internal_apps_name;
EXPECT_EQ(app_list::GetNumberOfInternalAppsShowInLauncherForTest(
&internal_apps_name),
model_updater_->ItemCount());
EXPECT_EQ(internal_apps_name, GetModelContent(model_updater_.get()));
}
......@@ -9,30 +9,12 @@
#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
#include "chrome/browser/ui/app_list/internal_app/internal_app_metadata.h"
#include "chrome/browser/ui/app_list/search/search_util.h"
#include "chrome/browser/ui/ash/ksv/keyboard_shortcut_viewer_util.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image_skia_operations.h"
namespace app_list {
namespace {
gfx::ImageSkia GetIconForInternalAppId(const std::string& app_id) {
const int resource_id = GetIconResourceIdByAppId(app_id);
if (resource_id == 0)
return gfx::ImageSkia();
gfx::ImageSkia* source =
ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
return gfx::ImageSkiaOperations::CreateResizedImage(
*source, skia::ImageOperations::RESIZE_BEST,
gfx::Size(kTileIconSize, kTileIconSize));
}
} // namespace
InternalAppResult::InternalAppResult(Profile* profile,
const std::string& app_id,
AppListControllerDelegate* controller,
......@@ -41,7 +23,7 @@ InternalAppResult::InternalAppResult(Profile* profile,
set_id(app_id);
set_result_type(ResultType::kInternalApp);
gfx::ImageSkia icon = GetIconForInternalAppId(app_id);
gfx::ImageSkia icon = GetIconForResourceId(GetIconResourceIdByAppId(app_id));
if (!icon.isNull())
SetIcon(icon);
}
......@@ -57,11 +39,7 @@ void InternalAppResult::Open(int event_flags) {
if (display_type() != DisplayType::kRecommendation)
RecordHistogram(APP_SEARCH_RESULT);
if (id() == kInternalAppIdKeyboardShortcutViewer) {
keyboard_shortcut_viewer_util::ShowKeyboardShortcutViewer();
} else if (id() == kInternalAppIdSettings) {
chrome::ShowSettingsSubPageForProfile(profile(), std::string());
}
OpenInternalApp(id(), profile());
}
std::unique_ptr<ChromeSearchResult> InternalAppResult::Duplicate() const {
......
......@@ -439,7 +439,7 @@ class ChromeLauncherControllerTest : public BrowserWithTestWindowTest {
app_service_ =
app_list::AppListSyncableServiceFactory::GetForProfile(profile());
StartAppSyncService(syncer::SyncDataList());
StartAppSyncService(app_service_->GetAllSyncData(syncer::APP_LIST));
std::string error;
extension_chrome_ = Extension::Create(base::FilePath(), Manifest::UNPACKED,
......
......@@ -4356,6 +4356,7 @@ test("unit_tests") {
"../browser/ui/app_list/arc/arc_app_utils_unittest.cc",
"../browser/ui/app_list/arc/arc_vpn_provider_unittest.cc",
"../browser/ui/app_list/extension_app_model_builder_unittest.cc",
"../browser/ui/app_list/internal_app/internal_app_model_builder_unittest.cc",
"../browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc",
"../browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc",
"../browser/ui/app_list/search/arc/arc_app_data_search_provider_unittest.cc",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment