From: uazo Date: Sun, 3 Oct 2021 16:18:24 +0000 Subject: Enable share intent This patch allows to activate the management of android.intent.action.SEND with new flag "shared-intent-ui" default active. See also: https://github.com/bromite/bromite/issues/1062 Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html --- chrome/android/chrome_java_resources.gni | 1 + chrome/android/chrome_java_sources.gni | 1 + chrome/android/java/AndroidManifest.xml | 18 +++ .../res/layout/sharing_intent_content.xml | 83 ++++++++++++ .../init/ProcessInitializationHandler.java | 3 + .../SharedIntentShareActivity.java | 118 ++++++++++++++++++ chrome/browser/about_flags.cc | 4 + chrome/browser/flag_descriptions.cc | 5 + chrome/browser/flag_descriptions.h | 3 + .../flags/android/chrome_feature_list.cc | 4 + .../flags/android/chrome_feature_list.h | 1 + .../browser/flags/ChromeFeatureList.java | 1 + .../strings/android_chrome_strings.grd | 13 ++ 13 files changed, 255 insertions(+) create mode 100644 chrome/android/java/res/layout/sharing_intent_content.xml create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_intent/SharedIntentShareActivity.java diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni @@ -596,6 +596,7 @@ chrome_java_resources = [ "java/res/layout/signin_activity.xml", "java/res/layout/status_indicator_container.xml", "java/res/layout/suggestions_tile_view_condensed.xml", + "java/res/layout/sharing_intent_content.xml", "java/res/layout/suspended_tab.xml", "java/res/layout/sync_custom_passphrase.xml", "java/res/layout/sync_enter_passphrase.xml", diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni @@ -963,6 +963,7 @@ chrome_java_sources = [ "java/src/org/chromium/chrome/browser/sharing/click_to_call/ClickToCallUma.java", "java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardMessageHandler.java", "java/src/org/chromium/chrome/browser/sharing/sms_fetcher/SmsFetcherMessageHandler.java", + "java/src/org/chromium/chrome/browser/sharing/shared_intent/SharedIntentShareActivity.java", "java/src/org/chromium/chrome/browser/site_settings/ChromeSiteSettingsDelegate.java", "java/src/org/chromium/chrome/browser/site_settings/CookieControlsServiceBridge.java", "java/src/org/chromium/chrome/browser/site_settings/ManageSpaceActivity.java", diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml @@ -739,6 +739,24 @@ by a child template that "extends" this file. android:process=":browser_restart_process"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java @@ -81,6 +81,7 @@ import org.chromium.chrome.browser.searchwidget.SearchWidgetProvider; import org.chromium.chrome.browser.tab.state.PersistedTabData; import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityPreferencesManager; +import org.chromium.chrome.browser.sharing.shared_intent.SharedIntentShareActivity; import org.chromium.chrome.browser.usb.UsbNotificationManager; import org.chromium.chrome.browser.util.AfterStartupTaskUtils; import org.chromium.chrome.browser.webapps.WebappRegistry; @@ -408,6 +409,8 @@ public class ProcessInitializationHandler { .resolveClearDataDialogResultRecorder()::makeDeferredRecordings); deferredStartupHandler.addDeferredTask(WebApkUninstallUmaTracker::recordDeferredUma); + deferredStartupHandler.addDeferredTask( + () -> SharedIntentShareActivity.updateComponentEnabledState()); deferredStartupHandler.addDeferredTask( () -> IncognitoTabLauncher.updateComponentEnabledState()); deferredStartupHandler.addDeferredTask( diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_intent/SharedIntentShareActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_intent/SharedIntentShareActivity.java new file mode 100644 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/sharing/shared_intent/SharedIntentShareActivity.java @@ -0,0 +1,118 @@ +// 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. + +package org.chromium.chrome.browser.sharing.shared_intent; + +import org.chromium.base.Log; + +import android.content.res.Resources; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.view.View; +import android.widget.TextView; +import android.net.Uri; + +import org.chromium.base.ContextUtils; +import org.chromium.base.IntentUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.base.task.PostTask; +import org.chromium.base.task.TaskTraits; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; +import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.init.AsyncInitializationActivity; +import org.chromium.chrome.browser.LaunchIntentDispatcher; +import org.chromium.chrome.browser.IntentHandler; +import org.chromium.ui.widget.ButtonCompat; + +/** + * Activity to display device targets to share text. + */ +public class SharedIntentShareActivity + extends AsyncInitializationActivity { + + /** + * Checks whether sending shared clipboard message is enabled for the user and enables/disables + * the SharedIntentShareActivity appropriately. This call requires native to be loaded. + */ + public static void updateComponentEnabledState() { + boolean enabled = ChromeFeatureList.isEnabled(ChromeFeatureList.SHARED_INTENT_UI); + PostTask.postTask(TaskTraits.USER_VISIBLE, () -> setComponentEnabled(enabled)); + } + + /** + * Sets whether or not the SharedIntentShareActivity should be enabled. This may trigger a + * StrictMode violation so shouldn't be called on the UI thread. + */ + private static void setComponentEnabled(boolean enabled) { + ThreadUtils.assertOnBackgroundThread(); + Context context = ContextUtils.getApplicationContext(); + PackageManager packageManager = context.getPackageManager(); + ComponentName componentName = + new ComponentName(context, SharedIntentShareActivity.class); + + int newState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED + : PackageManager.COMPONENT_ENABLED_STATE_DISABLED; + + // This indicates that we don't want to kill Chrome when changing component enabled state. + int flags = PackageManager.DONT_KILL_APP; + + if (packageManager.getComponentEnabledSetting(componentName) != newState) { + packageManager.setComponentEnabledSetting(componentName, newState, flags); + } + } + + @Override + protected void triggerLayoutInflation() { + setContentView(R.layout.sharing_intent_content); + + String linkUrl = IntentUtils.safeGetStringExtra(getIntent(), Intent.EXTRA_TEXT); + Resources resources = ContextUtils.getApplicationContext().getResources(); + TextView share_message_text = findViewById(R.id.share_message_text); + share_message_text.setText( + resources.getString(R.string.shared_intent_share_activity_text, linkUrl)); + + View mask = findViewById(R.id.mask); + mask.setOnClickListener(v -> finish()); + + ButtonCompat open_url_button = findViewById(R.id.open_url_button); + open_url_button.setVisibility(View.VISIBLE); + open_url_button.setOnClickListener(view -> { + Context applicationContext = ContextUtils.getApplicationContext(); + Intent chromeIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl)); + chromeIntent.setPackage(applicationContext.getPackageName()); + chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + LaunchIntentDispatcher.dispatch(this, chromeIntent); + finish(); + }); + + ButtonCompat open_url_incognito_button = findViewById(R.id.open_url_incognito_button); + open_url_incognito_button.setVisibility(View.VISIBLE); + open_url_incognito_button.setOnClickListener(view -> { + Context applicationContext = ContextUtils.getApplicationContext(); + Intent chromeIntent = IntentHandler.createTrustedOpenNewTabIntent(applicationContext, + /*incognito*/true); + + chromeIntent.setData(Uri.parse(linkUrl)); + chromeIntent.setPackage(applicationContext.getPackageName()); + chromeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + LaunchIntentDispatcher.dispatch(this, chromeIntent); + finish(); + }); + + if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) + open_url_incognito_button.setVisibility(View.GONE); + + onInitialLayoutInflationComplete(); + } + + @Override + public boolean shouldStartGpuProcess() { + return false; + } +} diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -6434,6 +6434,10 @@ const FeatureEntry kFeatureEntries[] = { #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_ANDROID) + {"shared-intent-ui", flag_descriptions::kSharedIntentUIName, + flag_descriptions::kSharedIntentUIDescription, kOsAll, + FEATURE_VALUE_TYPE(chrome::android::kSharedIntentUI)}, + {"ntp-tiles-title-wrap-around", flag_descriptions::kNewTabPageTilesTitleWrapAroundName, flag_descriptions::kNewTabPageTilesTitleWrapAroundDescription, kOsAndroid, diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc @@ -2626,6 +2626,11 @@ const char kIsolateOriginsDescription[] = "Requires dedicated processes for an additional set of origins, " "specified as a comma-separated list."; +const char kSharedIntentUIName[] = + "Enable shared feature"; +const char kSharedIntentUIDescription[] = + "Enables shared feature"; + const char kIsolationByDefaultName[] = "Change web-facing behaviors that prevent origin-level isolation"; const char kIsolationByDefaultDescription[] = diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h @@ -1487,6 +1487,9 @@ extern const char kIsolateOriginsDescription[]; extern const char kIsolationByDefaultName[]; extern const char kIsolationByDefaultDescription[]; +extern const char kSharedIntentUIName[]; +extern const char kSharedIntentUIDescription[]; + extern const char kWebViewTagSiteIsolationName[]; extern const char kWebViewTagSiteIsolationDescription[]; diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc @@ -281,6 +281,7 @@ const base::Feature* const kFeaturesExposedToJava[] = { &kRelatedSearchesAlternateUx, &kRelatedSearchesInBar, &kRelatedSearchesSimplifiedUx, + &kSharedIntentUI, &kRelatedSearchesUi, &kRequestDesktopSiteDefaults, &kSafeModeForCachedFlags, @@ -744,6 +745,9 @@ const base::Feature kNewInstanceFromDraggedLink{ const base::Feature kNewTabPageTilesTitleWrapAround{ "NewTabPageTilesTitleWrapAround", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSharedIntentUI{ + "SharedIntentUI", base::FEATURE_ENABLED_BY_DEFAULT}; + const base::Feature kNewWindowAppMenu{"NewWindowAppMenu", base::FEATURE_ENABLED_BY_DEFAULT}; diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h @@ -140,6 +140,7 @@ extern const base::Feature kRequestDesktopSiteDefaults; extern const base::Feature kSearchEnginePromoExistingDevice; extern const base::Feature kSearchEnginePromoExistingDeviceV2; extern const base::Feature kSearchEnginePromoNewDevice; +extern const base::Feature kSharedIntentUI; extern const base::Feature kSearchReadyOmniboxFeature; extern const base::Feature kSearchEnginePromoNewDeviceV2; extern const base::Feature kShareButtonInTopToolbar; diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java @@ -501,6 +501,7 @@ public abstract class ChromeFeatureList { public static final String QUIET_NOTIFICATION_PROMPTS = "QuietNotificationPrompts"; public static final String REACHED_CODE_PROFILER = "ReachedCodeProfiler"; public static final String READ_LATER = "ReadLater"; + public static final String SHARED_INTENT_UI = "SharedIntentUI"; public static final String READER_MODE_IN_CCT = "ReaderModeInCCT"; public static final String RECOVER_FROM_NEVER_SAVE_ANDROID = "RecoverFromNeverSaveAndroid"; public static final String REENGAGEMENT_NOTIFICATION = "ReengagementNotification"; diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd @@ -4846,6 +4846,19 @@ To change this setting, <resetlink>reset sync

+ + Open URL with Bromite + + + Will open %1$s with Bromite + + + Open with Bromite + + + Open with Bromite Incognito + + Submit %1$s123 on %2$sZoe's Macbook? -- 2.25.1