From bab0f9d95bc3d0435db77101e32c5d3085a904fb Mon Sep 17 00:00:00 2001 From: Sawyer Blatz Date: Fri, 10 Jul 2020 11:27:28 -0700 Subject: [PATCH 1/8] No issue: Update AC version --- .../java/org/mozilla/fenix/HomeActivity.kt | 26 ++++++++++++++++--- buildSrc/src/main/java/AndroidComponents.kt | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index e0ef1c075..0f44a8581 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -45,6 +45,8 @@ import mozilla.components.feature.search.SearchAdapter import mozilla.components.service.fxa.sync.SyncReason import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.ktx.android.arch.lifecycle.addObservers +import mozilla.components.support.ktx.android.content.call +import mozilla.components.support.ktx.android.content.email import mozilla.components.support.ktx.android.content.share import mozilla.components.support.ktx.kotlin.isUrl import mozilla.components.support.ktx.kotlin.toNormalizedUrl @@ -294,10 +296,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { EngineView::class.java.name -> components.core.engine.createView(context, attrs).apply { selectionActionDelegate = DefaultSelectionActionDelegate( getSearchAdapter(components.core.store), - resources = context.resources - ) { - share(it) - } + resources = context.resources, + shareTextClicked = { share(it) }, + emailTextClicked = { email(it) }, + callTextClicked = { call(it) }, + actionSorter = ::actionSorter + ) }.asView() TabsTray::class.java.name -> { val layout = LinearLayoutManager(context).apply { @@ -313,6 +317,20 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { else -> super.onCreateView(parent, name, context, attrs) } + private fun actionSorter(actions: Array) : Array { + val order = hashMapOf() + + order["org.mozilla.geckoview.COPY"] = 0 + order["CUSTOM_CONTEXT_MENU_SEARCH"] = 1 + order["org.mozilla.geckoview.SELECT_ALL"] = 2 + order["CUSTOM_CONTEXT_MENU_SHARE"] = 3 + + return actions.sortedBy { actionName -> + // Sort the actions in our preferred order, putting "other" actions unsorted at the end + order[actionName] ?: actions.size + }.toTypedArray() + } + final override fun onBackPressed() { supportFragmentManager.primaryNavigationFragment?.childFragmentManager?.fragments?.forEach { if (it is UserInteractionHandler && it.onBackPressed()) { diff --git a/buildSrc/src/main/java/AndroidComponents.kt b/buildSrc/src/main/java/AndroidComponents.kt index 670302c5a..6c5312277 100644 --- a/buildSrc/src/main/java/AndroidComponents.kt +++ b/buildSrc/src/main/java/AndroidComponents.kt @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ object AndroidComponents { - const val VERSION = "50.0.20200709130100" + const val VERSION = "50.0.20200710130140" } From 5d9fdd6266c340b125feaf5c9dfba11aef2c984c Mon Sep 17 00:00:00 2001 From: Sawyer Blatz Date: Fri, 10 Jul 2020 14:00:15 -0700 Subject: [PATCH 2/8] Update app/src/main/java/org/mozilla/fenix/HomeActivity.kt Co-authored-by: Tiger Oakes --- app/src/main/java/org/mozilla/fenix/HomeActivity.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 0f44a8581..c35e906ed 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -317,7 +317,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { else -> super.onCreateView(parent, name, context, attrs) } - private fun actionSorter(actions: Array) : Array { + @Suppress("MagicNumber") + // Defining the positions as constants doesn't seem super useful here. + private fun actionSorter(actions: Array): Array { val order = hashMapOf() order["org.mozilla.geckoview.COPY"] = 0 From 1202b15b17298d26674c999b0e74db4fc41cb614 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Fri, 10 Jul 2020 15:09:32 -0700 Subject: [PATCH 3/8] No issue: move autosignRelease... to local.properties section of README. --- README.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6e879b08a..ad6224826 100644 --- a/README.md +++ b/README.md @@ -123,10 +123,7 @@ If you want to run **performance tests/benchmarks** in automation or locally: For additional context on these recommendations, see [the perf build variant analysis](https://docs.google.com/document/d/1aW-m0HYncTDDiRz_2x6EjcYkjBpL9SHhhYix13Vil30/edit#). -Before you can install any release variants including `forPerformanceTest`, **you will need to sign them.** To do this automatically in local development, you can add the following to `/local.properties`: -```sh -autosignReleaseWithDebugKey -``` +Before you can install any release variants including `forPerformanceTest`, **you will need to sign them:** see [Automatically signing release builds](#automatically-sign-release-builds) for details. ## Pre-push hooks To reduce review turn-around time, we'd like all pushes to run tests locally. We'd @@ -164,8 +161,19 @@ Steps to downgrade Java Version on Mac with Brew: 7. Verify java-version by running ```java -version``` ## local.properties helpers -There are multiple helper flags available via `local.properties` that will help speed up local development workflow -when working across multiple layers of the dependency stack - specifically, with android-components, geckoview or application-services. +You can speed up local development by setting a few helper flags available in `local.properties`. Some flags will make it easy to +work across multiple layers of the dependency stack - specifically, with android-components, geckoview or application-services. + +### Automatically sign release builds +To sign your release builds with your debug key automatically, add the following to `/local.properties`: + +```sh +autosignReleaseWithDebugKey +``` + +With this line, release build variants will automatically be signed with your debug key (like debug builds), allowing them to be built and installed directly through Android Studio or the command line. + +This is helpful when you're building release variants frequently, for example to test feature flags and or do performance analyses. ### Auto-publication workflow for android-components and application-services If you're making changes to these projects and want to test them in Fenix, auto-publication workflow is the fastest, most reliable From 7319f77114f5bdedcfb0288af7c91cb54a38d318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Naz=C4=B1m=20Can=20Alt=C4=B1nova?= Date: Fri, 3 Jul 2020 16:47:18 +0200 Subject: [PATCH 4/8] Add profiler markers for HomeActivity.load and DefaultTabTrayController.onNewTabTapped --- app/src/main/java/org/mozilla/fenix/HomeActivity.kt | 7 +++++++ .../java/org/mozilla/fenix/tabtray/TabTrayController.kt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index c35e906ed..2112a3f3b 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -522,6 +522,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { engine: SearchEngine?, forceSearch: Boolean ) { + val startTime = components.core.engine.profiler?.getProfilerTime() val mode = browsingModeManager.mode val loadUrlUseCase = if (newTab) { @@ -549,6 +550,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { } else { searchUseCase.invoke(searchTermOrURL) } + + if (components.core.engine.profiler?.isProfilerActive() == true) { + // Wrapping the `addMarker` method with `isProfilerActive` even though it's no-op when + // profiler is not active. That way, `text` argument will not create a string builder all the time. + components.core.engine.profiler?.addMarker("HomeActivity.load", startTime, "newTab: $newTab") + } } override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt index 72718208c..27ac903cd 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayController.kt @@ -38,9 +38,11 @@ class DefaultTabTrayController( private val registerCollectionStorageObserver: () -> Unit ) : TabTrayController { override fun onNewTabTapped(private: Boolean) { + val startTime = activity.components.core.engine.profiler?.getProfilerTime() activity.browsingModeManager.mode = BrowsingMode.fromBoolean(private) navController.navigate(TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true)) dismissTabTray() + activity.components.core.engine.profiler?.addMarker("DefaultTabTrayController.onNewTabTapped", startTime) } override fun onTabTrayDismissed() { From 9fa241fbb063542423dbfe806b942404b4357efc Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Fri, 10 Jul 2020 16:17:02 -0700 Subject: [PATCH 5/8] No issue - post: mock profiler object in DefaultTabTrayControllerTest. Without this line, the tests fail when running the full suite (but not this test in isolation, for some reason). --- .../org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt index 503a316eb..a352a925b 100644 --- a/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabtray/DefaultTabTrayControllerTest.kt @@ -61,6 +61,7 @@ class DefaultTabTrayControllerTest { every { activity.components.core.sessionManager } returns sessionManager every { activity.components.core.tabCollectionStorage } returns tabCollectionStorage + every { activity.components.core.engine.profiler } returns mockk(relaxed = true) every { sessionManager.sessionsOfType(private = true) } returns listOf(session).asSequence() every { sessionManager.sessionsOfType(private = false) } returns listOf(nonPrivateSession).asSequence() every { sessionManager.createSessionSnapshot(any()) } returns SessionManager.Snapshot.Item( From 0add94e35336d87a8e122d00b3d8a3291b6f900e Mon Sep 17 00:00:00 2001 From: ekager Date: Fri, 10 Jul 2020 19:00:53 -0400 Subject: [PATCH 6/8] For #11324 - Adds trash icon to swipe to delete --- .../mozilla/fenix/browser/BrowserFragment.kt | 5 -- .../mozilla/fenix/tabtray/TabsTouchHelper.kt | 76 ++++++++++++++++++- .../main/res/drawable/tab_tray_background.xml | 8 ++ app/src/main/res/values/attrs.xml | 7 +- app/src/main/res/values/colors.xml | 6 +- 5 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/drawable/tab_tray_background.xml diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index c0ae508b4..ed9b83c58 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -275,9 +275,4 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { ) + ContextMenuCandidate.createOpenInExternalAppCandidate(requireContext(), contextMenuCandidateAppLinksUseCases) } - - companion object { - private const val SHARED_TRANSITION_MS = 200L - private const val TAB_ITEM_TRANSITION_NAME = "tab_item" - } } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabsTouchHelper.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabsTouchHelper.kt index b1d47985f..903b699c9 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabsTouchHelper.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabsTouchHelper.kt @@ -4,14 +4,86 @@ package org.mozilla.fenix.tabtray +import android.graphics.Canvas +import android.graphics.drawable.Drawable +import androidx.appcompat.content.res.AppCompatResources import androidx.recyclerview.widget.ItemTouchHelper +import androidx.recyclerview.widget.RecyclerView import mozilla.components.browser.tabstray.TabTouchCallback import mozilla.components.concept.tabstray.TabsTray import mozilla.components.support.base.observer.Observable +import mozilla.components.support.ktx.android.content.getColorFromAttr +import mozilla.components.support.ktx.android.content.getDrawableWithTint +import mozilla.components.support.ktx.android.util.dpToPx +import org.mozilla.fenix.R +import org.mozilla.fenix.home.sessioncontrol.SwipeToDeleteCallback class TabsTouchHelper(observable: Observable) : ItemTouchHelper(object : TabTouchCallback(observable) { - override fun alphaForItemSwipe(dX: Float, distanceToAlphaMin: Int): Float { - return 1f - 2f * Math.abs(dX) / distanceToAlphaMin + override fun onChildDraw( + c: Canvas, + recyclerView: RecyclerView, + viewHolder: RecyclerView.ViewHolder, + dX: Float, + dY: Float, + actionState: Int, + isCurrentlyActive: Boolean + ) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) + val icon = recyclerView.context.getDrawableWithTint( + R.drawable.ic_delete, + recyclerView.context.getColorFromAttr(R.attr.destructive) + )!! + val background = AppCompatResources.getDrawable( + recyclerView.context, + R.drawable.tab_tray_background + )!! + val itemView = viewHolder.itemView + val iconLeft: Int + val iconRight: Int + val margin = + SwipeToDeleteCallback.MARGIN.dpToPx(recyclerView.context.resources.displayMetrics) + val iconWidth = icon.intrinsicWidth + val iconHeight = icon.intrinsicHeight + val cellHeight = itemView.bottom - itemView.top + val iconTop = itemView.top + (cellHeight - iconHeight) / 2 + val iconBottom = iconTop + iconHeight + + when { + dX > 0 -> { // Swiping to the right + iconLeft = itemView.left + margin + iconRight = itemView.left + margin + iconWidth + background.setBounds( + itemView.left, itemView.top, + (itemView.left + dX).toInt() + SwipeToDeleteCallback.BACKGROUND_CORNER_OFFSET, + itemView.bottom + ) + icon.setBounds(iconLeft, iconTop, iconRight, iconBottom) + draw(background, icon, c) + } + dX < 0 -> { // Swiping to the left + iconLeft = itemView.right - margin - iconWidth + iconRight = itemView.right - margin + background.setBounds( + (itemView.right + dX).toInt() - SwipeToDeleteCallback.BACKGROUND_CORNER_OFFSET, + itemView.top, itemView.right, itemView.bottom + ) + icon.setBounds(iconLeft, iconTop, iconRight, iconBottom) + draw(background, icon, c) + } + else -> { // View not swiped + background.setBounds(0, 0, 0, 0) + icon.setBounds(0, 0, 0, 0) + } + } + } + + private fun draw( + background: Drawable, + icon: Drawable, + c: Canvas + ) { + background.draw(c) + icon.draw(c) } }) diff --git a/app/src/main/res/drawable/tab_tray_background.xml b/app/src/main/res/drawable/tab_tray_background.xml new file mode 100644 index 000000000..33f7b152b --- /dev/null +++ b/app/src/main/res/drawable/tab_tray_background.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 305e19826..881f04879 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -54,14 +54,15 @@ - - - + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 2efbf79d8..21854871f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -76,7 +76,7 @@ @color/ink_80 @color/dark_grey_05 @color/light_grey_10 - @color/violet_70_12a + #E5DFF4 @color/light_grey_10 @color/light_grey_30 #ffffff @@ -136,7 +136,7 @@ @color/light_grey_05 @color/light_grey_60 @color/dark_grey_80 - @color/violet_50_32a + #412E69 @color/dark_grey_50 @color/dark_grey_10 #9059FF @@ -190,7 +190,7 @@ @color/light_grey_05 @color/light_grey_60 @color/ink_90 - @color/violet_50_32a + #422875 @color/ink_50 @color/dark_grey_10 #9059FF From c265a7089ad40c81b8c3cace50a5d2ab3e05417d Mon Sep 17 00:00:00 2001 From: Tiger Oakes Date: Fri, 10 Jul 2020 17:21:10 -0700 Subject: [PATCH 7/8] Fix Robolectric tests SDK version (#12464) --- app/src/test/resources/robolectric.properties | 1 + 1 file changed, 1 insertion(+) create mode 100644 app/src/test/resources/robolectric.properties diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties new file mode 100644 index 000000000..89a6c8b4c --- /dev/null +++ b/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +sdk=28 \ No newline at end of file From 31248b835c03611c194822d070d899ccf495bb1b Mon Sep 17 00:00:00 2001 From: Grisha Kruglov Date: Fri, 10 Jul 2020 17:41:45 -0700 Subject: [PATCH 8/8] Synced Tabs: make sure to stop 'loading' when we encounter an error --- app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt index 1f2fd9a91..ba3db15fb 100644 --- a/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt +++ b/app/src/main/java/org/mozilla/fenix/sync/SyncedTabsLayout.kt @@ -34,6 +34,9 @@ class SyncedTabsLayout @JvmOverloads constructor( } override fun onError(error: SyncedTabsView.ErrorType) { + // We may still be displaying a "loading" spinner, hide it. + stopLoading() + val stringResId = when (error) { SyncedTabsView.ErrorType.MULTIPLE_DEVICES_UNAVAILABLE -> R.string.synced_tabs_connect_another_device SyncedTabsView.ErrorType.SYNC_ENGINE_UNAVAILABLE -> R.string.synced_tabs_enable_tab_syncing