[IntentHandling] Convert ARC intent filter action and mime types.

This CL converts the ARC intent filter action and mime types in to app
service intent filter struct. The match intent with intent filter logic
and intent filter overlap logic for preferred apps will not work fully
anymore, so the conversion is put behind a flag to avoid breaking
current intent picker feature.

BUG=1092784

Change-Id: I9d81fdf10b4be3f74ef8648514feb12283231880
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2237544
Commit-Queue: Maggie Cai <[email protected]>
Reviewed-by: Dominick Ng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#777665}
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index dedb830..1d1958b 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4636,6 +4636,10 @@
      flag_descriptions::kIntentPickerPWAPersistenceName,
      flag_descriptions::kIntentPickerPWAPersistenceDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kIntentPickerPWAPersistence)},
+
+    {"intent-handling-sharing", flag_descriptions::kIntentHandlingSharingName,
+     flag_descriptions::kIntentHandlingSharingDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(features::kIntentHandlingSharing)},
 #endif  // defined(OS_CHROMEOS)
 
 #if defined(OS_WIN)
diff --git a/chrome/browser/apps/app_service/arc_apps.cc b/chrome/browser/apps/app_service/arc_apps.cc
index 13917cab..501b6f6 100644
--- a/chrome/browser/apps/app_service/arc_apps.cc
+++ b/chrome/browser/apps/app_service/arc_apps.cc
@@ -28,9 +28,11 @@
 #include "chrome/grit/generated_resources.h"
 #include "components/arc/app_permissions/arc_app_permissions_bridge.h"
 #include "components/arc/arc_service_manager.h"
+#include "components/arc/intent_helper/intent_constants.h"
 #include "components/arc/mojom/app_permissions.mojom.h"
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/services/app_service/public/cpp/intent_filter_util.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
 #include "content/public/browser/system_connector.h"
 #include "extensions/grit/extensions_browser_resources.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -173,6 +175,30 @@
     const arc::IntentFilter& arc_intent_filter) {
   auto intent_filter = apps::mojom::IntentFilter::New();
 
+  if (base::FeatureList::IsEnabled(features::kIntentHandlingSharing)) {
+    std::vector<apps::mojom::ConditionValuePtr> action_condition_values;
+    for (auto& arc_action : arc_intent_filter.actions()) {
+      std::string action;
+      if (arc_action == arc::kIntentActionView) {
+        action = apps_util::kIntentActionView;
+      } else if (arc_action == arc::kIntentActionSend) {
+        action = apps_util::kIntentActionSend;
+      } else if (arc_action == arc::kIntentActionSendMultiple) {
+        action = apps_util::kIntentActionSendMultiple;
+      } else {
+        continue;
+      }
+      action_condition_values.push_back(apps_util::MakeConditionValue(
+          action, apps::mojom::PatternMatchType::kNone));
+    }
+    if (!action_condition_values.empty()) {
+      auto action_condition =
+          apps_util::MakeCondition(apps::mojom::ConditionType::kAction,
+                                   std::move(action_condition_values));
+      intent_filter->conditions.push_back(std::move(action_condition));
+    }
+  }
+
   std::vector<apps::mojom::ConditionValuePtr> scheme_condition_values;
   for (auto& scheme : arc_intent_filter.schemes()) {
     scheme_condition_values.push_back(apps_util::MakeConditionValue(
@@ -219,6 +245,20 @@
     intent_filter->conditions.push_back(std::move(path_condition));
   }
 
+  if (base::FeatureList::IsEnabled(features::kIntentHandlingSharing)) {
+    std::vector<apps::mojom::ConditionValuePtr> mime_type_condition_values;
+    for (auto& mime_type : arc_intent_filter.mime_types()) {
+      mime_type_condition_values.push_back(apps_util::MakeConditionValue(
+          mime_type, apps::mojom::PatternMatchType::kNone));
+    }
+    if (!mime_type_condition_values.empty()) {
+      auto mime_type_condition =
+          apps_util::MakeCondition(apps::mojom::ConditionType::kMimeType,
+                                   std::move(mime_type_condition_values));
+      intent_filter->conditions.push_back(std::move(mime_type_condition));
+    }
+  }
+
   return intent_filter;
 }
 
@@ -265,6 +305,10 @@
               condition_value->value, match_type));
         }
         break;
