diff --git a/build.sh b/build.sh index a571269..dd2441e 100755 --- a/build.sh +++ b/build.sh @@ -57,6 +57,16 @@ make \ -j"$(nproc)" popd +# Build microG libraries +pushd "$gmscore" +gradle -x javaDocReleaseGeneration \ + :play-services-ads-identifier:publishToMavenLocal \ + :play-services-base:publishToMavenLocal \ + :play-services-basement:publishToMavenLocal \ + :play-services-fido:publishToMavenLocal \ + :play-services-tasks:publishToMavenLocal +popd + pushd "$mozilla_release" MOZ_CHROME_MULTILOCALE=$(< "$patches/locales") export MOZ_CHROME_MULTILOCALE diff --git a/fenix-liberate.patch b/fenix-liberate.patch index e7fb4c8..1550da8 100644 --- a/fenix-liberate.patch +++ b/fenix-liberate.patch @@ -1,8 +1,8 @@ diff --git a/fenix/app/build.gradle b/fenix/app/build.gradle -index 78d698dad9..0fbf4cb1cf 100644 +index ecf270db09..eeb42dc674 100644 --- a/fenix/app/build.gradle +++ b/fenix/app/build.gradle -@@ -576,7 +576,6 @@ dependencies { +@@ -599,7 +599,6 @@ dependencies { implementation project(':lib-crash') implementation project(':lib-crash-sentry') @@ -10,15 +10,15 @@ index 78d698dad9..0fbf4cb1cf 100644 implementation project(':lib-state') implementation project(':lib-dataprotect') -@@ -615,15 +614,6 @@ dependencies { +@@ -638,15 +637,8 @@ dependencies { implementation FenixDependencies.protobuf_javalite implementation ComponentsDependencies.google_material - implementation FenixDependencies.adjust - implementation FenixDependencies.installreferrer // Required by Adjust - -- implementation FenixDependencies.google_ads_id // Required for the Google Advertising ID -- + implementation FenixDependencies.google_ads_id // Required for the Google Advertising ID + - // Required for in-app reviews - implementation FenixDependencies.google_play_review - implementation FenixDependencies.google_play_review_ktx @@ -353,63 +353,6 @@ index 0000000000..7efa1c6804 +public interface OnAttributionChangedListener { + void onAttributionChanged(AdjustAttribution attribution); +} -diff --git a/fenix/app/src/main/java/com/google/android/gms/ads/identifier/AdvertisingIdClient.java b/fenix/app/src/main/java/com/google/android/gms/ads/identifier/AdvertisingIdClient.java -new file mode 100644 -index 0000000000..0f2a47b141 ---- /dev/null -+++ b/fenix/app/src/main/java/com/google/android/gms/ads/identifier/AdvertisingIdClient.java -@@ -0,0 +1,23 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+package com.google.android.gms.ads.identifier; -+ -+import android.content.Context; -+ -+public class AdvertisingIdClient { -+ -+ public static final class Info { -+ -+ public String getId() { -+ return ""; -+ } -+ -+ } -+ -+ public static Info getAdvertisingIdInfo(Context context) { -+ return new Info(); -+ } -+ -+} -diff --git a/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesNotAvailableException.java b/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesNotAvailableException.java -new file mode 100644 -index 0000000000..d3bff12497 ---- /dev/null -+++ b/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesNotAvailableException.java -@@ -0,0 +1,8 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+package com.google.android.gms.common; -+ -+public class GooglePlayServicesNotAvailableException extends Exception { -+} -diff --git a/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesRepairableException.java b/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesRepairableException.java -new file mode 100644 -index 0000000000..b72a7cdb16 ---- /dev/null -+++ b/fenix/app/src/main/java/com/google/android/gms/common/GooglePlayServicesRepairableException.java -@@ -0,0 +1,8 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+package com.google.android.gms.common; -+ -+public class GooglePlayServicesRepairableException extends Exception { -+} diff --git a/fenix/app/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java b/fenix/app/src/main/java/com/google/firebase/messaging/FirebaseMessagingService.java new file mode 100644 index 0000000000..4d5fd8153d @@ -536,7 +479,7 @@ index 0000000000..b50a6f03a2 + } +} diff --git a/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt -index d3d63c17b9..7228e67716 100644 +index dbfd66328a..dad70c421f 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -18,7 +18,7 @@ object FeatureFlags { @@ -557,11 +500,41 @@ index d3d63c17b9..7228e67716 100644 } /** +diff --git a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +index 03e1b6b832..33bdbe364b 100644 +--- a/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt ++++ b/fenix/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +@@ -839,17 +839,14 @@ abstract class BaseBrowserFragment : + view = view, + ) + +- // This component feature only works on Fenix when built on Mozilla infrastructure. +- if (BuildConfig.MOZILLA_OFFICIAL) { +- webAuthnFeature.set( +- feature = WebAuthnFeature( +- engine = requireComponents.core.engine, +- activity = requireActivity(), +- ), +- owner = this, +- view = view, +- ) +- } ++ webAuthnFeature.set( ++ feature = WebAuthnFeature( ++ engine = requireComponents.core.engine, ++ activity = requireActivity(), ++ ), ++ owner = this, ++ view = view, ++ ) + + screenOrientationFeature.set( + feature = ScreenOrientationFeature( diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt -index 3cd954a5bb..31f4e6fe34 100644 +index da0fe53ea0..6ce3c2a4d6 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Analytics.kt -@@ -137,11 +137,7 @@ class Analytics( +@@ -147,11 +147,7 @@ class Analytics( MetricController.create( listOf( GleanMetricsService(context), @@ -575,7 +548,7 @@ index 3cd954a5bb..31f4e6fe34 100644 ), isDataTelemetryEnabled = { context.settings().isTelemetryEnabled }, diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt -index d077ca2972..a55a167ad5 100644 +index fb5dc10724..76e2de470e 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -10,7 +10,6 @@ import android.content.Context @@ -595,10 +568,10 @@ index d077ca2972..a55a167ad5 100644 ) } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt b/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt -index f6d7a2b0df..366c256bdb 100644 +index aece11e5ac..583f777fa8 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/components/Core.kt -@@ -510,8 +510,14 @@ class Core( +@@ -508,8 +508,14 @@ class Core( } else { defaultTopSites.add( Pair( @@ -823,7 +796,7 @@ index d69f27e570..171f54a6d5 100644 itemView.context.components.core.icons.loadIntoView(binding.faviconImage, topSite.url) } diff --git a/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt -index e867be39f2..a1667b1c2b 100644 +index 961ea541c3..7bb88bd7c2 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt @@ -38,6 +38,8 @@ object SupportUtils { @@ -836,10 +809,10 @@ index e867be39f2..a1667b1c2b 100644 enum class SumoTopic(internal val topicStr: String) { HELP("faq-android"), diff --git a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt -index 01ed68bbe6..c35ab607f7 100644 +index 4e4e6f38e9..37d64fd5fe 100644 --- a/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt -@@ -332,17 +332,17 @@ class Settings(private val appContext: Context) : PreferencesHolder { +@@ -334,17 +334,17 @@ class Settings(private val appContext: Context) : PreferencesHolder { var isTelemetryEnabled by booleanPreference( appContext.getPreferenceKey(R.string.pref_key_telemetry), @@ -860,7 +833,7 @@ index 01ed68bbe6..c35ab607f7 100644 ) var isOverrideTPPopupsForPerformanceTest = false -@@ -1553,7 +1553,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { +@@ -1593,7 +1593,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { var showPocketRecommendationsFeature by lazyFeatureFlagPreference( appContext.getPreferenceKey(R.string.pref_key_pocket_homescreen_recommendations), featureFlag = FeatureFlags.isPocketRecommendationsFeatureEnabled(appContext), @@ -869,7 +842,7 @@ index 01ed68bbe6..c35ab607f7 100644 ) /** -@@ -1611,7 +1611,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { +@@ -1651,7 +1651,7 @@ class Settings(private val appContext: Context) : PreferencesHolder { */ var showContileFeature by booleanPreference( key = appContext.getPreferenceKey(R.string.pref_key_enable_contile), @@ -893,7 +866,7 @@ index 0000000000..101f4e0d0a + EFF + diff --git a/fenix/app/src/main/res/xml/preferences.xml b/fenix/app/src/main/res/xml/preferences.xml -index 2e0366e11b..4a684b7fb6 100644 +index 9f62309f1e..d9732e9c03 100644 --- a/fenix/app/src/main/res/xml/preferences.xml +++ b/fenix/app/src/main/res/xml/preferences.xml @@ -133,11 +133,6 @@ @@ -908,7 +881,7 @@ index 2e0366e11b..4a684b7fb6 100644 @@ -957,10 +930,27 @@ index 64c90b599b..621f184e68 100644 getTransportsForByte(final byte transports) { -- final ArrayList result = new ArrayList(); -- if ((transports & AUTHENTICATOR_TRANSPORT_USB) == AUTHENTICATOR_TRANSPORT_USB) { -- result.add(Transport.USB); -- } -- if ((transports & AUTHENTICATOR_TRANSPORT_NFC) == AUTHENTICATOR_TRANSPORT_NFC) { -- result.add(Transport.NFC); -- } -- if ((transports & AUTHENTICATOR_TRANSPORT_BLE) == AUTHENTICATOR_TRANSPORT_BLE) { -- result.add(Transport.BLUETOOTH_LOW_ENERGY); -- } -- if ((transports & AUTHENTICATOR_TRANSPORT_INTERNAL) == AUTHENTICATOR_TRANSPORT_INTERNAL) { -- result.add(Transport.INTERNAL); -- } -- return result; -- } + final Task intentTask; - public static class WebAuthnPublicCredential { - public final byte[] id; -@@ -94,34 +23,12 @@ - - static ArrayList CombineBuffers( - final Object[] idObjectList, final ByteBuffer transportList) { -- if (idObjectList.length != transportList.remaining()) { -- throw new RuntimeException("Couldn't extract allowed list!"); -- } -- - final ArrayList credList = - new ArrayList(); -- -- final byte[] transportBytes = new byte[transportList.remaining()]; -- transportList.get(transportBytes); -- -- for (int i = 0; i < idObjectList.length; i++) { -- final ByteBuffer id = (ByteBuffer) idObjectList[i]; -- final byte[] idBytes = new byte[id.remaining()]; -- id.get(idBytes); -- -- credList.add(new WebAuthnPublicCredential(idBytes, transportBytes[i])); -- } - return credList; - } - } - -- // From WebAuthentication.webidl -- public enum AttestationPreference { -- NONE, -- INDIRECT, -- DIRECT, -- } -- - @WrapForJNI - public static class MakeCredentialResponse { - public final byte[] clientDataJson; -@@ -154,191 +61,7 @@ - final WebAuthnTokenManager.WebAuthnPublicCredential[] excludeList, - final GeckoBundle authenticatorSelection, - final GeckoBundle extensions) { -- if (!credentialBundle.containsKey("isWebAuthn")) { -- // FIDO U2F not supported by Android (for us anyway) at this time -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("NOT_SUPPORTED_ERR")); -- } -- -- final PublicKeyCredentialCreationOptions.Builder requestBuilder = -- new PublicKeyCredentialCreationOptions.Builder(); -- -- final List params = -- new ArrayList(); -- -- // WebAuthn supports more algorithms -- for (final Algorithm algo : SUPPORTED_ALGORITHMS) { -- params.add( -- new PublicKeyCredentialParameters( -- PublicKeyCredentialType.PUBLIC_KEY.toString(), algo.getAlgoValue())); -- } -- -- final PublicKeyCredentialUserEntity user = -- new PublicKeyCredentialUserEntity( -- userId, -- credentialBundle.getString("userName", ""), -- /* deprecated userIcon field */ "", -- credentialBundle.getString("userDisplayName", "")); -- -- AttestationConveyancePreference pref = AttestationConveyancePreference.NONE; -- final String attestationPreference = -- authenticatorSelection.getString("attestationPreference", "NONE"); -- if (attestationPreference.equalsIgnoreCase(AttestationConveyancePreference.DIRECT.name())) { -- pref = AttestationConveyancePreference.DIRECT; -- } else if (attestationPreference.equalsIgnoreCase( -- AttestationConveyancePreference.INDIRECT.name())) { -- pref = AttestationConveyancePreference.INDIRECT; -- } -- -- final AuthenticatorSelectionCriteria.Builder selBuild = -- new AuthenticatorSelectionCriteria.Builder(); -- if (authenticatorSelection.getInt("requirePlatformAttachment", 0) == 1) { -- selBuild.setAttachment(Attachment.PLATFORM); -- } -- if (authenticatorSelection.getInt("requireCrossPlatformAttachment", 0) == 1) { -- selBuild.setAttachment(Attachment.CROSS_PLATFORM); -- } -- final String residentKey = authenticatorSelection.getString("residentKey", ""); -- if (residentKey.equals("required")) { -- selBuild -- .setRequireResidentKey(true) -- .setResidentKeyRequirement(ResidentKeyRequirement.RESIDENT_KEY_REQUIRED); -- } else if (residentKey.equals("preferred")) { -- selBuild -- .setRequireResidentKey(false) -- .setResidentKeyRequirement(ResidentKeyRequirement.RESIDENT_KEY_PREFERRED); -- } else if (residentKey.equals("discouraged")) { -- selBuild -- .setRequireResidentKey(false) -- .setResidentKeyRequirement(ResidentKeyRequirement.RESIDENT_KEY_DISCOURAGED); -- } -- final AuthenticatorSelectionCriteria sel = selBuild.build(); -- -- final AuthenticationExtensions.Builder extBuilder = new AuthenticationExtensions.Builder(); -- if (extensions.containsKey("fidoAppId")) { -- extBuilder.setFido2Extension(new FidoAppIdExtension(extensions.getString("fidoAppId"))); -- } -- final AuthenticationExtensions ext = extBuilder.build(); -- -- // requireUserVerification are not yet consumed by Android's API -- -- final List excludedList = -- new ArrayList(); -- for (final WebAuthnTokenManager.WebAuthnPublicCredential cred : excludeList) { -- excludedList.add( -- new PublicKeyCredentialDescriptor( -- PublicKeyCredentialType.PUBLIC_KEY.toString(), -- cred.id, -- getTransportsForByte(cred.transports))); -- } -- -- final PublicKeyCredentialRpEntity rp = -- new PublicKeyCredentialRpEntity( -- credentialBundle.getString("rpId"), -- credentialBundle.getString("rpName", ""), -- /* deprecated rpIcon field */ ""); -- -- final PublicKeyCredentialCreationOptions requestOptions = -- requestBuilder -- .setUser(user) -- .setAttestationConveyancePreference(pref) -- .setAuthenticatorSelection(sel) -- .setAuthenticationExtensions(ext) -- .setChallenge(challenge) -- .setRp(rp) -- .setParameters(params) -- .setTimeoutSeconds(credentialBundle.getLong("timeoutMS") / 1000.0) -- .setExcludeList(excludedList) -- .build(); -- -- final Uri origin = Uri.parse(credentialBundle.getString("origin")); -- -- final BrowserPublicKeyCredentialCreationOptions browserOptions = -- new BrowserPublicKeyCredentialCreationOptions.Builder() -- .setPublicKeyCredentialCreationOptions(requestOptions) -- .setOrigin(origin) -- .build(); -- -- final Task intentTask; -- - if (BuildConfig.MOZILLA_OFFICIAL) { - // Certain Fenix builds and signing keys are whitelisted for Web Authentication. - // See https://wiki.mozilla.org/Security/Web_Authentication @@ -237,7 +24,14 @@ diff -r 2d7ee05a65e0 mobile/android/geckoview/src/main/java/org/mozilla/geckovie - // Third party apps will need to get whitelisted themselves. - final Fido2PrivilegedApiClient fidoClient = - Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); -- ++ // The privileged FIDO2 API normally is restricted to apps with package ++ // names and signatures that Google knows to be a browser. microG does not ++ // have such a list, instead it asks the user to confirm that the app doing ++ // the request is indeed a browser app (only for the first request from ++ // that app). ++ final Fido2PrivilegedApiClient fidoClient = ++ Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); + - intentTask = fidoClient.getRegisterPendingIntent(browserOptions); - } else { - // For non-official builds, websites have to opt-in to permit the @@ -251,175 +45,24 @@ diff -r 2d7ee05a65e0 mobile/android/geckoview/src/main/java/org/mozilla/geckovie - - intentTask = fidoClient.getRegisterPendingIntent(requestOptions); - } -- ++ intentTask = fidoClient.getRegisterPendingIntent(browserOptions); + final GeckoResult result = new GeckoResult<>(); -- -- intentTask.addOnSuccessListener( -- pendingIntent -> { -- GeckoRuntime.getInstance() -- .startActivityForResult(pendingIntent) -- .accept( -- intent -> { -- final WebAuthnTokenManager.Exception error = parseErrorIntent(intent); -- if (error != null) { -- result.completeExceptionally(error); -- return; -- } -- -- final byte[] rspData = intent.getByteArrayExtra(Fido.FIDO2_KEY_RESPONSE_EXTRA); -- if (rspData != null) { -- final AuthenticatorAttestationResponse responseData = -- AuthenticatorAttestationResponse.deserializeFromBytes(rspData); -- -- Log.d( -- LOGTAG, -- "key handle: " -- + Base64.encodeToString(responseData.getKeyHandle(), Base64.DEFAULT)); -- Log.d( -- LOGTAG, -- "clientDataJSON: " -- + Base64.encodeToString( -- responseData.getClientDataJSON(), Base64.DEFAULT)); -- Log.d( -- LOGTAG, -- "attestation Object: " -- + Base64.encodeToString( -- responseData.getAttestationObject(), Base64.DEFAULT)); -- -- Log.d( -- LOGTAG, "transports: " + String.join(", ", responseData.getTransports())); -- -- result.complete( -- new WebAuthnTokenManager.MakeCredentialResponse( -- responseData.getClientDataJSON(), -- responseData.getKeyHandle(), -- responseData.getAttestationObject(), -- responseData.getTransports())); -- } -- }, -- e -> { -- Log.w(LOGTAG, "Failed to launch activity: ", e); -- result.completeExceptionally(new WebAuthnTokenManager.Exception("ABORT_ERR")); -- }); -- }); -- -- intentTask.addOnFailureListener( -- e -> { -- Log.w(LOGTAG, "Failed to get FIDO intent", e); -- result.completeExceptionally(new WebAuthnTokenManager.Exception("ABORT_ERR")); -- }); -- - return result; - } -@@ -351,36 +74,8 @@ - final ByteBuffer transportList, - final GeckoBundle authenticatorSelection, - final GeckoBundle extensions) { -- final ArrayList excludeList; -- -- final byte[] challBytes = new byte[challenge.remaining()]; -- final byte[] userBytes = new byte[userId.remaining()]; -- try { -- challenge.get(challBytes); -- userId.get(userBytes); -- -- excludeList = WebAuthnPublicCredential.CombineBuffers(idList, transportList); -- } catch (final RuntimeException e) { -- Log.w(LOGTAG, "Couldn't extract nio byte arrays!", e); -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR")); -- } -- -- try { -- return makeCredential( -- credentialBundle, -- userBytes, -- challBytes, -- excludeList.toArray(new WebAuthnPublicCredential[0]), -- authenticatorSelection, -- extensions); -- } catch (final Exception e) { -- // We need to ensure we catch any possible exception here in order to ensure -- // that the Promise on the content side is appropriately rejected. In particular, -- // we will get `NoClassDefFoundError` if we're running on a device that does not -- // have Google Play Services. -- Log.w(LOGTAG, "Couldn't make credential", e); -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR")); -- } -+ final GeckoResult result = new GeckoResult<>(); -+ return result; - } +@@ -464,19 +452,12 @@ + .build(); - @WrapForJNI -@@ -405,138 +100,12 @@ - } - } - -- private static WebAuthnTokenManager.Exception parseErrorIntent(final Intent intent) { -- if (!intent.hasExtra(Fido.FIDO2_KEY_ERROR_EXTRA)) { -- return null; -- } -- -- final byte[] errData = intent.getByteArrayExtra(Fido.FIDO2_KEY_ERROR_EXTRA); -- final AuthenticatorErrorResponse responseData = -- AuthenticatorErrorResponse.deserializeFromBytes(errData); -- -- Log.e(LOGTAG, "errorCode.name: " + responseData.getErrorCode()); -- Log.e(LOGTAG, "errorMessage: " + responseData.getErrorMessage()); -- -- return new WebAuthnTokenManager.Exception(responseData.getErrorCode().name()); -- } -- - private static GeckoResult getAssertion( - final byte[] challenge, - final WebAuthnTokenManager.WebAuthnPublicCredential[] allowList, - final GeckoBundle assertionBundle, - final GeckoBundle extensions) { -- -- if (!assertionBundle.containsKey("isWebAuthn")) { -- // FIDO U2F not supported by Android (for us anyway) at this time -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("NOT_SUPPORTED_ERR")); -- } -- -- final List allowedList = -- new ArrayList(); -- for (final WebAuthnTokenManager.WebAuthnPublicCredential cred : allowList) { -- allowedList.add( -- new PublicKeyCredentialDescriptor( -- PublicKeyCredentialType.PUBLIC_KEY.toString(), -- cred.id, -- getTransportsForByte(cred.transports))); -- } -- -- final AuthenticationExtensions.Builder extBuilder = new AuthenticationExtensions.Builder(); -- if (extensions.containsKey("fidoAppId")) { -- extBuilder.setFido2Extension(new FidoAppIdExtension(extensions.getString("fidoAppId"))); -- } -- final AuthenticationExtensions ext = extBuilder.build(); -- -- final PublicKeyCredentialRequestOptions requestOptions = -- new PublicKeyCredentialRequestOptions.Builder() -- .setChallenge(challenge) -- .setAllowList(allowedList) -- .setTimeoutSeconds(assertionBundle.getLong("timeoutMS") / 1000.0) -- .setRpId(assertionBundle.getString("rpId")) -- .setAuthenticationExtensions(ext) -- .build(); -- -- final Uri origin = Uri.parse(assertionBundle.getString("origin")); -- final BrowserPublicKeyCredentialRequestOptions browserOptions = -- new BrowserPublicKeyCredentialRequestOptions.Builder() -- .setPublicKeyCredentialRequestOptions(requestOptions) -- .setOrigin(origin) -- .build(); -- -- final Task intentTask; + final Task intentTask; - // See the makeCredential method for documentation about this - // conditional. - if (BuildConfig.MOZILLA_OFFICIAL) { - final Fido2PrivilegedApiClient fidoClient = - Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); -- ++ // See the makeCredential method for documentation about the FIDO2 API and ++ // microG. ++ final Fido2PrivilegedApiClient fidoClient = ++ Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); + - intentTask = fidoClient.getSignPendingIntent(browserOptions); - } else { - final Fido2ApiClient fidoClient = @@ -427,101 +70,14 @@ diff -r 2d7ee05a65e0 mobile/android/geckoview/src/main/java/org/mozilla/geckovie - - intentTask = fidoClient.getSignPendingIntent(requestOptions); - } -- ++ intentTask = fidoClient.getSignPendingIntent(browserOptions); + final GeckoResult result = new GeckoResult<>(); -- intentTask.addOnSuccessListener( -- pendingIntent -> { -- GeckoRuntime.getInstance() -- .startActivityForResult(pendingIntent) -- .accept( -- intent -> { -- final WebAuthnTokenManager.Exception error = parseErrorIntent(intent); -- if (error != null) { -- result.completeExceptionally(error); -- return; -- } -- -- if (intent.hasExtra(Fido.FIDO2_KEY_RESPONSE_EXTRA)) { -- final byte[] rspData = -- intent.getByteArrayExtra(Fido.FIDO2_KEY_RESPONSE_EXTRA); -- final AuthenticatorAssertionResponse responseData = -- AuthenticatorAssertionResponse.deserializeFromBytes(rspData); -- -- Log.d( -- LOGTAG, -- "key handle: " -- + Base64.encodeToString(responseData.getKeyHandle(), Base64.DEFAULT)); -- Log.d( -- LOGTAG, -- "clientDataJSON: " -- + Base64.encodeToString( -- responseData.getClientDataJSON(), Base64.DEFAULT)); -- Log.d( -- LOGTAG, -- "auth data: " -- + Base64.encodeToString( -- responseData.getAuthenticatorData(), Base64.DEFAULT)); -- Log.d( -- LOGTAG, -- "signature: " -- + Base64.encodeToString(responseData.getSignature(), Base64.DEFAULT)); -- -- // Nullable field -- byte[] userHandle = responseData.getUserHandle(); -- if (userHandle == null) { -- userHandle = new byte[0]; -- } -- -- result.complete( -- new WebAuthnTokenManager.GetAssertionResponse( -- responseData.getClientDataJSON(), -- responseData.getKeyHandle(), -- responseData.getAuthenticatorData(), -- responseData.getSignature(), -- userHandle)); -- } -- }, -- e -> { -- Log.w(LOGTAG, "Failed to get FIDO intent", e); -- result.completeExceptionally(new WebAuthnTokenManager.Exception("UNKNOWN_ERR")); -- }); -- }); -- - return result; - } - -@@ -547,52 +116,13 @@ - final ByteBuffer transportList, - final GeckoBundle assertionBundle, - final GeckoBundle extensions) { -- final ArrayList allowList; -- -- final byte[] challBytes = new byte[challenge.remaining()]; -- try { -- challenge.get(challBytes); -- allowList = WebAuthnPublicCredential.CombineBuffers(idList, transportList); -- } catch (final RuntimeException e) { -- Log.w(LOGTAG, "Couldn't extract nio byte arrays!", e); -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR")); -- } -- -- try { -- return getAssertion( -- challBytes, -- allowList.toArray(new WebAuthnPublicCredential[0]), -- assertionBundle, -- extensions); -- } catch (final java.lang.Exception e) { -- Log.w(LOGTAG, "Couldn't get assertion", e); -- return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR")); -- } -+ final GeckoResult result = new GeckoResult<>(); -+ return result; - } - + intentTask.addOnSuccessListener( +@@ -573,15 +554,9 @@ @WrapForJNI(calledFrom = "gecko") private static GeckoResult webAuthnIsUserVerifyingPlatformAuthenticatorAvailable() { -- final Task task; + final Task task; - if (BuildConfig.MOZILLA_OFFICIAL) { - final Fido2PrivilegedApiClient fidoClient = - Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); @@ -531,17 +87,9 @@ diff -r 2d7ee05a65e0 mobile/android/geckoview/src/main/java/org/mozilla/geckovie - Fido.getFido2ApiClient(GeckoAppShell.getApplicationContext()); - task = fidoClient.isUserVerifyingPlatformAuthenticatorAvailable(); - } -- ++ final Fido2PrivilegedApiClient fidoClient = ++ Fido.getFido2PrivilegedApiClient(GeckoAppShell.getApplicationContext()); ++ task = fidoClient.isUserVerifyingPlatformAuthenticatorAvailable(); + final GeckoResult res = new GeckoResult<>(); -- task.addOnSuccessListener( -- isUVPAA -> { -- res.complete(isUVPAA); -- }); -- task.addOnFailureListener( -- e -> { -- Log.w(LOGTAG, "isUserVerifyingPlatformAuthenticatorAvailable is failed", e); -- res.complete(false); -- }); - return res; - } - } + task.addOnSuccessListener( diff --git a/paths.sh b/paths.sh index ce74f44..4a06cf5 100644 --- a/paths.sh +++ b/paths.sh @@ -27,3 +27,4 @@ readonly fenix=$(realpath ./fenix) readonly mozilla_release=$(realpath ../srclib/MozFennec) readonly rustup=$(realpath ../srclib/rustup) readonly wasi=$(realpath ../srclib/wasi-sdk) +readonly gmscore=$(realpath ../srclib/gmscore) diff --git a/prebuild.sh b/prebuild.sh index e99f7ac..421c557 100755 --- a/prebuild.sh +++ b/prebuild.sh @@ -258,12 +258,7 @@ hg revert media/openmax_dl -r ebd43acaeeb3a5b82ab6a9027ab88fa2a72aea81 # Revert https://bugzilla.mozilla.org/show_bug.cgi?id=1836826 hg revert media/libvpx -r 699059262f56 -# Remove proprietary libraries -sed -i \ - -e '/com.google.android.gms/d' \ - mobile/android/geckoview/build.gradle - -# Patch the use of proprietary libraries +# Replace GMS with microG client library patch -p1 --no-backup-if-mismatch --quiet < "$patches/gecko-liberate.patch" # Fixup, unsupported on Android @@ -344,9 +339,6 @@ pref("media.gmp-gmpopenh264.enabled", false); // Disable casting (Roku, Chromecast) pref("browser.casting.enabled", false); - -// Disable WebAuthn, since it is a stub -pref("security.webauth.webauthn", false); EOF popd