Commit 2ba53700 authored by Pavel Shmakov's avatar Pavel Shmakov Committed by Commit Bot

Enable opening site-settings in Chrome as a manage space activity for apps hosting TWAs

Android Apps can choose an Activity that Android Settings will link to
when the user presses "Manage Data" for that app. This CL, plus the
corresponding one to Custom Tabs library, https://crrev.com/c/1331527,
gives TWA developers the option to link to Chrome's site-settings for
the origin their app is verified with.

Bug: 888958
Change-Id: Ie003feb42c8fe82e75574ff0da6ac01ce577a72e
Reviewed-on: https://chromium-review.googlesource.com/c/1329978
Commit-Queue: Pavel Shmakov <pshmakov@chromium.org>
Reviewed-by: default avatarYusuf Ozuysal <yusufo@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Reviewed-by: default avatarRobert Sesek <rsesek@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610009}
parent 3a6f12a2
...@@ -666,7 +666,7 @@ deps = { ...@@ -666,7 +666,7 @@ deps = {
}, },
'src/third_party/custom_tabs_client/src': { 'src/third_party/custom_tabs_client/src': {
'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '4c092f007199e64798a0c6d48c4a847758392952', 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '23a570c65c45ad19725b53359c2556156b9a4363',
'condition': 'checkout_android', 'condition': 'checkout_android',
}, },
......
...@@ -841,6 +841,17 @@ by a child template that "extends" this file. ...@@ -841,6 +841,17 @@ by a child template that "extends" this file.
android:exported="false"> android:exported="false">
</service> </service>
<activity
android:name="org.chromium.chrome.browser.browserservices.ManageTrustedWebActivityDataActivity"
android:theme="@style/FullscreenTransparentActivityTheme"
android:exported="true">
<intent-filter>
<action android:name="android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https"/>
</intent-filter>
</activity>
<!-- Service for decoding images in a sandboxed process. --> <!-- Service for decoding images in a sandboxed process. -->
<service <service
android:description="@string/decoder_description" android:description="@string/decoder_description"
......
// 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.
package org.chromium.chrome.browser.browserservices;
import android.os.Bundle;
import android.support.customtabs.CustomTabsService;
import android.support.customtabs.CustomTabsSessionToken;
import android.support.customtabs.TrustedWebUtils;
import android.support.v7.app.AppCompatActivity;
import org.chromium.base.Log;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
import org.chromium.chrome.browser.preferences.PreferencesLauncher;
/**
* Launched by {@link android.support.customtabs.TrustedWebUtils#launchBrowserSiteSettings}.
* Verifies that url provided in intent has valid Digital Asset Link with the calling application,
* and if successful, launches site-settings activity for that url.
*/
public class ManageTrustedWebActivityDataActivity extends AppCompatActivity {
private static final String TAG = "TwaDataActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (LibraryLoader.getInstance().isInitialized()) {
verifyOriginAndLaunchSettings();
} else {
logNativeNotLoaded();
}
finish();
}
private void verifyOriginAndLaunchSettings() {
Origin origin = new Origin(getIntent().getData());
if (isVerifiedOrigin(origin)) {
startActivity(PreferencesLauncher.createIntentForSingleWebsitePreferences(this,
origin.toString()));
} else {
logVerificationFailed();
}
}
private boolean isVerifiedOrigin(Origin origin) {
CustomTabsSessionToken session =
CustomTabsSessionToken.getSessionTokenFromIntent(getIntent());
if (session == null) {
return false;
}
CustomTabsConnection connection =
ChromeApplication.getComponent().resolveCustomTabsConnection();
String clientPackageName = connection.getClientPackageNameForSession(session);
if (clientPackageName == null) {
return false;
}
// We expect that origin has been verified on the client side, and here we synchronously
// check if a result of a successful verification has been cached.
return OriginVerifier.isValidOrigin(clientPackageName, origin,
CustomTabsService.RELATION_HANDLE_ALL_URLS);
}
private void logNativeNotLoaded() {
Log.e(TAG, "Chrome's native libraries not initialized. Please call CustomTabsClient#warmup"
+ " before TrustedWebUtils#launchBrowserSiteSettings.");
}
private void logVerificationFailed() {
Log.e(TAG, "Failed to verify " + getIntent().getData() + " while launching site settings."
+ " Please use CustomTabsSession#validateRelationship to verify this origin"
+ " before launching an intent with "
+ TrustedWebUtils.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA);
}
}
...@@ -38,7 +38,6 @@ import org.chromium.chrome.browser.modelutil.PropertyObservable.PropertyObserver ...@@ -38,7 +38,6 @@ import org.chromium.chrome.browser.modelutil.PropertyObservable.PropertyObserver
import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory;
import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions;
import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
...@@ -164,9 +163,8 @@ public class PersistentNotificationView implements Destroyable, PropertyObserver ...@@ -164,9 +163,8 @@ public class PersistentNotificationView implements Destroyable, PropertyObserver
} }
private PendingIntent makeManageDataIntent() { private PendingIntent makeManageDataIntent() {
Intent settingsIntent = PreferencesLauncher.createIntentForSettingsPage(mAppContext, Intent settingsIntent = PreferencesLauncher.createIntentForSingleWebsitePreferences(
SingleWebsitePreferences.class.getName(), mAppContext, mOrigin.toString());
SingleWebsitePreferences.createFragmentArgsForSite(mOrigin.toString()));
return PendingIntent.getActivity(mAppContext, 0, settingsIntent, FLAG_UPDATE_CURRENT); return PendingIntent.getActivity(mAppContext, 0, settingsIntent, FLAG_UPDATE_CURRENT);
} }
......
...@@ -762,7 +762,12 @@ public class CustomTabsConnection { ...@@ -762,7 +762,12 @@ public class CustomTabsConnection {
CustomTabsSessionToken sessionToken, int relation, Origin origin, Bundle extras) { CustomTabsSessionToken sessionToken, int relation, Origin origin, Bundle extras) {
// Essential parts of the verification will depend on native code and will be run sync on UI // Essential parts of the verification will depend on native code and will be run sync on UI
// thread. Make sure the client has called warmup() beforehand. // thread. Make sure the client has called warmup() beforehand.
if (!mWarmupHasBeenCalled.get()) return false; if (!mWarmupHasBeenCalled.get()) {
Log.d(TAG, "Verification failed due to warmup not having been previously called.");
mClientManager.getCallbackForSession(sessionToken).onRelationshipValidationResult(
relation, Uri.parse(origin.toString()), false, null);
return false;
}
return mClientManager.validateRelationship(sessionToken, relation, origin, extras); return mClientManager.validateRelationship(sessionToken, relation, origin, extras);
} }
......
...@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.dependency_injection; ...@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.dependency_injection;
import org.chromium.chrome.browser.AppHooksModule; import org.chromium.chrome.browser.AppHooksModule;
import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule;
import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor;
import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityComponent; import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityComponent;
import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityModule; import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityModule;
import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
...@@ -28,6 +29,8 @@ public interface ChromeAppComponent { ...@@ -28,6 +29,8 @@ public interface ChromeAppComponent {
ContextualSuggestionsModule contextualSuggestionsModule, ContextualSuggestionsModule contextualSuggestionsModule,
CustomTabActivityModule customTabActivityModule); CustomTabActivityModule customTabActivityModule);
CustomTabsConnection resolveCustomTabsConnection();
// Temporary getters for DI migration process. All of these getters // Temporary getters for DI migration process. All of these getters
// should eventually be replaced with constructor injection. // should eventually be replaced with constructor injection.
EnabledStateMonitor resolveContextualSuggestionsEnabledStateMonitor(); EnabledStateMonitor resolveContextualSuggestionsEnabledStateMonitor();
......
...@@ -15,6 +15,7 @@ import org.chromium.base.annotations.CalledByNative; ...@@ -15,6 +15,7 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.AppHooks;
import org.chromium.chrome.browser.preferences.autofill.AutofillPaymentMethodsFragment; import org.chromium.chrome.browser.preferences.autofill.AutofillPaymentMethodsFragment;
import org.chromium.chrome.browser.preferences.autofill.AutofillProfilesFragment; import org.chromium.chrome.browser.preferences.autofill.AutofillProfilesFragment;
import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences;
import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.chrome.browser.util.IntentUtils;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.base.WindowAndroid;
...@@ -89,6 +90,15 @@ public class PreferencesLauncher { ...@@ -89,6 +90,15 @@ public class PreferencesLauncher {
return intent; return intent;
} }
/**
* Creates an intent to launch single website preferences for the specified {@param url}.
*/
public static Intent createIntentForSingleWebsitePreferences(Context context, String url) {
return createIntentForSettingsPage(
context, SingleWebsitePreferences.class.getName(),
SingleWebsitePreferences.createFragmentArgsForSite(url));
}
@CalledByNative @CalledByNative
private static void showAutofillProfileSettings(WebContents webContents) { private static void showAutofillProfileSettings(WebContents webContents) {
showSettingSubpage(webContents, AutofillProfilesFragment.class); showSettingSubpage(webContents, AutofillProfilesFragment.class);
......
...@@ -187,6 +187,7 @@ chrome_java_sources = [ ...@@ -187,6 +187,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/browserservices/ClientAppBroadcastReceiver.java", "java/src/org/chromium/chrome/browser/browserservices/ClientAppBroadcastReceiver.java",
"java/src/org/chromium/chrome/browser/browserservices/ClientAppDataRegister.java", "java/src/org/chromium/chrome/browser/browserservices/ClientAppDataRegister.java",
"java/src/org/chromium/chrome/browser/browserservices/DomainDataCleaner.java", "java/src/org/chromium/chrome/browser/browserservices/DomainDataCleaner.java",
"java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java",
"java/src/org/chromium/chrome/browser/browserservices/Origin.java", "java/src/org/chromium/chrome/browser/browserservices/Origin.java",
"java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java", "java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment