arc: add LaunchAppShortcutItem API and apply in ArcAppContextMenu
Changes: Design doc: go/arc-app-shortcuts Launch app shortcut has to be called by Android's LauncherApps' startShortcut API. Thus provide a mojo API to do the work. Bug: 803291 Test: tested on device with ag/3997639 Change-Id: Idece1c44836a9e43932b700b81d128883c15666d Reviewed-on: https://chromium-review.googlesource.com/1041574 Commit-Queue: Qiang Xu <warx@google.com> Reviewed-by: Luis Hector Chavez <lhchavez@chromium.org> Reviewed-by: Yury Khmel <khmel@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/master@{#556106}
This commit is contained in:
@ -480,6 +480,11 @@ TEST_P(AppContextMenuTest, ArcMenu) {
|
||||
EXPECT_EQ(base::StringPrintf("ShortLabel %d", i),
|
||||
base::UTF16ToUTF8(menu->GetLabelAt(i + index)));
|
||||
}
|
||||
|
||||
// Test launching app shortcut item.
|
||||
EXPECT_EQ(0, arc_test.app_instance()->launch_app_shortcut_item_count());
|
||||
menu->ActivatedAt(menu->GetItemCount() - 1);
|
||||
EXPECT_EQ(1, arc_test.app_instance()->launch_app_shortcut_item_count());
|
||||
}
|
||||
|
||||
// This makes all apps non-ready.
|
||||
|
@ -88,18 +88,17 @@ bool ArcAppContextMenu::IsCommandIdEnabled(int command_id) const {
|
||||
}
|
||||
|
||||
void ArcAppContextMenu::ExecuteCommand(int command_id, int event_flags) {
|
||||
switch (command_id) {
|
||||
case LAUNCH_NEW:
|
||||
delegate()->ExecuteLaunchCommand(event_flags);
|
||||
break;
|
||||
case UNINSTALL:
|
||||
arc::ShowArcAppUninstallDialog(profile(), controller(), app_id());
|
||||
break;
|
||||
case SHOW_APP_INFO:
|
||||
ShowPackageInfo();
|
||||
break;
|
||||
default:
|
||||
app_list::AppContextMenu::ExecuteCommand(command_id, event_flags);
|
||||
if (command_id == LAUNCH_NEW) {
|
||||
delegate()->ExecuteLaunchCommand(event_flags);
|
||||
} else if (command_id == UNINSTALL) {
|
||||
arc::ShowArcAppUninstallDialog(profile(), controller(), app_id());
|
||||
} else if (command_id == SHOW_APP_INFO) {
|
||||
ShowPackageInfo();
|
||||
} else if (command_id >= LAUNCH_APP_SHORTCUT_FIRST &&
|
||||
command_id <= LAUNCH_APP_SHORTCUT_LAST) {
|
||||
ExecuteLaunchAppShortcutCommand(command_id);
|
||||
} else {
|
||||
app_list::AppContextMenu::ExecuteCommand(command_id, event_flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,17 +131,30 @@ void ArcAppContextMenu::BuildAppShortcutsMenu(
|
||||
void ArcAppContextMenu::OnGetAppShortcutItems(
|
||||
std::unique_ptr<ui::SimpleMenuModel> menu_model,
|
||||
GetMenuModelCallback callback,
|
||||
std::unique_ptr<arc::ArcAppShortcutItems> shortcut_items) {
|
||||
if (shortcut_items) {
|
||||
std::unique_ptr<arc::ArcAppShortcutItems> app_shortcut_items) {
|
||||
app_shortcut_items_ = std::move(app_shortcut_items);
|
||||
if (app_shortcut_items_) {
|
||||
int command_id = LAUNCH_APP_SHORTCUT_FIRST;
|
||||
DCHECK_LT(command_id + shortcut_items->size(), LAUNCH_APP_SHORTCUT_LAST);
|
||||
for (const auto& item : *shortcut_items)
|
||||
DCHECK_LT(command_id + app_shortcut_items_->size(),
|
||||
LAUNCH_APP_SHORTCUT_LAST);
|
||||
for (const auto& item : *app_shortcut_items_)
|
||||
menu_model->AddItemWithIcon(command_id++, item.short_label, item.icon);
|
||||
}
|
||||
std::move(callback).Run(std::move(menu_model));
|
||||
arc_app_shortcuts_request_.reset();
|
||||
}
|
||||
|
||||
void ArcAppContextMenu::ExecuteLaunchAppShortcutCommand(int command_id) {
|
||||
DCHECK(command_id >= LAUNCH_APP_SHORTCUT_FIRST &&
|
||||
command_id <= LAUNCH_APP_SHORTCUT_LAST);
|
||||
size_t index = command_id - LAUNCH_APP_SHORTCUT_FIRST;
|
||||
DCHECK(app_shortcut_items_);
|
||||
DCHECK_LT(index, app_shortcut_items_->size());
|
||||
arc::LaunchAppShortcutItem(profile(), app_id(),
|
||||
app_shortcut_items_->at(index).shortcut_id,
|
||||
controller()->GetAppListDisplayId());
|
||||
}
|
||||
|
||||
void ArcAppContextMenu::ShowPackageInfo() {
|
||||
const ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile());
|
||||
DCHECK(arc_prefs);
|
||||
|
@ -45,10 +45,16 @@ class ArcAppContextMenu : public app_list::AppContextMenu {
|
||||
void OnGetAppShortcutItems(
|
||||
std::unique_ptr<ui::SimpleMenuModel> menu_model,
|
||||
GetMenuModelCallback callback,
|
||||
std::unique_ptr<arc::ArcAppShortcutItems> shortcut_items);
|
||||
std::unique_ptr<arc::ArcAppShortcutItems> app_shortcut_items);
|
||||
|
||||
// Executes launching app shortcut item.
|
||||
void ExecuteLaunchAppShortcutCommand(int command_id);
|
||||
|
||||
void ShowPackageInfo();
|
||||
|
||||
// Caches the app shortcut items from OnGetAppShortcutItems().
|
||||
std::unique_ptr<arc::ArcAppShortcutItems> app_shortcut_items_;
|
||||
|
||||
// Handles requesting app shortcuts from Android.
|
||||
std::unique_ptr<arc::ArcAppShortcutsRequest> arc_app_shortcuts_request_;
|
||||
|
||||
|
@ -150,6 +150,15 @@ bool Launch(content::BrowserContext* context,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns primary display id if |display_id| is invalid.
|
||||
int64_t GetValidDisplayId(int64_t display_id) {
|
||||
if (display_id != display::kInvalidDisplayId)
|
||||
return display_id;
|
||||
if (auto* screen = display::Screen::GetScreen())
|
||||
return screen->GetPrimaryDisplay().id();
|
||||
return display::kInvalidDisplayId;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
const char kPlayStoreAppId[] = "cnbgggchhmkkdmeppjobngjoejnihlei";
|
||||
@ -184,7 +193,8 @@ bool LaunchPlayStoreWithUrl(const std::string& url) {
|
||||
arc::mojom::IntentHelperInstance* instance =
|
||||
GET_INTENT_HELPER_INSTANCE(HandleUrl);
|
||||
if (!instance) {
|
||||
VLOG(1) << "Cannot find a mojo instance, ARC is unreachable";
|
||||
VLOG(1) << "Cannot find a mojo instance, ARC is unreachable or mojom"
|
||||
<< " version mismatch";
|
||||
return false;
|
||||
}
|
||||
instance->HandleUrl(url, kPlayStorePackage);
|
||||
@ -212,11 +222,6 @@ bool LaunchAppWithIntent(content::BrowserContext* context,
|
||||
int64_t display_id) {
|
||||
DCHECK(!launch_intent.has_value() || !launch_intent->empty());
|
||||
|
||||
if (display_id == display::kInvalidDisplayId) {
|
||||
if (auto* screen = display::Screen::GetScreen())
|
||||
display_id = screen->GetPrimaryDisplay().id();
|
||||
}
|
||||
|
||||
Profile* const profile = Profile::FromBrowserContext(context);
|
||||
|
||||
// Even when ARC is not allowed for the profile, ARC apps may still show up
|
||||
@ -273,7 +278,7 @@ bool LaunchAppWithIntent(content::BrowserContext* context,
|
||||
DCHECK(chrome_controller || !ash::Shell::HasInstance());
|
||||
if (chrome_controller) {
|
||||
chrome_controller->GetArcDeferredLauncher()->RegisterDeferredLaunch(
|
||||
app_id, event_flags, display_id);
|
||||
app_id, event_flags, GetValidDisplayId(display_id));
|
||||
|
||||
// On some boards, ARC is booted with a restricted set of resources by
|
||||
// default to avoid slowing down Chrome's user session restoration.
|
||||
@ -286,7 +291,37 @@ bool LaunchAppWithIntent(content::BrowserContext* context,
|
||||
}
|
||||
arc::ArcBootPhaseMonitorBridge::RecordFirstAppLaunchDelayUMA(context);
|
||||
|
||||
return Launch(context, app_id, launch_intent, event_flags, display_id);
|
||||
return Launch(context, app_id, launch_intent, event_flags,
|
||||
GetValidDisplayId(display_id));
|
||||
}
|
||||
|
||||
bool LaunchAppShortcutItem(content::BrowserContext* context,
|
||||
const std::string& app_id,
|
||||
const std::string& shortcut_id,
|
||||
int64_t display_id) {
|
||||
std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
|
||||
ArcAppListPrefs::Get(context)->GetApp(app_id);
|
||||
if (!app_info) {
|
||||
LOG(ERROR) << "App " << app_id << " is not available.";
|
||||
return false;
|
||||
}
|
||||
|
||||
mojom::AppInstance* app_instance =
|
||||
ArcServiceManager::Get()
|
||||
? ARC_GET_INSTANCE_FOR_METHOD(
|
||||
ArcServiceManager::Get()->arc_bridge_service()->app(),
|
||||
LaunchAppShortcutItem)
|
||||
: nullptr;
|
||||
|
||||
if (!app_instance) {
|
||||
LOG(ERROR) << "Cannot find a mojo instance, ARC is unreachable or mojom"
|
||||
<< " version mismatch.";
|
||||
return false;
|
||||
}
|
||||
|
||||
app_instance->LaunchAppShortcutItem(app_info->package_name, shortcut_id,
|
||||
GetValidDisplayId(display_id));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LaunchSettingsAppActivity(content::BrowserContext* context,
|
||||
|
@ -109,6 +109,12 @@ bool LaunchAppWithIntent(content::BrowserContext* context,
|
||||
int event_flags,
|
||||
int64_t display_id);
|
||||
|
||||
// Launches App Shortcut that was published by Android's ShortcutManager.
|
||||
bool LaunchAppShortcutItem(content::BrowserContext* context,
|
||||
const std::string& app_id,
|
||||
const std::string& shortcut_id,
|
||||
int64_t display_id);
|
||||
|
||||
// Launches a specific activity within Settings app on ARC.
|
||||
bool LaunchSettingsAppActivity(content::BrowserContext* context,
|
||||
const std::string& activity,
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
//
|
||||
// Next MinVersion: 30
|
||||
// Next MinVersion: 31
|
||||
|
||||
module arc.mojom;
|
||||
|
||||
@ -281,7 +281,7 @@ interface AppHost {
|
||||
};
|
||||
|
||||
// TODO(lhchavez): Migrate all request/response messages to Mojo.
|
||||
// Next method ID: 24
|
||||
// Next method ID: 25
|
||||
interface AppInstance {
|
||||
// DEPRECATED: Please use Init@21 instead.
|
||||
InitDeprecated@0(AppHost host_ptr);
|
||||
@ -311,6 +311,11 @@ interface AppInstance {
|
||||
[MinVersion=23] LaunchApp@18(string package_name, string activity,
|
||||
int64 display_id);
|
||||
|
||||
// Sends a request to ARC for the Android launcher to launch the specified app
|
||||
// shortcut.
|
||||
[MinVersion=30] LaunchAppShortcutItem@24(
|
||||
string package_name, string shortcut_id, int64 display_id);
|
||||
|
||||
[MinVersion=9] LaunchIntentDeprecated@12(string intent_uri,
|
||||
Rect? dimension_on_screen);
|
||||
|
||||
|
@ -74,6 +74,12 @@ void FakeAppInstance::LaunchApp(const std::string& package_name,
|
||||
launch_requests_.push_back(std::make_unique<Request>(package_name, activity));
|
||||
}
|
||||
|
||||
void FakeAppInstance::LaunchAppShortcutItem(const std::string& package_name,
|
||||
const std::string& shortcut_id,
|
||||
int64_t display_id) {
|
||||
++launch_app_shortcut_item_count_;
|
||||
}
|
||||
|
||||
void FakeAppInstance::RequestAppIcon(const std::string& package_name,
|
||||
const std::string& activity,
|
||||
mojom::ScaleFactor scale_factor) {
|
||||
|
@ -88,6 +88,9 @@ class FakeAppInstance : public mojom::AppInstance {
|
||||
void LaunchApp(const std::string& package_name,
|
||||
const std::string& activity,
|
||||
int64_t display_id) override;
|
||||
void LaunchAppShortcutItem(const std::string& package_name,
|
||||
const std::string& shortcut_id,
|
||||
int64_t display_id) override;
|
||||
void RequestAppIcon(const std::string& package_name,
|
||||
const std::string& activity,
|
||||
mojom::ScaleFactor scale_factor) override;
|
||||
@ -170,6 +173,10 @@ class FakeAppInstance : public mojom::AppInstance {
|
||||
|
||||
int start_pai_request_count() const { return start_pai_request_count_; }
|
||||
|
||||
int launch_app_shortcut_item_count() const {
|
||||
return launch_app_shortcut_item_count_;
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Request>>& launch_requests() const {
|
||||
return launch_requests_;
|
||||
}
|
||||
@ -195,6 +202,8 @@ class FakeAppInstance : public mojom::AppInstance {
|
||||
int refresh_app_list_count_ = 0;
|
||||
// Number of requests to start PAI flows.
|
||||
int start_pai_request_count_ = 0;
|
||||
// Keeps information about launch app shortcut requests.
|
||||
int launch_app_shortcut_item_count_ = 0;
|
||||
// Keeps information about launch requests.
|
||||
std::vector<std::unique_ptr<Request>> launch_requests_;
|
||||
// Keeps information about launch intents.
|
||||
|
Reference in New Issue
Block a user