// 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. module ash.mojom; import "ash/public/interfaces/menu.mojom"; import "components/sync/mojo/syncer.mojom"; import "mojo/public/mojom/base/string16.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; import "ui/gfx/image/mojo/image.mojom"; import "ui/gfx/range/mojo/range.mojom"; // A structure holding the common information which is sent between ash and, // chrome representing an app list item. // This structure should be kept as small as possible so that minimum data // is sent via mojo calls when an item is moved or reparented. struct AppListItemMetadata { string id; // The id of the app list item. string name; // The corresponding app or folder's name of the item. string short_name; // The corresponding app's short name of the item. It's // empty if the app doesn't have one or it's a folder. string folder_id; // The id of the item's folder. syncer.mojom.StringOrdinal position; // The position of the item. bool is_folder; // Whether this item is a folder. gfx.mojom.ImageSkia? icon; // The icon of this item. }; // A structure holding the common information which is sent from chrome to ash, // representing a search result. // This structure should be kept as small as possible so that ash can get and // render search results as early as possible. struct SearchResultMetadata { string id; // The id of the result. mojo_base.mojom.String16 title; // The title of the result, e.g. an app's // name, an autocomplete query, etc. mojo_base.mojom.String16 details; // A detail string of this result. array title_tags; // How the title matches the query. See // the SearchResultTag section for // more details. array details_tags; // How the details match the query. See // the SearchResultTag section for // more details. array actions; // Actions that can be performed on this // result. See the SearchResultAction // section for more details. float rating = -1.0; // The average rating score of the app // corresponding to this result, ranged from 0 to // 5. It's negative if there's no rating for the // result. mojo_base.mojom.String16 formatted_price; // A formatted price string, e.g. // "$7.09", "HK$3.94", etc. SearchResultType result_type; // The type of this result. SearchResultDisplayType display_type = kList; // How this result is displayed. double display_score; // A score to determine the result display order. bool is_omnibox_search; // Whether this result is searched from Omnibox. bool is_installing; // Whether this result is installing. mojo_base.mojom.UnguessableToken? answer_card_contents_token; // A token used to render answer card, which is // empty before initialized. It's illegal to pass // an empty UnguessableToken across processes. So // we use a null value when it's empty here. gfx.mojom.Size? answer_card_size; // Preferred size of answer card. It is // unset for non-answer-card results. For // answer card results, it is set when // the answer card WebContents finishes // loading and its renderer notifies it // about a new contents size. gfx.mojom.ImageSkia? icon; // The icon of this result. gfx.mojom.ImageSkia? badge_icon; // The badge icon of this result that // indicates its type, e.g. installable from // PlayStore, installable from WebStore, // etc. }; // All possible states of the app list. enum AppListState { kStateApps = 0, kStateSearchResults, kStateStart, }; // The status of the app list model. enum AppListModelStatus { kStatusNormal, kStatusSyncing, // Syncing apps or installing synced apps. }; // How the result should be displayed. Do not change the order of these as // they are used for metrics. enum SearchResultDisplayType { kNone = 0, kList, kTile, kRecommendation, kCard, // Add new values here. }; // Type of the search result, which is set in Chrome. enum SearchResultType { kInstalledApp, // Installed apps. kPlayStoreApp, // Installable apps from PlayStore. kInstantApp, // Instant apps. kInternalApp, // Chrome OS apps. kWebStoreApp, // Installable apps from WebStore. kWebStoreSearch, // A search query in WebStore. kOmnibox, // Results from Omninbox. kLauncher, // Results from launcher search (currently only from Files). kAnswerCard, // WebContents based answer card. // Add new values here. }; // A tagged range in search result text. struct SearchResultTag { // Similar to ACMatchClassification::Style, the style values are not // mutually exclusive. int16 styles; gfx.mojom.Range range; }; // Data representing an action that can be performed on a search result. // An action could be represented as an icon set or as a blue button with // a label. Icon set is chosen if label text is empty. Otherwise, a blue // button with the label text will be used. struct SearchResultActionImageLabel { gfx.mojom.ImageSkia base_image; gfx.mojom.ImageSkia hover_image; gfx.mojom.ImageSkia pressed_image; }; union SearchResultActionLabel { SearchResultActionImageLabel image_label; mojo_base.mojom.String16 text_label; }; struct SearchResultAction { mojo_base.mojom.String16 tooltip_text; SearchResultActionLabel label; }; // The Chrome app list (aka Launcher), is the place where user can find and // organize all installed apps, or search for various types of information. // // For apps: // The app list displays apps synced across devices based on a user account, in // an order that can be modified by the user. It supports up-to-3-layer app // organization, the root app list, folders, and apps: // - Each app can stay in the root app list or a folder. // - Each folder holds more than one apps, which means it'll automatically get // removed when there's only one app left in it. // - The OEM folder is a special folder where we cannot move items to/from it. // And we cannot rename it. // - Other folders are renamable. // - Folders cannot hold folders. // - Different items/folders never have a same GUID. // - Every item/folder has a same GUID on different devices. // // For searching: // The app list supports various kinds of searching (e.g. apps, onmibox, etc). // And search results can be displayed in different formats (e.g. tiles, cards). // - Result ids are url like string, e.g. // "chrome-extension://mgndgikekgjfcpckkfioiadnlibdjbkf/", // "play://hhbckbkcbnemggclionhhgaceohjfdkl", etc. // - Different search results never have a same id. // - Every search result has a same id on different devices. // - Every search result can have a list of actions (e.g. install), see // app_list::SearchResult::Action. // // Users can long press on any app list item or search result to show a context // menu. A context menu has a list of commands (e.g. open, uninstall, etc.). // - Different items/results may have different command lists. // - Each item/result usually has a same command list, but not always. Consider // when we pin an app to the shelf and when we unpin it, the context menu // looks different. // - Inside each command list, each command has its own unique command id. // - A same command in different command lists has a unique command id, see // app_list::AppContextMenu::CommandId. // The Chrome app list has its UI running in Ash, and everything else running in // Chrome (e.g. syncing, user profile, etc). This controller is implemented in // Ash to handle calls from Chrome. These include: // - When app list data changes in Chrome, it should notifies the UI models and // views in Ash to get updated. This can happen while syncing, searching, etc. // - When Chrome needs real-time UI information from Ash. This can happen while // calculating recommended search results based on the app list item order. // - When app list states in Chrome change that require UI's response. This can // happen while installing/uninstalling apps and the app list gets toggled. interface AppListController { // Sets a client to handle calls from Ash. SetClient(AppListClient client); ////////////////////////////////////////////////////////////////////////////// // Interfaces that come from AppListModelUpdater: // The following interfaces are called to update the app list model in Ash, // including both the app list item model, search result model and search box // model. // Adds an item to AppListModel. AddItem(AppListItemMetadata app_item); // Adds an item into a certain folder in AppListModel. AddItemToFolder(AppListItemMetadata app_item, string folder_id); // Removes an item by its id from AppListModel. RemoveItem(string id); // Removes an item by its id, and also cleans up if its parent folder has a // single child left. RemoveUninstalledItem(string id); // Moves the item with |id| to the folder with |folder_id|. MoveItemToFolder(string id, string folder_id); // Tells Ash what the current status of AppListModel should be, // e.g. the model is under synchronization or in normal status. SetStatus(AppListModelStatus status); // Tells Ash what the current state of the app list should be, // e.g. the user is searching for something, or showing apps, etc. SetState(AppListState state); // Highlights the given item in the app list. If not present and it is later // added, the item will be highlighted after being added. HighlightItemInstalledFromUI(string id); // Sets whether the search engine is Google or not. SetSearchEngineIsGoogle(bool is_google); // Sets the text for screen readers on the search box, and updates the // accessible names. SetSearchTabletAndClamshellAccessibleName( mojo_base.mojom.String16 tablet_accessible_name, mojo_base.mojom.String16 clamshell_accessible_name); // Sets the hint text to display when there is in input. SetSearchHintText(mojo_base.mojom.String16 hint_text); // Sets the text for the search box's Textfield and the voice search flag. UpdateSearchBox(mojo_base.mojom.String16 text, bool initiated_by_user); // Publishes search results to Ash to render them. PublishSearchResults(array results); // Update the whole model, usually when profile changes happen in Chrome. SetModelData(array apps, bool is_search_engine_google); ////////////////////////////////////////////////////////////////////////////// // Interfaces only used by ChromeAppListItem: // These interfaces are called when an item's data is updated in Chrome. // Updates an item's metadata (e.g. name, position, etc). SetItemMetadata(string id, AppListItemMetadata metadata); // Updates an item's icon. SetItemIcon(string id, gfx.mojom.ImageSkia? icon); // Updates whether an item is installing. SetItemIsInstalling(string id, bool is_installing); // Updates the downloaded percentage of an item. SetItemPercentDownloaded(string id, int32 percent_downloaded); ////////////////////////////////////////////////////////////////////////////// // Interfaces for item querying: // Returns a map from each item's id to its shown index in the app list. GetIdToAppListIndexMap() => (map indices); ////////////////////////////////////////////////////////////////////////////// // Interfaces for AppListSyncableService: // These interfaces are called while dealing with the OEM folder in the // AppListSyncableService in Chrome. // Finds the OEM folder or creates one if it doesn't exist. // |oem_folder_name|: the expected name of the OEM folder while creating. // |preferred_oem_position|: the preferred position of the OEM folder while // creating; if it's invalid then the final position // is determined in Ash. // |oem_folder|: the meta data of the existing/created OEM folder. FindOrCreateOemFolder( string oem_folder_name, syncer.mojom.StringOrdinal preferred_oem_position) => (AppListItemMetadata oem_folder); // Resolves the position of the OEM folder. // |preferred_oem_position|: the preferred position of the OEM folder; if it's // invalid then the final position is determined in // Ash. // |oem_folder|: the meta data of the OEM folder, or null if it doesn't exist. ResolveOemFolderPosition( syncer.mojom.StringOrdinal preferred_oem_position) => (AppListItemMetadata? oem_folder); ////////////////////////////////////////////////////////////////////////////// // Interfaces for ChromeSearchReult: SetSearchResultMetadata(SearchResultMetadata metadata); SetSearchResultIsInstalling(string result_id, bool is_installing); SetSearchResultPercentDownloaded(string result_id, int32 percent_downloaded); NotifySearchResultItemInstalled(string result_id); ////////////////////////////////////////////////////////////////////////////// // Interfaces for views: // Dismisses the app list. DismissAppList(); // Returns bounds of a rectangle to show an AppInfo dialog. GetAppInfoDialogBounds() => (gfx.mojom.Rect bounds); // Shows the app list and switches to |state|. ShowAppListAndSwitchToState(AppListState state); // Shows the app list. ShowAppList(); }; // In contrast to AppListController, this client is implemented in Chrome to // handle calls from Ash. These include: // - When Chrome components are needed to get involved in the user's actions on // app list views. This can happen while the user is searching, clicking on // any app list item, etc. // - When view changes in Ash and we want to notify Chrome. This can happen // while app list is performing animations. // - When a user action on views need information from Chrome to complete. This // can happen while populating context menu models, which depends on item data // in Chrome. interface AppListClient { ////////////////////////////////////////////////////////////////////////////// // Interfaces on searching: // Triggers a search query. // |raw_query|: the unmodified input texts in the search text field. StartSearch(mojo_base.mojom.String16 raw_query); // Opens a search result when its view is clicked or pressed. // |result_id|: the id of the search result the user wants to open. OpenSearchResult(string result_id, int32 event_flags); // Invokes a custom action on a result with |result_id|. // |action_index| corresponds to the index of an action on the search result, // for example, installing. They are stored in SearchResult::actions_. InvokeSearchResultAction(string result_id, int32 action_index, int32 event_flags); // Returns the context menu model for the search result with |result_id|, or // an empty array if there is currently no menu for the result. GetSearchResultContextMenuModel(string result_id) => (array items); // Invoked when a context menu item of a search result is clicked. // |result_id|: the clicked search result's id. // |command_id|: the clicked menu item's command id. // |event_flags|: flags from the event which triggered this command. SearchResultContextMenuItemSelected(string result_id, int32 command_id, int32 event_flags); ////////////////////////////////////////////////////////////////////////////// // Interfaces on the app list UI: // Invoked when the app list is shown in the display with |display_id|. ViewShown(int64 display_id); // Invoked when the app list is closed. ViewClosing(); // Notifies target visibility changes of the app list. OnAppListTargetVisibilityChanged(bool visible); // Notifies visibility changes of the app list. OnAppListVisibilityChanged(bool visible); ////////////////////////////////////////////////////////////////////////////// // Interfaces on app list items: // Activates (opens) the item with |id|. ActivateItem(string id, int32 event_flags); // Returns the context menu model for the item with |id|, or an empty array if // there is currently no menu for the item (e.g. during install). GetContextMenuModel(string id) => (array items); // Invoked when a context menu item of an app list item is clicked. // |id|: the clicked AppListItem's id. // |command_id|: the clicked menu item's command id. // |event_flags|: flags from the event which triggered this command. ContextMenuItemSelected(string id, int32 command_id, int32 event_flags); // Invoked when a folder is created in Ash (e.g. merge items into a folder). OnFolderCreated(AppListItemMetadata folder); // Invoked when a folder has only one item left and so gets removed. OnFolderDeleted(AppListItemMetadata folder); // Invoked when user changes a folder's name or an item's position. OnItemUpdated(AppListItemMetadata folder); ////////////////////////////////////////////////////////////////////////////// // Interfaces on voice interaction: // Starts a voice interaction session. StartVoiceInteractionSession(); // Starts or stops voice interaction session based on current state. ToggleVoiceInteractionSession(); };