Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Close #162: Add FxA pairing integration
  • Loading branch information
vladikoff committed Mar 28, 2019
1 parent ee765dc commit 521ae3b
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 4 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Expand Up @@ -185,13 +185,15 @@ dependencies {
implementation Deps.mozilla_feature_tabs
implementation Deps.mozilla_feature_downloads
implementation Deps.mozilla_feature_prompts
implementation Deps.mozilla_feature_qr

implementation Deps.mozilla_ui_autocomplete
implementation Deps.mozilla_ui_colors

implementation Deps.mozilla_service_firefox_accounts
implementation Deps.mozilla_service_glean

implementation Deps.mozilla_support_base
implementation Deps.mozilla_support_utils
implementation Deps.mozilla_support_ktx
implementation Deps.mozilla_support_rustlog
Expand Down
@@ -0,0 +1,12 @@
/* 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.reference.browser

object AppPermissionCodes {
const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1
const val REQUEST_CODE_PROMPT_PERMISSIONS = 2
const val REQUEST_CODE_APP_PERMISSIONS = 3
const val REQUEST_CODE_CAMERA_PERMISSIONS = 4
}
Expand Up @@ -24,6 +24,9 @@ import mozilla.components.support.base.feature.BackHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.view.enterToImmersiveMode
import mozilla.components.support.ktx.android.view.exitImmersiveModeIfNeeded
import org.mozilla.reference.browser.AppPermissionCodes.REQUEST_CODE_APP_PERMISSIONS
import org.mozilla.reference.browser.AppPermissionCodes.REQUEST_CODE_DOWNLOAD_PERMISSIONS
import org.mozilla.reference.browser.AppPermissionCodes.REQUEST_CODE_PROMPT_PERMISSIONS
import org.mozilla.reference.browser.R
import org.mozilla.reference.browser.UserInteractionHandler
import org.mozilla.reference.browser.ext.requireComponents
Expand Down Expand Up @@ -253,9 +256,6 @@ class BrowserFragment : Fragment(), BackHandler, UserInteractionHandler {

companion object {
private const val SESSION_ID = "session_id"
private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 2
private const val REQUEST_CODE_APP_PERMISSIONS = 3

fun create(sessionId: String? = null): BrowserFragment = BrowserFragment().apply {
arguments = Bundle().apply {
Expand Down
Expand Up @@ -25,7 +25,7 @@ class BackgroundServices(
companion object {
const val CLIENT_ID = "3c49430b43dfba77"
const val REDIRECT_URL = "https://accounts.firefox.com/oauth/success/$CLIENT_ID"
const val SUCCESS_PATH = "connect_another_device?showSuccessMessage=true"
const val SUCCESS_PATH = "signin_confirmed"
}

// This is slightly messy - here we need to know the union of all "scopes"
Expand Down
@@ -0,0 +1,62 @@
/* 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.reference.browser.settings

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import mozilla.components.feature.qr.QrFeature
import mozilla.components.support.base.feature.BackHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.reference.browser.AppPermissionCodes.REQUEST_CODE_CAMERA_PERMISSIONS
import org.mozilla.reference.browser.R
import org.mozilla.reference.browser.ext.requireComponents

class PairSettingsFragment : Fragment(), BackHandler {
private val qrFeature = ViewBoundFeatureWrapper<QrFeature>()

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_pairing, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
qrFeature.set(
feature = QrFeature(
requireContext(),
fragmentManager = fragmentManager!!,
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_CAMERA_PERMISSIONS)
},
onScanResult = { pairingUrl ->
requireComponents.services.accountsAuthFeature.beginPairingAuthentication(pairingUrl)
activity?.finish()
}
),
owner = this,
view = view
)

qrFeature.withFeature {
it.scan(R.id.pair_layout)
}
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE_CAMERA_PERMISSIONS -> qrFeature.withFeature {
it.onPermissionsResult(permissions, grantResults)
}
}
}

override fun onBackPressed(): Boolean {
qrFeature.onBackPressed()
fragmentManager?.popBackStack()
return true
}
}
Expand Up @@ -8,6 +8,7 @@ import android.R.id.content
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import mozilla.components.support.base.feature.BackHandler

class SettingsActivity : AppCompatActivity(), SettingsFragment.ActionBarUpdater {

Expand All @@ -33,4 +34,14 @@ class SettingsActivity : AppCompatActivity(), SettingsFragment.ActionBarUpdater
override fun updateTitle(titleResId: Int) {
setTitle(titleResId)
}

override fun onBackPressed() {
supportFragmentManager.fragments.forEach {
if (it is BackHandler && it.onBackPressed()) {
return
} else {
super.onBackPressed()
}
}
}
}
Expand Up @@ -17,6 +17,7 @@ import org.mozilla.reference.browser.R
import org.mozilla.reference.browser.R.string.pref_key_firefox_account
import org.mozilla.reference.browser.ext.getPreferenceKey
import org.mozilla.reference.browser.R.string.pref_key_sign_in
import org.mozilla.reference.browser.R.string.pref_key_pair_sign_in
import org.mozilla.reference.browser.R.string.pref_key_make_default_browser
import org.mozilla.reference.browser.R.string.pref_key_remote_debugging
import org.mozilla.reference.browser.R.string.pref_key_about_page
Expand Down Expand Up @@ -50,13 +51,15 @@ class SettingsFragment : PreferenceFragmentCompat() {
@Suppress("LongMethod") // Yep, this should be refactored.
private fun setupPreferences() {
val signInKey = context?.getPreferenceKey(pref_key_sign_in)
val signInPairKey = context?.getPreferenceKey(pref_key_pair_sign_in)
val firefoxAccountKey = context?.getPreferenceKey(pref_key_firefox_account)
val makeDefaultBrowserKey = context?.getPreferenceKey(pref_key_make_default_browser)
val remoteDebuggingKey = context?.getPreferenceKey(pref_key_remote_debugging)
val aboutPageKey = context?.getPreferenceKey(pref_key_about_page)
val privacyKey = context?.getPreferenceKey(pref_key_privacy)

val preferenceSignIn = findPreference(signInKey)
val preferencePairSignIn = findPreference(signInPairKey)
val preferenceFirefoxAccount = findPreference(firefoxAccountKey)
val preferenceMakeDefaultBrowser = findPreference(makeDefaultBrowserKey)
val preferenceRemoteDebugging = findPreference(remoteDebuggingKey)
Expand All @@ -66,13 +69,16 @@ class SettingsFragment : PreferenceFragmentCompat() {
val accountManager = requireComponents.backgroundServices.accountManager
if (accountManager.authenticatedAccount() != null) {
preferenceSignIn.isVisible = false
preferencePairSignIn.isVisible = false
preferenceFirefoxAccount.summary = accountManager.accountProfile()?.email.orEmpty()
preferenceFirefoxAccount.onPreferenceClickListener = getClickListenerForFirefoxAccount()
} else {
preferenceSignIn.isVisible = true
preferenceFirefoxAccount.isVisible = false
preferenceFirefoxAccount.onPreferenceClickListener = null
preferenceSignIn.onPreferenceClickListener = getClickListenerForSignIn()
preferencePairSignIn.isVisible = true
preferencePairSignIn.onPreferenceClickListener = getClickListenerForPairingSignIn()
}

preferenceMakeDefaultBrowser.onPreferenceClickListener = getClickListenerForMakeDefaultBrowser()
Expand Down Expand Up @@ -103,6 +109,19 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
}

private fun getClickListenerForPairingSignIn(): OnPreferenceClickListener {
return OnPreferenceClickListener {
fragmentManager?.beginTransaction()
?.replace(android.R.id.content, PairSettingsFragment())
?.addToBackStack(null)
?.commit()
getActionBarUpdater().apply {
updateTitle(R.string.pair_preferences)
}
true
}
}

private fun getClickListenerForFirefoxAccount(): OnPreferenceClickListener {
return OnPreferenceClickListener {
fragmentManager?.beginTransaction()
Expand Down
21 changes: 21 additions & 0 deletions app/src/main/res/layout/fragment_pairing.xml
@@ -0,0 +1,21 @@
<!-- 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/. -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/pair_layout" />

<TextView
android:id="@+id/text_view_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/pair_instructions"
android:textSize="20sp"
android:gravity="center"
android:textColor="@color/photonWhite" />
</RelativeLayout>
1 change: 1 addition & 0 deletions app/src/main/res/values/preference_keys.xml
Expand Up @@ -4,6 +4,7 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources>
<string name="pref_key_sign_in" translatable="false">pref_key_sign_in</string>
<string name="pref_key_pair_sign_in" translatable="false">pref_key_pair_sign_in</string>
<string name="pref_key_sign_out" translatable="false">pref_key_sign_out</string>
<string name="pref_key_sync_now" translatable="false">pref_key_sync_now</string>
<string name="pref_key_firefox_account" translatable="false">pref_key_firefox_account</string>
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/values/strings.xml
Expand Up @@ -18,6 +18,9 @@
<!-- Preference summary for settings related sign in -->
<string name="preferences_sign_in_summary">Sync your history</string>

<!-- Preference summary for pairing sign in -->
<string name="preferences_pair_sign_in_summary">Pair with Firefox Desktop</string>

<!-- Preference summary for settings related to send telemetry data -->
<string name="preferences_use_telemetry_summary">Send usage data</string>

Expand All @@ -42,6 +45,9 @@
<!-- Preference for signing in -->
<string name="sign_in">Sign in</string>

<!-- Preference for signing in -->
<string name="pair_sign_in">Sign in with a QR code</string>

<!-- Preference for settings related to the signed in Firefox Account -->
<string name="firefox_account">Firefox Account</string>

Expand Down Expand Up @@ -99,6 +105,10 @@
<!-- Menu option on the toolbar that takes you to privacy settings page-->
<string name="privacy_settings">Privacy Settings</string>

<!-- Menu option on the toolbar that takes you to pairing QR code page-->
<string name="pair_preferences">Pairing</string>
<string name="pair_instructions">Open accounts.firefox.com/pair in Firefox Desktop for your pairing code</string>

<!-- Snackbar message when a non fatal crash happen-->
<string name="crash_report_non_fatal_message">Sorry. We crashed</string>

Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/xml/preferences.xml
Expand Up @@ -10,6 +10,11 @@
android:title="@string/sign_in"
android:summary="@string/preferences_sign_in_summary"/>

<androidx.preference.Preference
android:key="@string/pref_key_pair_sign_in"
android:title="@string/pair_sign_in"
android:summary="@string/preferences_pair_sign_in_summary"/>

<androidx.preference.Preference
android:key="@string/pref_key_firefox_account"
android:title="@string/firefox_account" />
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/java/Dependencies.kt
Expand Up @@ -69,13 +69,15 @@ object Deps {
const val mozilla_feature_downloads = "org.mozilla.components:feature-downloads:${Versions.mozilla_android_components}"
const val mozilla_feature_storage = "org.mozilla.components:feature-storage:${Versions.mozilla_android_components}"
const val mozilla_feature_prompts = "org.mozilla.components:feature-prompts:${Versions.mozilla_android_components}"
const val mozilla_feature_qr = "org.mozilla.components:feature-qr:${Versions.mozilla_android_components}"

const val mozilla_ui_autocomplete = "org.mozilla.components:ui-autocomplete:${Versions.mozilla_android_components}"
const val mozilla_ui_colors = "org.mozilla.components:ui-colors:${Versions.mozilla_android_components}"

const val mozilla_service_firefox_accounts = "org.mozilla.components:service-firefox-accounts:${Versions.mozilla_android_components}"
const val mozilla_service_glean = "org.mozilla.components:service-glean:${Versions.mozilla_android_components}"

const val mozilla_support_base = "org.mozilla.components:support-base:${Versions.mozilla_android_components}"
const val mozilla_support_utils = "org.mozilla.components:support-utils:${Versions.mozilla_android_components}"
const val mozilla_support_ktx= "org.mozilla.components:support-ktx:${Versions.mozilla_android_components}"
const val mozilla_support_rustlog = "org.mozilla.components:support-rustlog:${Versions.mozilla_android_components}"
Expand Down

0 comments on commit 521ae3b

Please sign in to comment.