Bug 1810629 - Add an Android shortcut to go straight to the login and passwords

fenix/115.2.0
GitStart 1 year ago committed by mergify[bot]
parent f286cf7002
commit b5e24ffc3f

@ -3,6 +3,17 @@
- 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/. -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
android:shortcutShortLabel="@string/home_screen_shortcut_open_password_screen"
android:shortcutLongLabel="@string/home_screen_shortcut_open_password_screen">
<intent
android:action="org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
android:targetPackage="org.mozilla.firefox_beta"
android:targetClass="org.mozilla.fenix.IntentReceiverActivity" />
</shortcut>
<shortcut
android:shortcutId="open_new_tab"
android:enabled="true"

@ -4,6 +4,17 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
android:shortcutShortLabel="@string/home_screen_shortcut_open_password_screen"
android:shortcutLongLabel="@string/home_screen_shortcut_open_password_screen">
<intent
android:action="org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
android:targetPackage="org.mozilla.fenix.debug"
android:targetClass="org.mozilla.fenix.IntentReceiverActivity" />
</shortcut>
<shortcut
android:shortcutId="open_new_tab"
android:enabled="true"

@ -106,6 +106,7 @@ import org.mozilla.fenix.home.intent.AssistIntentProcessor
import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor
import org.mozilla.fenix.home.intent.HomeDeepLinkIntentProcessor
import org.mozilla.fenix.home.intent.OpenBrowserIntentProcessor
import org.mozilla.fenix.home.intent.OpenPasswordManagerIntentProcessor
import org.mozilla.fenix.home.intent.OpenSpecificTabIntentProcessor
import org.mozilla.fenix.home.intent.ReEngagementIntentProcessor
import org.mozilla.fenix.home.intent.SpeechProcessingIntentProcessor
@ -202,6 +203,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
StartSearchIntentProcessor(),
OpenBrowserIntentProcessor(this, ::getIntentSessionId),
OpenSpecificTabIntentProcessor(this),
OpenPasswordManagerIntentProcessor(),
ReEngagementIntentProcessor(this, settings()),
)
}
@ -1232,6 +1234,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
const val OPEN_TO_SEARCH = "open_to_search"
const val PRIVATE_BROWSING_MODE = "private_browsing_mode"
const val START_IN_RECENTS_SCREEN = "start_in_recents_screen"
const val OPEN_PASSWORD_MANAGER = "open_password_manager"
// PWA must have been used within last 30 days to be considered "recently used" for the
// telemetry purposes.

@ -114,6 +114,7 @@ class IntentReceiverActivity : Activity() {
components.intentProcessors.fennecPageShortcutIntentProcessor +
components.intentProcessors.externalDeepLinkIntentProcessor +
components.intentProcessors.webNotificationsIntentProcessor +
components.intentProcessors.passwordManagerIntentProcessor +
modeDependentProcessors +
NewTabShortcutIntentProcessor()
}

@ -25,6 +25,7 @@ import org.mozilla.fenix.customtabs.FennecWebAppIntentProcessor
import org.mozilla.fenix.home.intent.FennecBookmarkShortcutsIntentProcessor
import org.mozilla.fenix.intent.ExternalDeepLinkIntentProcessor
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.fenix.shortcut.PasswordManagerIntentProcessor
/**
* Component group for miscellaneous components.
@ -80,4 +81,8 @@ class IntentProcessors(
val webNotificationsIntentProcessor by lazyMonitored {
WebNotificationIntentProcessor(engine)
}
val passwordManagerIntentProcessor by lazyMonitored {
PasswordManagerIntentProcessor()
}
}

@ -0,0 +1,29 @@
/* 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.fenix.home.intent
import android.content.Intent
import androidx.navigation.NavController
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.ext.nav
/**
* When the open password manager shortcut is tapped, Fenix should open to the password and login fragment.
*/
class OpenPasswordManagerIntentProcessor : HomeIntentProcessor {
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
return if (intent.extras?.getBoolean(HomeActivity.OPEN_PASSWORD_MANAGER) == true) {
out.removeExtra(HomeActivity.OPEN_PASSWORD_MANAGER)
val directions = NavGraphDirections.actionGlobalSavedLoginsAuthFragment()
navController.nav(null, directions)
true
} else {
false
}
}
}

