Added startAnimations, exitAnimations, navigationBarColor, navigationBarDividerColor, secondaryToolbarColor ChromeSafariBrowser settings for Android, Added getVariationsHeader WebView static method, All ChromeSafariBrowserSettings properties are optionals
This commit is contained in:
parent
db7beffc03
commit
8e9c10246a
|
@ -3,13 +3,16 @@
|
||||||
- Added `headers`, `otherLikelyURLs` arguments on `ChromeSafariBrowser.open` method for Android
|
- Added `headers`, `otherLikelyURLs` arguments on `ChromeSafariBrowser.open` method for Android
|
||||||
- Added `onNavigationEvent`, `onServiceConnected`, `onRelationshipValidationResult` events on `ChromeSafariBrowser` for Android
|
- Added `onNavigationEvent`, `onServiceConnected`, `onRelationshipValidationResult` events on `ChromeSafariBrowser` for Android
|
||||||
- Added `mayLaunchUrl`, `launchUrl`, `updateActionButton`, `validateRelationship` methods on `ChromeSafariBrowser` for Android
|
- Added `mayLaunchUrl`, `launchUrl`, `updateActionButton`, `validateRelationship` methods on `ChromeSafariBrowser` for Android
|
||||||
|
- Added `startAnimations`, `exitAnimations`, `navigationBarColor`, `navigationBarDividerColor`, `secondaryToolbarColor` ChromeSafariBrowser settings for Android
|
||||||
- Added `didLoadSuccessfully` optional argument on `ChromeSafariBrowser.onCompletedInitialLoad` event for iOS
|
- Added `didLoadSuccessfully` optional argument on `ChromeSafariBrowser.onCompletedInitialLoad` event for iOS
|
||||||
- Added `onInitialLoadDidRedirect`, `onWillOpenInBrowser` events on `ChromeSafariBrowser` for iOS
|
- Added `onInitialLoadDidRedirect`, `onWillOpenInBrowser` events on `ChromeSafariBrowser` for iOS
|
||||||
- Added `clearWebsiteData`, `prewarmConnections`, `invalidatePrewarmingToken` static methods on `ChromeSafariBrowser` for iOS
|
- Added `clearWebsiteData`, `prewarmConnections`, `invalidatePrewarmingToken` static methods on `ChromeSafariBrowser` for iOS
|
||||||
|
- Added `getVariationsHeader` WebView static method
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
- `ChromeSafariBrowser.onCompletedInitialLoad` event has an optional argument
|
- `ChromeSafariBrowser.onCompletedInitialLoad` event has an optional argument
|
||||||
|
- All `ChromeSafariBrowserSettings` properties are optionals
|
||||||
|
|
||||||
## 6.0.0-beta.8
|
## 6.0.0-beta.8
|
||||||
|
|
||||||
|
@ -78,7 +81,7 @@
|
||||||
- Added `PullToRefreshController.isEnabled` method
|
- Added `PullToRefreshController.isEnabled` method
|
||||||
- Updated `getMetaThemeColor` on iOS 15.0+
|
- Updated `getMetaThemeColor` on iOS 15.0+
|
||||||
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes
|
- Deprecated `onLoadError` for `onReceivedError`. `onReceivedError` will be called also for subframes
|
||||||
- Deprecated `onLoadHttpError` for `onReceivedError`. `onReceivedHttpError` will be called also for subframes
|
- Deprecated `onLoadHttpError` for `onReceivedHttpError`. `onReceivedHttpError` will be called also for subframes
|
||||||
|
|
||||||
### BREAKING CHANGES
|
### BREAKING CHANGES
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,14 @@ public class InAppWebViewStatic extends ChannelDelegateImpl {
|
||||||
}
|
}
|
||||||
result.success(true);
|
result.success(true);
|
||||||
break;
|
break;
|
||||||
|
case "getVariationsHeader":
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.GET_VARIATIONS_HEADER)) {
|
||||||
|
result.success(WebViewCompat.getVariationsHeader());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.notImplemented();
|
result.notImplemented();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import androidx.browser.customtabs.CustomTabsService;
|
||||||
import androidx.browser.customtabs.CustomTabsSession;
|
import androidx.browser.customtabs.CustomTabsSession;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.R;
|
import com.pichillilorenzo.flutter_inappwebview.R;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.types.AndroidResource;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton;
|
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsActionButton;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem;
|
import com.pichillilorenzo.flutter_inappwebview.types.CustomTabsMenuItem;
|
||||||
import com.pichillilorenzo.flutter_inappwebview.types.Disposable;
|
import com.pichillilorenzo.flutter_inappwebview.types.Disposable;
|
||||||
|
@ -156,35 +157,27 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
|
||||||
public void launchUrl(@NonNull String url,
|
public void launchUrl(@NonNull String url,
|
||||||
@Nullable Map<String, String> headers,
|
@Nullable Map<String, String> headers,
|
||||||
@Nullable List<String> otherLikelyURLs) {
|
@Nullable List<String> otherLikelyURLs) {
|
||||||
Uri uri = mayLaunchUrl(url, headers, otherLikelyURLs);
|
mayLaunchUrl(url, otherLikelyURLs);
|
||||||
builder = new CustomTabsIntent.Builder(customTabsSession);
|
builder = new CustomTabsIntent.Builder(customTabsSession);
|
||||||
prepareCustomTabs();
|
prepareCustomTabs();
|
||||||
|
|
||||||
CustomTabsIntent customTabsIntent = builder.build();
|
CustomTabsIntent customTabsIntent = builder.build();
|
||||||
prepareCustomTabsIntent(customTabsIntent);
|
prepareCustomTabsIntent(customTabsIntent);
|
||||||
|
|
||||||
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
CustomTabActivityHelper.openCustomTab(this, customTabsIntent, Uri.parse(url), headers, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uri mayLaunchUrl(@NonNull String url,
|
public boolean mayLaunchUrl(@Nullable String url, @Nullable List<String> otherLikelyURLs) {
|
||||||
@Nullable Map<String, String> headers,
|
Uri uri = url != null ? Uri.parse(url) : null;
|
||||||
@Nullable List<String> otherLikelyURLs) {
|
|
||||||
Uri uri = Uri.parse(url);
|
|
||||||
Bundle bundleHeaders = new Bundle();
|
|
||||||
if (headers != null) {
|
|
||||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
|
||||||
bundleHeaders.putString(header.getKey(), header.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Bundle> bundleOtherLikelyURLs = new ArrayList<>();
|
List<Bundle> bundleOtherLikelyURLs = new ArrayList<>();
|
||||||
if (otherLikelyURLs != null) {
|
if (otherLikelyURLs != null) {
|
||||||
for (String otherLikelyURL : otherLikelyURLs) {
|
|
||||||
Bundle bundleOtherLikelyURL = new Bundle();
|
Bundle bundleOtherLikelyURL = new Bundle();
|
||||||
|
for (String otherLikelyURL : otherLikelyURLs) {
|
||||||
bundleOtherLikelyURL.putString(CustomTabsService.KEY_URL, otherLikelyURL);
|
bundleOtherLikelyURL.putString(CustomTabsService.KEY_URL, otherLikelyURL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customTabActivityHelper.mayLaunchUrl(uri, bundleHeaders, bundleOtherLikelyURLs);
|
return customTabActivityHelper.mayLaunchUrl(uri, null, bundleOtherLikelyURLs);
|
||||||
return uri;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void customTabsConnected() {
|
public void customTabsConnected() {
|
||||||
|
@ -206,16 +199,34 @@ public class ChromeCustomTabsActivity extends Activity implements Disposable {
|
||||||
builder.setShareState(customSettings.shareState);
|
builder.setShareState(customSettings.shareState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customSettings.toolbarBackgroundColor != null && !customSettings.toolbarBackgroundColor.isEmpty()) {
|
|
||||||
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
CustomTabColorSchemeParams.Builder defaultColorSchemeBuilder = new CustomTabColorSchemeParams.Builder();
|
||||||
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder
|
if (customSettings.toolbarBackgroundColor != null && !customSettings.toolbarBackgroundColor.isEmpty()) {
|
||||||
.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor))
|
defaultColorSchemeBuilder.setToolbarColor(Color.parseColor(customSettings.toolbarBackgroundColor));
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
|
if (customSettings.navigationBarColor != null && !customSettings.navigationBarColor.isEmpty()) {
|
||||||
|
defaultColorSchemeBuilder.setNavigationBarColor(Color.parseColor(customSettings.navigationBarColor));
|
||||||
|
}
|
||||||
|
if (customSettings.navigationBarDividerColor != null && !customSettings.navigationBarDividerColor.isEmpty()) {
|
||||||
|
defaultColorSchemeBuilder.setNavigationBarDividerColor(Color.parseColor(customSettings.navigationBarDividerColor));
|
||||||
|
}
|
||||||
|
if (customSettings.secondaryToolbarColor != null && !customSettings.secondaryToolbarColor.isEmpty()) {
|
||||||
|
defaultColorSchemeBuilder.setSecondaryToolbarColor(Color.parseColor(customSettings.secondaryToolbarColor));
|
||||||
|
}
|
||||||
|
builder.setDefaultColorSchemeParams(defaultColorSchemeBuilder.build());
|
||||||
|
|
||||||
builder.setShowTitle(customSettings.showTitle);
|
builder.setShowTitle(customSettings.showTitle);
|
||||||
builder.setUrlBarHidingEnabled(customSettings.enableUrlBarHiding);
|
builder.setUrlBarHidingEnabled(customSettings.enableUrlBarHiding);
|
||||||
builder.setInstantAppsEnabled(customSettings.instantAppsEnabled);
|
builder.setInstantAppsEnabled(customSettings.instantAppsEnabled);
|
||||||
|
if (customSettings.startAnimations.size() == 2) {
|
||||||
|
builder.setStartAnimations(this,
|
||||||
|
customSettings.startAnimations.get(0).getIdentifier(this),
|
||||||
|
customSettings.startAnimations.get(1).getIdentifier(this));
|
||||||
|
}
|
||||||
|
if (customSettings.exitAnimations.size() == 2) {
|
||||||
|
builder.setExitAnimations(this,
|
||||||
|
customSettings.exitAnimations.get(0).getIdentifier(this),
|
||||||
|
customSettings.exitAnimations.get(1).getIdentifier(this));
|
||||||
|
}
|
||||||
|
|
||||||
for (CustomTabsMenuItem menuItem : menuItems) {
|
for (CustomTabsMenuItem menuItem : menuItems) {
|
||||||
builder.addMenuItem(menuItem.getLabel(),
|
builder.addMenuItem(menuItem.getLabel(),
|
||||||
|
|
|
@ -48,14 +48,8 @@ public class ChromeCustomTabsChannelDelegate extends ChannelDelegateImpl {
|
||||||
case "mayLaunchUrl":
|
case "mayLaunchUrl":
|
||||||
if (chromeCustomTabsActivity != null) {
|
if (chromeCustomTabsActivity != null) {
|
||||||
String url = (String) call.argument("url");
|
String url = (String) call.argument("url");
|
||||||
if (url != null) {
|
|
||||||
Map<String, String> headers = (Map<String, String>) call.argument("headers");
|
|
||||||
List<String> otherLikelyURLs = (List<String>) call.argument("otherLikelyURLs");
|
List<String> otherLikelyURLs = (List<String>) call.argument("otherLikelyURLs");
|
||||||
chromeCustomTabsActivity.mayLaunchUrl(url, headers, otherLikelyURLs);
|
result.success(chromeCustomTabsActivity.mayLaunchUrl(url, otherLikelyURLs));
|
||||||
result.success(true);
|
|
||||||
} else {
|
|
||||||
result.success(false);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
result.success(false);
|
result.success(false);
|
||||||
}
|
}
|
||||||
|
@ -74,8 +68,7 @@ public class ChromeCustomTabsChannelDelegate extends ChannelDelegateImpl {
|
||||||
if (chromeCustomTabsActivity != null && chromeCustomTabsActivity.customTabsSession != null) {
|
if (chromeCustomTabsActivity != null && chromeCustomTabsActivity.customTabsSession != null) {
|
||||||
Integer relation = (Integer) call.argument("relation");
|
Integer relation = (Integer) call.argument("relation");
|
||||||
String origin = (String) call.argument("origin");
|
String origin = (String) call.argument("origin");
|
||||||
chromeCustomTabsActivity.customTabsSession.validateRelationship(relation, Uri.parse(origin), null);
|
result.success(chromeCustomTabsActivity.customTabsSession.validateRelationship(relation, Uri.parse(origin), null));
|
||||||
result.success(true);
|
|
||||||
} else {
|
} else {
|
||||||
result.success(false);
|
result.success(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.browser.trusted.ScreenOrientation;
|
||||||
import androidx.browser.trusted.TrustedWebActivityDisplayMode;
|
import androidx.browser.trusted.TrustedWebActivityDisplayMode;
|
||||||
|
|
||||||
import com.pichillilorenzo.flutter_inappwebview.ISettings;
|
import com.pichillilorenzo.flutter_inappwebview.ISettings;
|
||||||
|
import com.pichillilorenzo.flutter_inappwebview.types.AndroidResource;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -25,6 +26,12 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
||||||
public Boolean showTitle = true;
|
public Boolean showTitle = true;
|
||||||
@Nullable
|
@Nullable
|
||||||
public String toolbarBackgroundColor;
|
public String toolbarBackgroundColor;
|
||||||
|
@Nullable
|
||||||
|
public String navigationBarColor;
|
||||||
|
@Nullable
|
||||||
|
public String navigationBarDividerColor;
|
||||||
|
@Nullable
|
||||||
|
public String secondaryToolbarColor;
|
||||||
public Boolean enableUrlBarHiding = false;
|
public Boolean enableUrlBarHiding = false;
|
||||||
public Boolean instantAppsEnabled = false;
|
public Boolean instantAppsEnabled = false;
|
||||||
public String packageName;
|
public String packageName;
|
||||||
|
@ -35,6 +42,8 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
||||||
public List<String> additionalTrustedOrigins = new ArrayList<>();
|
public List<String> additionalTrustedOrigins = new ArrayList<>();
|
||||||
public TrustedWebActivityDisplayMode displayMode = null;
|
public TrustedWebActivityDisplayMode displayMode = null;
|
||||||
public Integer screenOrientation = ScreenOrientation.DEFAULT;
|
public Integer screenOrientation = ScreenOrientation.DEFAULT;
|
||||||
|
public List<AndroidResource> startAnimations = new ArrayList<>();
|
||||||
|
public List<AndroidResource> exitAnimations = new ArrayList<>();
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,6 +68,15 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
||||||
case "toolbarBackgroundColor":
|
case "toolbarBackgroundColor":
|
||||||
toolbarBackgroundColor = (String) value;
|
toolbarBackgroundColor = (String) value;
|
||||||
break;
|
break;
|
||||||
|
case "navigationBarColor":
|
||||||
|
navigationBarColor = (String) value;
|
||||||
|
break;
|
||||||
|
case "navigationBarDividerColor":
|
||||||
|
navigationBarDividerColor = (String) value;
|
||||||
|
break;
|
||||||
|
case "secondaryToolbarColor":
|
||||||
|
secondaryToolbarColor = (String) value;
|
||||||
|
break;
|
||||||
case "enableUrlBarHiding":
|
case "enableUrlBarHiding":
|
||||||
enableUrlBarHiding = (Boolean) value;
|
enableUrlBarHiding = (Boolean) value;
|
||||||
break;
|
break;
|
||||||
|
@ -102,6 +120,24 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
||||||
case "screenOrientation":
|
case "screenOrientation":
|
||||||
screenOrientation = (Integer) value;
|
screenOrientation = (Integer) value;
|
||||||
break;
|
break;
|
||||||
|
case "startAnimations":
|
||||||
|
List<Map<String, Object>> startAnimationsList = (List<Map<String, Object>>) value;
|
||||||
|
for (Map<String, Object> startAnimation : startAnimationsList) {
|
||||||
|
AndroidResource androidResource = AndroidResource.fromMap(startAnimation);
|
||||||
|
if (androidResource != null) {
|
||||||
|
startAnimations.add(AndroidResource.fromMap(startAnimation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "exitAnimations":
|
||||||
|
List<Map<String, Object>> exitAnimationsList = (List<Map<String, Object>>) value;
|
||||||
|
for (Map<String, Object> exitAnimation : exitAnimationsList) {
|
||||||
|
AndroidResource androidResource = AndroidResource.fromMap(exitAnimation);
|
||||||
|
if (androidResource != null) {
|
||||||
|
exitAnimations.add(AndroidResource.fromMap(exitAnimation));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +151,9 @@ public class ChromeCustomTabsSettings implements ISettings<ChromeCustomTabsActiv
|
||||||
options.put("addDefaultShareMenuItem", addDefaultShareMenuItem);
|
options.put("addDefaultShareMenuItem", addDefaultShareMenuItem);
|
||||||
options.put("showTitle", showTitle);
|
options.put("showTitle", showTitle);
|
||||||
options.put("toolbarBackgroundColor", toolbarBackgroundColor);
|
options.put("toolbarBackgroundColor", toolbarBackgroundColor);
|
||||||
|
options.put("navigationBarColor", navigationBarColor);
|
||||||
|
options.put("navigationBarDividerColor", navigationBarDividerColor);
|
||||||
|
options.put("secondaryToolbarColor", secondaryToolbarColor);
|
||||||
options.put("enableUrlBarHiding", enableUrlBarHiding);
|
options.put("enableUrlBarHiding", enableUrlBarHiding);
|
||||||
options.put("instantAppsEnabled", instantAppsEnabled);
|
options.put("instantAppsEnabled", instantAppsEnabled);
|
||||||
options.put("packageName", packageName);
|
options.put("packageName", packageName);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import android.app.Activity;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Browser;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.browser.customtabs.CustomTabsCallback;
|
import androidx.browser.customtabs.CustomTabsCallback;
|
||||||
|
@ -14,6 +15,7 @@ import androidx.browser.customtabs.CustomTabsSession;
|
||||||
import androidx.browser.trusted.TrustedWebActivityIntent;
|
import androidx.browser.trusted.TrustedWebActivityIntent;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a helper class to manage the connection to the Custom Tabs Service.
|
* This is a helper class to manage the connection to the Custom Tabs Service.
|
||||||
|
@ -35,19 +37,36 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
||||||
public static void openCustomTab(Activity activity,
|
public static void openCustomTab(Activity activity,
|
||||||
CustomTabsIntent customTabsIntent,
|
CustomTabsIntent customTabsIntent,
|
||||||
Uri uri,
|
Uri uri,
|
||||||
|
@Nullable Map<String, String> headers,
|
||||||
int requestCode) {
|
int requestCode) {
|
||||||
customTabsIntent.intent.setData(uri);
|
customTabsIntent.intent.setData(uri);
|
||||||
|
if (headers != null) {
|
||||||
|
Bundle bundleHeaders = new Bundle();
|
||||||
|
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||||
|
bundleHeaders.putString(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
customTabsIntent.intent.putExtra(Browser.EXTRA_HEADERS, bundleHeaders);
|
||||||
|
}
|
||||||
activity.startActivityForResult(customTabsIntent.intent, requestCode);
|
activity.startActivityForResult(customTabsIntent.intent, requestCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openCustomTab(Activity activity,
|
public static void openCustomTab(Activity activity,
|
||||||
TrustedWebActivityIntent trustedWebActivityIntent,
|
TrustedWebActivityIntent trustedWebActivityIntent,
|
||||||
Uri uri,
|
Uri uri,
|
||||||
|
@Nullable Map<String, String> headers,
|
||||||
int requestCode) {
|
int requestCode) {
|
||||||
trustedWebActivityIntent.getIntent().setData(uri);
|
trustedWebActivityIntent.getIntent().setData(uri);
|
||||||
|
if (headers != null) {
|
||||||
|
Bundle bundleHeaders = new Bundle();
|
||||||
|
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||||
|
bundleHeaders.putString(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
trustedWebActivityIntent.getIntent().putExtra(Browser.EXTRA_HEADERS, bundleHeaders);
|
||||||
|
}
|
||||||
activity.startActivityForResult(trustedWebActivityIntent.getIntent(), requestCode);
|
activity.startActivityForResult(trustedWebActivityIntent.getIntent(), requestCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isAvailable(Activity activity) {
|
public static boolean isAvailable(Activity activity) {
|
||||||
return CustomTabsHelper.getPackageNameToUse(activity) != null;
|
return CustomTabsHelper.getPackageNameToUse(activity) != null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,15 +31,16 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
||||||
if (customTabsSession == null) {
|
if (customTabsSession == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Uri uri = Uri.parse(url);
|
||||||
|
|
||||||
Uri uri = mayLaunchUrl(url, headers, otherLikelyURLs);
|
mayLaunchUrl(url, otherLikelyURLs);
|
||||||
builder = new TrustedWebActivityIntentBuilder(uri);
|
builder = new TrustedWebActivityIntentBuilder(uri);
|
||||||
prepareCustomTabs();
|
prepareCustomTabs();
|
||||||
|
|
||||||
TrustedWebActivityIntent trustedWebActivityIntent = builder.build(customTabsSession);
|
TrustedWebActivityIntent trustedWebActivityIntent = builder.build(customTabsSession);
|
||||||
prepareCustomTabsIntent(trustedWebActivityIntent);
|
prepareCustomTabsIntent(trustedWebActivityIntent);
|
||||||
|
|
||||||
CustomTabActivityHelper.openCustomTab(this, trustedWebActivityIntent, uri, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
CustomTabActivityHelper.openCustomTab(this, trustedWebActivityIntent, uri, headers, CHROME_CUSTOM_TAB_REQUEST_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,7 +49,6 @@ public class TrustedWebActivity extends ChromeCustomTabsActivity {
|
||||||
if (initialUrl != null) {
|
if (initialUrl != null) {
|
||||||
launchUrl(initialUrl, initialHeaders, initialOtherLikelyURLs);
|
launchUrl(initialUrl, initialHeaders, initialOtherLikelyURLs);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareCustomTabs() {
|
private void prepareCustomTabs() {
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.pichillilorenzo.flutter_inappwebview.types;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class AndroidResource {
|
||||||
|
@NonNull
|
||||||
|
String name;
|
||||||
|
@Nullable
|
||||||
|
String defType;
|
||||||
|
@Nullable
|
||||||
|
String defPackage;
|
||||||
|
|
||||||
|
public AndroidResource(@NonNull String name, @Nullable String defType, @Nullable String defPackage) {
|
||||||
|
this.name = name;
|
||||||
|
this.defType = defType;
|
||||||
|
this.defPackage = defPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static AndroidResource fromMap(@Nullable Map<String, Object> map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String name = (String) map.get("name");
|
||||||
|
String defType = (String) map.get("defType");
|
||||||
|
String defPackage = (String) map.get("defPackage");
|
||||||
|
return new AndroidResource(name, defType, defPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
Map<String, Object> urlRequestMap = new HashMap<>();
|
||||||
|
urlRequestMap.put("name", name);
|
||||||
|
urlRequestMap.put("defType", defType);
|
||||||
|
urlRequestMap.put("defPackage", defPackage);
|
||||||
|
return urlRequestMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(@NonNull String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getDefType() {
|
||||||
|
return defType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefType(@Nullable String defType) {
|
||||||
|
this.defType = defType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getDefPackage() {
|
||||||
|
return defPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefPackage(@Nullable String defPackage) {
|
||||||
|
this.defPackage = defPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIdentifier(@NonNull Context ctx) {
|
||||||
|
return ctx.getResources().getIdentifier(name, defType, defPackage);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
AndroidResource that = (AndroidResource) o;
|
||||||
|
|
||||||
|
if (!name.equals(that.name)) return false;
|
||||||
|
if (defType != null ? !defType.equals(that.defType) : that.defType != null) return false;
|
||||||
|
return defPackage != null ? defPackage.equals(that.defPackage) : that.defPackage == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = name.hashCode();
|
||||||
|
result = 31 * result + (defType != null ? defType.hashCode() : 0);
|
||||||
|
result = 31 * result + (defPackage != null ? defPackage.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AndroidResource{" +
|
||||||
|
"name='" + name + '\'' +
|
||||||
|
", type='" + defType + '\'' +
|
||||||
|
", defPackage='" + defPackage + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,10 +13,12 @@ void customActionButton() {
|
||||||
TargetPlatform.android,
|
TargetPlatform.android,
|
||||||
].contains(defaultTargetPlatform);
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
test('add custom action button', () async {
|
test('add custom action button and update icon', () async {
|
||||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
var actionButtonIcon =
|
var actionButtonIcon =
|
||||||
await rootBundle.load('test_assets/images/flutter-logo.png');
|
await rootBundle.load('test_assets/images/flutter-logo.png');
|
||||||
|
var actionButtonIcon2 =
|
||||||
|
await rootBundle.load('test_assets/images/flutter-logo.jpg');
|
||||||
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
chromeSafariBrowser.setActionButton(ChromeSafariBrowserActionButton(
|
||||||
id: 1,
|
id: 1,
|
||||||
description: 'Action Button description',
|
description: 'Action Button description',
|
||||||
|
@ -25,15 +27,18 @@ void customActionButton() {
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
await chromeSafariBrowser.opened.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
await chromeSafariBrowser.updateActionButton(
|
||||||
|
icon: actionButtonIcon2.buffer.asUint8List(),
|
||||||
|
description: 'New Action Button description');
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.closed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ void customMenuItem() {
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
await chromeSafariBrowser.opened.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
@ -26,7 +26,7 @@ void customMenuItem() {
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.closed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ void customTabs() {
|
||||||
await chromeSafariBrowser.open(
|
await chromeSafariBrowser.open(
|
||||||
url: TEST_URL_1,
|
url: TEST_URL_1,
|
||||||
settings: ChromeSafariBrowserSettings(isSingleInstance: true));
|
settings: ChromeSafariBrowserSettings(isSingleInstance: true));
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
@ -28,7 +28,43 @@ void customTabs() {
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('mayLaunchUrl and launchUrl', () async {
|
||||||
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open();
|
||||||
|
await expectLater(chromeSafariBrowser.serviceConnected.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
expect(
|
||||||
|
await chromeSafariBrowser.mayLaunchUrl(
|
||||||
|
url: TEST_URL_1, otherLikelyURLs: [TEST_CROSS_PLATFORM_URL_1]),
|
||||||
|
true);
|
||||||
|
await chromeSafariBrowser.launchUrl(
|
||||||
|
url: TEST_URL_1,
|
||||||
|
headers: {'accept-language': 'it-IT'},
|
||||||
|
otherLikelyURLs: [TEST_CROSS_PLATFORM_URL_1]);
|
||||||
|
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||||
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('onNavigationEvent', () async {
|
||||||
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||||
|
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
expect(await chromeSafariBrowser.navigationEvent.future, isNotNull);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
});
|
});
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'custom_menu_item.dart';
|
||||||
import 'custom_tabs.dart';
|
import 'custom_tabs.dart';
|
||||||
import 'open_and_close.dart';
|
import 'open_and_close.dart';
|
||||||
import 'trusted_web_activity.dart';
|
import 'trusted_web_activity.dart';
|
||||||
|
import 'sf_safari_view_controller.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
final shouldSkip =
|
final shouldSkip =
|
||||||
|
@ -17,5 +18,6 @@ void main() {
|
||||||
customActionButton();
|
customActionButton();
|
||||||
customTabs();
|
customTabs();
|
||||||
trustedWebActivity();
|
trustedWebActivity();
|
||||||
|
sfSafariViewController();
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,35 @@ void openAndClose() {
|
||||||
var chromeSafariBrowser = MyChromeSafariBrowser();
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
await chromeSafariBrowser.open(url: TEST_URL_1);
|
await chromeSafariBrowser.open(
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
url: TEST_URL_1,
|
||||||
|
settings: ChromeSafariBrowserSettings(
|
||||||
|
shareState: CustomTabsShareState.SHARE_STATE_OFF,
|
||||||
|
startAnimations: [
|
||||||
|
AndroidResource(
|
||||||
|
name: "slide_in_left",
|
||||||
|
defType: "anim",
|
||||||
|
defPackage: "android"),
|
||||||
|
AndroidResource(
|
||||||
|
name: "slide_out_right",
|
||||||
|
defType: "anim",
|
||||||
|
defPackage: "android")
|
||||||
|
],
|
||||||
|
exitAnimations: [
|
||||||
|
AndroidResource(
|
||||||
|
name: "abc_slide_in_top",
|
||||||
|
defType: "anim",
|
||||||
|
defPackage:
|
||||||
|
"com.pichillilorenzo.flutter_inappwebviewexample"),
|
||||||
|
AndroidResource(
|
||||||
|
name: "abc_slide_out_top",
|
||||||
|
defType: "anim",
|
||||||
|
defPackage: "com.pichillilorenzo.flutter_inappwebviewexample")
|
||||||
|
],
|
||||||
|
keepAliveEnabled: true,
|
||||||
|
dismissButtonStyle: DismissButtonStyle.CLOSE,
|
||||||
|
presentationStyle: ModalPresentationStyle.OVER_FULL_SCREEN));
|
||||||
|
await chromeSafariBrowser.opened.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
@ -24,7 +51,7 @@ void openAndClose() {
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.closed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../constants.dart';
|
||||||
|
import '../util.dart';
|
||||||
|
|
||||||
|
void sfSafariViewController() {
|
||||||
|
final shouldSkip = kIsWeb
|
||||||
|
? true
|
||||||
|
: ![
|
||||||
|
TargetPlatform.android,
|
||||||
|
].contains(defaultTargetPlatform);
|
||||||
|
|
||||||
|
group('SF Safari View Controller', () {
|
||||||
|
test('onCompletedInitialLoad did load successfully', () async {
|
||||||
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open(url: TEST_URL_1);
|
||||||
|
await expectLater(chromeSafariBrowser.opened.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
expect(() async {
|
||||||
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
}, throwsA(isInstanceOf<ChromeSafariBrowserAlreadyOpenedException>()));
|
||||||
|
|
||||||
|
expect(await chromeSafariBrowser.firstPageLoaded.future, true);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await expectLater(chromeSafariBrowser.closed.future, completes);
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('clearWebsiteData', () async {
|
||||||
|
await expectLater(ChromeSafariBrowser.clearWebsiteData(), completes);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('create and invalidate Prewarming Token', () async {
|
||||||
|
final prewarmingToken = await ChromeSafariBrowser.prewarmConnections([TEST_URL_1]);
|
||||||
|
expect(prewarmingToken, isNotNull);
|
||||||
|
await expectLater(ChromeSafariBrowser.invalidatePrewarmingToken(prewarmingToken!), completes);
|
||||||
|
});
|
||||||
|
}, skip: shouldSkip);
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ void trustedWebActivity() {
|
||||||
await chromeSafariBrowser.open(
|
await chromeSafariBrowser.open(
|
||||||
url: TEST_URL_1,
|
url: TEST_URL_1,
|
||||||
settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true));
|
settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true));
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
await chromeSafariBrowser.opened.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
@ -28,7 +28,7 @@ void trustedWebActivity() {
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.closed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void trustedWebActivity() {
|
||||||
url: TEST_URL_1,
|
url: TEST_URL_1,
|
||||||
settings: ChromeSafariBrowserSettings(
|
settings: ChromeSafariBrowserSettings(
|
||||||
isTrustedWebActivity: true, isSingleInstance: true));
|
isTrustedWebActivity: true, isSingleInstance: true));
|
||||||
await chromeSafariBrowser.browserCreated.future;
|
await chromeSafariBrowser.opened.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), true);
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
expect(() async {
|
expect(() async {
|
||||||
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
await chromeSafariBrowser.open(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
@ -48,7 +48,25 @@ void trustedWebActivity() {
|
||||||
|
|
||||||
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
await chromeSafariBrowser.close();
|
await chromeSafariBrowser.close();
|
||||||
await chromeSafariBrowser.browserClosed.future;
|
await chromeSafariBrowser.closed.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('validate relationship', () async {
|
||||||
|
var chromeSafariBrowser = MyChromeSafariBrowser();
|
||||||
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
|
|
||||||
|
await chromeSafariBrowser.open(
|
||||||
|
settings: ChromeSafariBrowserSettings(isTrustedWebActivity: true));
|
||||||
|
await chromeSafariBrowser.serviceConnected.future;
|
||||||
|
expect(await chromeSafariBrowser.validateRelationship(relation: CustomTabsRelationType.USE_AS_ORIGIN, origin: TEST_CROSS_PLATFORM_URL_1), true);
|
||||||
|
expect(await chromeSafariBrowser.relationshipValidationResult.future, true);
|
||||||
|
await chromeSafariBrowser.launchUrl(url: TEST_CROSS_PLATFORM_URL_1);
|
||||||
|
await chromeSafariBrowser.opened.future;
|
||||||
|
expect(chromeSafariBrowser.isOpened(), true);
|
||||||
|
await expectLater(chromeSafariBrowser.firstPageLoaded.future, completes);
|
||||||
|
await chromeSafariBrowser.close();
|
||||||
|
await chromeSafariBrowser.closed.future;
|
||||||
expect(chromeSafariBrowser.isOpened(), false);
|
expect(chromeSafariBrowser.isOpened(), false);
|
||||||
});
|
});
|
||||||
}, skip: shouldSkip);
|
}, skip: shouldSkip);
|
||||||
|
|
|
@ -54,22 +54,44 @@ class MyInAppBrowser extends InAppBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
class MyChromeSafariBrowser extends ChromeSafariBrowser {
|
||||||
final Completer<void> browserCreated = Completer<void>();
|
final Completer<void> serviceConnected = Completer<void>();
|
||||||
final Completer<void> firstPageLoaded = Completer<void>();
|
final Completer<void> opened = Completer<void>();
|
||||||
final Completer<void> browserClosed = Completer<void>();
|
final Completer<bool> firstPageLoaded = Completer<bool>();
|
||||||
|
final Completer<void> closed = Completer<void>();
|
||||||
|
final Completer<CustomTabsNavigationEventType?> navigationEvent = Completer<CustomTabsNavigationEventType?>();
|
||||||
|
final Completer<bool> relationshipValidationResult = Completer<bool>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onOpened() {
|
void onServiceConnected() {
|
||||||
browserCreated.complete();
|
serviceConnected.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onCompletedInitialLoad() {
|
void onOpened() {
|
||||||
firstPageLoaded.complete();
|
opened.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onCompletedInitialLoad(didLoadSuccessfully) {
|
||||||
|
firstPageLoaded.complete(didLoadSuccessfully);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onNavigationEvent(CustomTabsNavigationEventType? type) {
|
||||||
|
if (!navigationEvent.isCompleted) {
|
||||||
|
navigationEvent.complete(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onRelationshipValidationResult(
|
||||||
|
CustomTabsRelationType? relation, Uri? requestedOrigin, bool result) {
|
||||||
|
relationshipValidationResult.complete(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClosed() {
|
void onClosed() {
|
||||||
browserClosed.complete();
|
closed.complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class SafariBrowserSettings: ISettings<SafariViewController> {
|
||||||
var preferredBarTintColor: String?
|
var preferredBarTintColor: String?
|
||||||
var preferredControlTintColor: String?
|
var preferredControlTintColor: String?
|
||||||
var presentationStyle = 0 //fullscreen
|
var presentationStyle = 0 //fullscreen
|
||||||
var transitionStyle = 0 //crossDissolve
|
var transitionStyle = 0 //coverVertical
|
||||||
|
|
||||||
override init(){
|
override init(){
|
||||||
super.init()
|
super.init()
|
||||||
|
|
|
@ -217,6 +217,11 @@ class WebViewFeature_ {
|
||||||
const WebViewFeature_._internal(
|
const WebViewFeature_._internal(
|
||||||
"ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY");
|
"ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY");
|
||||||
|
|
||||||
|
///This feature covers [InAppWebViewController.getVariationsHeader].
|
||||||
|
static const GET_VARIATIONS_HEADER =
|
||||||
|
const WebViewFeature_._internal(
|
||||||
|
"GET_VARIATIONS_HEADER");
|
||||||
|
|
||||||
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
///Return whether a feature is supported at run-time. On devices running Android version `Build.VERSION_CODES.LOLLIPOP` and higher,
|
||||||
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
///this will check whether a feature is supported, depending on the combination of the desired feature, the Android version of device,
|
||||||
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
///and the WebView APK on the device. If running on a device with a lower API level, this will always return `false`.
|
||||||
|
|
|
@ -217,6 +217,10 @@ class WebViewFeature {
|
||||||
WebViewFeature._internal('ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY',
|
WebViewFeature._internal('ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY',
|
||||||
'ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY');
|
'ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY');
|
||||||
|
|
||||||
|
///This feature covers [InAppWebViewController.getVariationsHeader].
|
||||||
|
static const GET_VARIATIONS_HEADER = WebViewFeature._internal(
|
||||||
|
'GET_VARIATIONS_HEADER', 'GET_VARIATIONS_HEADER');
|
||||||
|
|
||||||
///Set of all values of [WebViewFeature].
|
///Set of all values of [WebViewFeature].
|
||||||
static final Set<WebViewFeature> values = [
|
static final Set<WebViewFeature> values = [
|
||||||
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL,
|
||||||
|
@ -266,6 +270,7 @@ class WebViewFeature {
|
||||||
WebViewFeature.ALGORITHMIC_DARKENING,
|
WebViewFeature.ALGORITHMIC_DARKENING,
|
||||||
WebViewFeature.REQUESTED_WITH_HEADER_CONTROL,
|
WebViewFeature.REQUESTED_WITH_HEADER_CONTROL,
|
||||||
WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY,
|
WebViewFeature.ENTERPRISE_AUTHENTICATION_APP_LINK_POLICY,
|
||||||
|
WebViewFeature.GET_VARIATIONS_HEADER,
|
||||||
].toSet();
|
].toSet();
|
||||||
|
|
||||||
///Gets a possible [WebViewFeature] instance from [String] value.
|
///Gets a possible [WebViewFeature] instance from [String] value.
|
||||||
|
|
|
@ -143,7 +143,9 @@ class ChromeSafariBrowser {
|
||||||
///
|
///
|
||||||
///[url] - The [url] to load. On iOS, the [url] is required and must use the `http` or `https` scheme.
|
///[url] - The [url] to load. On iOS, the [url] is required and must use the `http` or `https` scheme.
|
||||||
///
|
///
|
||||||
///[headers] - extra request headers. Supported only on Android.
|
///[headers] (Supported only on Android) - [whitelisted](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) cross-origin request headers.
|
||||||
|
///It is possible to attach non-whitelisted headers to cross-origin requests, when the server and client are related using a
|
||||||
|
///[digital asset link](https://developers.google.com/digital-asset-links/v1/getting-started).
|
||||||
///
|
///
|
||||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order. Supported only on Android.
|
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order. Supported only on Android.
|
||||||
///
|
///
|
||||||
|
@ -199,7 +201,9 @@ class ChromeSafariBrowser {
|
||||||
///
|
///
|
||||||
///[url] - initial url.
|
///[url] - initial url.
|
||||||
///
|
///
|
||||||
///[headers] - extra request headers.
|
///[headers] (Supported only on Android) - [whitelisted](https://fetch.spec.whatwg.org/#cors-safelisted-request-header) cross-origin request headers.
|
||||||
|
///It is possible to attach non-whitelisted headers to cross-origin requests, when the server and client are related using a
|
||||||
|
///[digital asset link](https://developers.google.com/digital-asset-links/v1/getting-started).
|
||||||
///
|
///
|
||||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
||||||
///
|
///
|
||||||
|
@ -225,22 +229,18 @@ class ChromeSafariBrowser {
|
||||||
///
|
///
|
||||||
///[url] - Most likely URL, may be null if otherLikelyBundles is provided.
|
///[url] - Most likely URL, may be null if otherLikelyBundles is provided.
|
||||||
///
|
///
|
||||||
///[headers] - extra request headers.
|
|
||||||
///
|
|
||||||
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
///[otherLikelyURLs] - Other likely destinations, sorted in decreasing likelihood order.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android ([Official API - CustomTabsSession.mayLaunchUrl](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#mayLaunchUrl(android.net.Uri,android.os.Bundle,java.util.List%3Candroid.os.Bundle%3E)))
|
///- Android ([Official API - CustomTabsSession.mayLaunchUrl](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#mayLaunchUrl(android.net.Uri,android.os.Bundle,java.util.List%3Candroid.os.Bundle%3E)))
|
||||||
Future<void> mayLaunchUrl(
|
Future<bool> mayLaunchUrl(
|
||||||
{Uri? url,
|
{Uri? url,
|
||||||
Map<String, String>? headers,
|
|
||||||
List<Uri>? otherLikelyURLs}) async {
|
List<Uri>? otherLikelyURLs}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('url', () => url?.toString());
|
args.putIfAbsent('url', () => url?.toString());
|
||||||
args.putIfAbsent('headers', () => headers);
|
|
||||||
args.putIfAbsent('otherLikelyURLs',
|
args.putIfAbsent('otherLikelyURLs',
|
||||||
() => otherLikelyURLs?.map((e) => e.toString()).toList());
|
() => otherLikelyURLs?.map((e) => e.toString()).toList());
|
||||||
await _channel.invokeMethod("mayLaunchUrl", args);
|
return await _channel.invokeMethod("mayLaunchUrl", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Requests to validate a relationship between the application and an origin.
|
///Requests to validate a relationship between the application and an origin.
|
||||||
|
@ -251,14 +251,20 @@ class ChromeSafariBrowser {
|
||||||
///If this method returns `true`, the validation result will be provided through [onRelationshipValidationResult].
|
///If this method returns `true`, the validation result will be provided through [onRelationshipValidationResult].
|
||||||
///Otherwise the request didn't succeed.
|
///Otherwise the request didn't succeed.
|
||||||
///
|
///
|
||||||
|
///[relation] – Relation to check, must be one of the [CustomTabsRelationType] constants.
|
||||||
|
///
|
||||||
|
///[origin] – Origin.
|
||||||
|
///
|
||||||
|
///[extras] – Reserved for future use.
|
||||||
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android ([Official API - CustomTabsSession.validateRelationship](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#validateRelationship(int,android.net.Uri,android.os.Bundle)))
|
///- Android ([Official API - CustomTabsSession.validateRelationship](https://developer.android.com/reference/androidx/browser/customtabs/CustomTabsSession#validateRelationship(int,android.net.Uri,android.os.Bundle)))
|
||||||
Future<void> validateRelationship(
|
Future<bool> validateRelationship(
|
||||||
{required CustomTabsRelationType relation, required Uri origin}) async {
|
{required CustomTabsRelationType relation, required Uri origin}) async {
|
||||||
Map<String, dynamic> args = <String, dynamic>{};
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
args.putIfAbsent('relation', () => relation.toNativeValue());
|
args.putIfAbsent('relation', () => relation.toNativeValue());
|
||||||
args.putIfAbsent('origin', () => origin.toString());
|
args.putIfAbsent('origin', () => origin.toString());
|
||||||
await _channel.invokeMethod("validateRelationship", args);
|
return await _channel.invokeMethod("validateRelationship", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Closes the [ChromeSafariBrowser] instance.
|
///Closes the [ChromeSafariBrowser] instance.
|
||||||
|
|
|
@ -1,11 +1,35 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||||
|
|
||||||
|
import '../types/android_resource.dart';
|
||||||
|
import '../types/custom_tabs_share_state.dart';
|
||||||
|
import '../types/dismiss_button_style.dart';
|
||||||
|
import '../types/main.dart';
|
||||||
|
import '../types/modal_presentation_style.dart';
|
||||||
|
import '../types/modal_transition_style.dart';
|
||||||
|
import '../types/trusted_web_activity_display_mode.dart';
|
||||||
|
import '../types/trusted_web_activity_screen_orientation.dart';
|
||||||
import '../util.dart';
|
import '../util.dart';
|
||||||
import 'android/chrome_custom_tabs_options.dart';
|
import 'android/chrome_custom_tabs_options.dart';
|
||||||
import 'apple/safari_options.dart';
|
import 'apple/safari_options.dart';
|
||||||
import '../types/main.dart';
|
|
||||||
|
part 'chrome_safari_browser_settings.g.dart';
|
||||||
|
|
||||||
|
TrustedWebActivityDisplayMode? _deserializeDisplayMode(
|
||||||
|
Map<String, dynamic>? displayMode) {
|
||||||
|
if (displayMode == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
switch (displayMode["type"]) {
|
||||||
|
case "IMMERSIVE_MODE":
|
||||||
|
return TrustedWebActivityImmersiveDisplayMode.fromMap(displayMode);
|
||||||
|
case "DEFAULT_MODE":
|
||||||
|
default:
|
||||||
|
return TrustedWebActivityDefaultDisplayMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ChromeSafariBrowserOptions {
|
class ChromeSafariBrowserOptions {
|
||||||
Map<String, dynamic> toMap() {
|
Map<String, dynamic> toMap() {
|
||||||
|
@ -31,14 +55,15 @@ class ChromeSafariBrowserOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Class that represents the settings that can be used for an [ChromeSafariBrowser] window.
|
///Class that represents the settings that can be used for an [ChromeSafariBrowser] window.
|
||||||
class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
@ExchangeableObject(copyMethod: true)
|
||||||
|
class ChromeSafariBrowserSettings_ implements ChromeSafariBrowserOptions {
|
||||||
///The share state that should be applied to the custom tab. The default value is [CustomTabsShareState.SHARE_STATE_DEFAULT].
|
///The share state that should be applied to the custom tab. The default value is [CustomTabsShareState.SHARE_STATE_DEFAULT].
|
||||||
///
|
///
|
||||||
///**NOTE**: Not available in a Trusted Web Activity.
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
CustomTabsShareState shareState;
|
CustomTabsShareState_? shareState;
|
||||||
|
|
||||||
///Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
|
///Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
|
||||||
///
|
///
|
||||||
|
@ -46,7 +71,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool showTitle;
|
bool? showTitle;
|
||||||
|
|
||||||
///Set the custom background color of the toolbar.
|
///Set the custom background color of the toolbar.
|
||||||
///
|
///
|
||||||
|
@ -54,13 +79,31 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///- Android
|
///- Android
|
||||||
Color? toolbarBackgroundColor;
|
Color? toolbarBackgroundColor;
|
||||||
|
|
||||||
|
///Sets the navigation bar color. Has no effect on Android API versions below L.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? navigationBarColor;
|
||||||
|
|
||||||
|
///Sets the navigation bar divider color. Has no effect on Android API versions below P.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? navigationBarDividerColor;
|
||||||
|
|
||||||
|
///Sets the color of the secondary toolbar.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? secondaryToolbarColor;
|
||||||
|
|
||||||
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**NOTE**: Not available in a Trusted Web Activity.
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool enableUrlBarHiding;
|
bool? enableUrlBarHiding;
|
||||||
|
|
||||||
///Set to `true` to enable Instant Apps. The default value is `false`.
|
///Set to `true` to enable Instant Apps. The default value is `false`.
|
||||||
///
|
///
|
||||||
|
@ -68,7 +111,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool instantAppsEnabled;
|
bool? instantAppsEnabled;
|
||||||
|
|
||||||
///Set an explicit application package name that limits
|
///Set an explicit application package name that limits
|
||||||
///the components this Intent will resolve to. If left to the default
|
///the components this Intent will resolve to. If left to the default
|
||||||
|
@ -84,25 +127,25 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool keepAliveEnabled;
|
bool? keepAliveEnabled;
|
||||||
|
|
||||||
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool isSingleInstance;
|
bool? isSingleInstance;
|
||||||
|
|
||||||
///Set to `true` to launch the Android intent with the flag `FLAG_ACTIVITY_NO_HISTORY`. The default value is `false`.
|
///Set to `true` to launch the Android intent with the flag `FLAG_ACTIVITY_NO_HISTORY`. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool noHistory;
|
bool? noHistory;
|
||||||
|
|
||||||
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
bool isTrustedWebActivity;
|
bool? isTrustedWebActivity;
|
||||||
|
|
||||||
///Sets a list of additional trusted origins that the user may navigate or be redirected to from the starting uri.
|
///Sets a list of additional trusted origins that the user may navigate or be redirected to from the starting uri.
|
||||||
///
|
///
|
||||||
|
@ -110,7 +153,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
List<String> additionalTrustedOrigins;
|
List<String>? additionalTrustedOrigins;
|
||||||
|
|
||||||
///Sets a display mode of a Trusted Web Activity.
|
///Sets a display mode of a Trusted Web Activity.
|
||||||
///
|
///
|
||||||
|
@ -118,7 +161,8 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
TrustedWebActivityDisplayMode? displayMode;
|
@ExchangeableObjectProperty(deserializer: _deserializeDisplayMode)
|
||||||
|
TrustedWebActivityDisplayMode_? displayMode;
|
||||||
|
|
||||||
///Sets a screen orientation. This can be used e.g. to enable the locking of an orientation lock type.
|
///Sets a screen orientation. This can be used e.g. to enable the locking of an orientation lock type.
|
||||||
///
|
///
|
||||||
|
@ -126,19 +170,35 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- Android
|
///- Android
|
||||||
TrustedWebActivityScreenOrientation screenOrientation;
|
TrustedWebActivityScreenOrientation_? screenOrientation;
|
||||||
|
|
||||||
|
///Sets the start animations.
|
||||||
|
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the browser
|
||||||
|
///and the second one represents the "exit" animation for the application.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
List<AndroidResource_>? startAnimations;
|
||||||
|
|
||||||
|
///Sets the exit animations.
|
||||||
|
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the application
|
||||||
|
///and the second one represents the "exit" animation for the browser.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
List<AndroidResource_>? exitAnimations;
|
||||||
|
|
||||||
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
bool entersReaderIfAvailable;
|
bool? entersReaderIfAvailable;
|
||||||
|
|
||||||
///Set to `true` to enable bar collapsing. The default value is `false`.
|
///Set to `true` to enable bar collapsing. The default value is `false`.
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
bool barCollapsingEnabled;
|
bool? barCollapsingEnabled;
|
||||||
|
|
||||||
///Set the custom style for the dismiss button. The default value is [DismissButtonStyle.DONE].
|
///Set the custom style for the dismiss button. The default value is [DismissButtonStyle.DONE].
|
||||||
///
|
///
|
||||||
|
@ -146,7 +206,7 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
DismissButtonStyle dismissButtonStyle;
|
DismissButtonStyle_? dismissButtonStyle;
|
||||||
|
|
||||||
///Set the custom background color of the navigation bar and the toolbar.
|
///Set the custom background color of the navigation bar and the toolbar.
|
||||||
///
|
///
|
||||||
|
@ -168,18 +228,22 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
ModalPresentationStyle presentationStyle;
|
ModalPresentationStyle_? presentationStyle;
|
||||||
|
|
||||||
///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL].
|
///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL].
|
||||||
///
|
///
|
||||||
///**Supported Platforms/Implementations**:
|
///**Supported Platforms/Implementations**:
|
||||||
///- iOS
|
///- iOS
|
||||||
ModalTransitionStyle transitionStyle;
|
ModalTransitionStyle_? transitionStyle;
|
||||||
|
|
||||||
ChromeSafariBrowserSettings(
|
@ExchangeableObjectConstructor()
|
||||||
{this.shareState = CustomTabsShareState.SHARE_STATE_DEFAULT,
|
ChromeSafariBrowserSettings_(
|
||||||
|
{this.shareState = CustomTabsShareState_.SHARE_STATE_DEFAULT,
|
||||||
this.showTitle = true,
|
this.showTitle = true,
|
||||||
this.toolbarBackgroundColor,
|
this.toolbarBackgroundColor,
|
||||||
|
this.navigationBarColor,
|
||||||
|
this.navigationBarDividerColor,
|
||||||
|
this.secondaryToolbarColor,
|
||||||
this.enableUrlBarHiding = false,
|
this.enableUrlBarHiding = false,
|
||||||
this.instantAppsEnabled = false,
|
this.instantAppsEnabled = false,
|
||||||
this.packageName,
|
this.packageName,
|
||||||
|
@ -189,99 +253,42 @@ class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
this.isTrustedWebActivity = false,
|
this.isTrustedWebActivity = false,
|
||||||
this.additionalTrustedOrigins = const [],
|
this.additionalTrustedOrigins = const [],
|
||||||
this.displayMode,
|
this.displayMode,
|
||||||
this.screenOrientation = TrustedWebActivityScreenOrientation.DEFAULT,
|
this.screenOrientation = TrustedWebActivityScreenOrientation_.DEFAULT,
|
||||||
|
this.startAnimations,
|
||||||
|
this.exitAnimations,
|
||||||
this.entersReaderIfAvailable = false,
|
this.entersReaderIfAvailable = false,
|
||||||
this.barCollapsingEnabled = false,
|
this.barCollapsingEnabled = false,
|
||||||
this.dismissButtonStyle = DismissButtonStyle.DONE,
|
this.dismissButtonStyle = DismissButtonStyle_.DONE,
|
||||||
this.preferredBarTintColor,
|
this.preferredBarTintColor,
|
||||||
this.preferredControlTintColor,
|
this.preferredControlTintColor,
|
||||||
this.presentationStyle = ModalPresentationStyle.FULL_SCREEN,
|
this.presentationStyle = ModalPresentationStyle_.FULL_SCREEN,
|
||||||
this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL});
|
this.transitionStyle = ModalTransitionStyle_.COVER_VERTICAL}) {
|
||||||
|
if (startAnimations != null) {
|
||||||
@override
|
assert(startAnimations!.length == 2,
|
||||||
Map<String, dynamic> toMap() {
|
"start animations must be have 2 android resources");
|
||||||
return {
|
|
||||||
"shareState": shareState.toNativeValue(),
|
|
||||||
"showTitle": showTitle,
|
|
||||||
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
|
|
||||||
"enableUrlBarHiding": enableUrlBarHiding,
|
|
||||||
"instantAppsEnabled": instantAppsEnabled,
|
|
||||||
"packageName": packageName,
|
|
||||||
"keepAliveEnabled": keepAliveEnabled,
|
|
||||||
"isSingleInstance": isSingleInstance,
|
|
||||||
"noHistory": noHistory,
|
|
||||||
"isTrustedWebActivity": isTrustedWebActivity,
|
|
||||||
"additionalTrustedOrigins": additionalTrustedOrigins,
|
|
||||||
"displayMode": displayMode?.toMap(),
|
|
||||||
"screenOrientation": screenOrientation.toNativeValue(),
|
|
||||||
"entersReaderIfAvailable": entersReaderIfAvailable,
|
|
||||||
"barCollapsingEnabled": barCollapsingEnabled,
|
|
||||||
"dismissButtonStyle": dismissButtonStyle.toNativeValue(),
|
|
||||||
"preferredBarTintColor": preferredBarTintColor?.toHex(),
|
|
||||||
"preferredControlTintColor": preferredControlTintColor?.toHex(),
|
|
||||||
"presentationStyle": presentationStyle.toNativeValue(),
|
|
||||||
"transitionStyle": transitionStyle.toNativeValue()
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
if (exitAnimations != null) {
|
||||||
static ChromeSafariBrowserSettings fromMap(Map<String, dynamic> map) {
|
assert(exitAnimations!.length == 2,
|
||||||
ChromeSafariBrowserSettings settings = new ChromeSafariBrowserSettings();
|
"exit animations must be have 2 android resources");
|
||||||
if (defaultTargetPlatform == TargetPlatform.android) {
|
|
||||||
settings.shareState = map["shareState"];
|
|
||||||
settings.showTitle = map["showTitle"];
|
|
||||||
settings.toolbarBackgroundColor =
|
|
||||||
UtilColor.fromHex(map["toolbarBackgroundColor"]);
|
|
||||||
settings.enableUrlBarHiding = map["enableUrlBarHiding"];
|
|
||||||
settings.instantAppsEnabled = map["instantAppsEnabled"];
|
|
||||||
settings.packageName = map["packageName"];
|
|
||||||
settings.keepAliveEnabled = map["keepAliveEnabled"];
|
|
||||||
settings.isSingleInstance = map["isSingleInstance"];
|
|
||||||
settings.noHistory = map["noHistory"];
|
|
||||||
settings.isTrustedWebActivity = map["isTrustedWebActivity"];
|
|
||||||
settings.additionalTrustedOrigins = map["additionalTrustedOrigins"];
|
|
||||||
switch (map["displayMode"]["type"]) {
|
|
||||||
case "IMMERSIVE_MODE":
|
|
||||||
settings.displayMode = TrustedWebActivityImmersiveDisplayMode.fromMap(
|
|
||||||
map["displayMode"]);
|
|
||||||
break;
|
|
||||||
case "DEFAULT_MODE":
|
|
||||||
default:
|
|
||||||
settings.displayMode = TrustedWebActivityDefaultDisplayMode();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
settings.screenOrientation = map["screenOrientation"];
|
|
||||||
}
|
|
||||||
if (defaultTargetPlatform == TargetPlatform.iOS ||
|
|
||||||
defaultTargetPlatform == TargetPlatform.macOS) {
|
|
||||||
settings.entersReaderIfAvailable = map["entersReaderIfAvailable"];
|
|
||||||
settings.barCollapsingEnabled = map["barCollapsingEnabled"];
|
|
||||||
settings.dismissButtonStyle =
|
|
||||||
DismissButtonStyle.fromNativeValue(map["dismissButtonStyle"])!;
|
|
||||||
settings.preferredBarTintColor =
|
|
||||||
UtilColor.fromHex(map["preferredBarTintColor"]);
|
|
||||||
settings.preferredControlTintColor =
|
|
||||||
UtilColor.fromHex(map["preferredControlTintColor"]);
|
|
||||||
settings.presentationStyle =
|
|
||||||
ModalPresentationStyle.fromNativeValue(map["presentationStyle"])!;
|
|
||||||
settings.transitionStyle =
|
|
||||||
ModalTransitionStyle.fromNativeValue(map["transitionStyle"])!;
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ExchangeableObjectMethod(ignore: true)
|
||||||
|
ChromeSafariBrowserSettings_ copy() {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@ExchangeableObjectMethod(ignore: true)
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return this.toMap();
|
throw UnimplementedError();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
@ExchangeableObjectMethod(ignore: true)
|
||||||
return toMap().toString();
|
Map<String, dynamic> toMap() {
|
||||||
}
|
throw UnimplementedError();
|
||||||
|
|
||||||
@override
|
|
||||||
ChromeSafariBrowserSettings copy() {
|
|
||||||
return ChromeSafariBrowserSettings.fromMap(this.toMap());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,330 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'chrome_safari_browser_settings.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ExchangeableObjectGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
///Class that represents the settings that can be used for an [ChromeSafariBrowser] window.
|
||||||
|
class ChromeSafariBrowserSettings implements ChromeSafariBrowserOptions {
|
||||||
|
///The share state that should be applied to the custom tab. The default value is [CustomTabsShareState.SHARE_STATE_DEFAULT].
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
CustomTabsShareState? shareState;
|
||||||
|
|
||||||
|
///Set to `false` if the title shouldn't be shown in the custom tab. The default value is `true`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? showTitle;
|
||||||
|
|
||||||
|
///Set the custom background color of the toolbar.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? toolbarBackgroundColor;
|
||||||
|
|
||||||
|
///Sets the navigation bar color. Has no effect on Android API versions below L.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? navigationBarColor;
|
||||||
|
|
||||||
|
///Sets the navigation bar divider color. Has no effect on Android API versions below P.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? navigationBarDividerColor;
|
||||||
|
|
||||||
|
///Sets the color of the secondary toolbar.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
Color? secondaryToolbarColor;
|
||||||
|
|
||||||
|
///Set to `true` to enable the url bar to hide as the user scrolls down on the page. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? enableUrlBarHiding;
|
||||||
|
|
||||||
|
///Set to `true` to enable Instant Apps. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**NOTE**: Not available in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? instantAppsEnabled;
|
||||||
|
|
||||||
|
///Set an explicit application package name that limits
|
||||||
|
///the components this Intent will resolve to. If left to the default
|
||||||
|
///value of null, all components in all applications will considered.
|
||||||
|
///If non-null, the Intent can only match the components in the given
|
||||||
|
///application package.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
String? packageName;
|
||||||
|
|
||||||
|
///Set to `true` to enable Keep Alive. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? keepAliveEnabled;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Android activity in `singleInstance` mode. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? isSingleInstance;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Android intent with the flag `FLAG_ACTIVITY_NO_HISTORY`. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? noHistory;
|
||||||
|
|
||||||
|
///Set to `true` to launch the Custom Tab as a Trusted Web Activity. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
bool? isTrustedWebActivity;
|
||||||
|
|
||||||
|
///Sets a list of additional trusted origins that the user may navigate or be redirected to from the starting uri.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
List<String>? additionalTrustedOrigins;
|
||||||
|
|
||||||
|
///Sets a display mode of a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
TrustedWebActivityDisplayMode? displayMode;
|
||||||
|
|
||||||
|
///Sets a screen orientation. This can be used e.g. to enable the locking of an orientation lock type.
|
||||||
|
///
|
||||||
|
///**NOTE**: Available only in a Trusted Web Activity.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
TrustedWebActivityScreenOrientation? screenOrientation;
|
||||||
|
|
||||||
|
///Sets the start animations.
|
||||||
|
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the browser
|
||||||
|
///and the second one represents the "exit" animation for the application.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
List<AndroidResource>? startAnimations;
|
||||||
|
|
||||||
|
///Sets the exit animations.
|
||||||
|
///It must contain 2 [AndroidResource], where the first one represents the "enter" animation for the application
|
||||||
|
///and the second one represents the "exit" animation for the browser.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android
|
||||||
|
List<AndroidResource>? exitAnimations;
|
||||||
|
|
||||||
|
///Set to `true` if Reader mode should be entered automatically when it is available for the webpage. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
bool? entersReaderIfAvailable;
|
||||||
|
|
||||||
|
///Set to `true` to enable bar collapsing. The default value is `false`.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
bool? barCollapsingEnabled;
|
||||||
|
|
||||||
|
///Set the custom style for the dismiss button. The default value is [DismissButtonStyle.DONE].
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 11.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
DismissButtonStyle? dismissButtonStyle;
|
||||||
|
|
||||||
|
///Set the custom background color of the navigation bar and the toolbar.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 10.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
Color? preferredBarTintColor;
|
||||||
|
|
||||||
|
///Set the custom color of the control buttons on the navigation bar and the toolbar.
|
||||||
|
///
|
||||||
|
///**NOTE**: available on iOS 10.0+.
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
Color? preferredControlTintColor;
|
||||||
|
|
||||||
|
///Set the custom modal presentation style when presenting the WebView. The default value is [ModalPresentationStyle.FULL_SCREEN].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
ModalPresentationStyle? presentationStyle;
|
||||||
|
|
||||||
|
///Set to the custom transition style when presenting the WebView. The default value is [ModalTransitionStyle.COVER_VERTICAL].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- iOS
|
||||||
|
ModalTransitionStyle? transitionStyle;
|
||||||
|
ChromeSafariBrowserSettings(
|
||||||
|
{this.shareState = CustomTabsShareState.SHARE_STATE_DEFAULT,
|
||||||
|
this.showTitle = true,
|
||||||
|
this.toolbarBackgroundColor,
|
||||||
|
this.navigationBarColor,
|
||||||
|
this.navigationBarDividerColor,
|
||||||
|
this.secondaryToolbarColor,
|
||||||
|
this.enableUrlBarHiding = false,
|
||||||
|
this.instantAppsEnabled = false,
|
||||||
|
this.packageName,
|
||||||
|
this.keepAliveEnabled = false,
|
||||||
|
this.isSingleInstance = false,
|
||||||
|
this.noHistory = false,
|
||||||
|
this.isTrustedWebActivity = false,
|
||||||
|
this.additionalTrustedOrigins = const [],
|
||||||
|
this.displayMode,
|
||||||
|
this.screenOrientation = TrustedWebActivityScreenOrientation.DEFAULT,
|
||||||
|
this.startAnimations,
|
||||||
|
this.exitAnimations,
|
||||||
|
this.entersReaderIfAvailable = false,
|
||||||
|
this.barCollapsingEnabled = false,
|
||||||
|
this.dismissButtonStyle = DismissButtonStyle.DONE,
|
||||||
|
this.preferredBarTintColor,
|
||||||
|
this.preferredControlTintColor,
|
||||||
|
this.presentationStyle = ModalPresentationStyle.FULL_SCREEN,
|
||||||
|
this.transitionStyle = ModalTransitionStyle.COVER_VERTICAL}) {
|
||||||
|
if (startAnimations != null) {
|
||||||
|
assert(startAnimations!.length == 2,
|
||||||
|
"start animations must be have 2 android resources");
|
||||||
|
}
|
||||||
|
if (exitAnimations != null) {
|
||||||
|
assert(exitAnimations!.length == 2,
|
||||||
|
"exit animations must be have 2 android resources");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///Gets a possible [ChromeSafariBrowserSettings] instance from a [Map] value.
|
||||||
|
static ChromeSafariBrowserSettings? fromMap(Map<String, dynamic>? map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final instance = ChromeSafariBrowserSettings(
|
||||||
|
toolbarBackgroundColor: map['toolbarBackgroundColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['toolbarBackgroundColor'])
|
||||||
|
: null,
|
||||||
|
navigationBarColor: map['navigationBarColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['navigationBarColor'])
|
||||||
|
: null,
|
||||||
|
navigationBarDividerColor: map['navigationBarDividerColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['navigationBarDividerColor'])
|
||||||
|
: null,
|
||||||
|
secondaryToolbarColor: map['secondaryToolbarColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['secondaryToolbarColor'])
|
||||||
|
: null,
|
||||||
|
packageName: map['packageName'],
|
||||||
|
displayMode: _deserializeDisplayMode(map['displayMode']),
|
||||||
|
startAnimations: map['startAnimations'] != null
|
||||||
|
? List<AndroidResource>.from(map['startAnimations']
|
||||||
|
.map((e) => AndroidResource.fromMap(e?.cast<String, dynamic>())!))
|
||||||
|
: null,
|
||||||
|
exitAnimations: map['exitAnimations'] != null
|
||||||
|
? List<AndroidResource>.from(map['exitAnimations']
|
||||||
|
.map((e) => AndroidResource.fromMap(e?.cast<String, dynamic>())!))
|
||||||
|
: null,
|
||||||
|
preferredBarTintColor: map['preferredBarTintColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['preferredBarTintColor'])
|
||||||
|
: null,
|
||||||
|
preferredControlTintColor: map['preferredControlTintColor'] != null
|
||||||
|
? UtilColor.fromStringRepresentation(map['preferredControlTintColor'])
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
instance.shareState =
|
||||||
|
CustomTabsShareState.fromNativeValue(map['shareState']);
|
||||||
|
instance.showTitle = map['showTitle'];
|
||||||
|
instance.enableUrlBarHiding = map['enableUrlBarHiding'];
|
||||||
|
instance.instantAppsEnabled = map['instantAppsEnabled'];
|
||||||
|
instance.keepAliveEnabled = map['keepAliveEnabled'];
|
||||||
|
instance.isSingleInstance = map['isSingleInstance'];
|
||||||
|
instance.noHistory = map['noHistory'];
|
||||||
|
instance.isTrustedWebActivity = map['isTrustedWebActivity'];
|
||||||
|
instance.additionalTrustedOrigins =
|
||||||
|
map['additionalTrustedOrigins']?.cast<String>();
|
||||||
|
instance.screenOrientation =
|
||||||
|
TrustedWebActivityScreenOrientation.fromNativeValue(
|
||||||
|
map['screenOrientation']);
|
||||||
|
instance.entersReaderIfAvailable = map['entersReaderIfAvailable'];
|
||||||
|
instance.barCollapsingEnabled = map['barCollapsingEnabled'];
|
||||||
|
instance.dismissButtonStyle =
|
||||||
|
DismissButtonStyle.fromNativeValue(map['dismissButtonStyle']);
|
||||||
|
instance.presentationStyle =
|
||||||
|
ModalPresentationStyle.fromNativeValue(map['presentationStyle']);
|
||||||
|
instance.transitionStyle =
|
||||||
|
ModalTransitionStyle.fromNativeValue(map['transitionStyle']);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Converts instance to a map.
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"shareState": shareState?.toNativeValue(),
|
||||||
|
"showTitle": showTitle,
|
||||||
|
"toolbarBackgroundColor": toolbarBackgroundColor?.toHex(),
|
||||||
|
"navigationBarColor": navigationBarColor?.toHex(),
|
||||||
|
"navigationBarDividerColor": navigationBarDividerColor?.toHex(),
|
||||||
|
"secondaryToolbarColor": secondaryToolbarColor?.toHex(),
|
||||||
|
"enableUrlBarHiding": enableUrlBarHiding,
|
||||||
|
"instantAppsEnabled": instantAppsEnabled,
|
||||||
|
"packageName": packageName,
|
||||||
|
"keepAliveEnabled": keepAliveEnabled,
|
||||||
|
"isSingleInstance": isSingleInstance,
|
||||||
|
"noHistory": noHistory,
|
||||||
|
"isTrustedWebActivity": isTrustedWebActivity,
|
||||||
|
"additionalTrustedOrigins": additionalTrustedOrigins,
|
||||||
|
"displayMode": displayMode?.toMap(),
|
||||||
|
"screenOrientation": screenOrientation?.toNativeValue(),
|
||||||
|
"startAnimations": startAnimations?.map((e) => e.toMap()).toList(),
|
||||||
|
"exitAnimations": exitAnimations?.map((e) => e.toMap()).toList(),
|
||||||
|
"entersReaderIfAvailable": entersReaderIfAvailable,
|
||||||
|
"barCollapsingEnabled": barCollapsingEnabled,
|
||||||
|
"dismissButtonStyle": dismissButtonStyle?.toNativeValue(),
|
||||||
|
"preferredBarTintColor": preferredBarTintColor?.toHex(),
|
||||||
|
"preferredControlTintColor": preferredControlTintColor?.toHex(),
|
||||||
|
"presentationStyle": presentationStyle?.toNativeValue(),
|
||||||
|
"transitionStyle": transitionStyle?.toNativeValue(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///Converts instance to a map.
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
///Returns a copy of ChromeSafariBrowserSettings.
|
||||||
|
ChromeSafariBrowserSettings copy() {
|
||||||
|
return ChromeSafariBrowserSettings.fromMap(toMap()) ??
|
||||||
|
ChromeSafariBrowserSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ChromeSafariBrowserSettings{shareState: $shareState, showTitle: $showTitle, toolbarBackgroundColor: $toolbarBackgroundColor, navigationBarColor: $navigationBarColor, navigationBarDividerColor: $navigationBarDividerColor, secondaryToolbarColor: $secondaryToolbarColor, enableUrlBarHiding: $enableUrlBarHiding, instantAppsEnabled: $instantAppsEnabled, packageName: $packageName, keepAliveEnabled: $keepAliveEnabled, isSingleInstance: $isSingleInstance, noHistory: $noHistory, isTrustedWebActivity: $isTrustedWebActivity, additionalTrustedOrigins: $additionalTrustedOrigins, displayMode: $displayMode, screenOrientation: $screenOrientation, startAnimations: $startAnimations, exitAnimations: $exitAnimations, entersReaderIfAvailable: $entersReaderIfAvailable, barCollapsingEnabled: $barCollapsingEnabled, dismissButtonStyle: $dismissButtonStyle, preferredBarTintColor: $preferredBarTintColor, preferredControlTintColor: $preferredControlTintColor, presentationStyle: $presentationStyle, transitionStyle: $transitionStyle}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
export 'chrome_safari_browser.dart';
|
export 'chrome_safari_browser.dart';
|
||||||
export 'chrome_safari_browser_settings.dart';
|
export 'chrome_safari_browser_settings.dart'
|
||||||
|
show
|
||||||
|
ChromeSafariBrowserOptions,
|
||||||
|
ChromeSafariBrowserSettings,
|
||||||
|
ChromeSafariBrowserClassOptions;
|
||||||
export 'android/main.dart';
|
export 'android/main.dart';
|
||||||
export 'apple/main.dart';
|
export 'apple/main.dart';
|
||||||
|
|
|
@ -3683,6 +3683,24 @@ class InAppWebViewController {
|
||||||
'setWebContentsDebuggingEnabled', args);
|
'setWebContentsDebuggingEnabled', args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///Gets the WebView variations encoded to be used as the X-Client-Data HTTP header.
|
||||||
|
///
|
||||||
|
///The app is responsible for adding the X-Client-Data header to any request
|
||||||
|
///that may use variations metadata, such as requests to Google web properties.
|
||||||
|
///The returned string will be a base64 encoded ClientVariations proto:
|
||||||
|
///https://source.chromium.org/chromium/chromium/src/+/main:components/variations/proto/client_variations.proto
|
||||||
|
///
|
||||||
|
///The string may be empty if the header is not available.
|
||||||
|
///
|
||||||
|
///**NOTE for Android native WebView**: This method should only be called if [WebViewFeature.isFeatureSupported] returns `true` for [WebViewFeature.GET_VARIATIONS_HEADER].
|
||||||
|
///
|
||||||
|
///**Supported Platforms/Implementations**:
|
||||||
|
///- Android native WebView ([Official API - WebViewCompat.getVariationsHeader](https://developer.android.com/reference/androidx/webkit/WebViewCompat#getVariationsHeader()))
|
||||||
|
static Future<String?> getVariationsHeader() async {
|
||||||
|
Map<String, dynamic> args = <String, dynamic>{};
|
||||||
|
return await _staticChannel.invokeMethod('getVariationsHeader', args);
|
||||||
|
}
|
||||||
|
|
||||||
///Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
///Returns a Boolean value that indicates whether WebKit natively supports resources with the specified URL scheme.
|
||||||
///
|
///
|
||||||
///[urlScheme] represents the URL scheme associated with the resource.
|
///[urlScheme] represents the URL scheme associated with the resource.
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import 'package:flutter_inappwebview_internal_annotations/flutter_inappwebview_internal_annotations.dart';
|
||||||
|
|
||||||
|
part 'android_resource.g.dart';
|
||||||
|
|
||||||
|
///Class that represents an android resource.
|
||||||
|
@ExchangeableObject()
|
||||||
|
class AndroidResource_ {
|
||||||
|
///Android resource name.
|
||||||
|
///
|
||||||
|
///A list of available `android.R.anim` can be found
|
||||||
|
///[here](https://developer.android.com/reference/android/R.anim).
|
||||||
|
///
|
||||||
|
///A list of available `androidx.appcompat.R.anim` can be found
|
||||||
|
///[here](https://android.googlesource.com/platform/frameworks/support/+/HEAD/appcompat/appcompat/src/main/res/anim/)
|
||||||
|
///(abc_*.xml files).
|
||||||
|
///In this case, [defPackage] must match your App Android package name.
|
||||||
|
String name;
|
||||||
|
|
||||||
|
///Optional default resource type to find, if "type/" is not included in the name.
|
||||||
|
///Can be `null` to require an explicit type.
|
||||||
|
///
|
||||||
|
///Example: "anim"
|
||||||
|
String? defType;
|
||||||
|
|
||||||
|
///Optional default package to find, if "package:" is not included in the name.
|
||||||
|
///Can be `null` to require an explicit package.
|
||||||
|
///
|
||||||
|
///Example: "android" if you want use resources from `android.R.`
|
||||||
|
String? defPackage;
|
||||||
|
|
||||||
|
AndroidResource_({required this.name,
|
||||||
|
this.defType, this.defPackage});
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'android_resource.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ExchangeableObjectGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
///Class that represents an android resource.
|
||||||
|
class AndroidResource {
|
||||||
|
///Android resource name.
|
||||||
|
///
|
||||||
|
///A list of available `android.R.anim` can be found
|
||||||
|
///[here](https://developer.android.com/reference/android/R.anim).
|
||||||
|
///
|
||||||
|
///A list of available `androidx.appcompat.R.anim` can be found
|
||||||
|
///[here](https://android.googlesource.com/platform/frameworks/support/+/HEAD/appcompat/appcompat/src/main/res/anim/)
|
||||||
|
///(abc_*.xml files).
|
||||||
|
///In this case, [defPackage] must match your App Android package name.
|
||||||
|
String name;
|
||||||
|
|
||||||
|
///Optional default resource type to find, if "type/" is not included in the name.
|
||||||
|
///Can be `null` to require an explicit type.
|
||||||
|
///
|
||||||
|
///Example: "anim"
|
||||||
|
String? defType;
|
||||||
|
|
||||||
|
///Optional default package to find, if "package:" is not included in the name.
|
||||||
|
///Can be `null` to require an explicit package.
|
||||||
|
///
|
||||||
|
///Example: "android" if you want use resources from `android.R.`
|
||||||
|
String? defPackage;
|
||||||
|
AndroidResource({required this.name, this.defType, this.defPackage});
|
||||||
|
|
||||||
|
///Gets a possible [AndroidResource] instance from a [Map] value.
|
||||||
|
static AndroidResource? fromMap(Map<String, dynamic>? map) {
|
||||||
|
if (map == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final instance = AndroidResource(
|
||||||
|
name: map['name'],
|
||||||
|
defType: map['defType'],
|
||||||
|
defPackage: map['defPackage'],
|
||||||
|
);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
///Converts instance to a map.
|
||||||
|
Map<String, dynamic> toMap() {
|
||||||
|
return {
|
||||||
|
"name": name,
|
||||||
|
"defType": defType,
|
||||||
|
"defPackage": defPackage,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
///Converts instance to a map.
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return toMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AndroidResource{name: $name, defType: $defType, defPackage: $defPackage}';
|
||||||
|
}
|
||||||
|
}
|
|
@ -218,3 +218,4 @@ export 'window_titlebar_separator_style.dart' show WindowTitlebarSeparatorStyle;
|
||||||
export 'custom_tabs_navigation_event_type.dart' show CustomTabsNavigationEventType;
|
export 'custom_tabs_navigation_event_type.dart' show CustomTabsNavigationEventType;
|
||||||
export 'custom_tabs_relation_type.dart' show CustomTabsRelationType;
|
export 'custom_tabs_relation_type.dart' show CustomTabsRelationType;
|
||||||
export 'prewarming_token.dart' show PrewarmingToken;
|
export 'prewarming_token.dart' show PrewarmingToken;
|
||||||
|
export 'android_resource.dart' show AndroidResource;
|
|
@ -34,6 +34,10 @@ dart $PROJECT_DIR/tool/env.dart
|
||||||
cd $PROJECT_DIR/test_node_server
|
cd $PROJECT_DIR/test_node_server
|
||||||
node index.js &
|
node index.js &
|
||||||
|
|
||||||
|
# Only for Android
|
||||||
|
# Open Chrome on the development device, navigate to chrome://flags, search for an item called Enable command line on non-rooted devices and change it to ENABLED and then restart the browser.
|
||||||
|
adb shell "echo '_ --disable-digital-asset-link-verification-for-url=\"https://flutter.dev\"' > /data/local/tmp/chrome-command-line" || true
|
||||||
|
|
||||||
flutter --version
|
flutter --version
|
||||||
flutter clean
|
flutter clean
|
||||||
flutter pub get
|
flutter pub get
|
||||||
|
|
|
@ -153,6 +153,19 @@ app.get("/", (req, res) => {
|
||||||
res.end()
|
res.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
app.get("/echo-headers", (req, res) => {
|
||||||
|
res.send(`
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre style="word-wrap: break-word; white-space: pre-wrap;">${JSON.stringify(req.headers)}</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
res.end()
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/test-index', (req, res) => {
|
app.get('/test-index', (req, res) => {
|
||||||
res.sendFile(__dirname + '/public/index.html');
|
res.sendFile(__dirname + '/public/index.html');
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue