| // Copyright 2019 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 COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_ |
| #define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_ |
| |
| // Utility functions for App Service intent handling. |
| |
| #include <string> |
| |
| #include "components/services/app_service/public/cpp/intent.h" |
| #include "components/services/app_service/public/cpp/intent_filter.h" |
| #include "components/services/app_service/public/mojom/types.mojom.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| #include "url/gurl.h" |
| |
| namespace base { |
| class DictionaryValue; |
| class Value; |
| } // namespace base |
| |
| namespace apps_util { |
| |
| extern const char kIntentActionMain[]; |
| extern const char kIntentActionView[]; |
| extern const char kIntentActionSend[]; |
| extern const char kIntentActionSendMultiple[]; |
| extern const char kIntentActionCreateNote[]; |
| extern const char kIntentActionStartOnLockScreen[]; |
| // A request to edit a file in an app. Must include an attached file. |
| extern const char kIntentActionEdit[]; |
| extern const char kIntentActionPotentialFileHandler[]; |
| |
| // App ID value which can be used as a Preferred App to denote that the browser |
| // will open the link, and that we should not prompt the user about it. |
| extern const char kUseBrowserForLink[]; |
| |
| // Activity name for GuestOS intent filters. TODO(crbug/1349974): Remove when |
| // default file handling preferences for Files App are migrated. |
| extern const char kGuestOsActivityName[]; |
| |
| struct SharedText { |
| std::string text; |
| GURL url; |
| }; |
| |
| // Creates an intent for sharing |filesystem_urls|. |filesystem_urls| must be |
| // co-indexed with |mime_types|. |
| apps::IntentPtr MakeShareIntent(const std::vector<GURL>& filesystem_urls, |
| const std::vector<std::string>& mime_types); |
| |
| // Creates an intent for sharing |filesystem_urls|, along with |text| and a |
| // |title|. |filesystem_urls| must be co-indexed with |mime_types|. |
| apps::IntentPtr MakeShareIntent(const std::vector<GURL>& filesystem_urls, |
| const std::vector<std::string>& mime_types, |
| const std::string& text, |
| const std::string& title); |
| |
| // Creates an intent for sharing `filesystem_url`, `mime_type` and |
| // `drive_share_url` for a Google Drive file. |
| apps::IntentPtr MakeShareIntent(const GURL& filesystem_url, |
| const std::string& mime_type, |
| const GURL& drive_share_url, |
| bool is_directory); |
| |
| // Creates an intent for sharing |text|, with |title|. |
| apps::IntentPtr MakeShareIntent(const std::string& text, |
| const std::string& title); |
| |
| // Create an edit intent for the file with a given |filesystem_url| and |
| // |mime_type|. |
| apps::IntentPtr MakeEditIntent(const GURL& filesystem_url, |
| const std::string& mime_type); |
| |
| // Create an intent struct from activity and start type. |
| apps::IntentPtr MakeIntentForActivity(const std::string& activity, |
| const std::string& start_type, |
| const std::string& category); |
| |
| // TODO(crbug.com/1253250): Remove below functions after migrating to non-mojo |
| // AppService. |
| |
| // Create an intent struct from URL. |
| apps::mojom::IntentPtr CreateIntentFromUrl(const GURL& url); |
| |
| // Create an intent struct for a Create Note action. |
| apps::IntentPtr CreateCreateNoteIntent(); |
| |
| // Create an intent struct for a "Start On Lock Screen" action. |
| apps::IntentPtr CreateStartOnLockScreenIntent(); |
| |
| // Create an intent struct with the list of files with action kIntentActionView. |
| apps::mojom::IntentPtr CreateViewIntentFromFiles( |
| std::vector<apps::mojom::IntentFilePtr> files); |
| |
| // Create an intent struct from the filesystem urls and mime types |
| // of a list of files with action kIntentActionSend{Multiple}. |
| apps::mojom::IntentPtr CreateShareIntentFromFiles( |
| const std::vector<GURL>& filesystem_urls, |
| const std::vector<std::string>& mime_types); |
| |
| // Create an intent struct from the filesystem urls, mime types |
| // of a list of files, and the share text and title. |
| apps::mojom::IntentPtr CreateShareIntentFromFiles( |
| const std::vector<GURL>& filesystem_urls, |
| const std::vector<std::string>& mime_types, |
| const std::string& share_text, |
| const std::string& share_title); |
| |
| // Create an intent struct from the filesystem url, mime type |
| // and the drive share url for a Google Drive file. |
| apps::mojom::IntentPtr CreateShareIntentFromDriveFile( |
| const GURL& filesystem_url, |
| const std::string& mime_type, |
| const GURL& drive_share_url, |
| bool is_directory); |
| |
| // Create an intent struct from share text and title. |
| apps::mojom::IntentPtr CreateShareIntentFromText( |
| const std::string& share_text, |
| const std::string& share_title); |
| |
| // Create an edit intent struct for the file with a given filesystem:// URL and |
| // mime type. |
| apps::mojom::IntentPtr CreateEditIntentFromFile(const GURL& filesystem_url, |
| const std::string& mime_type); |
| |
| // Create an intent struct from activity and start type. |
| apps::mojom::IntentPtr CreateIntentForActivity(const std::string& activity, |
| const std::string& start_type, |
| const std::string& category); |
| |
| // Return true if |value| matches with the |condition_value|, based on the |
| // pattern match type in the |condition_value|. |
| bool ConditionValueMatches(const std::string& value, |
| const apps::ConditionValuePtr& condition_value); |
| |
| // Return true if |value| matches with the |condition_value|, based on the |
| // pattern match type in the |condition_value|. |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool ConditionValueMatches( |
| const std::string& value, |
| const apps::mojom::ConditionValuePtr& condition_value); |
| |
| // Return true if |intent| matches with any of the values in |condition|. |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool IntentMatchesCondition(const apps::mojom::IntentPtr& intent, |
| const apps::mojom::ConditionPtr& condition); |
| |
| // Return true if a |filter| matches an |intent|. This is true when intent |
| // matches all existing conditions in the filter. |
| bool IntentMatchesFilter(const apps::mojom::IntentPtr& intent, |
| const apps::mojom::IntentFilterPtr& filter); |
| |
| // Return true if |filter| only contains file extension pattern matches. |
| bool FilterIsForFileExtensions(const apps::mojom::IntentFilterPtr& filter); |
| |
| bool IsGenericFileHandler(const apps::IntentPtr& intent, |
| const apps::IntentFilterPtr& filter); |
| |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool IsGenericFileHandler(const apps::mojom::IntentPtr& intent, |
| const apps::mojom::IntentFilterPtr& filter); |
| |
| // Return true if `intent` corresponds to a share intent. |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool IsShareIntent(const apps::mojom::IntentPtr& intent); |
| |
| // Return true if |value| matches |pattern| with simple glob syntax. |
| // In this syntax, you can use the '*' character to match against zero or |
| // more occurrences of the character immediately before. If the character |
| // before it is '.' it will match any character. The character '\' can be |
| // used as an escape. This essentially provides only the '*' wildcard part |
| // of a normal regexp. |
| // This function is transcribed from android's PatternMatcher#matchPattern. |
| // See |
| // https://android.googlesource.com/platform/frameworks/base.git/+/e93165456c3c28278f275566bd90bfbcf1a0e5f7/core/java/android/os/PatternMatcher.java#186 |
| bool MatchGlob(const std::string& value, const std::string& pattern); |
| |
| // TODO(crbug.com/1092784): Handle file path with extension with mime type. |
| // Unlike Android mime type matching logic, if the intent mime type has *, it |
| // can only match with *, not anything. The reason for this is the way we find |
| // the common mime type for multiple files. It uses * to represent more than one |
| // types in the list, which will cause an issue if we treat that as we want to |
| // match with any filter. e.g. If we select a .zip, .jep and a .txt, the common |
| // mime type will be */*, with Android matching logic, it will match with filter |
| // that has mime type video, which is not what we expected. |
| bool MimeTypeMatched(const std::string& intent_mime_type, |
| const std::string& filter_mime_type); |
| |
| bool ExtensionMatched(const std::string& file_name, |
| const std::string& filter_extension); |
| |
| // Check if the intent only mean to share to Google Drive. |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool OnlyShareToDrive(const apps::mojom::IntentPtr& intent); |
| |
| // Check the if the intent is valid, e.g. action matches content. |
| // TODO(crbug.com/1253250): Remove this function after migrating to non-mojo |
| // AppService. |
| bool IsIntentValid(const apps::mojom::IntentPtr& intent); |
| |
| // Converts |intent| to base::Value, e.g.: |
| // { |
| // "action": "xx", |
| // "url": "abc.com", |
| // "mime_type": "text/plain", |
| // "file_urls": "/abc, /a", |
| // "activity_name": "yy", |
| // "drive_share_url": "aa.com", |
| // "share_text": "text", |
| // "share_title": "title", |
| // } |
| base::Value ConvertIntentToValue(const apps::IntentPtr& intent); |
| |
| // Gets the string value from base::DictionaryValue, e.g. { "key": "value" } |
| // returns "value". |
| absl::optional<std::string> GetStringValueFromDict( |
| const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| // Gets absl::optional<bool> value from base::DictionaryValue, e.g. { |
| // "key": "value" } returns "value". |
| absl::optional<bool> GetBoolValueFromDict(const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| // Gets GURL from base::DictionaryValue, e.g. { "url": "abc.com" } returns |
| // "abc.com". |
| absl::optional<GURL> GetGurlValueFromDict(const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| // Gets std::vector<IntentFilePtr> from base::DictionaryValue, e.g. { |
| // "file_urls": "/abc, /a" } returns |
| // std::vector<apps::IntentFilePtr>{"/abc", "/a"}. |
| std::vector<apps::IntentFilePtr> GetFilesFromDict( |
| const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| std::vector<std::string> GetCategoriesFromDict( |
| const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| base::flat_map<std::string, std::string> GetExtrasFromDict( |
| const base::DictionaryValue& dict, |
| const std::string& key_name); |
| |
| // Converts base::Value to Intent. Returns nullptr for invalid base::Values. |
| apps::IntentPtr ConvertValueToIntent(base::Value&& value); |
| |
| // Calculates the least general mime type that matches all of the given ones. |
| // E.g., for ["image/jpeg", "image/png"] it will be "image/*". ["text/html", |
| // "text/html"] will return "text/html", and ["text/html", "image/jpeg"] |
| // becomes the fully wildcard pattern. |
| std::string CalculateCommonMimeType(const std::vector<std::string>& mime_types); |
| |
| // Extracts the text from |share_text| to populate the SharedText struct. If |
| // |SharedText.url| is populated, the value will always be a valid parsed URL. |
| // The |share_text| passed in here should be the share_text field from |
| // apps::mojom::IntentPtr. |
| // |
| // Testing covered by share_target_utils_unittest.cc as this function was |
| // migrated out from web_app::ShareTargetUtils. |
| SharedText ExtractSharedText(const std::string& share_text); |
| |
| } // namespace apps_util |
| |
| #endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_ |