Skip to content
This repository has been archived by the owner on Jun 17, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into bug1853058
Browse files Browse the repository at this point in the history
  • Loading branch information
ohall-m authored Mar 13, 2024
2 parents f49b570 + 245362f commit 9afd6dd
Show file tree
Hide file tree
Showing 16 changed files with 325 additions and 596 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class TranslationsMiddleware(
isEngineSupported = isEngineSupported,
),
)
logger.info("Success requesting engine support.")
logger.info("Success requesting engine support. isEngineSupported: $isEngineSupported")
continuation.resume(isEngineSupported)
},

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.net.Uri
import android.util.Log
import androidx.browser.customtabs.CustomTabsIntent
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiSelector
import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.availableSearchEngines
import org.junit.Assert
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.Constants.TAG
import org.mozilla.fenix.helpers.TestHelper.mDevice
import org.mozilla.fenix.utils.IntentUtils
import java.time.LocalDate
Expand All @@ -33,6 +35,7 @@ object DataGenerationHelper {
customMenuItemLabel: String = "",
customActionButtonDescription: String = "",
): Intent {
Log.i(TAG, "createCustomTabIntent: Trying to create custom tab intent with url: $pageUrl")
val appContext = InstrumentationRegistry.getInstrumentation()
.targetContext
.applicationContext
Expand All @@ -48,33 +51,44 @@ object DataGenerationHelper {
)
.build()
customTabsIntent.intent.data = Uri.parse(pageUrl)
Log.i(TAG, "createCustomTabIntent: Created custom tab intent with url: $pageUrl")
return customTabsIntent.intent
}

private fun createTestBitmap(): Bitmap {
Log.i(TAG, "createTestBitmap: Trying to create a test bitmap")
val bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
canvas.drawColor(Color.GREEN)
Log.i(TAG, "createTestBitmap: Created a test bitmap")
return bitmap
}

fun getStringResource(id: Int, argument: String = TestHelper.appName) = TestHelper.appContext.resources.getString(id, argument)

private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
fun generateRandomString(stringLength: Int) =
(1..stringLength)
.map { kotlin.random.Random.nextInt(0, charPool.size) }
.map(charPool::get)
.joinToString("")
fun generateRandomString(stringLength: Int): String {
Log.i(TAG, "generateRandomString: Trying to generate a random string with $stringLength characters")
val randomString =
(1..stringLength)
.map { kotlin.random.Random.nextInt(0, charPool.size) }
.map(charPool::get)
.joinToString("")
Log.i(TAG, "generateRandomString: Generated random string: $randomString")

return randomString
}

/**
* Creates clipboard data.
*/
fun setTextToClipBoard(context: Context, message: String) {
Log.i(TAG, "setTextToClipBoard: Trying to set clipboard text to: $message")
val clipBoard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clipData = ClipData.newPlainText("label", message)

clipBoard.setPrimaryClip(clipData)
Log.i(TAG, "setTextToClipBoard: Clipboard text was set to: $message")
}

