Skip to content

Commit

Permalink
fix(launcher): validate origin
Browse files Browse the repository at this point in the history
  • Loading branch information
dargmuesli committed May 3, 2024
1 parent 821891c commit ce4d801
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 28 deletions.
10 changes: 3 additions & 7 deletions app/src/main/java/si/maev/twa/LauncherActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.google.androidbrowserhelper.trusted.ChromeUpdatePrompt;
import com.google.androidbrowserhelper.trusted.LauncherActivityMetadata;
import com.google.androidbrowserhelper.trusted.ManageDataLauncherActivity;
import com.google.androidbrowserhelper.trusted.QualityEnforcer;
import com.google.androidbrowserhelper.trusted.SharingUtils;
import com.google.androidbrowserhelper.trusted.TwaSharedPreferencesManager;
import com.google.androidbrowserhelper.trusted.splashscreens.PwaWrapperSplashScreenStrategy;
Expand Down Expand Up @@ -231,10 +230,11 @@ protected void launchTwa() {

mTwaLauncher = createTwaLauncher();
mTwaLauncher.launch(twaBuilder,
getCustomTabsCallback(),
new ValidatedQualityEnforcer(() -> mTwaLauncher.launchWhenRelationshipValidated(twaBuilder, mSplashScreenStrategy, () -> mBrowserWasLaunched = true)),
mSplashScreenStrategy,
() -> mBrowserWasLaunched = true,
getFallbackStrategy());
getFallbackStrategy()
);

if (!sChromeVersionChecked) {
ChromeUpdatePrompt.promptIfNeeded(this, mTwaLauncher.getProviderPackage());
Expand All @@ -253,10 +253,6 @@ protected void launchTwa() {
mTwaLauncher.getProviderPackage());
}

protected CustomTabsCallback getCustomTabsCallback() {
return new QualityEnforcer();
}

protected TwaLauncher createTwaLauncher() {
return new TwaLauncher(this);
}
Expand Down
40 changes: 19 additions & 21 deletions app/src/main/java/si/maev/twa/TwaLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import android.provider.Browser;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.browser.customtabs.CustomTabsCallback;
import androidx.browser.customtabs.CustomTabsClient;
Expand Down Expand Up @@ -226,11 +227,8 @@ private void launchTwa(TrustedWebActivityIntentBuilder twaBuilder,
splashScreenStrategy.onTwaLaunchInitiated(mProviderPackage, twaBuilder);
}

Runnable onSessionCreatedRunnable = () ->
launchWhenSessionEstablished(twaBuilder, splashScreenStrategy, completionCallback);

if (mSession != null) {
onSessionCreatedRunnable.run();
launchWhenRelationshipValidated(twaBuilder, splashScreenStrategy, completionCallback);
return;
}

Expand All @@ -242,18 +240,19 @@ private void launchTwa(TrustedWebActivityIntentBuilder twaBuilder,
};

if (mServiceConnection == null) {
mServiceConnection = new TwaCustomTabsServiceConnection(customTabsCallback);
mServiceConnection = new TwaCustomTabsServiceConnection(customTabsCallback, twaBuilder.getUri());
}

mServiceConnection.setSessionCreationRunnables(
onSessionCreatedRunnable, onSessionCreationFailedRunnable);
onSessionCreationFailedRunnable
);
CustomTabsClient.bindCustomTabsServicePreservePriority(
mContext, mProviderPackage, mServiceConnection);
}

private void launchWhenSessionEstablished(TrustedWebActivityIntentBuilder twaBuilder,
@Nullable SplashScreenStrategy splashScreenStrategy,
@Nullable Runnable completionCallback) {
public void launchWhenRelationshipValidated(TrustedWebActivityIntentBuilder twaBuilder,
@Nullable SplashScreenStrategy splashScreenStrategy,
@Nullable Runnable completionCallback) {
if (mSession == null) {
throw new IllegalStateException("mSession is null in launchWhenSessionEstablished");
}
Expand Down Expand Up @@ -311,23 +310,22 @@ public String getProviderPackage() {
}

private class TwaCustomTabsServiceConnection extends CustomTabsServiceConnection {
private Runnable mOnSessionCreatedRunnable;
private Runnable mOnSessionCreationFailedRunnable;
private CustomTabsCallback mCustomTabsCallback;
private final CustomTabsCallback mCustomTabsCallback;
private final Uri mLaunchUri;

TwaCustomTabsServiceConnection(CustomTabsCallback callback) {
TwaCustomTabsServiceConnection(CustomTabsCallback callback, Uri launchUri) {
mCustomTabsCallback = callback;
mLaunchUri = launchUri;
}

private void setSessionCreationRunnables(@Nullable Runnable onSuccess,
@Nullable Runnable onFailure) {
mOnSessionCreatedRunnable = onSuccess;
private void setSessionCreationRunnables(@Nullable Runnable onFailure) {
mOnSessionCreationFailedRunnable = onFailure;
}

@Override
public void onCustomTabsServiceConnected(ComponentName componentName,
CustomTabsClient client) {
public void onCustomTabsServiceConnected(@NonNull ComponentName componentName,
@NonNull CustomTabsClient client) {
if (!ChromeLegacyUtils
.supportsLaunchWithoutWarmup(mContext.getPackageManager(), mProviderPackage)) {
client.warmup(0);
Expand All @@ -336,17 +334,17 @@ public void onCustomTabsServiceConnected(ComponentName componentName,
try {
mSession = client.newSession(mCustomTabsCallback, mSessionId);

if (mSession != null && mOnSessionCreatedRunnable != null) {
mOnSessionCreatedRunnable.run();
} else if (mSession == null && mOnSessionCreationFailedRunnable != null) {
if (mSession != null) {
mSession.validateRelationship(CustomTabsService.RELATION_USE_AS_ORIGIN,
mLaunchUri, null);
} else if (mOnSessionCreationFailedRunnable != null) {
mOnSessionCreationFailedRunnable.run();
}
} catch (RuntimeException e) {
Log.w(TAG, e);
mOnSessionCreationFailedRunnable.run();
}

mOnSessionCreatedRunnable = null;
mOnSessionCreationFailedRunnable = null;
}

Expand Down
34 changes: 34 additions & 0 deletions app/src/main/java/si/maev/twa/ValidatedQualityEnforcer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package si.maev.twa;

import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.google.androidbrowserhelper.trusted.QualityEnforcer;

public class ValidatedQualityEnforcer extends QualityEnforcer {
@Nullable
private final Runnable mOnRelationValidatedRunnable;

public ValidatedQualityEnforcer(@Nullable Runnable onRelationValidatedRunnable) {
mOnRelationValidatedRunnable = onRelationValidatedRunnable;
}

@Override
public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin, boolean result, @Nullable Bundle extras) {
super.onRelationshipValidationResult(relation, requestedOrigin, result, extras);

if (result) {
Log.d(this.getClass().getSimpleName(), "Validation result: " + result);
} else {
Log.e(this.getClass().getSimpleName(), "Validation result: " + result);
}

if (mOnRelationValidatedRunnable != null) {
mOnRelationValidatedRunnable.run();
}
}
}

0 comments on commit ce4d801

Please sign in to comment.