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

Commit

Permalink
AC WebExtensions + WebCompat + FxAWebChannels (#3498)
Browse files Browse the repository at this point in the history
Co-authored-by: Randall E. Barker <simstorm@mac.com>
  • Loading branch information
keianhzo and bluemarvin authored Jun 23, 2020
1 parent 31d8a7c commit df4c777
Show file tree
Hide file tree
Showing 31 changed files with 1,252 additions and 106 deletions.
Binary file removed app/aars/appcompat.aar
Binary file not shown.
11 changes: 5 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ android {
configurations {
armImplementation
x86Implementation
all*.exclude group: 'androidx.appcompat', module: 'appcompat'
}

repositories {
Expand All @@ -414,8 +413,7 @@ dependencies {
implementation deps.lifecycle.runtime
implementation deps.lifecycle.viewmodel
implementation deps.support.cardview
//implementation deps.support.app_compat
implementation(name:'appcompat', ext:'aar')
implementation deps.support.app_compat
implementation deps.support.vector_drawable
implementation deps.support.annotations
implementation deps.constraint_layout
Expand All @@ -429,24 +427,25 @@ dependencies {
implementation deps.android_components.telemetry
implementation deps.android_components.browser_errorpages
implementation deps.android_components.browser_search
implementation deps.android_components.browser_state
implementation deps.android_components.browser_storage
implementation deps.android_components.browser_domains
implementation deps.android_components.service_accounts
implementation deps.android_components.mozilla_service_location
implementation deps.android_components.ui_autocomplete
implementation deps.android_components.concept_engine
implementation deps.android_components.concept_fetch
implementation deps.android_components.lib_fetch
implementation deps.android_components.support_rustlog
implementation deps.android_components.support_rusthttp
implementation deps.android_components.feature_accounts
implementation deps.android_components.feature_webcompat
implementation deps.android_components.glean
implementation deps.app_services.rustlog

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

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

// Kotlin dependency
implementation deps.kotlin.stdlib
implementation deps.kotlin.coroutines
Expand Down
18 changes: 2 additions & 16 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,7 @@ protected void onCreate(Bundle savedInstanceState) {
BitmapCache.getInstance(this).onCreate();

Bundle extras = getIntent() != null ? getIntent().getExtras() : null;
SessionStore.get().setContext(this, extras);
SessionStore.get().initializeServices();
SessionStore.get().initializeStores(this);
SessionStore.get().initialize(this, extras);
SessionStore.get().setLocales(LocaleUtils.getPreferredLanguageTags(this));

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

EngineProvider.INSTANCE.loadExtensions()
.thenAcceptAsync(aVoid -> {
Log.d(LOGTAG, "WebExtensions loaded");
mWindows.restoreSessions();
}, getServicesProvider().getExecutors().mainThread())
.exceptionally(throwable -> {
String msg = throwable.getLocalizedMessage();
if (msg != null) {
Log.e(LOGTAG, "Extensions load error: " + msg);
}
mWindows.restoreSessions();
return null;
});
mWindows.restoreSessions();
}

private void attachToWindow(@NonNull WindowWidget aWindow, @Nullable WindowWidget aPrevWindow) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.mozilla.vrbrowser.browser.Accounts;
import org.mozilla.vrbrowser.browser.Places;
import org.mozilla.vrbrowser.browser.Services;
import org.mozilla.vrbrowser.browser.engine.EngineProvider;
import org.mozilla.vrbrowser.db.AppDatabase;
import org.mozilla.vrbrowser.db.DataRepository;
import org.mozilla.vrbrowser.downloads.DownloadsManager;
Expand All @@ -37,11 +38,6 @@ public class VRBrowserApplication extends Application implements AppServicesProv
@Override
public void onCreate() {
super.onCreate();
mAppExecutors = new AppExecutors();
mBitmapCache = new BitmapCache(this, mAppExecutors.diskIO(), mAppExecutors.mainThread());

TelemetryWrapper.init(this);
GleanMetricsService.init(this);
}

protected void onActivityCreate() {
Expand All @@ -50,6 +46,11 @@ protected void onActivityCreate() {
mAccounts = new Accounts(this);
mDownloadsManager = new DownloadsManager(this);
mSpeechService = new SpeechService(this);
mAppExecutors = new AppExecutors();
mBitmapCache = new BitmapCache(this, mAppExecutors.diskIO(), mAppExecutors.mainThread());

TelemetryWrapper.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
GleanMetricsService.init(this, EngineProvider.INSTANCE.getDefaultClient(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel

companion object {
const val CLIENT_ID = "7ad9917f6c55fb77"
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
const val REDIRECT_URL = "urn:ietf:wg:oauth:2.0:oob:oauth-redirect-webchannel"
}
interface TabReceivedDelegate {
fun onTabsReceived(uri: List<TabData>)
Expand Down Expand Up @@ -98,9 +98,11 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel
}
}
}
public val serverConfig = ServerConfig(Server.RELEASE, CLIENT_ID, REDIRECT_URL)

val accountManager = FxaAccountManager(
context = context,
serverConfig = ServerConfig(Server.RELEASE, CLIENT_ID, REDIRECT_URL),
serverConfig = serverConfig,
deviceConfig = DeviceConfig(
// This is a default name, and can be changed once user is logged in.
// E.g. accountManager.authenticatedAccount()?.deviceConstellation()?.setDeviceNameAsync("new name")
Expand Down Expand Up @@ -150,4 +152,5 @@ class Services(val context: Context, places: Places): GeckoSession.NavigationDel

return GeckoResult.ALLOW
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import org.mozilla.vrbrowser.browser.engine.Session;

public interface SessionChangeListener {
default void onRemoveSession(Session aSession) {}
default void onSessionAdded(Session aSession) {}
default void onSessionOpened(Session aSession) {}
default void onSessionClosed(String aId) {}
default void onSessionRemoved(String aId) {}
default void onSessionStateChanged(Session aSession, boolean aActive) {}
default void onCurrentSessionChange(GeckoSession aOldSession, GeckoSession aSession) {}
default void onStackSession(Session aSession) {}
default void onUnstackSession(Session aSession, Session aParent) {}
default void onActiveStateChange(Session aSession, boolean aActive) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public void setTelemetryEnabled(boolean isEnabled) {
// If the state of Telemetry is not the same, we reinitialize it.
final boolean hasEnabled = isTelemetryEnabled();
if (hasEnabled != isEnabled) {
TelemetryWrapper.init(mContext);
TelemetryWrapper.init(mContext, EngineProvider.INSTANCE.getDefaultClient(mContext));
}

TelemetryHolder.get().getConfiguration().setUploadEnabled(isEnabled);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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 org.mozilla.vrbrowser.browser.adapter

import mozilla.components.browser.state.action.EngineAction
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.state.ContentState
import mozilla.components.browser.state.state.EngineState
import mozilla.components.browser.state.state.ReaderState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
import org.mozilla.geckoview.GeckoSession
import org.mozilla.vrbrowser.browser.components.GeckoEngineSession
import org.mozilla.vrbrowser.browser.engine.Session

class ComponentsAdapter private constructor(
val store: BrowserStore = BrowserStore()
) {
companion object {
private val instance: ComponentsAdapter = ComponentsAdapter()

@JvmStatic
fun get(): ComponentsAdapter = instance
}

fun addSession(session: Session) {
store.dispatch(TabListAction.AddTabAction(
tab = session.toTabSessionState()
))
}

fun removeSession(id: String) {
store.dispatch(TabListAction.RemoveTabAction(
tabId = id
))
}

fun selectSession(session: Session) {
store.dispatch(TabListAction.SelectTabAction(
tabId = session.id
))
}

fun link(tabId: String, geckoSession: GeckoSession) {
store.dispatch(EngineAction.LinkEngineSessionAction(
tabId,
GeckoEngineSession(geckoSession)
))
}

fun unlink(tabId: String) {
store.dispatch(EngineAction.UnlinkEngineSessionAction(
tabId
))
}
}

private fun Session.toTabSessionState(): TabSessionState {
return TabSessionState(
id = id,
content = ContentState(
url = currentUri,
private = isPrivateMode,
title = currentTitle
),
parentId = null,
extensionState = emptyMap(),
readerState = ReaderState(),
engineState = EngineState(
GeckoEngineSession(geckoSession),
null
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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 org.mozilla.vrbrowser.browser.components

import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineSessionState
import mozilla.components.concept.engine.Settings
import org.json.JSONObject
import org.mozilla.geckoview.GeckoSession
import org.mozilla.vrbrowser.browser.engine.SessionStore

class GeckoEngineSession(
val geckoSession: GeckoSession
): EngineSession() {
constructor() :
this(SessionStore.get().createSession(false, false).geckoSession)

override fun loadUrl(url: String, parent: EngineSession?, flags: LoadUrlFlags, additionalHeaders: Map<String, String>?) {
geckoSession.loadUri(url)
}

override val settings: Settings = object : Settings() {}
override fun clearFindMatches() = Unit
override fun disableTrackingProtection() = Unit
override fun enableTrackingProtection(policy: TrackingProtectionPolicy) = Unit
override fun exitFullScreenMode() = Unit
override fun findAll(text: String) = Unit
override fun findNext(forward: Boolean) = Unit
override fun goBack() = Unit
override fun goForward() = Unit
override fun loadData(data: String, mimeType: String, encoding: String) = Unit
override fun recoverFromCrash(): Boolean = true
override fun reload() = Unit
override fun restoreState(state: EngineSessionState) = true
override fun saveState(): EngineSessionState = DummyEngineSessionState()
override fun stopLoading() = Unit
override fun toggleDesktopMode(enable: Boolean, reload: Boolean) = Unit
}

private class DummyEngineSessionState : EngineSessionState {
override fun toJSON(): JSONObject = JSONObject()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* 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 org.mozilla.vrbrowser.browser.components

import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.launch
import mozilla.components.concept.engine.CancellableOperation
import org.mozilla.geckoview.GeckoResult
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

/**
* Wait for a GeckoResult to be complete in a co-routine.
*/
suspend fun <T> GeckoResult<T>.await() = suspendCoroutine<T?> { continuation ->
then({
continuation.resume(it)
GeckoResult<Void>()
}, {
continuation.resumeWithException(it)
GeckoResult<Void>()
})
}

/**
* Converts a [GeckoResult] to a [CancellableOperation].
*/
fun <T> GeckoResult<T>.asCancellableOperation(): CancellableOperation {
val geckoResult = this
return object : CancellableOperation {
override fun cancel(): Deferred<Boolean> {
val result = CompletableDeferred<Boolean>()
geckoResult.cancel().then({
result.complete(it ?: false)
GeckoResult<Void>()
}, { throwable ->
result.completeExceptionally(throwable)
GeckoResult<Void>()
})
return result
}
}
}

/**
* Create a GeckoResult from a co-routine.
*/
@Suppress("TooGenericExceptionCaught")
fun <T> CoroutineScope.launchGeckoResult(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
) = GeckoResult<T>().apply {
launch(context, start) {
try {
val value = block()
complete(value)
} catch (exception: Throwable) {
completeExceptionally(exception)
}
}
}
Loading

0 comments on commit df4c777

Please sign in to comment.