diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml new file mode 100644 index 000000000..5074c39c0 --- /dev/null +++ b/.github/workflows/android-build.yml @@ -0,0 +1,101 @@ +name: Android build +on: + push: + branches: + - fork + pull_request: + branches: + - fork + schedule: + - cron: '0 12 * * *' # Every day at 12 PM UTC +jobs: + run-build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Build forkRelease variant of app + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: assembleForkRelease -PversionName="$(git describe --tags HEAD)" + run-testDebug: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Run tests + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: testDebug + run-detekt: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Run detekt + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: detekt + - name: Archive detekt results + uses: actions/upload-artifact@v2 + with: + name: detekt report + path: build/reports/detekt.html + run-ktlint: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Run ktlint + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: ktlint + run-lintDebug: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - name: Setup Java + uses: actions/setup-java@v1 + with: + java-version: 11 + - name: Run lintDebug + uses: eskatos/gradle-command-action@v1 + with: + wrapper-cache-enabled: true + dependencies-cache-enabled: true + configuration-cache-enabled: true + arguments: lintDebug + - name: Archive lint results + uses: actions/upload-artifact@v2 + with: + name: lintDebug report + path: app/build/reports/lint-results-debug.html diff --git a/README.md b/README.md index 048d5f34b..d1f29df1a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# Iceweasel Mobile! [![Build Status](https://travis-ci.org/fork-maintainers/iceweasel.svg?branch=fork)](https://travis-ci.org/fork-maintainers/iceweasel) +# Iceweasel Mobile! [![Build Status](https://travis-ci.org/fork-maintainers/iceweasel.svg?branch=fork)](https://travis-ci.org/fork-maintainers/iceweasel) ![Android build](https://github.com/fork-maintainers/iceweasel/workflows/Android%20build/badge.svg) + Definitely not brought to you by Mozilla! Iceweasel Mobile is a web browser for Android, based on [Mozilla's Fenix version of Firefox](https://github.com/mozilla-mobile/fenix/), [GeckoView](https://mozilla.github.io/geckoview/) and [Mozilla Android Components](https://mozac.org/). diff --git a/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java b/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java index 3dc60634f..24371f8f8 100644 --- a/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java +++ b/app/src/main/java/com/google/firebase/messaging/RemoteMessage.java @@ -20,6 +20,25 @@ import java.util.Map; public class RemoteMessage implements Parcelable { + protected RemoteMessage(Parcel in) + { + } + + public static final Creator CREATOR = new Creator() + { + @Override + public RemoteMessage createFromParcel(Parcel in) + { + return new RemoteMessage(in); + } + + @Override + public RemoteMessage[] newArray(int size) + { + return new RemoteMessage[size]; + } + }; + public int describeContents() { return 0; } diff --git a/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt b/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt index b50a6f03a..7df9b1522 100644 --- a/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt +++ b/app/src/main/java/mozilla/components/lib/push/firebase/AbstractFirebasePushService.kt @@ -9,21 +9,26 @@ import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import mozilla.components.concept.push.PushService -abstract class AbstractFirebasePushService() : FirebaseMessagingService(), PushService { +abstract class AbstractFirebasePushService : FirebaseMessagingService(), PushService { override fun start(context: Context) { + // no-op } override fun onNewToken(newToken: String) { + // no-op } override fun onMessageReceived(remoteMessage: RemoteMessage?) { + // no-op } final override fun stop() { + // no-op } override fun deleteToken() { + // no-op } override fun isServiceAvailable(context: Context): Boolean { diff --git a/app/src/main/java/network/novak/fenix/components/PagedAddonCollectionProvider.kt b/app/src/main/java/network/novak/fenix/components/PagedAddonCollectionProvider.kt index 03d5c5053..9fab092f6 100644 --- a/app/src/main/java/network/novak/fenix/components/PagedAddonCollectionProvider.kt +++ b/app/src/main/java/network/novak/fenix/components/PagedAddonCollectionProvider.kt @@ -16,7 +16,6 @@ import mozilla.components.concept.fetch.Request import mozilla.components.concept.fetch.isSuccess import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonsProvider -import mozilla.components.feature.addons.amo.AddonCollectionProvider import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.kotlin.sanitizeURL import mozilla.components.support.ktx.util.readAndDeserialize @@ -359,4 +358,3 @@ internal fun JSONArray.concat(other: JSONArray) { put(length(), other.getJSONObject(index)) } } - diff --git a/app/src/main/java/network/novak/fenix/components/PagedAddonInstallationDialogFragment.kt b/app/src/main/java/network/novak/fenix/components/PagedAddonInstallationDialogFragment.kt index 63316ce68..91e935437 100644 --- a/app/src/main/java/network/novak/fenix/components/PagedAddonInstallationDialogFragment.kt +++ b/app/src/main/java/network/novak/fenix/components/PagedAddonInstallationDialogFragment.kt @@ -34,12 +34,10 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.R -import mozilla.components.feature.addons.amo.AddonCollectionProvider import mozilla.components.feature.addons.ui.translatedName import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.android.content.appName import mozilla.components.support.ktx.android.content.res.resolveAttribute -import network.novak.fenix.components.PagedAddonCollectionProvider import java.io.IOException @VisibleForTesting internal const val KEY_INSTALLED_ADDON = "KEY_ADDON" @@ -65,7 +63,7 @@ class PagedAddonInstallationDialogFragment : AppCompatDialogFragment() { var onConfirmButtonClicked: ((Addon, Boolean) -> Unit)? = null /** - * Reference to the application's [AddonCollectionProvider] to fetch add-on icons. + * Reference to the application's [PagedAddonCollectionProvider] to fetch add-on icons. */ var addonCollectionProvider: PagedAddonCollectionProvider? = null diff --git a/app/src/main/java/network/novak/fenix/components/PagedAddonsManagerAdapter.kt b/app/src/main/java/network/novak/fenix/components/PagedAddonsManagerAdapter.kt index 5d6e68e7c..f1e1847f0 100644 --- a/app/src/main/java/network/novak/fenix/components/PagedAddonsManagerAdapter.kt +++ b/app/src/main/java/network/novak/fenix/components/PagedAddonsManagerAdapter.kt @@ -29,7 +29,6 @@ import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Job import kotlinx.coroutines.launch import mozilla.components.feature.addons.Addon -import mozilla.components.feature.addons.AddonsProvider import mozilla.components.feature.addons.R import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate import mozilla.components.feature.addons.ui.CustomViewHolder @@ -40,7 +39,6 @@ import mozilla.components.feature.addons.ui.translatedName import mozilla.components.feature.addons.ui.translatedSummary import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.android.content.res.resolveAttribute -import network.novak.fenix.components.PagedAddonCollectionProvider import java.io.IOException import java.text.NumberFormat import java.util.Locale @@ -429,4 +427,3 @@ private fun Addon.inDisabledSection() = isInstalled() && isSupported() && !isEna internal fun getFormattedAmount(amount: Int): String { return NumberFormat.getNumberInstance(Locale.getDefault()).format(amount) } - diff --git a/app/src/main/java/org/mozilla/fenix/Config.kt b/app/src/main/java/org/mozilla/fenix/Config.kt index b97518c01..40bd95ac5 100644 --- a/app/src/main/java/org/mozilla/fenix/Config.kt +++ b/app/src/main/java/org/mozilla/fenix/Config.kt @@ -56,12 +56,12 @@ enum class ReleaseChannel { */ val isFenix: Boolean get() = !isFennec - + /** * Is this a rebranded fork? */ val isFork: Boolean - get() = when (this) { + get() = when (this) { ForkDebug -> true ForkRelease -> true else -> false diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index 1dbc87d2a..d8430356c 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -34,11 +34,10 @@ object FeatureFlags { /** * Enables wait til first contentful paint */ - val waitUntilPaintToDraw = true + const val waitUntilPaintToDraw = true /** * Enables downloads with external download managers. */ - val externalDownloadManager = true - + const val externalDownloadManager = true } diff --git a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt index a28e8de94..deffc9123 100644 --- a/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/addons/AddonsManagementFragment.kt @@ -6,7 +6,12 @@ package org.mozilla.fenix.addons import android.content.Context import android.os.Bundle -import android.view.* +import android.view.Gravity +import android.view.LayoutInflater +import android.view.Menu +import android.view.MenuInflater +import android.view.View +import android.view.ViewGroup import android.view.accessibility.AccessibilityEvent import android.view.inputmethod.EditorInfo import androidx.appcompat.widget.SearchView @@ -16,9 +21,12 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_add_ons_management.* -import kotlinx.android.synthetic.main.fragment_add_ons_management.view.* -import kotlinx.android.synthetic.main.overlay_add_on_progress.view.* +import kotlinx.android.synthetic.main.fragment_add_ons_management.addonProgressOverlay +import kotlinx.android.synthetic.main.fragment_add_ons_management.view.add_ons_empty_message +import kotlinx.android.synthetic.main.fragment_add_ons_management.view.add_ons_list +import kotlinx.android.synthetic.main.fragment_add_ons_management.view.add_ons_progress_bar +import kotlinx.android.synthetic.main.overlay_add_on_progress.view.add_ons_overlay_text +import kotlinx.android.synthetic.main.overlay_add_on_progress.view.cancel_button import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch @@ -26,8 +34,8 @@ import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.ui.PermissionsDialogFragment import mozilla.components.feature.addons.ui.translatedName -import network.novak.fenix.components.PagedAddonsManagerAdapter import network.novak.fenix.components.PagedAddonInstallationDialogFragment +import network.novak.fenix.components.PagedAddonsManagerAdapter import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.components @@ -42,7 +50,7 @@ import java.util.concurrent.CancellationException /** * Fragment use for managing add-ons. */ -@Suppress("TooManyFunctions") +@Suppress("LargeClass", "TooManyFunctions") class AddonsManagementFragment : Fragment(R.layout.fragment_add_ons_management) { /** diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt index e8ae3b7dc..af3b18942 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Components.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt @@ -82,7 +82,6 @@ class Components(private val context: Context) { ) } - val appStartupTelemetry by lazy { AppStartupTelemetry(analytics.metrics) } @Suppress("MagicNumber") diff --git a/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt b/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt index e1779b9dd..43784b44d 100644 --- a/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/ReviewPromptController.kt @@ -7,8 +7,6 @@ package org.mozilla.fenix.components import android.app.Activity import android.content.Context import androidx.annotation.VisibleForTesting -import kotlinx.coroutines.Dispatchers.Main -import kotlinx.coroutines.withContext import org.mozilla.fenix.utils.Settings /** diff --git a/app/src/main/java/org/mozilla/fenix/components/topsheet/TopSheetBehavior.kt b/app/src/main/java/org/mozilla/fenix/components/topsheet/TopSheetBehavior.kt index 0b107d83a..5d70b18f2 100644 --- a/app/src/main/java/org/mozilla/fenix/components/topsheet/TopSheetBehavior.kt +++ b/app/src/main/java/org/mozilla/fenix/components/topsheet/TopSheetBehavior.kt @@ -1,3 +1,25 @@ +/* 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/. */ + +/* Added the Mozilla Public License above to avoid failing detekt rule */ + +/* +* Copyright (C) 2015 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + package org.mozilla.fenix.components.topsheet import android.animation.ValueAnimator @@ -6,7 +28,12 @@ import android.os.Parcel import android.os.Parcelable import android.util.AttributeSet import android.util.TypedValue -import android.view.* +import android.view.AbsSavedState +import android.view.MotionEvent +import android.view.VelocityTracker +import android.view.View +import android.view.ViewConfiguration +import android.view.ViewGroup import androidx.annotation.IntDef import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.NestedScrollingChild @@ -19,47 +46,31 @@ import com.google.android.material.shape.ShapeAppearanceModel import java.lang.ref.WeakReference import kotlin.math.abs -/* -* Copyright (C) 2015 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ /** +/** * An interaction behavior plugin for a child view of [CoordinatorLayout] to make it work as * a top sheet. */ +@Suppress("TooManyFunctions", "LargeClass") class TopSheetBehavior /** * Default constructor for inflating TopSheetBehaviors from layout. * * @param context The [Context]. - * @param attrs The [AttributeSet]. + * @param attrs The [AttributeSet]. */(context: Context, attrs: AttributeSet?) : CoordinatorLayout.Behavior(context, attrs) { /** * Callback for monitoring events about top sheets. */ - abstract class TopSheetCallback { + interface TopSheetCallback { /** * Called when the top sheet changes its state. * * @param topSheet The top sheet view. - * @param newState The new state. This will be one of [.STATE_DRAGGING], + * @param newState The new state. This will be one of [.STATE_DRAGGING], * [.STATE_SETTLING], [.STATE_EXPANDED], * [.STATE_COLLAPSED], or [.STATE_HIDDEN]. */ - abstract fun onStateChanged( - topSheet: View, - @State newState: Int - ) + fun onStateChanged(topSheet: View, @State newState: Int) /** * Called when the top sheet is being dragged. @@ -67,13 +78,9 @@ class TopSheetBehavior * @param topSheet The top sheet view. * @param slideOffset The new offset of this top sheet within its range, from 0 to 1 * when it is moving upward, and from 0 to -1 when it moving downward. - * @param isOpening detect showing + * @param isOpening detect showing */ - abstract fun onSlide( - topSheet: View, - slideOffset: Float, - isOpening: Boolean? - ) + fun onSlide(topSheet: View, slideOffset: Float, isOpening: Boolean?) } /** @@ -148,7 +155,7 @@ class TopSheetBehavior a.hasValue(R.styleable.BottomSheetBehavior_Layout_shapeAppearance) createMaterialShapeDrawable(context, attrs!!) createShapeValueAnimator() - peekHeight = context.resources.displayMetrics.heightPixels * 3 / 4 + peekHeight = context.resources.displayMetrics.heightPixels * PEEK_HEIGHT_RATIO isHideable = a.getBoolean( R.styleable.BottomSheetBehavior_Layout_behavior_hideable, false @@ -188,6 +195,7 @@ class TopSheetBehavior } } + @Suppress("ComplexMethod") override fun onLayoutChild( parent: CoordinatorLayout, child: V, @@ -238,6 +246,7 @@ class TopSheetBehavior return true } + @Suppress("ComplexMethod", "ReturnCount") override fun onInterceptTouchEvent( parent: CoordinatorLayout, child: V, @@ -306,7 +315,7 @@ class TopSheetBehavior return true } if (mViewDragHelper != null) { - //no crash + // no crash mViewDragHelper!!.processTouchEvent(event) // Record the velocity if (action == MotionEvent.ACTION_DOWN) { @@ -318,13 +327,12 @@ class TopSheetBehavior mVelocityTracker!!.addMovement(event) // The ViewDragHelper tries to capture only the top-most View. We have to explicitly tell it // to capture the top sheet in case it is not captured and the touch slop is passed. - if (action == MotionEvent.ACTION_MOVE && !mIgnoreEvents) { - if (abs(mInitialY - event.y) > mViewDragHelper!!.touchSlop) { - mViewDragHelper!!.captureChildView( - child, - event.getPointerId(event.actionIndex) - ) - } + if (action == MotionEvent.ACTION_MOVE && !mIgnoreEvents && + abs(mInitialY - event.y) > mViewDragHelper!!.touchSlop) { + mViewDragHelper!!.captureChildView( + child, + event.getPointerId(event.actionIndex) + ) } } return !mIgnoreEvents @@ -343,8 +351,12 @@ class TopSheetBehavior } override fun onNestedPreScroll( - coordinatorLayout: CoordinatorLayout, child: V, target: View, dx: Int, - dy: Int, consumed: IntArray + coordinatorLayout: CoordinatorLayout, + child: V, + target: View, + dx: Int, + dy: Int, + consumed: IntArray ) { val scrollingChild = mNestedScrollingChildRef!!.get() if (target !== scrollingChild) { @@ -430,8 +442,11 @@ class TopSheetBehavior } override fun onNestedPreFling( - coordinatorLayout: CoordinatorLayout, child: V, target: View, - velocityX: Float, velocityY: Float + coordinatorLayout: CoordinatorLayout, + child: V, + target: View, + velocityX: Float, + velocityY: Float ): Boolean { return target === mNestedScrollingChildRef!!.get() && (mState != STATE_EXPANDED || @@ -466,9 +481,9 @@ class TopSheetBehavior } if (mViewRef == null) { // The view is not laid out yet; modify mState and let onLayoutChild handle it later - if (state == STATE_COLLAPSED || state == STATE_EXPANDED || - isHideable && state == STATE_HIDDEN - ) { + val stateCondition = state == STATE_COLLAPSED || state == STATE_EXPANDED || + isHideable && state == STATE_HIDDEN + if (stateCondition) { mState = state } return @@ -509,6 +524,7 @@ class TopSheetBehavior } } + @Suppress("NestedBlockDepth") private fun updateDrawableForTargetState(@BottomSheetBehavior.State state: Int) { if (state == BottomSheetBehavior.STATE_SETTLING) { // Special case: we want to know which state we're settling to, so wait for another call. @@ -567,11 +583,12 @@ class TopSheetBehavior private val yVelocity: Float get() { - mVelocityTracker!!.computeCurrentVelocity(1000, mMaximumVelocity) + mVelocityTracker!!.computeCurrentVelocity(VELOCITY_UNITS, mMaximumVelocity) return mVelocityTracker!!.getYVelocity(mActivePointerId) } private val mDragCallback: ViewDragHelper.Callback = object : ViewDragHelper.Callback() { + @Suppress("ReturnCount") override fun tryCaptureView( child: View, pointerId: Int @@ -709,7 +726,6 @@ class TopSheetBehavior } } - private fun dispatchOnSlide(top: Int) { val topSheet: View? = mViewRef!!.get() if (topSheet != null && mCallback != null) { @@ -742,7 +758,6 @@ class TopSheetBehavior setStateInternal(mTargetState) } } - } private class SavedState(superState: Parcelable?, @State val state: Int) : @@ -806,5 +821,7 @@ class TopSheetBehavior private const val CORNER_ANIMATION_DURATION = 500 private val DEF_STYLE_RES = R.style.Widget_Design_BottomSheet_Modal + private const val PEEK_HEIGHT_RATIO = 3 / 4 + private const val VELOCITY_UNITS = 1000 } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt index 5dc464418..6725adfe7 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlAdapter.kt @@ -23,7 +23,18 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.NoCollectionsMessageVie import org.mozilla.fenix.home.sessioncontrol.viewholders.PrivateBrowsingDescriptionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.TabInCollectionViewHolder import org.mozilla.fenix.home.sessioncontrol.viewholders.TopSitePagerViewHolder -import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.* +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingAutomaticSignInViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingFinishViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingHeaderViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingManualSignInViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivacyNoticeViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingPrivateBrowsingViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingSectionHeaderViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTabsTrayLayoutViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingThemePickerViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingToolbarPositionPickerViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingTrackingProtectionViewHolder +import org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding.OnboardingWhatsNewViewHolder import org.mozilla.fenix.home.tips.ButtonTipViewHolder import mozilla.components.feature.tab.collections.Tab as ComponentTab diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingTabsTrayLayoutViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingTabsTrayLayoutViewHolder.kt index 0892e7f53..29777a1d2 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingTabsTrayLayoutViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/viewholders/onboarding/OnboardingTabsTrayLayoutViewHolder.kt @@ -8,9 +8,6 @@ import android.view.View import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.onboarding_tabs_tray_layout.view.* import org.mozilla.fenix.R -import org.mozilla.fenix.components.metrics.Event -import org.mozilla.fenix.components.metrics.Event.OnboardingTrackingProtection.Setting -import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.settings import org.mozilla.fenix.onboarding.OnboardingRadioButton import org.mozilla.fenix.utils.view.addToRadioGroup @@ -44,7 +41,6 @@ class OnboardingTabsTrayLayoutViewHolder(view: View) : RecyclerView.ViewHolder(v reverseTabOrderInTabsTray = !enabled useNewTabFloatingActionButton = !enabled placeNewTabFloatingActionButtonAtTop = false - } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt index 581b5171f..e1c6e3c25 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/CustomizationFragment.kt @@ -10,7 +10,11 @@ import android.os.Build.VERSION.SDK_INT import android.os.Bundle import androidx.appcompat.app.AppCompatDelegate import androidx.core.content.edit -import androidx.preference.* +import androidx.preference.EditTextPreference +import androidx.preference.Preference +import androidx.preference.PreferenceCategory +import androidx.preference.PreferenceFragmentCompat +import androidx.preference.SwitchPreference import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event @@ -25,7 +29,7 @@ import org.mozilla.fenix.utils.view.addToRadioGroup * Lets the user customize the UI. */ -@Suppress("TooManyFunctions") +@Suppress("LargeClass", "TooManyFunctions") class CustomizationFragment : PreferenceFragmentCompat() { private lateinit var radioLightTheme: RadioButtonPreference private lateinit var radioDarkTheme: RadioButtonPreference @@ -154,7 +158,8 @@ class CustomizationFragment : PreferenceFragmentCompat() { onPreferenceChangeListener = SharedPreferenceUpdater() } - val reverseOrderPref = requirePreference(R.string.pref_key_tabs_tray_reverse_tab_order).apply { + val reverseOrderPref = requirePreference( + R.string.pref_key_tabs_tray_reverse_tab_order).apply { if (context.settings().enableCompactTabs) { isChecked = false isEnabled = false @@ -210,8 +215,6 @@ class CustomizationFragment : PreferenceFragmentCompat() { true } } - - } private fun setupHomeCategory() { @@ -240,7 +243,6 @@ class CustomizationFragment : PreferenceFragmentCompat() { isChecked = context.settings().isSwipeToolbarToSwitchTabsEnabled onPreferenceChangeListener = SharedPreferenceUpdater() } - } private fun setupAddonsCustomizationCategory() { @@ -253,6 +255,5 @@ class CustomizationFragment : PreferenceFragmentCompat() { text = context.settings().customAddonsCollection onPreferenceChangeListener = SharedPreferenceUpdater() } - } } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index e8507d767..113a98c27 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -164,6 +164,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler } } + @Suppress("LongMethod") @OptIn(ExperimentalCoroutinesApi::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt index 6fe097bb9..c0cd9f1f5 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayView.kt @@ -148,7 +148,7 @@ class TabTrayView( if (!isTabsTrayFullScreenMode) { if (useTopTabsTray) { (behavior as TopSheetBehavior).setTopSheetCallback(object : - TopSheetBehavior.TopSheetCallback() { + TopSheetBehavior.TopSheetCallback { override fun onSlide(topSheet: View, slideOffset: Float, isOpening: Boolean?) { if (interactor.onModeRequested() is Mode.Normal && useFab) { if (slideOffset >= SLIDE_OFFSET) { @@ -262,9 +262,9 @@ class TabTrayView( concatAdapter.addAdapter(syncedTabsController.adapter) } - if (hasAccessibilityEnabled) { + if (hasAccessibilityEnabled) { tabsAdapter.notifyItemRangeChanged(0, tabs.size) - } + } if (!hasLoaded) { hasLoaded = true @@ -321,7 +321,7 @@ class TabTrayView( private fun gridViewNumberOfCols(context: Context): Int { val displayMetrics = context.resources.displayMetrics val dpWidth = displayMetrics.widthPixels / displayMetrics.density - val columnWidthDp = 190 + val columnWidthDp = COLUMN_WIDTH_DP val columnCount = (dpWidth / columnWidthDp).toInt() return if (columnCount >= 2) columnCount else 2 } @@ -359,41 +359,51 @@ class TabTrayView( } fun updateTabsTrayLayout() { + if (enableCompactTabs) { + setupCompactTabsTrayLayout() + } else { + setupRegularTabsTrayLayout() + } + } + + private fun setupCompactTabsTrayLayout() { view.tabsTray.apply { - if (enableCompactTabs) { - val gridLayoutManager = GridLayoutManager(container.context, gridViewNumberOfCols(container.context)) - if (useTopTabsTray) { - gridLayoutManager.reverseLayout = true - } - gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { - override fun getSpanSize(position: Int): Int { - val numTabs = tabsAdapter.itemCount - return if (position < numTabs) { - 1 - } else { - gridViewNumberOfCols(container.context) - } + val gridLayoutManager = GridLayoutManager(container.context, gridViewNumberOfCols(container.context)) + if (useTopTabsTray) { + gridLayoutManager.reverseLayout = true + } + gridLayoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { + override fun getSpanSize(position: Int): Int { + val numTabs = tabsAdapter.itemCount + return if (position < numTabs) { + 1 + } else { + gridViewNumberOfCols(container.context) } } + } - layoutManager = gridLayoutManager - } else { - val linearLayoutManager = LinearLayoutManager(container.context) - if (useTopTabsTray) { - if (!reverseTabOrderInTabsTray) { - linearLayoutManager.reverseLayout = true - } else { - linearLayoutManager.stackFromEnd = true - } + layoutManager = gridLayoutManager + } + } + + private fun setupRegularTabsTrayLayout() { + view.tabsTray.apply { + val linearLayoutManager = LinearLayoutManager(container.context) + if (useTopTabsTray) { + if (!reverseTabOrderInTabsTray) { + linearLayoutManager.reverseLayout = true } else { - if (reverseTabOrderInTabsTray) { - linearLayoutManager.reverseLayout = true - linearLayoutManager.stackFromEnd = true - } + linearLayoutManager.stackFromEnd = true + } + } else { + if (reverseTabOrderInTabsTray) { + linearLayoutManager.reverseLayout = true + linearLayoutManager.stackFromEnd = true } - - layoutManager = linearLayoutManager } + + layoutManager = linearLayoutManager } } @@ -729,6 +739,7 @@ class TabTrayView( private const val NORMAL_TOP_MARGIN = 8 private const val NORMAL_BOTTOM_MARGIN = 8 private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F + private const val COLUMN_WIDTH_DP = 190 } } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt index 7b71b339d..eaf06e929 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayViewHolder.kt @@ -30,7 +30,14 @@ import mozilla.components.support.images.loader.ImageLoader import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController -import org.mozilla.fenix.ext.* +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.getMediaStateForSession +import org.mozilla.fenix.ext.increaseTapArea +import org.mozilla.fenix.ext.removeAndDisable +import org.mozilla.fenix.ext.removeTouchDelegate +import org.mozilla.fenix.ext.settings +import org.mozilla.fenix.ext.showAndEnable +import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.utils.Do import kotlin.math.max diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index b059c5485..8b996cb67 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -15,7 +15,6 @@ import android.view.accessibility.AccessibilityManager import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting.PRIVATE import androidx.lifecycle.LifecycleOwner -import androidx.preference.EditTextPreference import mozilla.components.feature.sitepermissions.SitePermissionsRules import mozilla.components.feature.sitepermissions.SitePermissionsRules.Action import mozilla.components.feature.sitepermissions.SitePermissionsRules.AutoplayAction