/**
Expand All @@ -88,6 +102,7 @@ object DataGenerationHelper {
* @return A string representing the current date and time in the specified format.
*/
fun getSponsoredFxSuggestPlaceHolder(): String {
Log.i(TAG, "getSponsoredFxSuggestPlaceHolder: Trying to get the sponsored search suggestion placeholder")
val currentDate = LocalDate.now()
val currentTime = LocalTime.now()

Expand All @@ -96,13 +111,16 @@ object DataGenerationHelper {
val currentYear = currentDate.year.toString()
val currentHour = currentTime.hour.toString().padStart(2, '0')

Log.i(TAG, "getSponsoredFxSuggestPlaceHolder: Got: ${currentYear + currentMonth + currentDay + currentHour} as the sponsored search suggestion placeholder")

return currentYear + currentMonth + currentDay + currentHour
}

/**
* Returns sponsored shortcut title based on the index.
*/
fun getSponsoredShortcutTitle(position: Int): String {
Log.i(TAG, "getSponsoredShortcutTitle: Trying to get the title of the sponsored shortcut at position: ${position - 1}")
val sponsoredShortcut = mDevice.findObject(
UiSelector()
.resourceId("${TestHelper.packageName}:id/top_site_item")
Expand All @@ -111,7 +129,7 @@ object DataGenerationHelper {
UiSelector()
.resourceId("${TestHelper.packageName}:id/top_site_title"),
).text

Log.i(TAG, "getSponsoredShortcutTitle: The sponsored shortcut at position: ${position - 1} has title: $sponsoredShortcut")
return sponsoredShortcut
}

Expand All @@ -120,8 +138,10 @@ object DataGenerationHelper {
* For en-us it will return the 6 engines selected by default: Google, Bing, DuckDuckGo, Amazon, Ebay, Wikipedia.
*/
fun getRegionSearchEnginesList(): List<SearchEngine> {
Log.i(TAG, "getRegionSearchEnginesList: Trying to get the search engines based on the region of the user")
val searchEnginesList = appContext.components.core.store.state.search.regionSearchEngines
Assert.assertTrue("Search engines list returned nothing", searchEnginesList.isNotEmpty())
Assert.assertTrue("$TAG: Search engines list returned nothing", searchEnginesList.isNotEmpty())
Log.i(TAG, "getRegionSearchEnginesList: Got $searchEnginesList based on the region of the user")
return searchEnginesList
}

Expand All @@ -130,8 +150,10 @@ object DataGenerationHelper {
* For en-us it will return the 2 engines: Reddit, Youtube.
*/
fun getAvailableSearchEngines(): List<SearchEngine> {
Log.i(TAG, "getAvailableSearchEngines: Trying to get the alternative search engines based on the region of the user")
val searchEnginesList = TestHelper.appContext.components.core.store.state.search.availableSearchEngines
Assert.assertTrue("Search engines list returned nothing", searchEnginesList.isNotEmpty())
Assert.assertTrue("$TAG: Search engines list returned nothing", searchEnginesList.isNotEmpty())
Log.i(TAG, "getAvailableSearchEngines: Got $searchEnginesList based on the region of the user")
return searchEnginesList
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class PwaRobot {
fun verifyCustomTabToolbarIsNotDisplayed() = assertUIObjectExists(itemWithResId("$packageName:id/toolbar"), exists = false)
fun verifyPwaActivityInCurrentTask() {
assertTrue("$TAG: The latest activity of the application is not used for custom tabs or PWAs", isExternalAppBrowserActivityInCurrentTask())
Log.i(TAG, "verifyPwaActivityInCurrentTask: Verified that the latest activity of the application is used for custom tabs or PWAs")
}

class Transition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import mozilla.components.feature.addons.ui.translateName
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.DownloadDialogLayoutBinding
import org.mozilla.fenix.databinding.FragmentAddOnInternalSettingsBinding
import org.mozilla.fenix.ext.showToolbar

Expand All @@ -22,8 +21,6 @@ import org.mozilla.fenix.ext.showToolbar
class AddonInternalSettingsFragment : AddonPopupBaseFragment() {

private val args by navArgs<AddonInternalSettingsFragmentArgs>()
private var _binding: FragmentAddOnInternalSettingsBinding? = null
internal val binding get() = _binding!!

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -34,17 +31,9 @@ class AddonInternalSettingsFragment : AddonPopupBaseFragment() {
return inflater.inflate(R.layout.fragment_add_on_internal_settings, container, false)
}

override fun getSnackBarContainer(): ViewGroup {
return binding.dynamicSnackbarContainer
}

override fun getDownloadDialogLayoutBinding(): DownloadDialogLayoutBinding {
return binding.viewDynamicDownloadDialog
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentAddOnInternalSettingsBinding.bind(view)
val binding = FragmentAddOnInternalSettingsBinding.bind(view)
args.addon.installedState?.optionsPageUrl?.let {
engineSession?.let { engineSession ->
binding.addonSettingsEngineView.render(engineSession)
Expand All @@ -59,9 +48,4 @@ class AddonInternalSettingsFragment : AddonPopupBaseFragment() {
showToolbar(title = args.addon.translateName(it))
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,21 @@
package org.mozilla.fenix.addons

import android.os.Bundle
import android.os.Environment
import android.view.View
import android.view.ViewGroup
import androidx.annotation.VisibleForTesting
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.snackbar.Snackbar
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.CustomTabListAction
import mozilla.components.browser.state.state.CustomTabSessionState
import mozilla.components.browser.state.state.EngineState
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.concept.engine.window.WindowRequest
import mozilla.components.concept.fetch.Response
import mozilla.components.feature.downloads.DownloadsFeature
import mozilla.components.feature.prompts.PromptFeature
import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.browser.DownloadDialogUtils
import org.mozilla.fenix.components.DownloadStyling
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.databinding.DownloadDialogLayoutBinding
import org.mozilla.fenix.downloads.DynamicDownloadDialog
import org.mozilla.fenix.ext.requireComponents

/**
Expand All @@ -40,22 +28,19 @@ import org.mozilla.fenix.ext.requireComponents
*/
abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, UserInteractionHandler {
private val promptsFeature = ViewBoundFeatureWrapper<PromptFeature>()
private val downloadsFeature = ViewBoundFeatureWrapper<DownloadsFeature>()

internal var session: SessionState? = null
protected var session: SessionState? = null
protected var engineSession: EngineSession? = null
private var canGoBack: Boolean = false

@Suppress("DEPRECATION")
// https://github.com/mozilla-mobile/fenix/issues/19920
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val store = requireComponents.core.store
val safeContext = requireContext()
session?.let {
promptsFeature.set(
feature = PromptFeature(
fragment = this,
store = store,
store = requireComponents.core.store,
customTabId = it.id,
fragmentManager = parentFragmentManager,
fileUploadsDirCleaner = requireComponents.core.fileUploadsDirCleaner,
Expand All @@ -67,52 +52,6 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
owner = this,
view = view,
)

downloadsFeature.set(
DownloadsFeature(
safeContext,
store = store,
useCases = requireComponents.useCases.downloadUseCases,
fragmentManager = parentFragmentManager,
tabId = it.id,
downloadManager = requireComponents.downloadManager,
promptsStyling = DownloadStyling.createPrompt(safeContext),
onNeedToRequestPermissions = { permissions ->
requestPermissions(permissions, REQUEST_CODE_DOWNLOAD_PERMISSIONS)
},
),
owner = this,
view = view,
)

downloadsFeature.get()?.onDownloadStopped = { downloadState, _, downloadJobStatus ->
val onCannotOpenFile: (DownloadState) -> Unit = {
FenixSnackbar.make(
view = getSnackBarContainer(),
duration = Snackbar.LENGTH_SHORT,
isDisplayedWithBrowserToolbar = true,
).setText(DynamicDownloadDialog.getCannotOpenFileErrorMessage(requireContext(), it))
.show()
}
DownloadDialogUtils.handleOnDownloadFinished(
context = requireContext(),
downloadState = downloadState,
downloadJobStatus = downloadJobStatus,
currentTab = it,
onCannotOpenFile = onCannotOpenFile,
onFinishedDialogShown = {
DynamicDownloadDialog(
context = requireContext(),
downloadState = downloadState,
didFail = downloadJobStatus == DownloadState.Status.FAILED,
tryAgain = downloadsFeature.get()!!::tryAgain,
onCannotOpenFile = onCannotOpenFile,
binding = getDownloadDialogLayoutBinding(),
toolbarHeight = 0,
) {}.show()
},
)
}
}
}

Expand All @@ -134,44 +73,6 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
engineSession?.unregister(this)
}

override fun onExternalResource(
url: String,
fileName: String?,
contentLength: Long?,
contentType: String?,
cookie: String?,
userAgent: String?,
isPrivate: Boolean,
skipConfirmation: Boolean,
openInApp: Boolean,
response: Response?,
) {
session?.let { session ->
val fileSize = if (contentLength != null && contentLength < 0) null else contentLength
val download = DownloadState(
url,
fileName,
contentType,
fileSize,
0,
DownloadState.Status.INITIATED,
userAgent,
Environment.DIRECTORY_DOWNLOADS,
private = isPrivate,
skipConfirmation = skipConfirmation,
openInApp = openInApp,
response = response,
)

provideBrowserStore().dispatch(
ContentAction.UpdateDownloadAction(
session.id,
download,
),
)
}
}

override fun onPromptRequest(promptRequest: PromptRequest) {
session?.let { session ->
requireComponents.core.store.dispatch(
Expand Down Expand Up @@ -213,34 +114,17 @@ abstract class AddonPopupBaseFragment : Fragment(), EngineSession.Observer, User
requireComponents.core.store.dispatch(CustomTabListAction.AddCustomTabAction(session as CustomTabSessionState))
}

@VisibleForTesting
internal fun provideBrowserStore() = requireComponents.core.store

final override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray,
) {
val feature = when (requestCode) {
REQUEST_CODE_PROMPT_PERMISSIONS -> promptsFeature.get()
REQUEST_CODE_DOWNLOAD_PERMISSIONS -> downloadsFeature.get()
else -> null
when (requestCode) {
REQUEST_CODE_PROMPT_PERMISSIONS -> promptsFeature.get()?.onPermissionsResult(permissions, grantResults)
}
feature?.onPermissionsResult(permissions, grantResults)
}

/**
* Returns a [ViewGroup] where a SnackBar message should be anchored.
*/
abstract fun getSnackBarContainer(): ViewGroup

/**
* Returns a [DownloadDialogLayoutBinding] to access the download dialog items.
*/
abstract fun getDownloadDialogLayoutBinding(): DownloadDialogLayoutBinding

companion object {
private const val REQUEST_CODE_PROMPT_PERMISSIONS = 1
private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 2
}
}
Loading

0 comments on commit 9afd6dd

Please sign in to comment.