summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview/src/main/java/org/mozilla/geckoview
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/geckoview')
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java17
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java47
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java26
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java30
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java4
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java6
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java54
-rw-r--r--mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md25
8 files changed, 183 insertions, 26 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
index aa3f5c3174..bc9eff98f0 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/ContentInputStream.java
@@ -37,6 +37,11 @@ import org.mozilla.gecko.annotation.WrapForJNI;
try {
mFd = cr.openAssetFileDescriptor(uri, "r");
+ if (mFd == null) {
+ Log.e(LOGTAG, "Cannot open the uri: " + aUri + " (no file descriptor)");
+ close();
+ return;
+ }
setInputStream(mFd.createInputStream());
if (!checkHeaders(HEADERS)) {
@@ -127,7 +132,17 @@ import org.mozilla.gecko.annotation.WrapForJNI;
|| isExported(context, uri)
|| wasGrantedPermission(context, uri)) {
final ContentResolver cr = context.getContentResolver();
- cr.openAssetFileDescriptor(uri, "r").close();
+ if (cr == null) {
+ Log.e(LOGTAG, "No content resolver");
+ return false;
+ }
+ final AssetFileDescriptor fd = cr.openAssetFileDescriptor(uri, "r");
+ if (fd == null) {
+ // The descriptor can be null because the provider crashed.
+ Log.e(LOGTAG, "No asset file descriptor");
+ return false;
+ }
+ fd.close();
Log.d(LOGTAG, "The uri is readable: " + uri);
return true;
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
index 5426adb501..2e8f2e55d7 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoInputConnection.java
@@ -655,6 +655,53 @@ import org.mozilla.gecko.util.ThreadUtils;
return replaceComposingSpanWithSelection()
&& mKeyInputConnection.commitText(text, newCursorPosition);
}
+
+ // Bug 1818268 - Unexpected crash on Galaxy J7
+ if (InputMethods.dontOverrideCommitText()) {
+ return super.commitText(text, newCursorPosition);
+ }
+
+ // Default implementation is
+ // 1. Set selection
+ // 2. Call Editable.replace
+ // 3. Set selection in Editable.replace
+ //
+ // However, this results in additional IPC in Gecko and unexpected selection before replacing
+ // text.
+ // When changing text in Gecko, the selection will be updated, so the default implementation is
+ // not compatible with Gecko's text handling.
+ // Therefore, we set the selection after replacing the text. However, if there is a composition,
+ // the selection may be an IME cursor, not a standard selection. In such cases, this step is not
+ // necessary.
+ final Editable content = getEditable();
+ if (content != null) {
+ final int compositionStart = getComposingSpanStart(content);
+ final int compositionEnd = getComposingSpanEnd(content);
+
+ if (compositionStart < 0 || compositionEnd < 0) {
+ // No composition
+ int selStart = Math.max(Selection.getSelectionStart(content), 0);
+ int selEnd = Math.max(Selection.getSelectionEnd(content), 0);
+ if (selStart > selEnd) {
+ final int tmp = selEnd;
+ selEnd = selStart;
+ selStart = tmp;
+ }
+
+ beginBatchEdit();
+ content.replace(selStart, selEnd, text);
+
+ int cursorPosition =
+ newCursorPosition > 0
+ ? selStart + text.length() + newCursorPosition - 1
+ : selStart + newCursorPosition;
+ cursorPosition = Math.min(Math.max(0, cursorPosition), content.length());
+ Selection.setSelection(content, cursorPosition);
+ endBatchEdit();
+ return true;
+ }
+ }
+
return super.commitText(text, newCursorPosition);
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
index 3da044e603..0a80b02b04 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntimeSettings.java
@@ -27,6 +27,7 @@ import java.util.Locale;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoSystemStateListener;
import org.mozilla.gecko.util.GeckoBundle;
+import org.mozilla.gecko.util.LocaleUtils;
@AnyThread
public final class GeckoRuntimeSettings extends RuntimeSettings {
@@ -462,6 +463,8 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
* @param delegate the delegate that will handle telemetry
* @return The builder instance.
*/
+ @Deprecated
+ @DeprecationSchedule(id = "geckoview-gvst", version = 127)
public @NonNull Builder telemetryDelegate(final @NonNull RuntimeTelemetry.Delegate delegate) {
getSettings().mTelemetryProxy = new RuntimeTelemetry.Proxy(delegate);
getSettings().mTelemetryEnabled.set(true);
@@ -1054,7 +1057,7 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
}
}
// OS prefs come second:
- for (final String locale : getDefaultLocales()) {
+ for (final String locale : getSystemLocalesForAcceptLanguage()) {
final String localeLowerCase = locale.toLowerCase(Locale.ROOT);
if (!locales.containsKey(localeLowerCase)) {
locales.put(localeLowerCase, locale);
@@ -1064,35 +1067,22 @@ public final class GeckoRuntimeSettings extends RuntimeSettings {
return TextUtils.join(",", locales.values());
}
- private static String[] getDefaultLocales() {
+ private static String[] getSystemLocalesForAcceptLanguage() {
if (VERSION.SDK_INT >= 24) {
final LocaleList localeList = LocaleList.getDefault();
final String[] locales = new String[localeList.size()];
for (int i = 0; i < localeList.size(); i++) {
- locales[i] = localeList.get(i).toLanguageTag();
+ // accept-language should be language or language-region format.
+ locales[i] = LocaleUtils.getLanguageTagForAcceptLanguage(localeList.get(i));
}
return locales;
}
final String[] locales = new String[1];
final Locale locale = Locale.getDefault();
- locales[0] = locale.toLanguageTag();
+ locales[0] = LocaleUtils.getLanguageTagForAcceptLanguage(locale);
return locales;
}
- private static String getLanguageTag(final Locale locale) {
- final StringBuilder out = new StringBuilder(locale.getLanguage());
- final String country = locale.getCountry();
- final String variant = locale.getVariant();
- if (!TextUtils.isEmpty(country)) {
- out.append('-').append(country);
- }
- if (!TextUtils.isEmpty(variant)) {
- out.append('-').append(variant);
- }
- // e.g. "en", "en-US", or "en-US-POSIX".
- return out.toString();
- }
-
/**
* Sets whether Web Manifest processing support is enabled.
*
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
index f8f7f858e3..85b3abf9a9 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -685,7 +685,11 @@ public class GeckoSession {
final GeckoBundle[] perms = message.getBundleArray("permissions");
final List<PermissionDelegate.ContentPermission> permList =
PermissionDelegate.ContentPermission.fromBundleArray(perms);
- delegate.onLocationChange(GeckoSession.this, message.getString("uri"), permList);
+ delegate.onLocationChange(
+ GeckoSession.this,
+ message.getString("uri"),
+ permList,
+ message.getBoolean("hasUserGesture"));
}
delegate.onCanGoBack(GeckoSession.this, message.getBoolean("canGoBack"));
delegate.onCanGoForward(GeckoSession.this, message.getBoolean("canGoForward"));
@@ -1928,7 +1932,7 @@ public class GeckoSession {
// https://searchfox.org/mozilla-central/source/docshell/base/nsIWebNavigation.idl
//
// We do not use the same values directly in order to insulate ourselves from
- // changes in Gecko. Instead, the flags are converted in GeckoViewNavigation.jsm.
+ // changes in Gecko. Instead, the flags are converted in GeckoViewNavigation.sys.mjs.
/** Default load flag, no special considerations. */
public static final int LOAD_FLAGS_NONE = 0;
@@ -4935,17 +4939,39 @@ public class GeckoSession {
/**
* A view has started loading content from the network.
*
+ * @deprecated use {@link #onLocationChange(GeckoSession, String,
+ * List<PermissionDelegate.ContentPermission>, Boolean) onLocationChange} instead
* @param session The GeckoSession that initiated the callback.
* @param url The resource being loaded.
* @param perms The permissions currently associated with this url.
*/
@UiThread
+ @Deprecated
+ @DeprecationSchedule(id = "geckoview-onlocationchange", version = 127)
default void onLocationChange(
@NonNull GeckoSession session,
@Nullable String url,
final @NonNull List<PermissionDelegate.ContentPermission> perms) {}
/**
+ * A view has started loading content from the network.
+ *
+ * @param session The GeckoSession that initiated the callback.
+ * @param url The resource being loaded.
+ * @param perms The permissions currently associated with this url.
+ * @param hasUserGesture Whether or not there was an active user gesture when the location
+ * change was requested.
+ */
+ @UiThread
+ default void onLocationChange(
+ @NonNull GeckoSession session,
+ @Nullable String url,
+ final @NonNull List<PermissionDelegate.ContentPermission> perms,
+ final @NonNull Boolean hasUserGesture) {
+ session.getNavigationDelegate().onLocationChange(session, url, perms);
+ }
+
+ /**
* The view's ability to go back has changed.
*
* @param session The GeckoSession that initiated the callback.
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
index 046f7a3072..14f6b14c47 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSessionSettings.java
@@ -203,7 +203,7 @@ public final class GeckoSessionSettings implements Parcelable {
})
public @interface DisplayMode {}
- // This needs to match GeckoViewSettings.jsm
+ // This needs to match GeckoViewSettings.sys.mjs
/** "browser" value of the display member in Web App Manifests */
public static final int DISPLAY_MODE_BROWSER = 0;
@@ -225,7 +225,7 @@ public final class GeckoSessionSettings implements Parcelable {
})
public @interface UserAgentMode {}
- // This needs to match GeckoViewSettingsChild.js and GeckoViewSettings.jsm
+ // This needs to match GeckoViewSettingsChild.js and GeckoViewSettings.sys.mjs
/** The user agent mode is mobile device */
public static final int USER_AGENT_MODE_MOBILE = 0;
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
index 74eccaeb15..2271ff71f7 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -767,6 +767,9 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
if (super.onKeyUp(keyCode, event)) {
return true;
}
+ if (AndroidGamepadManager.handleKeyEvent(event)) {
+ return true;
+ }
return mSession != null && mSession.getTextInput().onKeyUp(keyCode, event);
}
@@ -775,6 +778,9 @@ public class GeckoView extends FrameLayout implements GeckoDisplay.NewSurfacePro
if (super.onKeyDown(keyCode, event)) {
return true;
}
+ if (AndroidGamepadManager.handleKeyEvent(event)) {
+ return true;
+ }
return mSession != null && mSession.getTextInput().onKeyDown(keyCode, event);
}
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
index d553a1aa3f..1caa5508ed 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebExtension.java
@@ -1688,7 +1688,7 @@ public class WebExtension {
* in Firefox. </a>
*/
public static class SignedStateFlags {
- // Keep in sync with AddonManager.jsm
+ // Keep in sync with AddonManager.sys.mjs
/**
* This extension may be signed but by a certificate that doesn't chain to our our trusted
* certificate.
@@ -1820,6 +1820,50 @@ public class WebExtension {
public final @NonNull String[] permissions;
/**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">optional
+ * permissions</a> requested or granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] optionalPermissions;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">optional
+ * permissions</a> granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] grantedOptionalPermissions;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">
+ * optional origin permissions</a> requested or granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] optionalOrigins;
+
+ /**
+ * API <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions">
+ * optional origin permissions</a> granted to this extension.
+ *
+ * <p>Permission identifiers match entries in the manifest, see <a
+ * href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions#API_permissions">
+ * API permissions </a>.
+ */
+ public final @NonNull String[] grantedOptionalOrigins;
+
+ /**
* Host permissions requested or granted to this extension.
*
* <p>See <a
@@ -1999,6 +2043,10 @@ public class WebExtension {
protected MetaData() {
icon = null;
permissions = null;
+ optionalPermissions = null;
+ grantedOptionalPermissions = null;
+ grantedOptionalOrigins = null;
+ optionalOrigins = null;
origins = null;
name = null;
description = null;
@@ -2029,6 +2077,10 @@ public class WebExtension {
/* package */ MetaData(final GeckoBundle bundle) {
// We only expose permissions that the embedder should prompt for
permissions = bundle.getStringArray("promptPermissions");
+ optionalPermissions = bundle.getStringArray("optionalPermissions");
+ grantedOptionalPermissions = bundle.getStringArray("grantedOptionalPermissions");
+ optionalOrigins = bundle.getStringArray("optionalOrigins");
+ grantedOptionalOrigins = bundle.getStringArray("grantedOptionalOrigins");
origins = bundle.getStringArray("origins");
description = bundle.getString("description");
version = bundle.getString("version");
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
index 10a6eb16cd..5776cf5afc 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -13,6 +13,27 @@ exclude: true
⚠️ breaking change and deprecation notices
+## v125
+- ⚠️ Deprecated [`GeckoSession.NavigationDelegate.onLocationChange`][125.1], to be removed in v127.
+([bug 1837601]({{bugzilla}}1837601))
+- Added [`GeckoSession.NavigationDelegate.onLocationChange#hasUserGesture`][125.2]. This indicates if a location change was requested
+while a user gesture was active (e.g., a tap).
+([bug 1837601]({{bugzilla}}1837601))
+- Added [`WebExtension.MetaData.optionalPermissions`][125.3] and [`WebExtension.MetaData.optionalOrigins`][125.4] which expose the optional and origin optional permissions of an extension ([bug 1811900]({{bugzilla}}1811900)).
+- ⚠️ Deprecated [`RuntimeTelemetry`][125.5], [`GeckoRuntimeSettings.getTelemetryDelegate`][125.6] and [`GeckoRuntimeSettings.telemetryDelegate`][125.7], to be removed in v127.
+([bug 1877836]({{bugzilla}}1877836))
+- Added [`WebExtension.MetaData.grantedOptionalPermissions`][125.8] and [`WebExtension.MetaData.grantedOptionalOrigins`][125.9] which expose the granted optional and origin optional permissions of an extension ([bug 1879543]({{bugzilla}}1879543)).
+
+[125.1]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List)
+[125.2]: {{javadoc_uri}}/GeckoSession.NavigationDelegate#onLocationChange(org.mozilla.geckoview.GeckoSession,java.lang.String,java.util.List,boolean)
+[125.3]: {{javadoc_uri}}/WebExtension.MetaData.html#optionalPermissions
+[125.4]: {{javadoc_uri}}/WebExtension.MetaData.html#optionalOrigins
+[125.5]: {{javadoc_uri}}/RuntimeTelemetry.html
+[125.6]: {{javadoc_uri}}/GeckoRuntimeSettings.html#getTelemetryDelegate
+[125.7]: {{javadoc_uri}}/GeckoRuntimeSettings.html#telemetryDelegate
+[125.8]: {{javadoc_uri}}/WebExtension.MetaData.html#grantedOptionalPermissions
+[125.9]: {{javadoc_uri}}/WebExtension.MetaData.html#grantedOptionalOrigins
+
## v124
- Added [`GeckoRuntimeSettings#setTrustedRecursiveResolverMode`][124.1] to enable DNS-over-HTTPS using different resolver modes ([bug 1591533]({{bugzilla}}1591533)).
@@ -36,7 +57,7 @@ exclude: true
[123.1]: {{javadoc_uri}}/TranslationsController.RuntimeTranslation.html#checkPairDownloadSize(java.lang.String,java.lang.String)
[123.2]: {{javadoc_uri}}/TranslationsController.TranslationsException.html#ERROR_MODEL_LANGUAGE_REQUIRED
-[121.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
+[123.3]: {{javadoc_uri}}/GeckoSession.html#sendPlacementAttributionEvent(String)
## v122
- ⚠️ Removed [`onGetNimbusFeature`][115.5], please use `ExperimentDelegate.onGetExperimentFeature` instead.
@@ -1519,4 +1540,4 @@ to allow adding gecko profiler markers.
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport(android.content.Context,android.os.Bundle,java.lang.String)
[65.25]: {{javadoc_uri}}/GeckoResult.html
-[api-version]: ff5a513251f19534bbf4ebe0084909665d00a227
+[api-version]: fc9fd590333bebf38058b7abddbb7a860cd6e4de