Skip to content

Commit

Permalink
Lint odyssey (#17292)
Browse files Browse the repository at this point in the history
* lint: remove never-used edit text selector + related lint ignore

this was slated to be part of CSV/TSV import but it appears it was
never integrated and used in the PR final form, there are zero references
to this drawable in the code base

* lint: remove vestigial lint ignore for integrated resource

the related PR is integrated, the resource is used

* lint: the API project no longer has problems with unknown issue ids

best not to ignore things if we do not have to

* lint: ExportedContentReceiver - widget permission receiver should be internal

it is only used internally and only used in one place

to make it internal you also have to specifically scope the calling intent
to the desired receiver so that it is not an implicit launch

* lint: we export our card content provider on purpose, ignore specific lint

this one has been examined and is on purpose, disable the general lint ignore
for the ExportedContentProvider but specifically ignore this one

* lint: protect our boot broadcast receiver from intent spoofing

* lint: our imports are no longer suspicious

Android.R in particular is suspicious and should only be used fully-qualified

* lint: fix retrieval of themed color, partial fix of RestrictedApi lint

* lint: stop ignoring a pile of lint issues that we no longer trigger

this is not exhaustive these were just some obvious ones I tried

* lint: re-enable ellipses checking, but with prompt to use crowdin for fix

just disabling it was lazy, and a big pile of ellipses crept in
they are easy to fix on crowdin and I did so, we should re-enable this

* refactor: rename jetbrains annotations dep to be unambiguous

how many annotations libraries do we have? lots, so the bare name was confusing

* build(deps): use updated jetbrains annotations in resolutionStrategy

this had gone stale because it was hard-referenced here instead of using libs.versions.toml

Confirmed via `./gradlew :AnkiDroid:dependences`::
- without this, things did not resolve, was mix of "failed", "13" and "23" etc
- before the change, was correctly resolving to 24ish like we were forcing
- after the change, is correctly resolving to 26.0.1 which is our dependabot version / current

* lint: Timber - throwable should be first argument in log call

* lint: timber - incorrect argument count for format string

* lint: timber - incorrect format string type

* lint: timber - use string format instead of concatenation

fixed this by just reducing the wall of text to a one-liner
  • Loading branch information
mikehardy authored Oct 26, 2024
1 parent 17748ef commit e9fe007
Show file tree
Hide file tree
Showing 30 changed files with 88 additions and 136 deletions.
2 changes: 1 addition & 1 deletion AnkiDroid/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ dependencies {
configurations.configureEach {
resolutionStrategy {
// Timber has this as a dependency but they are not up to date. We want to force our version.
force 'org.jetbrains:annotations:24.1.0'
force libs.jetbrains.annotations
}
}
api project(":api")
Expand Down
3 changes: 2 additions & 1 deletion AnkiDroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@
</activity>

<receiver android:name="com.ichi2.widget.WidgetPermissionReceiver"
android:exported="true">
android:exported="false">
<intent-filter>
<action android:name="com.ichi2.widget.UPDATE_WIDGET" />
</intent-filter>
Expand Down Expand Up @@ -661,6 +661,7 @@
android:authorities="${applicationId}.flashcards"
android:enabled="true"
android:exported="true"
tools:ignore="ExportedContentProvider"
>
<meta-data android:name="com.ichi2.anki.provider.spec" android:value="2" />
</provider>
Expand Down
3 changes: 1 addition & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import androidx.annotation.UiThread
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.widget.ThemeUtils
import androidx.appcompat.widget.Toolbar
import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK
Expand Down Expand Up @@ -622,7 +621,7 @@ open class AnkiActivity : AppCompatActivity, SimpleMessageDialogListener, Shortc

/** @see Window.setNavigationBarColor */
fun setNavigationBarColor(@AttrRes attr: Int) {
window.navigationBarColor = ThemeUtils.getThemeAttrColor(this, attr)
window.navigationBarColor = Themes.getColorFromAttr(this, attr)
}

fun closeCollectionAndFinish() {
Expand Down
7 changes: 4 additions & 3 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ import androidx.annotation.AttrRes
import androidx.annotation.IdRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.appcompat.widget.ThemeUtils
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import com.ichi2.async.CollectionLoader
import com.ichi2.compat.CompatV24
import com.ichi2.libanki.Collection
import com.ichi2.themes.Themes
import com.ichi2.utils.increaseHorizontalPaddingOfOverflowMenuIcons
import com.ichi2.utils.tintOverflowMenuIcons
import timber.log.Timber
Expand Down Expand Up @@ -69,7 +69,7 @@ open class AnkiFragment(@LayoutRes layout: Int) : Fragment(layout), AnkiActivity
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().window.statusBarColor = ThemeUtils.getThemeAttrColor(requireContext(), R.attr.appBarColor)
requireActivity().window.statusBarColor = Themes.getColorFromAttr(requireContext(), R.attr.appBarColor)
super.onViewCreated(view, savedInstanceState)
}

Expand Down Expand Up @@ -97,7 +97,8 @@ open class AnkiFragment(@LayoutRes layout: Int) : Fragment(layout), AnkiActivity
protected suspend fun userAcceptsSchemaChange() = ankiActivity.userAcceptsSchemaChange()

fun setNavigationBarColor(@AttrRes attr: Int) {
requireActivity().window.navigationBarColor = ThemeUtils.getThemeAttrColor(requireContext(), attr)
requireActivity().window.navigationBarColor =
Themes.getColorFromAttr(requireContext(), attr)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import androidx.annotation.ColorInt
import androidx.annotation.MainThread
import androidx.annotation.VisibleForTesting
import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.ThemeUtils
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import anki.collection.OpChanges
Expand Down Expand Up @@ -131,6 +130,7 @@ import com.ichi2.libanki.Utils
import com.ichi2.libanki.stripAvRefs
import com.ichi2.libanki.undoableOp
import com.ichi2.libanki.utils.TimeManager
import com.ichi2.themes.Themes
import com.ichi2.ui.CardBrowserSearchView
import com.ichi2.ui.FixedTextView
import com.ichi2.utils.HandlerUtils
Expand Down Expand Up @@ -2173,7 +2173,7 @@ open class CardBrowser :
} else {
android.R.attr.colorBackground
}
return ThemeUtils.getThemeAttrColor(context, colorAttr)
return Themes.getColorFromAttr(context, colorAttr)
}

fun getColumnHeaderText(key: CardBrowserColumn?): String? {
Expand Down
4 changes: 2 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import androidx.annotation.CheckResult
import androidx.annotation.StringRes
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.ThemeUtils
import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider
import androidx.core.view.ViewCompat
Expand Down Expand Up @@ -83,6 +82,7 @@ import com.ichi2.libanki.NotetypeJson
import com.ichi2.libanki.Notetypes
import com.ichi2.libanki.Notetypes.Companion.NOT_FOUND_NOTE_TYPE
import com.ichi2.libanki.exception.ConfirmModSchemaException
import com.ichi2.themes.Themes
import com.ichi2.ui.FixedEditText
import com.ichi2.ui.FixedTextView
import com.ichi2.utils.KotlinCleanup
Expand Down Expand Up @@ -206,7 +206,7 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener {
tags = note.tags,
fillEmpty = true
)
val backgroundColor = ThemeUtils.getThemeAttrColor(this@CardTemplateEditor, R.attr.alternativeBackgroundColor)
val backgroundColor = Themes.getColorFromAttr(this@CardTemplateEditor, R.attr.alternativeBackgroundColor)
val fragment = TemplatePreviewerFragment.newInstance(args, backgroundColor)
supportFragmentManager.commitNow {
replace(R.id.fragment_container, fragment)
Expand Down
4 changes: 2 additions & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/Info.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.ThemeUtils
import com.google.android.material.button.MaterialButton
import com.ichi2.anki.preferences.sharedPrefs
import com.ichi2.anki.snackbar.BaseSnackbarBuilderProvider
import com.ichi2.anki.snackbar.SnackbarBuilder
import com.ichi2.themes.Themes
import com.ichi2.utils.IntentUtil.canOpenIntent
import com.ichi2.utils.IntentUtil.tryOpenIntent
import com.ichi2.utils.VersionUtils.appName
Expand Down Expand Up @@ -102,7 +102,7 @@ class Info : AnkiActivity(), BaseSnackbarBuilderProvider {
val backgroundColor = typedArray.getColor(0, -1)
val textColor = typedArray.getColor(1, -1).toRGBHex()

val anchorTextThemeColor = ThemeUtils.getThemeAttrColor(this, android.R.attr.colorAccent)
val anchorTextThemeColor = Themes.getColorFromAttr(this, android.R.attr.colorAccent)
val anchorTextColor = anchorTextThemeColor.toRGBHex()

webView.setBackgroundColor(backgroundColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ abstract class NavigationDrawerActivity :
drawerLayout.addDrawerListener(drawerToggle)

enablePostShortcut(this)
val intent = Intent("com.ichi2.widget.UPDATE_WIDGET")
val intent = Intent("com.ichi2.widget.UPDATE_WIDGET").setClassName("com.ichi2.widget", "WidgetPermissionReceiver")
this.sendBroadcast(intent)
}

Expand Down
2 changes: 1 addition & 1 deletion AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,7 @@ class NoteEditor : AnkiFragment(R.layout.note_editor), DeckSelectionListener, Su
val photoFile: File? = try {
requireContext().createImageFile()
} catch (e: Exception) {
Timber.w("Error creating the file", e)
Timber.w(e, "Error creating the file")
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,7 @@ class SharedDecksDownloadFragment : Fragment(R.layout.fragment_shared_decks_down

// Return if mDownloadId does not match with the ID of the completed download.
if (downloadId != intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0)) {
Timber.w(
"Download ID did not match with the ID of the completed download. " +
"Download completion related to some other download might have been received. " +
"Deck download might still be going on, when it completes then the method would be called again."
)
Timber.w("Download id did not match expected id. Ignoring this download completion")
return false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class CardMediaPlayer : Closeable {
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
Timber.w("retry audio failed", e)
Timber.w(e, "retry audio failed")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ class TgzPackageExtract(private val context: Context) {
companion object {
fun throwIfInsufficientSpace(context: Context, requiredMinSpace: Long, availableSpace: Long) {
if (requiredMinSpace > availableSpace) {
Timber.w("Not enough space, need %d, available %d", Formatter.formatFileSize(context, requiredMinSpace), Formatter.formatFileSize(context, availableSpace))
Timber.w("Not enough space, need %s, available %s", Formatter.formatFileSize(context, requiredMinSpace), Formatter.formatFileSize(context, availableSpace))
throw InsufficientSpaceException(requiredMinSpace, availableSpace, context)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_
val photoFile: File? = try {
requireContext().createImageFile()
} catch (e: Exception) {
Timber.w("Error creating the file", e)
Timber.w(e, "Error creating the file")
return
}

Expand Down Expand Up @@ -497,7 +497,7 @@ class MultimediaImageFragment : MultimediaFragment(R.layout.fragment_multimedia_
Timber.w(error, "cropImage threw an error")
// condition can be removed if #12768 get fixed by Canhub
if (error is CropException.Cancellation) {
Timber.i("CropException caught, seemingly nothing to do ", error)
Timber.i(error, "CropException caught, seemingly nothing to do ")
} else {
showErrorDialog(resources.getString(R.string.activity_result_unexpected))
CrashReportService.sendExceptionReport(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package com.ichi2.anki.multimediacard.activity

import android.R
import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
Expand All @@ -44,7 +43,7 @@ class PickStringDialogFragment : DialogFragment() {
builder.setTitle(title)
val adapter = ArrayAdapter(
requireActivity(),
R.layout.simple_list_item_1,
android.R.layout.simple_list_item_1,
possibleChoices!!
)
builder.setAdapter(adapter, listener)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ open class PageChromeClient : WebChromeClient() {
cancelable(false)
}
} catch (e: WindowManager.BadTokenException) {
Timber.w("onJsConfirm", e)
Timber.w(e, "onJsConfirm")
return false // unhandled - shown in WebView
}
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.widget.ThemeUtils
import androidx.fragment.app.Fragment
import com.ichi2.anki.R
import com.ichi2.anki.SingleFragmentActivity
import com.ichi2.anki.utils.navBarNeedsScrim
import com.ichi2.themes.Themes
import kotlin.reflect.KClass
import kotlin.reflect.jvm.jvmName

Expand All @@ -39,7 +39,7 @@ class CardViewerActivity : SingleFragmentActivity() {
// use the screen background color if the nav bar doesn't need a scrim when using a
// transparent background. e.g. when navigation gestures are enabled
if (!navBarNeedsScrim) {
window.navigationBarColor = ThemeUtils.getThemeAttrColor(this, R.attr.alternativeBackgroundColor)
window.navigationBarColor = Themes.getColorFromAttr(this, R.attr.alternativeBackgroundColor)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*/
package com.ichi2.anki.previewer

import android.R
import android.content.Context
import com.google.android.material.color.MaterialColors
import com.ichi2.anki.AnkiDroidApp
Expand Down Expand Up @@ -50,20 +49,20 @@ fun stdHtml(
val colors = if (!nightMode) {
val canvasColor = MaterialColors.getColor(
context,
R.attr.colorBackground,
R.color.white
android.R.attr.colorBackground,
android.R.color.white
).toRGBHex()
val fgColor =
MaterialColors.getColor(context, R.attr.textColor, R.color.black).toRGBHex()
MaterialColors.getColor(context, android.R.attr.textColor, android.R.color.black).toRGBHex()
":root { --canvas: $canvasColor ; --fg: $fgColor; }"
} else {
val canvasColor = MaterialColors.getColor(
context,
R.attr.colorBackground,
R.color.black
android.R.attr.colorBackground,
android.R.color.black
).toRGBHex()
val fgColor =
MaterialColors.getColor(context, R.attr.textColor, R.color.white).toRGBHex()
MaterialColors.getColor(context, android.R.attr.textColor, android.R.color.white).toRGBHex()
":root[class*=night-mode] { --canvas: $canvasColor; --fg: $fgColor; }"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ enum class AnswerButtons {
}

fun getTextColors(ctx: Context): IntArray {
return Themes.getColorFromAttr(
return Themes.getColorsFromAttrs(
ctx,
intArrayOf(
R.attr.againButtonTextColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import java.util.Calendar
class BootService : BroadcastReceiver() {
private var failedToShowNotifications = false
override fun onReceive(context: Context, intent: Intent) {
if (!intent.action.equals("android.intent.action.BOOT_COMPLETED")) {
Timber.w("BootService - unexpected action received, ignoring: %s", intent.action)
return
}
if (sWasRun) {
Timber.d("BootService - Already run")
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class DeckAdapter(private val layoutInflater: LayoutInflater, context: Context)
inner class DeckFilter(private val top: DeckNode) : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val out = top.filterAndFlatten(constraint)
Timber.i("deck filter: %d", out.size, constraint)
Timber.i("deck filter: %d (%s)", out.size, constraint)
return FilterResults().also {
it.values = out
it.count = out.size
Expand Down
2 changes: 1 addition & 1 deletion AnkiDroid/src/main/java/com/ichi2/compat/CompatV24.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ open class CompatV24 : CompatV23() {
val uLocale = ULocale(locale.language, locale.country, locale.variant)
Locale(uLocale.language, uLocale.country, uLocale.variant)
} catch (e: Exception) {
Timber.w("Failed to normalize locale %s", locale, e)
Timber.w(e, "Failed to normalize locale %s", locale)
locale
}
}
Expand Down
22 changes: 8 additions & 14 deletions AnkiDroid/src/main/java/com/ichi2/themes/Themes.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ import android.content.SharedPreferences
import android.content.res.Configuration
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import androidx.annotation.AttrRes
import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.WindowInsetsControllerCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.google.android.material.color.MaterialColors
import com.ichi2.anki.AnkiDroidApp
Expand Down Expand Up @@ -115,21 +113,17 @@ object Themes {

@JvmStatic // tests failed when removing, maybe try later
@ColorInt
fun getColorFromAttr(context: Context, attrs: IntArray): IntArray {
val ta = context.obtainStyledAttributes(attrs)
for (i in attrs.indices) {
attrs[i] = ta.getColor(i, context.getColor(R.color.white))
}
ta.recycle()
return attrs
fun getColorFromAttr(context: Context, attr: Int): Int {
return MaterialColors.getColor(context, attr, 0)
}

/**
* @return required color depending on the theme from the given attribute
*/
@JvmStatic // tests failed when removing, maybe try later
@ColorInt
fun Fragment.getColorFromAttr(@AttrRes attribute: Int): Int {
return MaterialColors.getColor(requireContext(), attribute, 0)
fun getColorsFromAttrs(context: Context, attrs: IntArray): IntArray {
for (i in attrs.indices) {
attrs[i] = getColorFromAttr(context, attrs[i])
}
return attrs
}

/**
Expand Down
2 changes: 1 addition & 1 deletion AnkiDroid/src/main/java/com/ichi2/utils/SyncStatus.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ enum class SyncStatus {
} catch (_: BackendNetworkException) {
NO_CHANGES
} catch (e: Exception) {
Timber.d("error obtaining sync status: collection likely closed", e)
Timber.d(e, "error obtaining sync status: collection likely closed")
ERROR
}
}
Expand Down
Loading

0 comments on commit e9fe007

Please sign in to comment.