diff --git a/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaLauncherTest.java b/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaLauncherTest.java index af59ff27..b3ce0495 100644 --- a/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaLauncherTest.java +++ b/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaLauncherTest.java @@ -70,7 +70,6 @@ public class TwaLauncherTest { private static final Uri URL = Uri.parse("https://www.test.com/default_url/"); private Context mContext = InstrumentationRegistry.getContext(); - private static final CustomTabsCallback mCustomTabsCallback = new QualityEnforcer(); @Rule public final EnableComponentsTestRule mEnableComponents = new EnableComponentsTestRule( @@ -120,7 +119,7 @@ public void transfersTwaBuilderParams() { int expected = color | 0xff000000; TrustedWebActivityIntentBuilder builder = makeBuilder().setToolbarColor(color); - Runnable launchRunnable = () -> mTwaLauncher.launch(builder, mCustomTabsCallback, + Runnable launchRunnable = () -> mTwaLauncher.launch(builder, null, null, null); Intent intent = getBrowserActivityWhenLaunched(launchRunnable).getIntent(); @@ -158,7 +157,7 @@ public void customTabFallbackUsesStatusBarColor() { int expected = color | 0xff000000; TrustedWebActivityIntentBuilder builder = makeBuilder().setToolbarColor(color); - Runnable launchRunnable = () -> launcher.launch(builder, mCustomTabsCallback, + Runnable launchRunnable = () -> launcher.launch(builder, null, null, null); Intent intent = getBrowserActivityWhenLaunched(launchRunnable).getIntent(); @@ -206,7 +205,7 @@ public void createsDifferentSessions_IfDifferentIdsSpecified() { @Test public void completionCallbackCalled() { Runnable callback = mock(Runnable.class); - Runnable launchRunnable = () -> mTwaLauncher.launch(makeBuilder(), mCustomTabsCallback, + Runnable launchRunnable = () -> mTwaLauncher.launch(makeBuilder(), null, null, callback); getBrowserActivityWhenLaunched(launchRunnable); verify(callback).run(); @@ -218,7 +217,7 @@ public void completionCallbackCalled_WhenFallingBackToCct() { TwaLauncher twaLauncher = new TwaLauncher(mActivity); Runnable callback = mock(Runnable.class); - Runnable launchRunnable = () -> twaLauncher.launch(makeBuilder(), mCustomTabsCallback, + Runnable launchRunnable = () -> twaLauncher.launch(makeBuilder(), null, null, callback); getBrowserActivityWhenLaunched(launchRunnable); verify(callback).run(); @@ -229,7 +228,7 @@ public void completionCallbackCalled_WhenFallingBackToCct() { public void notifiesSplashScreenStrategyOfLaunchInitiation() { SplashScreenStrategy strategy = mock(SplashScreenStrategy.class); TrustedWebActivityIntentBuilder builder = makeBuilder(); - mTwaLauncher.launch(builder, mCustomTabsCallback, strategy, null); + mTwaLauncher.launch(builder, null, strategy, null); verify(strategy).onTwaLaunchInitiated( eq(InstrumentationRegistry.getContext().getPackageName()), eq(builder)); @@ -242,7 +241,7 @@ public void doesntLaunch_UntilSplashScreenStrategyFinishesConfiguring() { // Using spy to verify intent is never built to avoid testing directly that activity is // not launched. TrustedWebActivityIntentBuilder builder = spy(makeBuilder()); - mTwaLauncher.launch(builder, mCustomTabsCallback, strategy, null); + mTwaLauncher.launch(builder, null, strategy, null); verify(builder, never()).build(any()); } @@ -254,7 +253,7 @@ public void launches_WhenSplashScreenStrategyFinishesConfiguring() { return null; }).when(strategy).configureTwaBuilder(any(), any(), any()); - Runnable launchRunnable = () -> mTwaLauncher.launch(makeBuilder(), mCustomTabsCallback, + Runnable launchRunnable = () -> mTwaLauncher.launch(makeBuilder(), null, strategy, null); assertNotNull(getBrowserActivityWhenLaunched(launchRunnable)); } @@ -271,7 +270,7 @@ public void cancelsLaunch_IfSplashScreenStrategyFinishes_AfterDestroy() throws E }).when(strategy).configureTwaBuilder(any(), any(), any()); TrustedWebActivityIntentBuilder builder = spy(makeBuilder()); - mTwaLauncher.launch(builder, mCustomTabsCallback, strategy, null); + mTwaLauncher.launch(builder, null, strategy, null); assertTrue(latch.await(3, TimeUnit.SECONDS)); verify(builder, never()).build(any()); } diff --git a/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaQualityEnforcerTest.java b/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaQualityEnforcerTest.java deleted file mode 100644 index a84b4ab2..00000000 --- a/androidbrowserhelper/src/androidTest/java/com/google/androidbrowserhelper/trusted/TwaQualityEnforcerTest.java +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2020 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.androidbrowserhelper.trusted; - -import android.content.Context; -import android.net.Uri; -import android.os.Bundle; - -import androidx.browser.customtabs.CustomTabsCallback; -import androidx.browser.customtabs.CustomTabsSessionToken; -import androidx.browser.trusted.TrustedWebActivityIntentBuilder; -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.MediumTest; -import androidx.test.rule.ActivityTestRule; - -import com.google.androidbrowserhelper.trusted.testcomponents.TestActivity; -import com.google.androidbrowserhelper.trusted.testcomponents.TestBrowser; -import com.google.androidbrowserhelper.trusted.testcomponents.TestCustomTabsService; -import com.google.androidbrowserhelper.trusted.testcomponents.TestCustomTabsServiceSupportsTwas; -import com.google.androidbrowserhelper.trusted.testutils.EnableComponentsTestRule; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; - -import static com.google.androidbrowserhelper.trusted.testutils.TestUtil.getBrowserActivityWhenLaunched; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Instrumentation tests for {@link QualityEnforcer} - */ -@RunWith(AndroidJUnit4.class) -@MediumTest -public class TwaQualityEnforcerTest { - private static final Uri URL = Uri.parse("https://www.test.com/default_url/"); - - private Context mContext = ApplicationProvider.getApplicationContext(); - - private boolean mCrashed = false; - - private CustomTabsCallback mCustomTabsCallback = new QualityEnforcer((String message) -> { - mCrashed = true; - }); - - @Rule - public final EnableComponentsTestRule mEnableComponents = new EnableComponentsTestRule( - TestActivity.class, - TestBrowser.class, - TestCustomTabsServiceSupportsTwas.class, - TestCustomTabsService.class - ); - @Rule - public final ActivityTestRule mActivityTestRule = - new ActivityTestRule<>(TestActivity.class, false, true); - - private TestActivity mActivity; - - private TwaLauncher mTwaLauncher; - - @Before - public void setUp() { - TwaProviderPicker.restrictToPackageForTesting(mContext.getPackageName()); - - TestCustomTabsService.setCanCreateSessions(true); - mActivity = mActivityTestRule.getActivity(); - mTwaLauncher = new TwaLauncher(mActivity); - } - - @Test - public void triggerQualityEnforcement_Crash() { - Runnable launchRunnable = () -> mTwaLauncher.launch( - new TrustedWebActivityIntentBuilder(URL), mCustomTabsCallback, null, null); - CustomTabsSessionToken token = - CustomTabsSessionToken.getSessionTokenFromIntent( - getBrowserActivityWhenLaunched(launchRunnable).getIntent()); - CustomTabsCallback callback = token.getCallback(); - - Bundle args = new Bundle(); - String message = "TestMessage"; - args.putString(QualityEnforcer.KEY_CRASH_REASON, message); - Bundle result = - callback.extraCallbackWithResult(QualityEnforcer.CRASH, args); - assertTrue(result.getBoolean(QualityEnforcer.KEY_SUCCESS)); - assertTrue(mCrashed); - } - - @Test - public void triggerQualityEnforcement_NoCrashReason() { - Runnable launchRunnable = () -> mTwaLauncher.launch( - new TrustedWebActivityIntentBuilder(URL), mCustomTabsCallback, null, null); - CustomTabsSessionToken token = - CustomTabsSessionToken.getSessionTokenFromIntent( - getBrowserActivityWhenLaunched(launchRunnable).getIntent()); - CustomTabsCallback callback = token.getCallback(); - - Bundle args = Bundle.EMPTY; - Bundle result = - callback.extraCallbackWithResult(QualityEnforcer.CRASH, args); - assertFalse(result.getBoolean(QualityEnforcer.KEY_SUCCESS)); - } -} diff --git a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java index c3237af7..f8eafe47 100644 --- a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java +++ b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java @@ -243,7 +243,7 @@ protected void launchTwa() { } protected CustomTabsCallback getCustomTabsCallback() { - return new QualityEnforcer(); + return null; } protected TwaLauncher createTwaLauncher() { diff --git a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/QualityEnforcer.java b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/QualityEnforcer.java deleted file mode 100644 index 8ec7f5aa..00000000 --- a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/QualityEnforcer.java +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 Google Inc. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.androidbrowserhelper.trusted; - -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.browser.customtabs.CustomTabsCallback; - -/** - * This class handles the quality enforcement messages from the browser to enforce the quality bar - * on the websites shown inside Trusted Web Activities. - * Browser should send a message when violation occurs. For example if a link from a page on the - * verified origin 404s or if a page cannot be displayed while offline. - * - * The purpose of this is to bring TWAs in line with native applications - if a native application - * tries to start an Activity that doesn't exist, it will crash. We should hold web apps to the - * same standard. - */ -public class QualityEnforcer extends CustomTabsCallback { - private static final String TAG = "TwaQualityEnforcement"; - static final String CRASH = "quality_enforcement.crash"; - static final String KEY_CRASH_REASON = "crash_reason"; - static final String KEY_SUCCESS = "success"; - - private final Delegate mDelegate; - - /** - * A Delegate interface that provides implementations for handling quality enforcement messages. - */ - interface Delegate { - /* Handling the CRASH message from browser. */ - void crash(String message); - } - - /* Constructor to be used in prod that throws a RuntimeException. */ - public QualityEnforcer() { - mDelegate = (message) -> { - // Put the exception in a looper so that the crash will not prevent returning the - // execution result to browser. - new Handler(Looper.getMainLooper()).post(() -> { - throw new RuntimeException(message); - }); - }; - } - - /* Constructor for use in tests. */ - QualityEnforcer(Delegate delegate) { mDelegate = delegate; } - - @Nullable - @Override - public Bundle extraCallbackWithResult( - @NonNull String callbackName, @Nullable Bundle args) { - String message = (args != null) ? args.getString(KEY_CRASH_REASON) : null; - if (message == null) return Bundle.EMPTY; - - Bundle result = new Bundle(); - if (callbackName.equals(CRASH)) { - result.putBoolean(KEY_SUCCESS, true); - mDelegate.crash(message); - } - return result; - } -}; diff --git a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/TwaLauncher.java b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/TwaLauncher.java index 95342faf..bbbe49ab 100644 --- a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/TwaLauncher.java +++ b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/TwaLauncher.java @@ -149,7 +149,7 @@ public TwaLauncher(Context context, @Nullable String providerPackage, int sessio * @param url Url to open. */ public void launch(Uri url) { - launch(new TrustedWebActivityIntentBuilder(url), new QualityEnforcer(), null, null, null); + launch(new TrustedWebActivityIntentBuilder(url), null, null, null, null); } diff --git a/demos/twa-custom-launcher/src/main/java/com/google/androidbrowserhelper/launchtwa/LaunchTwaActivity.java b/demos/twa-custom-launcher/src/main/java/com/google/androidbrowserhelper/launchtwa/LaunchTwaActivity.java index 08c9989e..77e7af15 100644 --- a/demos/twa-custom-launcher/src/main/java/com/google/androidbrowserhelper/launchtwa/LaunchTwaActivity.java +++ b/demos/twa-custom-launcher/src/main/java/com/google/androidbrowserhelper/launchtwa/LaunchTwaActivity.java @@ -24,7 +24,6 @@ import android.widget.Toast; import com.google.androidbrowserhelper.demo.R; -import com.google.androidbrowserhelper.trusted.QualityEnforcer; import com.google.androidbrowserhelper.trusted.TwaLauncher; import com.google.androidbrowserhelper.trusted.TwaProviderPicker; @@ -32,7 +31,6 @@ import java.util.Arrays; import java.util.List; -import androidx.browser.customtabs.CustomTabsCallback; import androidx.browser.customtabs.CustomTabsClient; import androidx.browser.customtabs.CustomTabsServiceConnection; import androidx.browser.customtabs.CustomTabsSession; @@ -45,7 +43,6 @@ public class LaunchTwaActivity extends Activity { private final TrustedWebActivityIntentBuilder builder = new TrustedWebActivityIntentBuilder( LAUNCH_URI); - private CustomTabsCallback mCustomTabsCallback = new QualityEnforcer(); /** * A bag to put all TwaLauncher in so we can dispose all at once. */ @@ -109,7 +106,7 @@ public void launchWithCustomColors(View view) { TwaLauncher launcher = new TwaLauncher(this); - launcher.launch(builder, mCustomTabsCallback, null, null); + launcher.launch(builder, null, null, null); launchers.add(launcher); } @@ -129,7 +126,7 @@ public void launcherWithMultipleOrigins(View view) { TwaLauncher launcher = new TwaLauncher(this); - launcher.launch(builder, mCustomTabsCallback, null , null); + launcher.launch(builder, null, null , null); launchers.add(launcher); }