Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
felipeerias committed Jan 22, 2025
1 parent 2b9d1e0 commit 2c22b48
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 12 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,10 @@ dependencies {
implementation deps.android_components.support_webextensions
implementation deps.android_components.support_ktx
implementation deps.android_components.feature_accounts
implementation deps.android_components.concept_push
implementation deps.android_components.feature_push
implementation deps.android_components.feature_accounts_push
implementation deps.android_components.lib_push_firebase
implementation deps.android_components.feature_webcompat
implementation deps.android_components.feature_webcompat_reporter
implementation deps.android_components.feature_addons
Expand Down
114 changes: 105 additions & 9 deletions app/src/common/shared/com/igalia/wolvic/browser/Accounts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,38 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.future.future
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import mozilla.components.concept.sync.*
import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthFlowError
import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.ConstellationState
import mozilla.components.concept.sync.Device
import mozilla.components.concept.sync.DeviceCapability
import mozilla.components.concept.sync.DeviceCommandOutgoing
import mozilla.components.concept.sync.DeviceConstellationObserver
import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.concept.sync.Profile
import mozilla.components.feature.accounts.push.FxaPushSupportFeature
import mozilla.components.feature.accounts.push.SendTabFeature
import mozilla.components.feature.push.AutoPushFeature
import mozilla.components.feature.push.PushConfig
import mozilla.components.feature.push.PushScope
import mozilla.components.lib.push.firebase.AbstractFirebasePushService
import mozilla.components.service.fxa.FirefoxAccount
import mozilla.components.service.fxa.SyncEngine
import mozilla.components.service.fxa.manager.SyncEnginesStorage
import mozilla.components.service.fxa.sync.SyncReason
import mozilla.components.service.fxa.sync.SyncStatusObserver
import mozilla.components.service.fxa.sync.getLastSynced
import mozilla.components.support.base.log.logger.Logger
import org.json.JSONObject
import java.net.URL
import java.util.concurrent.CompletableFuture
import kotlin.concurrent.thread

const val PROFILE_PICTURE_TAG = "fxa_profile_picture"

class FirebasePushService : AbstractFirebasePushService()

class Accounts constructor(val context: Context) {

private val LOGTAG = SystemUtils.createLogtag(Accounts::class.java)
Expand Down Expand Up @@ -74,6 +93,7 @@ class Accounts constructor(val context: Context) {
private val syncStatusObserver = object : SyncStatusObserver {
override fun onStarted() {
Log.d(LOGTAG, "Account syncing has started")
Logger(LOGTAG).error("TabReceived : SyncStatusObserver Account syncing has started")

isSyncing = true
syncListeners.toMutableList().forEach {
Expand All @@ -85,6 +105,7 @@ class Accounts constructor(val context: Context) {

override fun onIdle() {
Log.d(LOGTAG, "Account syncing has finished")
Logger(LOGTAG).error("TabReceived : SyncStatusObserver Account syncing has finished")

isSyncing = false

Expand All @@ -101,6 +122,7 @@ class Accounts constructor(val context: Context) {

override fun onError(error: Exception?) {
Log.d(LOGTAG, "There was an error while syncing the account: " + error?.localizedMessage)
Logger(LOGTAG).error("TabReceived : SyncStatusObserver There was an error while syncing the account: " + error?.localizedMessage)

isSyncing = false
syncListeners.toMutableList().forEach {
Expand All @@ -127,12 +149,16 @@ class Accounts constructor(val context: Context) {
private val accountObserver = object : AccountObserver {
override fun onAuthenticated(account: OAuthAccount, authType: AuthType) {
Log.d(LOGTAG, "The user has been successfully logged in")
Logger(LOGTAG).error("TabReceived : AccountObserver The user has been successfully logged in account: " + account)

Logger(LOGTAG).error("TabReceived : " + account.toJSONString())

if (authType !== AuthType.Existing) {
TelemetryService.FxA.signInResult(true)
}

accountStatus = AccountStatus.SIGNED_IN
Logger(LOGTAG).error("TabReceived : onAuthenticated account status $accountStatus")

// We must delay applying the device name from settings after we are authenticated
// as we will stuck if we get it directly when initializing services.accountManager
Expand All @@ -155,28 +181,68 @@ class Accounts constructor(val context: Context) {
it.onAuthenticated(account, authType)
}
originSessionId = null
}

runBlocking {
refreshJob = launch {
while (isSignedIn()) {
Log.d(LOGTAG, "Polling for events")
pollForEventsAsync()
kotlinx.coroutines.delay(10000)
var jsonString = (account as FirefoxAccount).toJSONString()
var senderId: String? = runCatching {
JSONObject(jsonString).optJSONObject("config")?.optString("client_id", null)
}.getOrNull()


senderId = runCatching {
JSONObject(jsonString).optJSONObject("server_local_device_info")
?.optString("id", null)
}.getOrNull()

Logger(LOGTAG).error("TabReceived : onAuthenticated client_id $senderId")

var pushConfig = PushConfig(
senderId = senderId.toString()
)
Logger(LOGTAG).error("TabReceived : onAuthenticated push config $pushConfig")

var autoPushFeature = AutoPushFeature(
context = context,
service = FirebasePushService(),
config = pushConfig
)
autoPushFeature.register(object : AutoPushFeature.Observer {
override fun onSubscriptionChanged(scope: PushScope) {
Logger(LOGTAG).error("TabReceived : autoPushFeature onSubscriptionChanged $scope")
}

override fun onMessageReceived(scope: PushScope, message: ByteArray?) {
Logger(LOGTAG).error("TabReceived : autoPushFeature onMessageReceived $scope $message")
}
})
Logger(LOGTAG).error("TabReceived : onAuthenticated auto push feature $autoPushFeature")

// this works, but the push configuration does not
SendTabFeature(services.accountManager) { device, tabs ->
tabs.forEach { tab ->
Logger(LOGTAG).error("TabReceived : Received tab: Device=$device Title=${tab.title}, URL=${tab.url}")
}
}

// manual sync shows "Current device needs push endpoint registration, so checking for missed commands"
var fxaPushSupportFeature =
FxaPushSupportFeature(context, services.accountManager, autoPushFeature)
fxaPushSupportFeature.initialize()
Logger(LOGTAG).error("TabReceived : onAuthenticated auto push feature $fxaPushSupportFeature")
}

}

override fun onAuthenticationProblems() {
Log.d(LOGTAG, "There was a problem authenticating the user")
Logger(LOGTAG).error("TabReceived : AccountObserver There was a problem authenticating the user")

TelemetryService.FxA.signInResult(false)

originSessionId = null
refreshJob?.cancel(null)

accountStatus = AccountStatus.NEEDS_RECONNECT
Logger(LOGTAG).error("TabReceived : onAuthenticationProblems account status $accountStatus")
accountListeners.toMutableList().forEach {
Handler(Looper.getMainLooper()).post {
it.onAuthenticationProblems()
Expand All @@ -186,11 +252,13 @@ class Accounts constructor(val context: Context) {

override fun onLoggedOut() {
Log.d(LOGTAG, "The user has been logged out")
Logger(LOGTAG).error("TabReceived : AccountObserver The user has been logged out")

originSessionId = null
refreshJob?.cancel(null)

accountStatus = AccountStatus.SIGNED_OUT
Logger(LOGTAG).error("TabReceived : onLoggedOut account status $accountStatus")
accountListeners.toMutableList().forEach {
Handler(Looper.getMainLooper()).post {
it.onLoggedOut()
Expand All @@ -202,6 +270,7 @@ class Accounts constructor(val context: Context) {

override fun onProfileUpdated(profile: Profile) {
Log.d(LOGTAG, "The user profile has been updated")
Logger(LOGTAG).error("TabReceived : AccountObserver The user profile has been updated profile: " + profile)

accountListeners.toMutableList().forEach {
Handler(Looper.getMainLooper()).post {
Expand All @@ -211,14 +280,27 @@ class Accounts constructor(val context: Context) {

loadProfilePicture(profile)
}

override fun onFlowError(error: AuthFlowError) {
Logger(LOGTAG).error("TabReceived : AccountObserver onFlowError $error")
super.onFlowError(error)
}

override fun onReady(authenticatedAccount: OAuthAccount?) {
Logger(LOGTAG).error("TabReceived : AccountObserver onReady account: $authenticatedAccount")
super.onReady(authenticatedAccount)
}
}

init {
Logger(LOGTAG).error("TabReceived : ${services.accountManager} register")
services.accountManager.register(accountObserver)
Logger(LOGTAG).error("TabReceived : ${services.accountManager} registerForSyncEvents")
services.accountManager.registerForSyncEvents(
syncStatusObserver, ProcessLifecycleOwner.get(), false
)
services.accountManager.register(accountObserver)
accountStatus = if (services.accountManager.authenticatedAccount() != null) {
Logger(LOGTAG).error("TabReceived : account " + services.accountManager.authenticatedAccount())
if (services.accountManager.accountNeedsReauth()) {
AccountStatus.NEEDS_RECONNECT

Expand All @@ -229,6 +311,11 @@ class Accounts constructor(val context: Context) {
} else {
AccountStatus.SIGNED_OUT
}
Logger(LOGTAG).error("TabReceived : init account status $accountStatus")
// accountStatus is SIGNED_OUT at this point



}

private fun loadProfilePicture(profile: Profile) {
Expand Down Expand Up @@ -331,6 +418,9 @@ class Accounts constructor(val context: Context) {
}

fun updateProfileAsync(): CompletableFuture<Profile?>? {

Logger("Accounts").error("TabReceived : needs reauth " + services.accountManager.accountNeedsReauth())

return CoroutineScope(Dispatchers.Main).future {
services.accountManager.accountProfile()
}
Expand Down Expand Up @@ -379,7 +469,13 @@ class Accounts constructor(val context: Context) {
}

fun lastSync(): Long {

Logger("Accounts").error("TabReceived : lastSync()")
Logger("Accounts").error("TabReceived : lastSync() ${services.accountManager.accountProfile()}")
Logger("Accounts").error("TabReceived : lastSync() ${services.accountManager.accountProfile()?.email}")

services.accountManager.accountProfile()?.email?.let {
Logger("Accounts").error("TabReceived : getFxALastSync $it")
return SettingsStore.getInstance(context).getFxALastSync(it)
}
return 0
Expand Down
16 changes: 16 additions & 0 deletions app/src/common/shared/com/igalia/wolvic/browser/Services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,23 @@ class Services(val context: Context, places: Places): WSession.NavigationDelegat
private val logTag = "DeviceEventsObserver"

override fun onEvents(events: List<AccountEvent>) {

Logger(logTag).error("TabReceived : AccountEventsObserver onEvents")

CoroutineScope(Dispatchers.Main).launch {
Logger(logTag).info("Received ${events.size} device event(s)")
Logger(logTag).error("TabReceived : onEvents Received ${events.size} device event(s)")

events.forEach { event ->
Logger(logTag).error("TabReceived : event $event")
}

events
.filterIsInstance<AccountEvent.DeviceCommandIncoming>()
.map { it.command }
.filterIsInstance<DeviceCommandIncoming.TabReceived>()
.forEach { command ->
Logger(logTag).error("TabReceived : Received a TabReceived event")
command.from?.deviceType?.let { TelemetryService.FxA.receivedTab(it) }
tabReceivedDelegate?.onTabsReceived(command.entries)
}
Expand All @@ -101,6 +111,9 @@ class Services(val context: Context, places: Places): WSession.NavigationDelegat
syncConfig = SyncConfig(setOf(SyncEngine.History, SyncEngine.Bookmarks, SyncEngine.Passwords), PeriodicSyncConfig(periodMinutes = 1440))

).also {

Logger("Services").error("TabReceived : $it registerForAccountEvents")

it.registerForAccountEvents(deviceEventObserver, ProcessLifecycleOwner.get(), true)
}

Expand All @@ -117,7 +130,10 @@ class Services(val context: Context, places: Places): WSession.NavigationDelegat
}

private fun init() {
Logger("Services").error("TabReceived : init() will call $accountManager start")
CoroutineScope(Dispatchers.Main).launch {
Logger("Services").error("TabReceived : $accountManager start")

accountManager.start()
}
}
Expand Down
11 changes: 11 additions & 0 deletions app/src/common/shared/com/igalia/wolvic/browser/SettingsStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -928,23 +928,34 @@ public void setFxALastSync(@NonNull String email, long timestamp) {
}

public long getFxALastSync(@NonNull String email) {

Log.e(LOGTAG, "TabReceived : getFxALastSync " + email);

String json = mPrefs.getString(
mContext.getString(R.string.settings_key_fxa_last_sync),
null);

Log.e(LOGTAG, "TabReceived : " + json);

try {
JSONObject jsonObject = new JSONObject(json);
Iterator<String> iterator = jsonObject.keys();
while (iterator.hasNext()) {
String key = iterator.next();
if (key.equals(email)) {

Log.e(LOGTAG, "TabReceived : found " + jsonObject.getLong(key));

return jsonObject.getLong(key);
}
}

Log.e(LOGTAG, "TabReceived : not found");

return FXA_LAST_SYNC_NEVER;

} catch (Exception e) {
Log.e(LOGTAG, "TabReceived : error");
return FXA_LAST_SYNC_NEVER;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ static Session createWebExtensionSession(Context aContext, WRuntime aRuntime, @N

@NonNull
static Session createSession(Context aContext, WRuntime aRuntime, @NonNull SessionSettings aSettings, @Session.SessionOpenModeFlags int aOpenMode, @NonNull SessionChangeListener listener) {

Log.e(LOGTAG, "TabReceived : Session createSession");

Session session = new Session(aContext, aRuntime, aSettings);
session.addSessionChangeListener(listener);
listener.onSessionAdded(session);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ public void onTrackingProtectionLevelUpdated(int level) {

@NonNull
private Session addSession(@NonNull Session aSession) {

Log.e(LOGTAG, "TabReceived : addSession " + aSession);

aSession.setPermissionDelegate(this);
aSession.addNavigationListener(mServices);
mSessions.add(aSession);
Expand Down Expand Up @@ -220,6 +223,9 @@ public Session createWebExtensionSession(boolean openSession, boolean aPrivateMo

@NonNull
public Session createSession(boolean aPrivateMode) {

Log.e(LOGTAG, "TabReceived : createSession(boolean aPrivateMode)");

SessionSettings settings = new SessionSettings(new SessionSettings.Builder().withDefaultSettings(mContext).withPrivateBrowsing(aPrivateMode));
return createSession(settings, Session.SESSION_OPEN);
}
Expand All @@ -232,7 +238,13 @@ public Session createSession(boolean openSession, boolean aPrivateMode) {

@NonNull
Session createSession(@NonNull SessionSettings aSettings, @Session.SessionOpenModeFlags int aOpenMode) {

Log.e(LOGTAG, "TabReceived : createSession(@NonNull SessionSettings aSettings, @Session.SessionOpenModeFlags int aOpenMode)");

Session session = Session.createSession(mContext, mRuntime, aSettings, aOpenMode, this);

Log.e(LOGTAG, "TabReceived : created " + session);

return addSession(session);
}

Expand Down Expand Up @@ -528,6 +540,9 @@ public void removePermissionException(@NonNull String uri, @SitePermission.Categ

@Override
public void onSessionAdded(Session aSession) {

Log.e(LOGTAG, "TabReceived : SessionStore.onSessionAdded");

ComponentsAdapter.get().addSession(aSession);
for (SessionChangeListener listener : mSessionChangeListeners) {
listener.onSessionAdded(aSession);
Expand Down
Loading

0 comments on commit 2c22b48

Please sign in to comment.