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.