Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit df4c777

Browse files
keianhzobluemarvin
andauthored
AC WebExtensions + WebCompat + FxAWebChannels (#3498)
Co-authored-by: Randall E. Barker <[email protected]>
1 parent 31d8a7c commit df4c777

31 files changed

Lines changed: 1252 additions & 106 deletions

app/aars/appcompat.aar

-1.03 MB
Binary file not shown.

app/build.gradle

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,6 @@ android {
397397
configurations {
398398
armImplementation
399399
x86Implementation
400-
all*.exclude group: 'androidx.appcompat', module: 'appcompat'
401400
}
402401

403402
repositories {
@@ -414,8 +413,7 @@ dependencies {
414413
implementation deps.lifecycle.runtime
415414
implementation deps.lifecycle.viewmodel
416415
implementation deps.support.cardview
417-
//implementation deps.support.app_compat
418-
implementation(name:'appcompat', ext:'aar')
416+
implementation deps.support.app_compat
419417
implementation deps.support.vector_drawable
420418
implementation deps.support.annotations
421419
implementation deps.constraint_layout
@@ -429,24 +427,25 @@ dependencies {
429427
implementation deps.android_components.telemetry
430428
implementation deps.android_components.browser_errorpages
431429
implementation deps.android_components.browser_search
430+
implementation deps.android_components.browser_state
432431
implementation deps.android_components.browser_storage
433432
implementation deps.android_components.browser_domains
434433
implementation deps.android_components.service_accounts
435434
implementation deps.android_components.mozilla_service_location
436435
implementation deps.android_components.ui_autocomplete
436+
implementation deps.android_components.concept_engine
437437
implementation deps.android_components.concept_fetch
438438
implementation deps.android_components.lib_fetch
439439
implementation deps.android_components.support_rustlog
440440
implementation deps.android_components.support_rusthttp
441+
implementation deps.android_components.feature_accounts
442+
implementation deps.android_components.feature_webcompat
441443
implementation deps.android_components.glean
442444
implementation deps.app_services.rustlog
443445

444446
// TODO this should not be necessary at all, see Services.kt
445447
implementation deps.work.runtime
446448

447-
// TODO this should not be necessary at all, see Services.kt
448-
implementation deps.work.runtime
449-
450449
// Kotlin dependency
451450
implementation deps.kotlin.stdlib
452451
implementation deps.kotlin.coroutines

app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,7 @@ protected void onCreate(Bundle savedInstanceState) {
252252
BitmapCache.getInstance(this).onCreate();
253253

254254
Bundle extras = getIntent() != null ? getIntent().getExtras() : null;
255-
SessionStore.get().setContext(this, extras);
256-
SessionStore.get().initializeServices();
257-
SessionStore.get().initializeStores(this);
255+
SessionStore.get().initialize(this, extras);
258256
SessionStore.get().setLocales(LocaleUtils.getPreferredLanguageTags(this));
259257

260258
EngineProvider.INSTANCE.getOrCreateRuntime(this).appendAppNotesToCrashReport("Firefox Reality " + BuildConfig.VERSION_NAME + "-" + BuildConfig.VERSION_CODE + "-" + BuildConfig.FLAVOR + "-" + BuildConfig.BUILD_TYPE + " (" + BuildConfig.GIT_HASH + ")");
@@ -393,19 +391,7 @@ public void onWindowVideoAvailabilityChanged(@NonNull WindowWidget aWindow) {
393391
mWhatsNewWidget.show(UIWidget.REQUEST_FOCUS);
394392
}
395393

396-
EngineProvider.INSTANCE.loadExtensions()
397-
.thenAcceptAsync(aVoid -> {
398-
Log.d(LOGTAG, "WebExtensions loaded");
399-
mWindows.restoreSessions();
400-
}, getServicesProvider().getExecutors().mainThread())
401-
.exceptionally(throwable -> {
402-
String msg = throwable.getLocalizedMessage();
403-
if (msg != null) {
404-
Log.e(LOGTAG, "Extensions load error: " + msg);
405-
}
406-
mWindows.restoreSessions();
407-
return null;
408-
});
394+
mWindows.restoreSessions();
409395
}
410396

411397
private void attachToWindow(@NonNull WindowWidget aWindow, @Nullable WindowWidget aPrevWindow) {

app/src/common/shared/org/mozilla/vrbrowser/VRBrowserApplication.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.mozilla.vrbrowser.browser.Accounts;
1515
import org.mozilla.vrbrowser.browser.Places;
1616
import org.mozilla.vrbrowser.browser.Services;
17+
import org.mozilla.vrbrowser.browser.engine.EngineProvider;
1718
import org.mozilla.vrbrowser.db.AppDatabase;
1819
import org.mozilla.vrbrowser.db.DataRepository;
1920
import org.mozilla.vrbrowser.downloads.DownloadsManager;
@@ -37,11 +38,6 @@ public class VRBrowserApplication extends Application implements AppServicesProv
3738
@Override
3839
public void onCreate() {
3940
super.onCreate();
40-
mAppExecutors = new AppExecutors();
41-
mBitmapCache = new BitmapCache(this, mAppExecutors.diskIO(), mAppExecutors.mainThread());
42-
43-
TelemetryWrapper.init(this);
44-
GleanMetricsService.init(this);
4541
}
4642

4743
protected void onActivityCreate() {
@@ -50,6 +46,11 @@ protected void onActivityCreate() {
5046
mAccounts = new Accounts(this);
5147
mDownloadsManager = new DownloadsManager(this);
5248
mSpeechService = new SpeechService(this);
49+
mAppExecutors = new AppExecutors();
50+
mBitmapCache = new BitmapCache(this, mAppExecutors.diskIO(), mAppExecutors.mainThread());
51+
52+
TelemetryWrapper.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
53+
GleanMetricsService.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
5354
}
5455

5556
@Override

app/src/common/shared/org/mozilla/vrbrowser/browser/Services.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel
4040

4141
companion object {
4242
const val CLIENT_ID = "7ad9917f6c55fb77"
43-
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
43+
const val REDIRECT_URL = "urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
4444
}
4545
interface TabReceivedDelegate {
4646
fun onTabsReceived(uri: List<TabData>)
@@ -98,9 +98,11 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel
9898
}
9999
}
100100
}
101+
public val serverConfig = ServerConfig(Server.RELEASE, CLIENT_ID, REDIRECT_URL)
102+
101103
val accountManager = FxaAccountManager(
102104
context = context,
103-
serverConfig = ServerConfig(Server.RELEASE, CLIENT_ID, REDIRECT_URL),
105+
serverConfig = serverConfig,
104106
deviceConfig = DeviceConfig(
105107
// This is a default name, and can be changed once user is logged in.
106108
// E.g. accountManager.authenticatedAccount()?.deviceConstellation()?.setDeviceNameAsync("new name")
@@ -150,4 +152,5 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel
150152

151153
return GeckoResult.ALLOW
152154
}
155+
153156
}

app/src/common/shared/org/mozilla/vrbrowser/browser/SessionChangeListener.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
import org.mozilla.vrbrowser.browser.engine.Session;
55

66
public interface SessionChangeListener {
7-
default void onRemoveSession(Session aSession) {}
7+
default void onSessionAdded(Session aSession) {}
8+
default void onSessionOpened(Session aSession) {}
9+
default void onSessionClosed(String aId) {}
10+
default void onSessionRemoved(String aId) {}
11+
default void onSessionStateChanged(Session aSession, boolean aActive) {}
812
default void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSession) {}
913
default void onStackSession(Session aSession) {}
1014
default void onUnstackSession(Session aSession, Session aParent) {}
11-
default void onActiveStateChange(Session aSession, boolean aActive) {}
1215
}

app/src/common/shared/org/mozilla/vrbrowser/browser/SettingsStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ public void setTelemetryEnabled(boolean isEnabled) {
205205
// If the state of Telemetry is not the same, we reinitialize it.
206206
final boolean hasEnabled = isTelemetryEnabled();
207207
if (hasEnabled != isEnabled) {
208-
TelemetryWrapper.init(mContext);
208+
TelemetryWrapper.init(mContext, EngineProvider.INSTANCE.getDefaultClient(mContext));
209209
}
210210

211211
TelemetryHolder.get().getConfiguration().setUploadEnabled(isEnabled);
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
package org.mozilla.vrbrowser.browser.adapter
7+
8+
import mozilla.components.browser.state.action.EngineAction
9+
import mozilla.components.browser.state.action.TabListAction
10+
import mozilla.components.browser.state.state.ContentState
11+
import mozilla.components.browser.state.state.EngineState
12+
import mozilla.components.browser.state.state.ReaderState
13+
import mozilla.components.browser.state.state.TabSessionState
14+
import mozilla.components.browser.state.store.BrowserStore
15+
import org.mozilla.geckoview.GeckoSession
16+
import org.mozilla.vrbrowser.browser.components.GeckoEngineSession
17+
import org.mozilla.vrbrowser.browser.engine.Session
18+
19+
class ComponentsAdapter private constructor(
20+
val store: BrowserStore = BrowserStore()
21+
) {
22+
companion object {
23+
private val instance: ComponentsAdapter = ComponentsAdapter()
24+
25+
@JvmStatic
26+
fun get(): ComponentsAdapter = instance
27+
}
28+
29+
fun addSession(session: Session) {
30+
store.dispatch(TabListAction.AddTabAction(
31+
tab = session.toTabSessionState()
32+
))
33+
}
34+
35+
fun removeSession(id: String) {
36+
store.dispatch(TabListAction.RemoveTabAction(
37+
tabId = id
38+
))
39+
}
40+
41+
fun selectSession(session: Session) {
42+
store.dispatch(TabListAction.SelectTabAction(
43+
tabId = session.id
44+
))
45+
}
46+
47+
fun link(tabId: String, geckoSession: GeckoSession) {
48+
store.dispatch(EngineAction.LinkEngineSessionAction(
49+
tabId,
50+
GeckoEngineSession(geckoSession)
51+
))
52+
}
53+
54+
fun unlink(tabId: String) {
55+
store.dispatch(EngineAction.UnlinkEngineSessionAction(
56+
tabId
57+
))
58+
}
59+
}
60+
61+
private fun Session.toTabSessionState(): TabSessionState {
62+
return TabSessionState(
63+
id = id,
64+
content = ContentState(
65+
url = currentUri,
66+
private = isPrivateMode,
67+
title = currentTitle
68+
),
69+
parentId = null,
70+
extensionState = emptyMap(),
71+
readerState = ReaderState(),
72+
engineState = EngineState(
73+
GeckoEngineSession(geckoSession),
74+
null
75+
)
76+
)
77+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
package org.mozilla.vrbrowser.browser.components
7+
8+
import mozilla.components.concept.engine.EngineSession
9+
import mozilla.components.concept.engine.EngineSessionState
10+
import mozilla.components.concept.engine.Settings
11+
import org.json.JSONObject
12+
import org.mozilla.geckoview.GeckoSession
13+
import org.mozilla.vrbrowser.browser.engine.SessionStore
14+
15+
class GeckoEngineSession(
16+
val geckoSession: GeckoSession
17+
): EngineSession() {
18+
constructor() :
19+
this(SessionStore.get().createSession(false, false).geckoSession)
20+
21+
override fun loadUrl(url: String, parent: EngineSession?, flags: LoadUrlFlags, additionalHeaders: Map<String, String>?) {
22+
geckoSession.loadUri(url)
23+
}
24+
25+
override val settings: Settings = object : Settings() {}
26+
override fun clearFindMatches() = Unit
27+
override fun disableTrackingProtection() = Unit
28+
override fun enableTrackingProtection(policy: TrackingProtectionPolicy) = Unit
29+
override fun exitFullScreenMode() = Unit
30+
override fun findAll(text: String) = Unit
31+
override fun findNext(forward: Boolean) = Unit
32+
override fun goBack() = Unit
33+
override fun goForward() = Unit
34+
override fun loadData(data: String, mimeType: String, encoding: String) = Unit
35+
override fun recoverFromCrash(): Boolean = true
36+
override fun reload() = Unit
37+
override fun restoreState(state: EngineSessionState) = true
38+
override fun saveState(): EngineSessionState = DummyEngineSessionState()
39+
override fun stopLoading() = Unit
40+
override fun toggleDesktopMode(enable: Boolean, reload: Boolean) = Unit
41+
}
42+
43+
private class DummyEngineSessionState : EngineSessionState {
44+
override fun toJSON(): JSONObject = JSONObject()
45+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
package org.mozilla.vrbrowser.browser.components
7+
8+
import kotlinx.coroutines.CompletableDeferred
9+
import kotlinx.coroutines.CoroutineScope
10+
import kotlinx.coroutines.CoroutineStart
11+
import kotlinx.coroutines.Deferred
12+
import kotlinx.coroutines.launch
13+
import mozilla.components.concept.engine.CancellableOperation
14+
import org.mozilla.geckoview.GeckoResult
15+
import kotlin.coroutines.CoroutineContext
16+
import kotlin.coroutines.EmptyCoroutineContext
17+
import kotlin.coroutines.resume
18+
import kotlin.coroutines.resumeWithException
19+
import kotlin.coroutines.suspendCoroutine
20+
21+
/**
22+
* Wait for a GeckoResult to be complete in a co-routine.
23+
*/
24+
suspend fun <T> GeckoResult<T>.await() = suspendCoroutine<T?> { continuation ->
25+
then({
26+
continuation.resume(it)
27+
GeckoResult<Void>()
28+
}, {
29+
continuation.resumeWithException(it)
30+
GeckoResult<Void>()
31+
})
32+
}
33+
34+
/**
35+
* Converts a [GeckoResult] to a [CancellableOperation].
36+
*/
37+
fun <T> GeckoResult<T>.asCancellableOperation(): CancellableOperation {
38+
val geckoResult = this
39+
return object : CancellableOperation {
40+
override fun cancel(): Deferred<Boolean> {
41+
val result = CompletableDeferred<Boolean>()
42+
geckoResult.cancel().then({
43+
result.complete(it ?: false)
44+
GeckoResult<Void>()
45+
}, { throwable ->
46+
result.completeExceptionally(throwable)
47+
GeckoResult<Void>()
48+
})
49+
return result
50+
}
51+
}
52+
}
53+
54+
/**
55+
* Create a GeckoResult from a co-routine.
56+
*/
57+
@Suppress("TooGenericExceptionCaught")
58+
fun <T> CoroutineScope.launchGeckoResult(
59+
context: CoroutineContext = EmptyCoroutineContext,
60+
start: CoroutineStart = CoroutineStart.DEFAULT,
61+
block: suspend CoroutineScope.() -> T
62+
) = GeckoResult<T>().apply {
63+
launch(context, start) {
64+
try {
65+
val value = block()
66+
complete(value)
67+
} catch (exception: Throwable) {
68+
completeExceptionally(exception)
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)