diff --git a/app/src/common/shared/com/igalia/wolvic/browser/Accounts.kt b/app/src/common/shared/com/igalia/wolvic/browser/Accounts.kt index aca7b0b885..170f6d50bb 100644 --- a/app/src/common/shared/com/igalia/wolvic/browser/Accounts.kt +++ b/app/src/common/shared/com/igalia/wolvic/browser/Accounts.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.future.future import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import mozilla.components.concept.sync.* import mozilla.components.service.fxa.FirefoxAccount import mozilla.components.service.fxa.SyncEngine @@ -131,6 +132,10 @@ class Accounts constructor(val context: Context) { accountStatus = AccountStatus.SIGNED_IN + // 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 + runBlocking { setDeviceName(SettingsStore.getInstance(context).deviceName) } + // Enable syncing after signing in syncNowAsync(SyncReason.EngineChange, true) @@ -397,4 +402,8 @@ class Accounts constructor(val context: Context) { originSessionId = sessionId } + suspend fun setDeviceName(deviceName: String) { + services.accountManager.authenticatedAccount()?.deviceConstellation()?.setDeviceName(deviceName, context); + } + } \ No newline at end of file diff --git a/app/src/common/shared/com/igalia/wolvic/browser/Services.kt b/app/src/common/shared/com/igalia/wolvic/browser/Services.kt index e7c7c45843..48e5ba367b 100644 --- a/app/src/common/shared/com/igalia/wolvic/browser/Services.kt +++ b/app/src/common/shared/com/igalia/wolvic/browser/Services.kt @@ -8,6 +8,7 @@ package com.igalia.wolvic.browser import android.content.Context import android.net.Uri import android.os.Build +import android.provider.Settings import androidx.lifecycle.ProcessLifecycleOwner import com.igalia.wolvic.BuildConfig import com.igalia.wolvic.R @@ -92,8 +93,8 @@ class Services(val context: Context, places: Places): WSession.NavigationDelegat 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") - name = "${context.getString(R.string.app_name)} on ${Build.MANUFACTURER} ${Build.MODEL}", + // E.g. accountManager.authenticatedAccount()?.deviceConstellation()?.setDeviceName("new name", context) + name = com.igalia.wolvic.utils.DeviceType.getDeviceName(context), type = DeviceType.VR, capabilities = setOf(DeviceCapability.SEND_TAB) ), diff --git a/app/src/common/shared/com/igalia/wolvic/browser/SettingsStore.java b/app/src/common/shared/com/igalia/wolvic/browser/SettingsStore.java index e88d740281..bfd49aa363 100644 --- a/app/src/common/shared/com/igalia/wolvic/browser/SettingsStore.java +++ b/app/src/common/shared/com/igalia/wolvic/browser/SettingsStore.java @@ -415,6 +415,17 @@ public float getWindowAspect() { return (float)getWindowWidth() / (float)getWindowHeight(); } + public String getDeviceName() { + return mPrefs.getString( + mContext.getString(R.string.settings_key_device_name), DeviceType.getDeviceName(mContext)); + } + + public void setDeviceName(String aDeviceName) { + SharedPreferences.Editor editor = mPrefs.edit(); + editor.putString(mContext.getString(R.string.settings_key_device_name), aDeviceName); + editor.commit(); + } + public int getDisplayDpi() { return mPrefs.getInt( mContext.getString(R.string.settings_key_display_dpi), DISPLAY_DPI_DEFAULT); diff --git a/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/FxAAccountOptionsView.java b/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/FxAAccountOptionsView.java index 65e786abdd..f4c52e0b2d 100644 --- a/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/FxAAccountOptionsView.java +++ b/app/src/common/shared/com/igalia/wolvic/ui/widgets/settings/FxAAccountOptionsView.java @@ -23,6 +23,7 @@ import com.igalia.wolvic.ui.widgets.UIWidget; import com.igalia.wolvic.ui.widgets.WidgetManagerDelegate; import com.igalia.wolvic.ui.widgets.dialogs.SignOutDialogWidget; +import com.igalia.wolvic.utils.DeviceType; import com.igalia.wolvic.utils.SystemUtils; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,10 @@ import java.util.Objects; import java.util.concurrent.Executor; +import kotlin.Unit; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.CoroutineContext; +import kotlin.coroutines.EmptyCoroutineContext; import mozilla.components.concept.sync.AccountObserver; import mozilla.components.concept.sync.AuthFlowError; import mozilla.components.concept.sync.AuthType; @@ -78,6 +83,12 @@ protected void updateUI() { mBinding.signButton.setOnClickListener(this::signOut); mBinding.syncButton.setOnClickListener(this::sync); + mBinding.deviceNameEdit.setHint1(DeviceType.getDeviceName(getContext())); + mBinding.deviceNameEdit.setDefaultFirstValue(DeviceType.getDeviceName(getContext())); + mBinding.deviceNameEdit.setFirstText(SettingsStore.getInstance(getContext()).getDeviceName()); + mBinding.deviceNameEdit.setOnClickListener(mDeviceNameListener); + setDeviceName(SettingsStore.getInstance(getContext()).getDeviceName(), false); + mBinding.setIsSyncing(mAccounts.isSyncing()); mBinding.setLastSync(mAccounts.lastSync()); @@ -91,6 +102,34 @@ protected void updateUI() { mBinding.footerLayout.setFooterButtonClickListener(v -> resetOptions()); } + @Override + protected void onDismiss() { + if (isEditing()) { + return; + } + super.onDismiss(); + } + + @Override + public boolean isEditing() { + boolean editing = mBinding.deviceNameEdit.isEditing(); + if (editing) { + mBinding.deviceNameEdit.cancel(); + } + + return editing; + } + + @Override + public void onGlobalFocusChanged(View oldFocus, View newFocus) { + if (oldFocus == null) { + return; + } + if (mBinding.deviceNameEdit.contains(oldFocus) && mBinding.deviceNameEdit.isEditing()) { + mBinding.deviceNameEdit.cancel(); + } + } + @Override public void onShown() { super.onShown(); @@ -107,6 +146,9 @@ public void onShown() { @Override public void onHidden() { + if (isEditing()) { + return; + } super.onHidden(); mAccounts.removeAccountListener(mAccountListener); @@ -132,6 +174,7 @@ private void resetOptions() { mBinding.bookmarksSyncSwitch.setValue(SettingsStore.BOOKMARKS_SYNC_DEFAULT, true); mBinding.historySyncSwitch.setValue(SettingsStore.HISTORY_SYNC_DEFAULT, true); mBinding.loginsSyncSwitch.setValue(SettingsStore.LOGIN_SYNC_DEFAULT, true); + setDeviceName(DeviceType.getDeviceName(getContext()), true); } private SyncStatusObserver mSyncListener = new SyncStatusObserver() { @@ -169,6 +212,32 @@ private void updateSyncBindings(boolean isSyncing) { mBinding.executePendingBindings(); } + private void setDeviceName(String newDeviceName, boolean doApply) { + mBinding.deviceNameEdit.setOnClickListener(null); + if (newDeviceName.isEmpty()) { + newDeviceName = DeviceType.getDeviceName(getContext()); + } + if (doApply) { + String prevDeviceName = SettingsStore.getInstance(getContext()).getDeviceName(); + if (!Objects.equals(prevDeviceName, newDeviceName)) { + SettingsStore.getInstance(getContext()).setDeviceName(newDeviceName); + Continuation completion = new Continuation() { + @NonNull + @Override + public CoroutineContext getContext() { + return EmptyCoroutineContext.INSTANCE; + } + + @Override + public void resumeWith(@NonNull Object o) {} + }; + mAccounts.setDeviceName(newDeviceName, completion); + } + } + mBinding.deviceNameEdit.setFirstText(newDeviceName); + mBinding.deviceNameEdit.setOnClickListener(mDeviceNameListener); + } + void updateCurrentAccountState() { switch(mAccounts.getAccountStatus()) { case NEEDS_RECONNECT: @@ -225,6 +294,11 @@ private void signOut(View view) { mSignOutDialog.show(UIWidget.REQUEST_FOCUS); } + private OnClickListener mDeviceNameListener = (view) -> { + String newDeviceName = mBinding.deviceNameEdit.getFirstText(); + setDeviceName(newDeviceName, true); + }; + private AccountObserver mAccountListener = new AccountObserver() { @Override diff --git a/app/src/common/shared/com/igalia/wolvic/utils/DeviceType.java b/app/src/common/shared/com/igalia/wolvic/utils/DeviceType.java index d68703cd2a..b2a0dcb349 100644 --- a/app/src/common/shared/com/igalia/wolvic/utils/DeviceType.java +++ b/app/src/common/shared/com/igalia/wolvic/utils/DeviceType.java @@ -1,9 +1,13 @@ package com.igalia.wolvic.utils; +import android.content.Context; +import android.os.Build; +import android.provider.Settings; import android.util.Log; import androidx.annotation.IntDef; +import com.igalia.wolvic.R; import com.igalia.wolvic.BuildConfig; public class DeviceType { @@ -30,60 +34,60 @@ public class DeviceType { public static final int MetaQuest3 = 18; private static @Type int mType = Unknown; + private static String mDeviceName = "Unknown Device"; public static void setType(@Type int aType) { - String name; switch (aType) { case OculusGo: - name = "Oculus Go"; + mDeviceName = "Oculus Go"; break; case OculusQuest: - name = "Oculus Quest"; + mDeviceName = "Oculus Quest"; break; case OculusQuest2: - name = "Oculus Quest 2"; + mDeviceName = "Oculus Quest 2"; break; case MetaQuestPro: - name = "Meta Quest Pro"; + mDeviceName = "Meta Quest Pro"; break; case ViveFocus: - name = "Vive Focus"; + mDeviceName = "Vive Focus"; break; case ViveFocusPlus: - name = "Vive Focus Plus"; + mDeviceName = "Vive Focus Plus"; break; case PicoNeo2: - name = "Pico Neo 2"; + mDeviceName = "Pico Neo 2"; break; case PicoNeo3: - name = "Pico Neo 3"; + mDeviceName = "Pico Neo 3"; break; case PicoG2: - name = "Pico G2"; + mDeviceName = "Pico G2"; break; case PicoXR: - name = "Pico XR"; + mDeviceName = "Pico XR"; break; case LynxR1: - name = "Lynx-R1"; + mDeviceName = "Lynx-R1"; break; case LenovoA3: - name = "Lenovo A3"; + mDeviceName = "Lenovo A3"; break; case LenovoVRX: - name = "Lenovo VRX"; + mDeviceName = "Lenovo VRX"; break; case MagicLeap2: - name = "Magic Leap 2"; + mDeviceName = "Magic Leap 2"; break; case MetaQuest3: - name = "Meta Quest 3"; + mDeviceName = "Meta Quest 3"; break; default: - name = "Unknown Type"; + mDeviceName = "Unknown Device"; break; } - Log.d("VRB", "Setting device type to: " + name); + Log.d("VRB", "Setting device type to: " + mDeviceName); mType = aType; } public static @Type int getType() { @@ -146,4 +150,13 @@ else if (BuildConfig.FLAVOR_store.toLowerCase().contains("applab")) else return StoreType.NONE; } + + public static String getDeviceName(Context aContext) { + String appName = aContext.getString(R.string.app_name); + String deviceName = mDeviceName; + if (mType == DeviceType.Unknown) { + deviceName = Build.MANUFACTURER + " " + Build.MODEL; + } + return aContext.getString(R.string.device_name, appName, deviceName); + } } diff --git a/app/src/main/res/layout/options_fxa_account.xml b/app/src/main/res/layout/options_fxa_account.xml index 01f7491c33..cfb08c5f73 100644 --- a/app/src/main/res/layout/options_fxa_account.xml +++ b/app/src/main/res/layout/options_fxa_account.xml @@ -72,6 +72,16 @@ android:text="" tools:text="mozilla@mozilla.com" /> + + Account + + Device Name + Sync Settings @@ -1708,6 +1711,9 @@ '%1$s' will be replaced at runtime with the app's name. --> %1$s Home (Default) + + %1$s on %2$s Authentication Required diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4f6b1e6814..edac674b20 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -511,6 +511,8 @@ 主页 账户 + + 设备名称 同步设置 %1$s 主页(默认) + + %2$s 上的 %1$s 需要验证身份 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f03f6aef9c..05861bcb41 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -663,6 +663,9 @@ 帳號 + + 裝置名稱 + 同步設定 @@ -1706,7 +1709,9 @@ %1$s 首頁(預設值) - + + %2$s 上的 %1$s 需要驗證 diff --git a/app/src/main/res/values/dimen.xml b/app/src/main/res/values/dimen.xml index 0ebc7458b9..95a834df15 100644 --- a/app/src/main/res/values/dimen.xml +++ b/app/src/main/res/values/dimen.xml @@ -137,7 +137,7 @@ 585dp - 385dp + 420dp 140dp diff --git a/app/src/main/res/values/non_L10n.xml b/app/src/main/res/values/non_L10n.xml index f1f6c62af2..ae74719aa9 100644 --- a/app/src/main/res/values/non_L10n.xml +++ b/app/src/main/res/values/non_L10n.xml @@ -21,7 +21,8 @@ settings_user_agent_version_v2 settings_touch_mode settings_display_density - settings_display_dpi> + settings_display_dpi + settings_device_name settings_env settings_pointer_color settings_scroll_direction diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 04c8043047..2e6485f8c2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -706,6 +706,9 @@ Account + + Device Name + Sync Settings @@ -1822,6 +1825,10 @@ '%1$s' will be replaced at runtime with the app's name. --> %1$s Home (Default) + + %1$s on %2$s + Authentication Required