1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
// Copyright 2019 The Chromium Authors
// 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 <optional>
#include <string>
#include <string_view>
#include "base/values.h"
#include "components/services/app_service/public/cpp/intent.h"
#include "components/services/app_service/public/cpp/intent_filter.h"
#include "url/gurl.h"
#include "url/origin.h"
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.com/40233967): 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);
// Creates an intent for sharing |filesystem_urls|, with |dlpSourceUrls|.
apps::IntentPtr MakeShareIntent(
const std::vector<GURL>& filesystem_urls,
const std::vector<std::string>& mime_types,
const std::vector<std::string>& dlp_source_urls);
// 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);
// 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();
// Return true if |value| matches with the |condition_value|, based on the
// pattern match type in the |condition_value|.
bool ConditionValueMatches(std::string_view value,
const apps::ConditionValuePtr& condition_value);
bool PatternMatchValue(std::string_view test_value,
apps::PatternMatchType match_type,
std::string_view match_value);
bool IsGenericFileHandler(const apps::IntentPtr& intent,
const apps::IntentFilterPtr& filter);
// 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(std::string_view value, std::string_view pattern);
// TODO(crbug.com/40134747): 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(std::string_view intent_mime_type,
std::string_view filter_mime_type);
bool ExtensionMatched(const std::string& file_name,
const std::string& filter_extension);
// 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);
// Converts base::Value to Intent. Returns nullptr for invalid base::Values.
apps::IntentPtr ConvertValueToIntent(base::Value&& value);
apps::IntentPtr ConvertDictToIntent(const base::Value::Dict& dict);
// 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 Intent.
//
// 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);
// A view object onto a host and optional port string, represents the same thing
// as arc::IntentFilter::AuthorityEntry with an emphasis on string
// encoding/decoding for use with ConditionValue's std::string value.
// The underlying strings must be kept alive while the AuthorityView is around.
struct AuthorityView {
const std::string_view host;
const std::optional<std::string_view> port;
// Stringifies the effective port of `url` if there is one. Not all URL
// schemes have ports.
static std::optional<std::string> PortToString(const GURL& url);
static std::optional<std::string> PortToString(const url::Origin& url);
// Decodes strings of the form:
// "www.example.com:1234" into {.host="www.example.com", .port="1234"}
// or "www.example.com" into {.host="www.example.com", .port=nullopt}
static AuthorityView Decode(std::string_view);
// Delegates to Encode().
static std::string Encode(const GURL& url);
static std::string Encode(const url::Origin& origin);
// Encodes into the form:
// "www.example.com:1234" if port is set
// or "www.example.com" if port is unset.
// Note that the default scheme port will be used even if not explicitly
// specified e.g.: Encode(GURL("https://www.foo.com")) == "www.foo.com:443"
std::string Encode();
};
} // namespace apps_util
#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_
|