diff --git a/components/browser/session-storage/src/main/java/mozilla/components/browser/session/storage/SessionStorage.kt b/components/browser/session-storage/src/main/java/mozilla/components/browser/session/storage/SessionStorage.kt
index 1649e0084cf..38e765e0e7a 100644
--- a/components/browser/session-storage/src/main/java/mozilla/components/browser/session/storage/SessionStorage.kt
+++ b/components/browser/session-storage/src/main/java/mozilla/components/browser/session/storage/SessionStorage.kt
@@ -70,13 +70,18 @@ class SessionStorage(
return true
}
- val stateToPersist = if (state.selectedTabId != null && state.selectedTab == null) {
+ // "about:crashparent" is meant for testing purposes only. If saved/restored then it will
+ // continue to crash the app until data is cleared. Therefore, we are filtering it out.
+ val updatedTabList = state.tabs.filterNot { it.content.url == "about:crashparent" }
+ val updatedState = state.copy(tabs = updatedTabList)
+
+ val stateToPersist = if (updatedState.selectedTabId != null && updatedState.selectedTab == null) {
// Needs investigation to figure out and prevent cause:
// https://github.com/mozilla-mobile/android-components/issues/8417
logger.error("Selected tab ID set, but tab with matching ID not found. Clearing selection.")
- state.copy(selectedTabId = null)
+ updatedState.copy(selectedTabId = null)
} else {
- state
+ updatedState
}
return synchronized(sessionFileLock) {
diff --git a/components/browser/session-storage/src/test/java/mozilla/components/browser/session/storage/SessionStorageTest.kt b/components/browser/session-storage/src/test/java/mozilla/components/browser/session/storage/SessionStorageTest.kt
index e4eddabf574..9fbf9d9c5f9 100644
--- a/components/browser/session-storage/src/test/java/mozilla/components/browser/session/storage/SessionStorageTest.kt
+++ b/components/browser/session-storage/src/test/java/mozilla/components/browser/session/storage/SessionStorageTest.kt
@@ -357,6 +357,34 @@ class SessionStorageTest {
// the first one if all tabs have the same last access value.
assertEquals("mozilla", browsingSession.selectedTabId)
}
+
+ @Test
+ fun `WHEN saving state with crash parent tab THEN don't save tab`() {
+ val state = BrowserState(
+ tabs = listOf(
+ createTab(url = "about:crashparent", id = "crash"),
+ createTab(url = "https://getpocket.com", id = "pocket")
+ ),
+ selectedTabId = "crash"
+ )
+
+ val engine = FakeEngine()
+
+ val storage = SessionStorage(testContext, engine)
+ val persisted = storage.save(state)
+ assertTrue(persisted)
+
+ // Read it back
+ val browsingSession = storage.restore()
+ assertNotNull(browsingSession!!)
+
+ assertEquals(1, browsingSession.tabs.size)
+ assertEquals("https://getpocket.com", browsingSession.tabs[0].state.url)
+
+ // Selected tab doesn't exist so we take to most recently accessed one, or
+ // the first one if all tabs have the same last access value.
+ assertEquals("pocket", browsingSession.selectedTabId)
+ }
}
internal fun TabSessionState.assertSameAs(tab: RecoverableTab) {
diff --git a/components/feature/search/src/main/AndroidManifest.xml b/components/feature/search/src/main/AndroidManifest.xml
index eac0d4df6cf..e2ccfb4ee0a 100644
--- a/components/feature/search/src/main/AndroidManifest.xml
+++ b/components/feature/search/src/main/AndroidManifest.xml
@@ -1,11 +1,4 @@
-
-
-
-
+
diff --git a/components/feature/search/src/main/java/mozilla/components/feature/search/widget/AppSearchWidgetProvider.kt b/components/feature/search/src/main/java/mozilla/components/feature/search/widget/AppSearchWidgetProvider.kt
index 0e518df259a..b0a3be263a2 100644
--- a/components/feature/search/src/main/java/mozilla/components/feature/search/widget/AppSearchWidgetProvider.kt
+++ b/components/feature/search/src/main/java/mozilla/components/feature/search/widget/AppSearchWidgetProvider.kt
@@ -26,8 +26,8 @@ import mozilla.components.feature.search.widget.BaseVoiceSearchActivity.Companio
import mozilla.components.support.utils.PendingIntentUtils
/**
- * It contains all the Gui and behaviour for AppWidgetProvider.
- * Needs to be extended in client app.
+ * An abstract [AppWidgetProvider] that implements core behaviour needed to support a Search Widget
+ * on the launcher.
*/
abstract class AppSearchWidgetProvider : AppWidgetProvider() {
diff --git a/components/feature/search/src/main/java/mozilla/components/feature/search/widget/BaseVoiceSearchActivity.kt b/components/feature/search/src/main/java/mozilla/components/feature/search/widget/BaseVoiceSearchActivity.kt
index 5701180243d..077b38e49ea 100644
--- a/components/feature/search/src/main/java/mozilla/components/feature/search/widget/BaseVoiceSearchActivity.kt
+++ b/components/feature/search/src/main/java/mozilla/components/feature/search/widget/BaseVoiceSearchActivity.kt
@@ -5,9 +5,11 @@
package mozilla.components.feature.search.widget
import android.app.Activity
+import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.speech.RecognizerIntent
+import android.util.Log
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
@@ -26,8 +28,7 @@ abstract class BaseVoiceSearchActivity : AppCompatActivity() {
*/
private var previousIntent: Intent? = null
- @VisibleForTesting
- private var activityResultLauncher: ActivityResultLauncher? = null
+ private var activityResultLauncher: ActivityResultLauncher = getActivityResultLauncher()
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
@@ -36,12 +37,6 @@ abstract class BaseVoiceSearchActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- activityResultLauncher = getActivityResultLauncher()
- if (Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH).resolveActivity(packageManager) == null) {
- finish()
- return
- }
-
// Retrieve the previous intent from the saved state
previousIntent = savedInstanceState?.get(PREVIOUS_INTENT) as Intent?
if (previousIntent.isForSpeechProcessing()) {
@@ -111,7 +106,12 @@ abstract class BaseVoiceSearchActivity : AppCompatActivity() {
)
}
onSpeechRecognitionStarted()
- activityResultLauncher?.launch(intentSpeech)
+ try {
+ activityResultLauncher.launch(intentSpeech)
+ } catch (e: ActivityNotFoundException) {
+ Log.e(TAG, "ActivityNotFoundException " + e.message.toString())
+ finish()
+ }
}
/**
@@ -128,5 +128,6 @@ abstract class BaseVoiceSearchActivity : AppCompatActivity() {
* In [BaseVoiceSearchActivity] activity, used to store if the speech processing should start.
*/
const val SPEECH_PROCESSING = "speech_processing"
+ const val TAG = "BaseVoiceSearchActivity"
}
}
diff --git a/components/lib/crash/src/main/res/values-fr/strings.xml b/components/lib/crash/src/main/res/values-fr/strings.xml
index 99b5534cf2b..87ebf25320a 100644
--- a/components/lib/crash/src/main/res/values-fr/strings.xml
+++ b/components/lib/crash/src/main/res/values-fr/strings.xml
@@ -25,6 +25,9 @@
Envoi du rapport de plantage à %1$s
+
+ Collecte des données de plantage
+
Collecte des données de télémétrie du plantage
diff --git a/components/lib/crash/src/main/res/values-sl/strings.xml b/components/lib/crash/src/main/res/values-sl/strings.xml
index abc8a5fc324..a0a020d1c41 100644
--- a/components/lib/crash/src/main/res/values-sl/strings.xml
+++ b/components/lib/crash/src/main/res/values-sl/strings.xml
@@ -24,6 +24,9 @@
Pošiljanje poročila o sesutju organizaciji %1$s
+
+ Zbiranje podatkov o sesutju
+
Zbiranje telemetričnih podatkov o sesutju
diff --git a/components/tooling/nimbus-gradle-plugin/src/main/groovy/mozilla/components/tooling/nimbus/NimbusGradlePlugin.groovy b/components/tooling/nimbus-gradle-plugin/src/main/groovy/mozilla/components/tooling/nimbus/NimbusGradlePlugin.groovy
index dbe0d81e300..d43002e7ad3 100644
--- a/components/tooling/nimbus-gradle-plugin/src/main/groovy/mozilla/components/tooling/nimbus/NimbusGradlePlugin.groovy
+++ b/components/tooling/nimbus-gradle-plugin/src/main/groovy/mozilla/components/tooling/nimbus/NimbusGradlePlugin.groovy
@@ -171,7 +171,7 @@ class NimbusPlugin implements Plugin {
// a) this plugin is going to live in the AS repo (eventually)
// See https://github.com/mozilla-mobile/android-components/issues/11422 for tying this
// to a version that is specified in buildSrc/src/main/java/Dependencies.kt
- return "93.5.0"
+ return "93.6.0"
}
// Try one or more hosts to download the given file.