@ -0,0 +1,40 @@
/* 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.fenix.shortcut
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import mozilla.components.feature.intent.processing.IntentProcessor
import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.HomeActivity
/**
* Intent processor that will handle intents for the password manager shortcut
*/
class PasswordManagerIntentProcessor : IntentProcessor {
/**
* Processes the given [Intent].
*
* @param intent The intent to process.
* @return True if the intent was processed, otherwise false.
*/
override fun process(intent: Intent): Boolean {
val safeIntent = SafeIntent(intent)
if (!safeIntent.action.equals(ACTION_OPEN_PASSWORD_MANAGER)) {
return false
}
intent.putExtra(HomeActivity.OPEN_PASSWORD_MANAGER, true)
intent.flags = intent.flags or FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK
return true
}
companion object {
const val ACTION_OPEN_PASSWORD_MANAGER = "org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
}
}

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/static_shortcut_background"/>
<foreground android:drawable="@drawable/ic_static_lock"/>
</adaptive-icon>

@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<group android:translateX="12"
android:translateY="12">
<path
android:pathData="M7,11V7C7,4.239 9.239,2 12,2C14.761,2 17,4.239 17,7V11C18.38,11 19.5,12.12 19.5,13.5V19.5C19.5,20.88 18.38,22 17,22H7C5.62,22 4.5,20.88 4.5,19.5V13.5C4.5,12.12 5.62,11 7,11ZM8.75,7C8.75,5.205 10.205,3.75 12,3.75C13.795,3.75 15.25,5.205 15.25,7V11H8.75V7ZM6.25,13.5C6.25,13.086 6.586,12.75 7,12.75H17C17.414,12.75 17.75,13.086 17.75,13.5V19.5C17.75,19.914 17.414,20.25 17,20.25H7C6.586,20.25 6.25,19.914 6.25,19.5V13.5Z"
android:fillColor="#000000"
android:fillType="evenOdd"/>
</group>
</vector>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_static_shortcut_background" />
<item android:drawable="@drawable/ic_static_lock" />
</layer-list>

@ -121,6 +121,8 @@
<string name="home_screen_shortcut_open_new_tab_2">New tab</string>
<!-- Shortcut action to open new private tab -->
<string name="home_screen_shortcut_open_new_private_tab_2">New private tab</string>
<!-- Shortcut action to open Passwords screens -->
<string name="home_screen_shortcut_open_password_screen">Passwords shortcut</string>
<!-- Recent Tabs -->
<!-- Header text for jumping back into the recent tab in the home screen -->

@ -4,6 +4,17 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
android:shortcutShortLabel="@string/home_screen_shortcut_open_password_screen"
android:shortcutLongLabel="@string/home_screen_shortcut_open_password_screen">
<intent
android:action="org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
android:targetPackage="org.mozilla.fenix"
android:targetClass="org.mozilla.fenix.IntentReceiverActivity" />
</shortcut>
<shortcut
android:shortcutId="open_new_tab"
android:enabled="true"

@ -4,6 +4,17 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
android:shortcutShortLabel="@string/home_screen_shortcut_open_password_screen"
android:shortcutLongLabel="@string/home_screen_shortcut_open_password_screen">
<intent
android:action="org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
android:targetPackage="org.mozilla.fenix"
android:targetClass="org.mozilla.fenix.IntentReceiverActivity" />
</shortcut>
<shortcut
android:shortcutId="open_new_tab"
android:enabled="true"