+      // TODO(crbug.com/1092784): Handle action and mime type.
+      case apps::mojom::ConditionType::kAction:
+      case apps::mojom::ConditionType::kMimeType:
+        NOTIMPLEMENTED();
     }
   }
   // TODO(crbug.com/853604): Add support for other action and category types.
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 0f46d34..9908362 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -2854,6 +2854,11 @@
     "expiry_milestone": -1
   },
   {
+    "name": "intent-handling-sharing",
+    "owners": [ "[email protected]" ],
+    "expiry_milestone": 90
+  },
+  {
     "name": "intent-picker-pwa-persistence",
     "owners": [ "[email protected]" ],
     "expiry_milestone": 88
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e48efdc6..c0d31d7 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3750,6 +3750,10 @@
 const char kImeServiceSandboxDescription[] =
     "Controls whether the IME service on CrOS uses the 'ime' sandbox.";
 
+const char kIntentHandlingSharingName[] = "Intent handling for sharing";
+const char kIntentHandlingSharingDescription[] =
+    "Support sharing in Chrome OS intent handling.";
+
 const char kIntentPickerPWAPersistenceName[] = "Intent picker PWA Persistence";
 const char kIntentPickerPWAPersistenceDescription[] =
     "Allow user to always open with PWA in intent picker.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 8a9a88a..2ca6afb 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2202,6 +2202,9 @@
 extern const char kImeServiceSandboxName[];
 extern const char kImeServiceSandboxDescription[];
 
+extern const char kIntentHandlingSharingName[];
+extern const char kIntentHandlingSharingDescription[];
+
 extern const char kIntentPickerPWAPersistenceName[];
 extern const char kIntentPickerPWAPersistenceDescription[];
 
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index b7e64c66..a59df95 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -442,6 +442,9 @@
 #endif
 
 #if !defined(OS_ANDROID)
+// Support sharing in Chrome OS intent handling.
+const base::Feature kIntentHandlingSharing{"IntentHandlingSharing",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
 // Allow user to have preference for PWA in the intent picker.
 const base::Feature kIntentPickerPWAPersistence{
     "IntentPickerPWAPersistence", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 081c534..fa2b28d 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -268,6 +268,8 @@
 
 #if !defined(OS_ANDROID)
 COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kIntentHandlingSharing;
+COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kIntentPickerPWAPersistence;
 #endif  // !defined(OS_ANDROID)
 
diff --git a/components/services/app_service/public/cpp/intent_filter_util.cc b/components/services/app_service/public/cpp/intent_filter_util.cc
index 0b020a6d..b92207bc 100644
--- a/components/services/app_service/public/cpp/intent_filter_util.cc
+++ b/components/services/app_service/public/cpp/intent_filter_util.cc
@@ -87,6 +87,10 @@
       case apps::mojom::ConditionType::kPattern:
         match_level += IntentFilterMatchLevel::kPattern;
         break;
+      // TODO(crbug.com/1092784): Handle action and mime type.
+      case apps::mojom::ConditionType::kAction:
+      case apps::mojom::ConditionType::kMimeType:
+        NOTIMPLEMENTED();
     }
   }
   return match_level;
diff --git a/components/services/app_service/public/cpp/intent_util.cc b/components/services/app_service/public/cpp/intent_util.cc
index 9bbdf5a..cb8ab63 100644
--- a/components/services/app_service/public/cpp/intent_util.cc
+++ b/components/services/app_service/public/cpp/intent_util.cc
@@ -22,6 +22,11 @@
       return intent->host;
     case apps::mojom::ConditionType::kPattern:
       return intent->path;
+    // TODO(crbug.com/1092784): Handle action and mime type.
+    case apps::mojom::ConditionType::kAction:
+    case apps::mojom::ConditionType::kMimeType:
+      NOTIMPLEMENTED();
+      return base::nullopt;
   }
 }
 
@@ -29,6 +34,10 @@
 
 namespace apps_util {
 
+const char kIntentActionView[] = "view";
+const char kIntentActionSend[] = "send";
+const char kIntentActionSendMultiple[] = "send_multiple";
+
 apps::mojom::IntentPtr CreateIntentFromUrl(const GURL& url) {
   auto intent = apps::mojom::Intent::New();
   intent->scheme = url.scheme();
diff --git a/components/services/app_service/public/cpp/intent_util.h b/components/services/app_service/public/cpp/intent_util.h
index 144cb93..0b9e8ba 100644
--- a/components/services/app_service/public/cpp/intent_util.h
+++ b/components/services/app_service/public/cpp/intent_util.h
@@ -15,6 +15,10 @@
 
 namespace apps_util {
 
+extern const char kIntentActionView[];
+extern const char kIntentActionSend[];
+extern const char kIntentActionSendMultiple[];
+
 // Create an intent struct from URL.
 apps::mojom::IntentPtr CreateIntentFromUrl(const GURL& url);
 
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom
index 4740e99f..fd0e679 100644
--- a/components/services/app_service/public/mojom/types.mojom
+++ b/components/services/app_service/public/mojom/types.mojom
@@ -254,6 +254,8 @@
   kScheme,    // Matches the URL scheme (e.g. https, tel).
   kHost,      // Matches the URL host (e.g. www.google.com).
   kPattern,   // Matches the URL pattern (e.g. /abc/*).
+  kAction,    // Matches the action type (e.g. view, send).
+  kMimeType,  // Matches the data mime type (e.g. image/jpeg).
 };
 
 // The pattern match type for intent filter pattern condition.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 0499ecdb..ff2e75d 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -40698,6 +40698,7 @@
   <int value="79595680" label="OmniboxTabSwitchSuggestions:enabled"/>
   <int value="79729295" label="WebBundles:enabled"/>
   <int value="82303171" label="AccountIdMigration:disabled"/>
+  <int value="82816692" label="IntentHandlingSharing:disabled"/>
   <int value="83422372"
       label="ChromeHomePersonalizedOmniboxSuggestions:enabled"/>
   <int value="84911198" label="ScanCardsInWebPayments:disabled"/>
@@ -41835,6 +41836,7 @@
   <int value="1373777956" label="disable-threaded-gpu-rasterization"/>
   <int value="1375165388" label="LazyFrameLoading:enabled"/>
   <int value="1376437124" label="show-cert-link"/>
+  <int value="1376446149" label="IntentHandlingSharing:enabled"/>
   <int value="1377056573" label="browser-side-navigation:enabled"/>
   <int value="1378310092" label="disable-suggestions-service"/>
   <int value="1379571437" label="ExoPointerLock:disabled"/>