@ -3,6 +3,17 @@
- 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/. -->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="password_manager"
android:enabled="true"
android:icon="@drawable/ic_static_password_shortcut"
android:shortcutShortLabel="@string/home_screen_shortcut_open_password_screen"
android:shortcutLongLabel="@string/home_screen_shortcut_open_password_screen">
<intent
android:action="org.mozilla.fenix.OPEN_PASSWORD_MANAGER"
android:targetPackage="org.mozilla.firefox"
android:targetClass="org.mozilla.fenix.IntentReceiverActivity" />
</shortcut>
<shortcut
android:shortcutId="open_new_tab"
android:enabled="true"

@ -40,6 +40,7 @@ import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.helpers.perf.TestStrictModeManager
import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor
import org.mozilla.fenix.shortcut.PasswordManagerIntentProcessor
import org.mozilla.fenix.utils.Settings
import org.robolectric.Robolectric
import org.robolectric.Shadows.shadowOf
@ -68,6 +69,7 @@ class IntentReceiverActivityTest {
every { intentProcessors.fennecPageShortcutIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.externalDeepLinkIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.webNotificationsIntentProcessor } returns mockIntentProcessor()
every { intentProcessors.passwordManagerIntentProcessor } returns mockIntentProcessor()
coEvery { intentProcessors.intentProcessor.process(any()) } returns true
}
@ -290,6 +292,21 @@ class IntentReceiverActivityTest {
verify { activity.launch(intent, IntentProcessorType.NEW_TAB) }
}
@Test
fun `process intent with action OPEN_PASSWORD_MANAGER`() = runTest {
val intent = Intent()
intent.action = PasswordManagerIntentProcessor.ACTION_OPEN_PASSWORD_MANAGER
val activity = Robolectric.buildActivity(IntentReceiverActivity::class.java, intent).get()
attachMocks(activity)
activity.processIntent(intent)
val shadow = shadowOf(activity)
val actualIntent = shadow.peekNextStartedActivity()
assertEquals(HomeActivity::class.java.name, actualIntent.component?.className)
}
private fun attachMocks(activity: Activity) {
every { activity.settings() } returns settings
every { activity.components.analytics } returns mockk(relaxed = true)

@ -0,0 +1,77 @@
/* 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.fenix.home.intent
import android.content.Intent
import androidx.navigation.NavController
import io.mockk.Called
import io.mockk.mockk
import io.mockk.verify
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.shortcut.PasswordManagerIntentProcessor
@RunWith(FenixRobolectricTestRunner::class)
class OpenPasswordManagerIntentProcessorTest {
private lateinit var activity: HomeActivity
private lateinit var navController: NavController
private lateinit var out: Intent
private lateinit var processor: OpenPasswordManagerIntentProcessor
@Before
fun setup() {
activity = mockk(relaxed = true)
navController = mockk(relaxed = true)
out = mockk(relaxed = true)
processor = OpenPasswordManagerIntentProcessor()
}
@Test
fun `GIVEN a blank intent WHEN it is processed THEN nothing should happen`() {
assertFalse(processor.process(Intent(), navController, out))
verify { activity wasNot Called }
verify { navController wasNot Called }
verify { out wasNot Called }
}
@Test
fun `GIVEN an intent with wrong action WHEN it is processed THEN nothing should happen`() {
val intent = Intent().apply {
action = TEST_WRONG_ACTION
}
assertFalse(processor.process(intent, navController, out))
verify { activity wasNot Called }
verify { navController wasNot Called }
verify { out wasNot Called }
}
@Test
fun `GIVEN an intent with correct action and extra boolean WHEN it is processed THEN navigate should be called`() {
val intent = Intent().apply {
action = PasswordManagerIntentProcessor.Companion.ACTION_OPEN_PASSWORD_MANAGER
putExtra(HomeActivity.OPEN_PASSWORD_MANAGER, true)
}
assertTrue(processor.process(intent, navController, out))
verify { navController.nav(null, NavGraphDirections.actionGlobalSavedLoginsAuthFragment()) }
verify { out.removeExtra(HomeActivity.OPEN_PASSWORD_MANAGER) }
}
companion object {
const val TEST_WRONG_ACTION = "test-action"
}
}
Loading…
Cancel
Save